From dc85623c308bc4b4c6c8a7c23d47ef80c950ab21 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 18 Aug 2017 15:13:04 -0700 Subject: [PATCH 001/189] Fix #17069 and #15371 1. `T[K]` now correctly produces `number` when `K extends string, T extends Record`. 2. `T[K]` no longer allows any type to be assigned to it when `T extends object, K extends keyof T`. Previously both of these cases failed in getConstraintOfIndexedAccessType because both bases followed `K`'s base constraint to `string` and then incorrectly produced `any` for types (like `object`) with no string index signature. In (1), this produced an error in checkBinaryLikeExpression`. In (2), this failed to produce an error in `checkTypeRelatedTo`. --- src/compiler/checker.ts | 19 ++++++++++++------- src/compiler/core.ts | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6df6b1f9ce1..ec67df6b80d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5911,7 +5911,14 @@ namespace ts { return transformed; } const baseObjectType = getBaseConstraintOfType(type.objectType); - const baseIndexType = getBaseConstraintOfType(type.indexType); + const keepTypeParameterForMappedType = baseObjectType && getObjectFlags(baseObjectType) & ObjectFlags.Mapped && + type.indexType.flags & TypeFlags.TypeParameter; + const baseIndexType = !keepTypeParameterForMappedType && getBaseConstraintOfType(type.indexType); + if (baseObjectType && baseIndexType === stringType && !getIndexInfoOfType(baseObjectType, 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; } @@ -5961,8 +5968,9 @@ namespace ts { function computeBaseConstraint(t: Type): Type { if (t.flags & TypeFlags.TypeParameter) { const constraint = getConstraintFromTypeParameter(t); - return (t).isThisType ? constraint : - constraint ? getBaseConstraint(constraint) : undefined; + return (t as TypeParameter).isThisType || !constraint ? + constraint : + getBaseConstraint(constraint); } if (t.flags & TypeFlags.UnionOrIntersection) { const types = (t).types; @@ -5990,9 +5998,6 @@ namespace ts { const baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined; } - if (isGenericMappedType(t)) { - return emptyObjectType; - } return t; } } @@ -9289,7 +9294,7 @@ 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 S. + // A is the apparent type of T. const constraint = getConstraintOfType(target); if (constraint) { if (result = isRelatedTo(source, constraint, reportErrors)) { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 8cab1b41155..422df2ead05 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -718,7 +718,7 @@ namespace ts { export function sum, K extends string>(array: T[], prop: K): number { let result = 0; for (const v of array) { - // Note: we need the following type assertion because of GH #17069 + // TODO: Remove the following type assertion once the fix for #17069 is merged result += v[prop] as number; } return result; From ecae295c5a70ebe1be2c13119a818a8bfabfbc1b Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 18 Aug 2017 15:16:24 -0700 Subject: [PATCH 002/189] Test getConstraintOfIndexedAccess fixes and update baselines --- ...ionOperatorWithConstrainedTypeParameter.js | 27 ++++++++ ...eratorWithConstrainedTypeParameter.symbols | 54 +++++++++++++++ ...OperatorWithConstrainedTypeParameter.types | 64 ++++++++++++++++++ ...tiveConstraintOfIndexAccessType.errors.txt | 67 +++++++++++++++++++ ...nonPrimitiveConstraintOfIndexAccessType.js | 67 +++++++++++++++++++ ...ionOperatorWithConstrainedTypeParameter.ts | 11 +++ ...nonPrimitiveConstraintOfIndexAccessType.ts | 32 +++++++++ 7 files changed, 322 insertions(+) create mode 100644 tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.js create mode 100644 tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.symbols create mode 100644 tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.types create mode 100644 tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt create mode 100644 tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.js create mode 100644 tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts create mode 100644 tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts diff --git a/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.js b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.js new file mode 100644 index 00000000000..1366e242182 --- /dev/null +++ b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.js @@ -0,0 +1,27 @@ +//// [additionOperatorWithConstrainedTypeParameter.ts] +// test for #17069 +function sum, K extends string>(n: number, v: T, k: K) { + n = n + v[k]; + n += v[k]; // += should work the same way +} +function realSum, K extends string>(n: number, vs: T[], k: K) { + for (const v of vs) { + n = n + v[k]; + n += v[k]; + } +} + + +//// [additionOperatorWithConstrainedTypeParameter.js] +// test for #17069 +function sum(n, v, k) { + n = n + v[k]; + n += v[k]; // += should work the same way +} +function realSum(n, vs, k) { + for (var _i = 0, vs_1 = vs; _i < vs_1.length; _i++) { + var v = vs_1[_i]; + n = n + v[k]; + n += v[k]; + } +} diff --git a/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.symbols b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.symbols new file mode 100644 index 00000000000..e7055c1e38f --- /dev/null +++ b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.symbols @@ -0,0 +1,54 @@ +=== tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts === +// test for #17069 +function sum, K extends string>(n: number, v: T, k: K) { +>sum : Symbol(sum, Decl(additionOperatorWithConstrainedTypeParameter.ts, 0, 0)) +>T : Symbol(T, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 13)) +>Record : Symbol(Record, Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 41)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 41)) +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 60)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 70)) +>T : Symbol(T, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 13)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 76)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 41)) + + n = n + v[k]; +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 60)) +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 60)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 70)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 76)) + + n += v[k]; // += should work the same way +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 60)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 70)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 76)) +} +function realSum, K extends string>(n: number, vs: T[], k: K) { +>realSum : Symbol(realSum, Decl(additionOperatorWithConstrainedTypeParameter.ts, 4, 1)) +>T : Symbol(T, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 17)) +>Record : Symbol(Record, Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 45)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 45)) +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 64)) +>vs : Symbol(vs, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 74)) +>T : Symbol(T, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 17)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 83)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 45)) + + for (const v of vs) { +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 6, 14)) +>vs : Symbol(vs, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 74)) + + n = n + v[k]; +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 64)) +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 64)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 6, 14)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 83)) + + n += v[k]; +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 64)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 6, 14)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 83)) + } +} + diff --git a/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.types b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.types new file mode 100644 index 00000000000..d52c77a94fd --- /dev/null +++ b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.types @@ -0,0 +1,64 @@ +=== tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts === +// test for #17069 +function sum, K extends string>(n: number, v: T, k: K) { +>sum : , K extends string>(n: number, v: T, k: K) => void +>T : T +>Record : Record +>K : K +>K : K +>n : number +>v : T +>T : T +>k : K +>K : K + + n = n + v[k]; +>n = n + v[k] : number +>n : number +>n + v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K + + n += v[k]; // += should work the same way +>n += v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K +} +function realSum, K extends string>(n: number, vs: T[], k: K) { +>realSum : , K extends string>(n: number, vs: T[], k: K) => void +>T : T +>Record : Record +>K : K +>K : K +>n : number +>vs : T[] +>T : T +>k : K +>K : K + + for (const v of vs) { +>v : T +>vs : T[] + + n = n + v[k]; +>n = n + v[k] : number +>n : number +>n + v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K + + n += v[k]; +>n += v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K + } +} + diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt new file mode 100644 index 00000000000..56781157131 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt @@ -0,0 +1,67 @@ +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(3,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(6,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(9,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(12,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(15,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(18,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(21,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(24,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(27,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(30,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. + Type 'string' is not assignable to type 'number'. + + +==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts (10 errors) ==== + // test for #15371 + function f(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function g(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function h(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function i(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function j(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function k(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function o(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function l(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function m(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function n(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.js b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.js new file mode 100644 index 00000000000..7a24345a94b --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.js @@ -0,0 +1,67 @@ +//// [nonPrimitiveConstraintOfIndexAccessType.ts] +// test for #15371 +function f(s: string, tp: T[P]): void { + tp = s; +} +function g(s: string, tp: T[P]): void { + tp = s; +} +function h(s: string, tp: T[P]): void { + tp = s; +} +function i(s: string, tp: T[P]): void { + tp = s; +} +function j(s: string, tp: T[P]): void { + tp = s; +} +function k(s: string, tp: T[P]): void { + tp = s; +} +function o(s: string, tp: T[P]): void { + tp = s; +} +function l(s: string, tp: T[P]): void { + tp = s; +} +function m(s: string, tp: T[P]): void { + tp = s; +} +function n(s: string, tp: T[P]): void { + tp = s; +} + + +//// [nonPrimitiveConstraintOfIndexAccessType.js] +"use strict"; +// test for #15371 +function f(s, tp) { + tp = s; +} +function g(s, tp) { + tp = s; +} +function h(s, tp) { + tp = s; +} +function i(s, tp) { + tp = s; +} +function j(s, tp) { + tp = s; +} +function k(s, tp) { + tp = s; +} +function o(s, tp) { + tp = s; +} +function l(s, tp) { + tp = s; +} +function m(s, tp) { + tp = s; +} +function n(s, tp) { + tp = s; +} diff --git a/tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts b/tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts new file mode 100644 index 00000000000..2303bb33944 --- /dev/null +++ b/tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts @@ -0,0 +1,11 @@ +// test for #17069 +function sum, K extends string>(n: number, v: T, k: K) { + n = n + v[k]; + n += v[k]; // += should work the same way +} +function realSum, K extends string>(n: number, vs: T[], k: K) { + for (const v of vs) { + n = n + v[k]; + n += v[k]; + } +} diff --git a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts new file mode 100644 index 00000000000..1e852f12f92 --- /dev/null +++ b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts @@ -0,0 +1,32 @@ +// @strict: true +// test for #15371 +function f(s: string, tp: T[P]): void { + tp = s; +} +function g(s: string, tp: T[P]): void { + tp = s; +} +function h(s: string, tp: T[P]): void { + tp = s; +} +function i(s: string, tp: T[P]): void { + tp = s; +} +function j(s: string, tp: T[P]): void { + tp = s; +} +function k(s: string, tp: T[P]): void { + tp = s; +} +function o(s: string, tp: T[P]): void { + tp = s; +} +function l(s: string, tp: T[P]): void { + tp = s; +} +function m(s: string, tp: T[P]): void { + tp = s; +} +function n(s: string, tp: T[P]): void { + tp = s; +} From 04339d2df7c3483bcbc44a92a8e4840274aaef02 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 28 Aug 2017 09:05:56 -0700 Subject: [PATCH 003/189] Disallow T[K] = T[keyof T] where K extends keyof T `K = keyof T` was already correctly disallowed. --- 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 8e34b24cf1b..27b0752f53f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5914,7 +5914,7 @@ namespace ts { const keepTypeParameterForMappedType = baseObjectType && getObjectFlags(baseObjectType) & ObjectFlags.Mapped && type.indexType.flags & TypeFlags.TypeParameter; const baseIndexType = !keepTypeParameterForMappedType && getBaseConstraintOfType(type.indexType); - if (baseObjectType && baseIndexType === stringType && !getIndexInfoOfType(baseObjectType, IndexKind.String)) { + if (baseIndexType === stringType && (!baseObjectType || !getIndexInfoOfType(baseObjectType, IndexKind.String))) { // getIndexedAccessType returns `any` for X[string] where X doesn't have an index signature. // to avoid this, return `undefined`. return undefined; From 20e579847a086119e309906e6811508cf08d7287 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 28 Aug 2017 09:12:14 -0700 Subject: [PATCH 004/189] Test:T[keyof T] =/=> T[K] where K extends keyof T --- .../indexedAccessRelation2.errors.txt | 18 ++++++++++++++++++ .../reference/indexedAccessRelation2.js | 19 +++++++++++++++++++ .../cases/compiler/indexedAccessRelation2.ts | 8 ++++++++ 3 files changed, 45 insertions(+) create mode 100644 tests/baselines/reference/indexedAccessRelation2.errors.txt create mode 100644 tests/baselines/reference/indexedAccessRelation2.js create mode 100644 tests/cases/compiler/indexedAccessRelation2.ts diff --git a/tests/baselines/reference/indexedAccessRelation2.errors.txt b/tests/baselines/reference/indexedAccessRelation2.errors.txt new file mode 100644 index 00000000000..b208e92250f --- /dev/null +++ b/tests/baselines/reference/indexedAccessRelation2.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/indexedAccessRelation2.ts(4,9): error TS2322: Type 'keyof T' is not assignable to type 'K'. +tests/cases/compiler/indexedAccessRelation2.ts(5,9): error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'. + + +==== tests/cases/compiler/indexedAccessRelation2.ts (2 errors) ==== + // Repro from #17166 + function f(obj: T, k: K, value: T[K]): void { + for (let key in obj) { + k = key // error, keyof T =/=> K + ~ +!!! error TS2322: Type 'keyof T' is not assignable to type 'K'. + value = obj[key]; // error, T[keyof T] =/=> T[K] + ~~~~~ +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'. + } + } + + \ No newline at end of file diff --git a/tests/baselines/reference/indexedAccessRelation2.js b/tests/baselines/reference/indexedAccessRelation2.js new file mode 100644 index 00000000000..39b093ef3f7 --- /dev/null +++ b/tests/baselines/reference/indexedAccessRelation2.js @@ -0,0 +1,19 @@ +//// [indexedAccessRelation2.ts] +// Repro from #17166 +function f(obj: T, k: K, value: T[K]): void { + for (let key in obj) { + k = key // error, keyof T =/=> K + value = obj[key]; // error, T[keyof T] =/=> T[K] + } +} + + + +//// [indexedAccessRelation2.js] +// Repro from #17166 +function f(obj, k, value) { + for (var key in obj) { + k = key; // error, keyof T =/=> K + value = obj[key]; // error, T[keyof T] =/=> T[K] + } +} diff --git a/tests/cases/compiler/indexedAccessRelation2.ts b/tests/cases/compiler/indexedAccessRelation2.ts new file mode 100644 index 00000000000..736651099dc --- /dev/null +++ b/tests/cases/compiler/indexedAccessRelation2.ts @@ -0,0 +1,8 @@ +// Repro from #17166 +function f(obj: T, k: K, value: T[K]): void { + for (let key in obj) { + k = key // error, keyof T =/=> K + value = obj[key]; // error, T[keyof T] =/=> T[K] + } +} + From 2f646daf0ab38c10e2149507f2497204f2eb09f9 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 28 Aug 2017 10:53:11 -0700 Subject: [PATCH 005/189] Move lone test case into central test file --- .../indexedAccessRelation2.errors.txt | 18 ----------------- .../reference/indexedAccessRelation2.js | 19 ------------------ .../keyofAndIndexedAccessErrors.errors.txt | 20 +++++++++++++++++-- .../reference/keyofAndIndexedAccessErrors.js | 19 +++++++++++++++++- .../cases/compiler/indexedAccessRelation2.ts | 8 -------- .../keyof/keyofAndIndexedAccessErrors.ts | 11 +++++++++- 6 files changed, 46 insertions(+), 49 deletions(-) delete mode 100644 tests/baselines/reference/indexedAccessRelation2.errors.txt delete mode 100644 tests/baselines/reference/indexedAccessRelation2.js delete mode 100644 tests/cases/compiler/indexedAccessRelation2.ts diff --git a/tests/baselines/reference/indexedAccessRelation2.errors.txt b/tests/baselines/reference/indexedAccessRelation2.errors.txt deleted file mode 100644 index b208e92250f..00000000000 --- a/tests/baselines/reference/indexedAccessRelation2.errors.txt +++ /dev/null @@ -1,18 +0,0 @@ -tests/cases/compiler/indexedAccessRelation2.ts(4,9): error TS2322: Type 'keyof T' is not assignable to type 'K'. -tests/cases/compiler/indexedAccessRelation2.ts(5,9): error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'. - - -==== tests/cases/compiler/indexedAccessRelation2.ts (2 errors) ==== - // Repro from #17166 - function f(obj: T, k: K, value: T[K]): void { - for (let key in obj) { - k = key // error, keyof T =/=> K - ~ -!!! error TS2322: Type 'keyof T' is not assignable to type 'K'. - value = obj[key]; // error, T[keyof T] =/=> T[K] - ~~~~~ -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'. - } - } - - \ No newline at end of file diff --git a/tests/baselines/reference/indexedAccessRelation2.js b/tests/baselines/reference/indexedAccessRelation2.js deleted file mode 100644 index 39b093ef3f7..00000000000 --- a/tests/baselines/reference/indexedAccessRelation2.js +++ /dev/null @@ -1,19 +0,0 @@ -//// [indexedAccessRelation2.ts] -// Repro from #17166 -function f(obj: T, k: K, value: T[K]): void { - for (let key in obj) { - k = key // error, keyof T =/=> K - value = obj[key]; // error, T[keyof T] =/=> T[K] - } -} - - - -//// [indexedAccessRelation2.js] -// Repro from #17166 -function f(obj, k, value) { - for (var key in obj) { - k = key; // error, keyof T =/=> K - value = obj[key]; // error, T[keyof T] =/=> T[K] - } -} diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index 0634c3419e0..2981cb0366d 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -27,9 +27,11 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(76,5): error 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 & U)' is not assignable to type 'keyof (T | U)'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(84,9): error TS2322: Type 'keyof T' is not assignable to type 'K'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(85,9): error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'. -==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (25 errors) ==== +==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (27 errors) ==== class Shape { name: string; width: number; @@ -162,4 +164,18 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error ~~ !!! error TS2322: Type 'keyof (T & U)' is not assignable to type 'keyof (T | U)'. k2 = k1; - } \ No newline at end of file + } + + // Repro from #17166 + function f3(obj: T, k: K, value: T[K]): void { + for (let key in obj) { + k = key // error, keyof T =/=> K + ~ +!!! error TS2322: Type 'keyof T' is not assignable to type 'K'. + value = obj[key]; // error, T[keyof T] =/=> T[K] + ~~~~~ +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'. + } + } + + \ No newline at end of file diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.js b/tests/baselines/reference/keyofAndIndexedAccessErrors.js index 838a3a6a86b..2a1042cf4ee 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.js +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.js @@ -77,7 +77,17 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { o2 = o1; // Error k1 = k2; // Error k2 = k1; -} +} + +// Repro from #17166 +function f3(obj: T, k: K, value: T[K]): void { + for (let key in obj) { + k = key // error, keyof T =/=> K + value = obj[key]; // error, T[keyof T] =/=> T[K] + } +} + + //// [keyofAndIndexedAccessErrors.js] var Shape = /** @class */ (function () { @@ -109,3 +119,10 @@ function f20(k1, k2, o1, o2) { k1 = k2; // Error k2 = k1; } +// Repro from #17166 +function f3(obj, k, value) { + for (var key in obj) { + k = key; // error, keyof T =/=> K + value = obj[key]; // error, T[keyof T] =/=> T[K] + } +} diff --git a/tests/cases/compiler/indexedAccessRelation2.ts b/tests/cases/compiler/indexedAccessRelation2.ts deleted file mode 100644 index 736651099dc..00000000000 --- a/tests/cases/compiler/indexedAccessRelation2.ts +++ /dev/null @@ -1,8 +0,0 @@ -// Repro from #17166 -function f(obj: T, k: K, value: T[K]): void { - for (let key in obj) { - k = key // error, keyof T =/=> K - value = obj[key]; // error, T[keyof T] =/=> T[K] - } -} - diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts index cbbc9a52200..ffc5076831a 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts @@ -76,4 +76,13 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { o2 = o1; // Error k1 = k2; // Error k2 = k1; -} \ No newline at end of file +} + +// Repro from #17166 +function f3(obj: T, k: K, value: T[K]): void { + for (let key in obj) { + k = key // error, keyof T =/=> K + value = obj[key]; // error, T[keyof T] =/=> T[K] + } +} + From 71b7429cb26237e97748c839fa7ded0f422b47d9 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 4 Dec 2017 15:40:09 -0800 Subject: [PATCH 006/189] Update baselines After merging with master, even erroneous tests generate types and symbols baselines --- .../keyofAndIndexedAccessErrors.symbols | 31 ++++ .../keyofAndIndexedAccessErrors.types | 34 ++++ ...imitiveConstraintOfIndexAccessType.symbols | 145 ++++++++++++++++ ...PrimitiveConstraintOfIndexAccessType.types | 156 ++++++++++++++++++ 4 files changed, 366 insertions(+) create mode 100644 tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.symbols create mode 100644 tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.types diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols index 36fb8d2989b..0e97ef793fb 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols @@ -268,3 +268,34 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { >k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 37)) >k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 19)) } + +// Repro from #17166 +function f3(obj: T, k: K, value: T[K]): void { +>f3 : Symbol(f3, Decl(keyofAndIndexedAccessErrors.ts, 78, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) +>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 81, 41)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) +>value : Symbol(value, Decl(keyofAndIndexedAccessErrors.ts, 81, 47)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) + + for (let key in obj) { +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34)) + + k = key // error, keyof T =/=> K +>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 81, 41)) +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12)) + + value = obj[key]; // error, T[keyof T] =/=> T[K] +>value : Symbol(value, Decl(keyofAndIndexedAccessErrors.ts, 81, 47)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34)) +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12)) + } +} + + diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index 4d2e25641d3..f5cc7c093d9 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -299,3 +299,37 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { >k2 : keyof (T & U) >k1 : keyof (T | U) } + +// Repro from #17166 +function f3(obj: T, k: K, value: T[K]): void { +>f3 : (obj: T, k: K, value: T[K]) => void +>T : T +>K : K +>T : T +>obj : T +>T : T +>k : K +>K : K +>value : T[K] +>T : T +>K : K + + for (let key in obj) { +>key : keyof T +>obj : T + + k = key // error, keyof T =/=> K +>k = key : keyof T +>k : K +>key : keyof T + + value = obj[key]; // error, T[keyof T] =/=> T[K] +>value = obj[key] : T[keyof T] +>value : T[K] +>obj[key] : T[keyof T] +>obj : T +>key : keyof T + } +} + + diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.symbols b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.symbols new file mode 100644 index 00000000000..3ada1e3f3d1 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.symbols @@ -0,0 +1,145 @@ +=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts === +// test for #15371 +function f(s: string, tp: T[P]): void { +>f : Symbol(f, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 0, 0)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 28)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 48)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 58)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 28)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 58)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 48)) +} +function g(s: string, tp: T[P]): void { +>g : Symbol(g, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 3, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 26)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 46)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 56)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 26)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 56)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 46)) +} +function h(s: string, tp: T[P]): void { +>h : Symbol(h, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 6, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 31)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 51)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 61)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 31)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 61)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 51)) +} +function i(s: string, tp: T[P]): void { +>i : Symbol(i, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 9, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 26)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 46)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 56)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 26)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 56)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 46)) +} +function j(s: string, tp: T[P]): void { +>j : Symbol(j, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 12, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 27)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 47)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 57)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 27)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 57)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 47)) +} +function k(s: string, tp: T[P]): void { +>k : Symbol(k, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 15, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 28)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 48)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 58)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 28)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 58)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 48)) +} +function o(s: string, tp: T[P]): void { +>o : Symbol(o, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 18, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 28)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 48)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 58)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 28)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 58)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 48)) +} +function l(s: string, tp: T[P]): void { +>l : Symbol(l, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 21, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 24)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 44)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 54)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 24)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 54)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 44)) +} +function m(s: string, tp: T[P]): void { +>m : Symbol(m, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 24, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 11)) +>a : Symbol(a, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 22)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 35)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 55)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 65)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 35)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 65)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 55)) +} +function n(s: string, tp: T[P]): void { +>n : Symbol(n, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 27, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 24)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 45)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 65)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 75)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 45)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 75)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 65)) +} + diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.types b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.types new file mode 100644 index 00000000000..d5e8560d7cf --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.types @@ -0,0 +1,156 @@ +=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts === +// test for #15371 +function f(s: string, tp: T[P]): void { +>f : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function g(s: string, tp: T[P]): void { +>g : (s: string, tp: T[P]) => void +>T : T +>null : null +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function h(s: string, tp: T[P]): void { +>h : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function i(s: string, tp: T[P]): void { +>i : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function j(s: string, tp: T[P]): void { +>j : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function k(s: string, tp: T[P]): void { +>k : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function o(s: string, tp: T[P]): void { +>o : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function l(s: string, tp: T[P]): void { +>l : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function m(s: string, tp: T[P]): void { +>m : (s: string, tp: T[P]) => void +>T : T +>a : number +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function n(s: string, tp: T[P]): void { +>n : (s: string, tp: T[P]) => void +>T : T +>s : string +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} + From 7d1a980ad2db5a3be8fe1cabf5898e5bebf9d6f9 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 13 Dec 2017 16:29:36 -0800 Subject: [PATCH 007/189] First attempt. Basically broken. --- src/compiler/checker.ts | 85 ++++++++++++++++++++++------------------- src/compiler/types.ts | 6 +++ 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c1b57e5def7..d333424dcb3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -334,6 +334,7 @@ namespace ts { const jsObjectLiteralIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false); const globals = createSymbolTable(); + const deferredInferenceCache = createMap(); let ambientModulesCache: Symbol[] | undefined; /** * List of every ambient module with a "*" wildcard. @@ -4867,6 +4868,9 @@ namespace ts { if (getCheckFlags(symbol) & CheckFlags.Instantiated) { return getTypeOfInstantiatedSymbol(symbol); } + if (getCheckFlags(symbol) & CheckFlags.DeferredInferred) { + return inferTargetType((symbol as DeferredTransientSymbol).propertyType, (symbol as DeferredTransientSymbol).mappedType); + } if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) { return getTypeOfVariableOrParameterOrProperty(symbol); } @@ -11224,42 +11228,49 @@ namespace ts { * property is computed by inferring from the source property type to X for the type * variable T[P] (i.e. we treat the type T[P] as the type variable we're inferring for). */ - function inferTypeForHomomorphicMappedType(source: Type, target: MappedType, mappedTypeStack: string[]): Type { - const properties = getPropertiesOfType(source); - let indexInfo = getIndexInfoOfType(source, IndexKind.String); - if (properties.length === 0 && !indexInfo) { - return undefined; + function inferTypeForHomomorphicMappedType(source: Type, target: MappedType): Type { + const key = source.id + "," + target.id; + if (deferredInferenceCache.has(key)) { + return deferredInferenceCache.get(key); } - const typeParameter = getIndexedAccessType((getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target)); - const inference = createInferenceInfo(typeParameter); - const inferences = [inference]; - const templateType = getTemplateTypeFromMappedType(target); - const readonlyMask = target.declaration.readonlyToken ? false : true; - const optionalMask = target.declaration.questionToken ? 0 : SymbolFlags.Optional; - const members = createSymbolTable(); - for (const prop of properties) { - const propType = getTypeOfSymbol(prop); - // If any property contains context sensitive functions that have been skipped, the source type - // is incomplete and we can't infer a meaningful input type. - if (propType.flags & TypeFlags.ContainsAnyFunctionType) { + deferredInferenceCache.set(key, function() { + const properties = getPropertiesOfType(source); + let indexInfo = getIndexInfoOfType(source, IndexKind.String); + if (properties.length === 0 && !indexInfo) { return undefined; } - const checkFlags = readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0; - const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags); - inferredProp.declarations = prop.declarations; - inferredProp.type = inferTargetType(propType); - members.set(prop.escapedName, inferredProp); - } - if (indexInfo) { - indexInfo = createIndexInfo(inferTargetType(indexInfo.type), readonlyMask && indexInfo.isReadonly); - } - return createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfo, undefined); + const readonlyMask = target.declaration.readonlyToken ? false : true; + const optionalMask = target.declaration.questionToken ? 0 : SymbolFlags.Optional; + const members = createSymbolTable(); + for (const prop of properties) { + const propType = getTypeOfSymbol(prop); + // If any property contains context sensitive functions that have been skipped, the source type + // is incomplete and we can't infer a meaningful input type. + if (propType.flags & TypeFlags.ContainsAnyFunctionType) { + return undefined; + } + const checkFlags = CheckFlags.DeferredInferred | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); + const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as DeferredTransientSymbol; + inferredProp.declarations = prop.declarations; + inferredProp.propertyType = propType; // not sure I need this. + inferredProp.mappedType = target; + members.set(prop.escapedName, inferredProp); + } + if (indexInfo) { + // TODO: Defer this too. BARREL OF LAUGHS RIGHT THERE + indexInfo = createIndexInfo(inferTargetType(indexInfo.type, target), readonlyMask && indexInfo.isReadonly); + } + return createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfo, undefined); + }()); + } - function inferTargetType(sourceType: Type): Type { - inference.candidates = undefined; - inferTypes(inferences, sourceType, templateType, 0, mappedTypeStack); - return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : emptyObjectType; - } + function inferTargetType(sourceType: Type, target: MappedType): Type { + const typeParameter = getIndexedAccessType((getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target)); + const templateType = getTemplateTypeFromMappedType(target); + const inference = createInferenceInfo(typeParameter); + inference.candidates = undefined; + inferTypes([inference], sourceType, templateType); + return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : emptyObjectType; } function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean) { @@ -11275,7 +11286,7 @@ namespace ts { return undefined; } - function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0, mappedTypeStack?: string[]) { + function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) { let symbolStack: Symbol[]; let visited: Map; inferFromTypes(originalSource, originalTarget); @@ -11492,13 +11503,7 @@ namespace ts { // such that direct inferences to T get priority over inferences to Partial, for example. const inference = getInferenceInfoForType((constraintType).type); if (inference && !inference.isFixed) { - const key = (source.symbol ? getSymbolId(source.symbol) + "," : "") + getSymbolId(target.symbol); - if (contains(mappedTypeStack, key)) { - return; - } - (mappedTypeStack || (mappedTypeStack = [])).push(key); - const inferredType = inferTypeForHomomorphicMappedType(source, target, mappedTypeStack); - mappedTypeStack.pop(); + const inferredType = inferTypeForHomomorphicMappedType(source, target); if (inferredType) { const savePriority = priority; priority |= InferencePriority.MappedType; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 54f2ebfae42..16f546cecb2 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3217,6 +3217,7 @@ namespace ts { ContainsPrivate = 1 << 8, // Synthetic property with private constituent(s) ContainsStatic = 1 << 9, // Synthetic property with static constituent(s) Late = 1 << 10, // Late-bound symbol for a computed property with a dynamic name + DeferredInferred = 1 << 11, // Deferred inferred property of homomorphic mapped type. It is HILARIOUS. Synthetic = SyntheticProperty | SyntheticMethod } @@ -3226,6 +3227,11 @@ namespace ts { isRestParameter?: boolean; } + export interface DeferredTransientSymbol extends TransientSymbol { + propertyType: Type; + mappedType: MappedType; + } + export const enum InternalSymbolName { Call = "__call", // Call signatures Constructor = "__constructor", // Constructor implementations From 05de0a7da392e5385192f7638adeb249d98e695b Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 14 Dec 2017 13:33:02 -0800 Subject: [PATCH 008/189] Get it working: 1. Actually return the cached result! 2. Unnest worker function. 3. Improve all the names. 4. Pre-set the cache to undefined to avoid loops. (Not sure this is needed, though.) 5. Make the new type internal to avoid baseline changes. 6. Cut off recursion in the printing of recursive deferred mapped types. Note that (6) required introducing a new stack that is exactly like mappedTypeStack. I think the cache may actually be needed here, not in the creation of the deferred type. --- src/compiler/checker.ts | 41 +++++++++++++++---- src/compiler/types.ts | 1 + .../mappedTypeRecursiveInference.types | 4 +- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d333424dcb3..dbc12b1461a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -335,6 +335,7 @@ namespace ts { const globals = createSymbolTable(); const deferredInferenceCache = createMap(); + const deferredMappedTypeInstantiationStack: string[] = []; let ambientModulesCache: Symbol[] | undefined; /** * List of every ambient module with a "*" wildcard. @@ -2867,7 +2868,23 @@ namespace ts { } for (const propertySymbol of properties) { - const propertyType = getTypeOfSymbol(propertySymbol); + let propertyType: Type; + if (getCheckFlags(propertySymbol) & CheckFlags.DeferredInferred) { + const deferred = propertySymbol as DeferredTransientSymbol; + const key = deferred.propertyType.id + "," + (deferred.mappedType.symbol ? deferred.mappedType.symbol.id : ""); + // Temporary solution to recursive printing: zero out repeated types. + if (contains(deferredMappedTypeInstantiationStack, key)) { + // TODO: Could probably be an actual cache that returns {} when it contains undefined. + propertyType = emptyObjectType; + } + else { + deferredMappedTypeInstantiationStack.push(key) + propertyType = getTypeOfSymbol(propertySymbol); + } + } + else { + propertyType = getTypeOfSymbol(propertySymbol); + } const saveEnclosingDeclaration = context.enclosingDeclaration; context.enclosingDeclaration = undefined; const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true); @@ -2894,6 +2911,9 @@ namespace ts { /*initializer*/ undefined); typeElements.push(propertySignature); } + if (getCheckFlags(propertySymbol) & CheckFlags.DeferredInferred) { + deferredMappedTypeInstantiationStack.pop(); + } } return typeElements.length ? typeElements : undefined; } @@ -4869,7 +4889,7 @@ namespace ts { return getTypeOfInstantiatedSymbol(symbol); } if (getCheckFlags(symbol) & CheckFlags.DeferredInferred) { - return inferTargetType((symbol as DeferredTransientSymbol).propertyType, (symbol as DeferredTransientSymbol).mappedType); + return inferDeferredMappedType((symbol as DeferredTransientSymbol).propertyType, (symbol as DeferredTransientSymbol).mappedType); } if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) { return getTypeOfVariableOrParameterOrProperty(symbol); @@ -11233,7 +11253,13 @@ namespace ts { if (deferredInferenceCache.has(key)) { return deferredInferenceCache.get(key); } - deferredInferenceCache.set(key, function() { + deferredInferenceCache.set(key, undefined); + const type = createDeferredMappedType(source, target); + deferredInferenceCache.set(key, type); + return type; + } + + function createDeferredMappedType(source: Type, target: MappedType) { const properties = getPropertiesOfType(source); let indexInfo = getIndexInfoOfType(source, IndexKind.String); if (properties.length === 0 && !indexInfo) { @@ -11257,14 +11283,15 @@ namespace ts { members.set(prop.escapedName, inferredProp); } if (indexInfo) { - // TODO: Defer this too. BARREL OF LAUGHS RIGHT THERE - indexInfo = createIndexInfo(inferTargetType(indexInfo.type, target), readonlyMask && indexInfo.isReadonly); + // TODO: Defer this too. + // (probably the simplest way is to have a special type that defers the creation of (at least) its index info in + // resolveStructuredTypeMembers + indexInfo = createIndexInfo(inferDeferredMappedType(indexInfo.type, target), readonlyMask && indexInfo.isReadonly); } return createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfo, undefined); - }()); } - function inferTargetType(sourceType: Type, target: MappedType): Type { + function inferDeferredMappedType(sourceType: Type, target: MappedType): Type { const typeParameter = getIndexedAccessType((getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target)); const templateType = getTemplateTypeFromMappedType(target); const inference = createInferenceInfo(typeParameter); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 16f546cecb2..dc8c6d71618 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3227,6 +3227,7 @@ namespace ts { isRestParameter?: boolean; } + /* @internal */ export interface DeferredTransientSymbol extends TransientSymbol { propertyType: Type; mappedType: MappedType; diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.types b/tests/baselines/reference/mappedTypeRecursiveInference.types index 382135591d5..0da9029f379 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.types +++ b/tests/baselines/reference/mappedTypeRecursiveInference.types @@ -26,8 +26,8 @@ declare function foo(deep: Deep): T; >T : T const out = foo(a); ->out : { a: {}; } ->foo(a) : { a: {}; } +>out : { a: { a: {}; }; } +>foo(a) : { a: { a: {}; }; } >foo : (deep: Deep) => T >a : A From 6b024f64955bea7d2d6720bb28df5af355590dc6 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 11 Dec 2017 09:47:04 -0800 Subject: [PATCH 009/189] Test:XMLHttpRequest inference to PartialDeep Compilation didn't finish before! Now it does. --- .../reference/mappedTypeRecursiveInference.js | 5 +++++ .../reference/mappedTypeRecursiveInference.symbols | 9 +++++++++ .../reference/mappedTypeRecursiveInference.types | 10 ++++++++++ tests/cases/compiler/mappedTypeRecursiveInference.ts | 4 ++++ 4 files changed, 28 insertions(+) diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.js b/tests/baselines/reference/mappedTypeRecursiveInference.js index 5b7631818bc..eda4d0b618e 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.js +++ b/tests/baselines/reference/mappedTypeRecursiveInference.js @@ -4,7 +4,12 @@ declare let a: A; type Deep = { [K in keyof T]: Deep } declare function foo(deep: Deep): T; const out = foo(a); + +let xhr: XMLHttpRequest; +const out2 = foo(xhr); //// [mappedTypeRecursiveInference.js] var out = foo(a); +var xhr; +var out2 = foo(xhr); diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.symbols b/tests/baselines/reference/mappedTypeRecursiveInference.symbols index a3fa3722551..96ed980c4c2 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.symbols +++ b/tests/baselines/reference/mappedTypeRecursiveInference.symbols @@ -30,3 +30,12 @@ const out = foo(a); >foo : Symbol(foo, Decl(mappedTypeRecursiveInference.ts, 2, 45)) >a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 1, 11)) +let xhr: XMLHttpRequest; +>xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 6, 3)) +>XMLHttpRequest : Symbol(XMLHttpRequest, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +const out2 = foo(xhr); +>out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 7, 5)) +>foo : Symbol(foo, Decl(mappedTypeRecursiveInference.ts, 2, 45)) +>xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 6, 3)) + diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.types b/tests/baselines/reference/mappedTypeRecursiveInference.types index 0da9029f379..8dbc33e0b2a 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.types +++ b/tests/baselines/reference/mappedTypeRecursiveInference.types @@ -31,3 +31,13 @@ const out = foo(a); >foo : (deep: Deep) => T >a : A +let xhr: XMLHttpRequest; +>xhr : XMLHttpRequest +>XMLHttpRequest : XMLHttpRequest + +const out2 = foo(xhr); +>out2 : { onreadystatechange: {}; readonly readyState: { toString: {}; toFixed: {}; toExponential: {}; toPrecision: {}; valueOf: {}; toLocaleString: {}; }; readonly response: {}; readonly responseText: { toString: {}; charAt: {}; charCodeAt: {}; concat: {}; indexOf: {}; lastIndexOf: {}; localeCompare: {}; match: {}; replace: {}; search: {}; slice: {}; split: {}; substring: {}; toLowerCase: {}; toLocaleLowerCase: {}; toUpperCase: {}; toLocaleUpperCase: {}; trim: {}; readonly length: {}; substr: {}; valueOf: {}; [Symbol.iterator]: {}; codePointAt: {}; includes: {}; endsWith: {}; normalize: {}; repeat: {}; startsWith: {}; anchor: {}; big: {}; blink: {}; bold: {}; fixed: {}; fontcolor: {}; fontsize: {}; italics: {}; link: {}; small: {}; strike: {}; sub: {}; sup: {}; }; responseType: {}; readonly responseURL: {}; readonly responseXML: { readonly activeElement: { readonly classList: { readonly length: {}; add: {}; contains: {}; item: {}; remove: {}; toggle: {}; toString: {}; }; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: { name: {}; assignedNodes: {}; accessKey: {}; readonly children: { namedItem: {}; readonly length: {}; item: {}; }; contentEditable: {}; readonly dataset: { [x: string]: {}; }; dir: {}; draggable: { valueOf: {}; }; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: { alignContent: {}; alignItems: {}; alignmentBaseline: {}; alignSelf: {}; animation: {}; animationDelay: {}; animationDirection: {}; animationDuration: {}; animationFillMode: {}; animationIterationCount: {}; animationName: {}; animationPlayState: {}; animationTimingFunction: {}; backfaceVisibility: {}; background: {}; backgroundAttachment: {}; backgroundClip: {}; backgroundColor: {}; backgroundImage: {}; backgroundOrigin: {}; backgroundPosition: {}; backgroundPositionX: {}; backgroundPositionY: {}; backgroundRepeat: {}; backgroundSize: {}; baselineShift: {}; border: {}; borderBottom: {}; borderBottomColor: {}; borderBottomLeftRadius: {}; borderBottomRightRadius: {}; borderBottomStyle: {}; borderBottomWidth: {}; borderCollapse: {}; borderColor: {}; borderImage: {}; borderImageOutset: {}; borderImageRepeat: {}; borderImageSlice: {}; borderImageSource: {}; borderImageWidth: {}; borderLeft: {}; borderLeftColor: {}; borderLeftStyle: {}; borderLeftWidth: {}; borderRadius: {}; borderRight: {}; borderRightColor: {}; borderRightStyle: {}; borderRightWidth: {}; borderSpacing: {}; borderStyle: {}; borderTop: {}; borderTopColor: {}; borderTopLeftRadius: {}; borderTopRightRadius: {}; borderTopStyle: {}; borderTopWidth: {}; borderWidth: {}; bottom: {}; boxShadow: {}; boxSizing: {}; breakAfter: {}; breakBefore: {}; breakInside: {}; captionSide: {}; clear: {}; clip: {}; clipPath: {}; clipRule: {}; color: {}; colorInterpolationFilters: {}; columnCount: {}; columnFill: {}; columnGap: {}; columnRule: {}; columnRuleColor: {}; columnRuleStyle: {}; columnRuleWidth: {}; columns: {}; columnSpan: {}; columnWidth: {}; content: {}; counterIncrement: {}; counterReset: {}; cssFloat: {}; cssText: {}; cursor: {}; direction: {}; display: {}; dominantBaseline: {}; emptyCells: {}; enableBackground: {}; fill: {}; fillOpacity: {}; fillRule: {}; filter: {}; flex: {}; flexBasis: {}; flexDirection: {}; flexFlow: {}; flexGrow: {}; flexShrink: {}; flexWrap: {}; floodColor: {}; floodOpacity: {}; font: {}; fontFamily: {}; fontFeatureSettings: {}; fontSize: {}; fontSizeAdjust: {}; fontStretch: {}; fontStyle: {}; fontVariant: {}; fontWeight: {}; glyphOrientationHorizontal: {}; glyphOrientationVertical: {}; height: {}; imeMode: {}; justifyContent: {}; kerning: {}; layoutGrid: {}; layoutGridChar: {}; layoutGridLine: {}; layoutGridMode: {}; layoutGridType: {}; left: {}; readonly length: {}; letterSpacing: {}; lightingColor: {}; lineBreak: {}; lineHeight: {}; listStyle: {}; listStyleImage: {}; listStylePosition: {}; listStyleType: {}; margin: {}; marginBottom: {}; marginLeft: {}; marginRight: {}; marginTop: {}; marker: {}; markerEnd: {}; markerMid: {}; markerStart: {}; mask: {}; maxHeight: {}; maxWidth: {}; minHeight: {}; minWidth: {}; msContentZoomChaining: {}; msContentZooming: {}; msContentZoomLimit: {}; msContentZoomLimitMax: {}; msContentZoomLimitMin: {}; msContentZoomSnap: {}; msContentZoomSnapPoints: {}; msContentZoomSnapType: {}; msFlowFrom: {}; msFlowInto: {}; msFontFeatureSettings: {}; msGridColumn: {}; msGridColumnAlign: {}; msGridColumns: {}; msGridColumnSpan: {}; msGridRow: {}; msGridRowAlign: {}; msGridRows: {}; msGridRowSpan: {}; msHighContrastAdjust: {}; msHyphenateLimitChars: {}; msHyphenateLimitLines: {}; msHyphenateLimitZone: {}; msHyphens: {}; msImeAlign: {}; msOverflowStyle: {}; msScrollChaining: {}; msScrollLimit: {}; msScrollLimitXMax: {}; msScrollLimitXMin: {}; msScrollLimitYMax: {}; msScrollLimitYMin: {}; msScrollRails: {}; msScrollSnapPointsX: {}; msScrollSnapPointsY: {}; msScrollSnapType: {}; msScrollSnapX: {}; msScrollSnapY: {}; msScrollTranslation: {}; msTextCombineHorizontal: {}; msTextSizeAdjust: {}; msTouchAction: {}; msTouchSelect: {}; msUserSelect: {}; msWrapFlow: {}; msWrapMargin: {}; msWrapThrough: {}; opacity: {}; order: {}; orphans: {}; outline: {}; outlineColor: {}; outlineOffset: {}; outlineStyle: {}; outlineWidth: {}; overflow: {}; overflowX: {}; overflowY: {}; padding: {}; paddingBottom: {}; paddingLeft: {}; paddingRight: {}; paddingTop: {}; pageBreakAfter: {}; pageBreakBefore: {}; pageBreakInside: {}; readonly parentRule: { cssText: {}; readonly parentRule: {}; readonly parentStyleSheet: { readonly cssRules: { readonly length: {}; item: {}; }; cssText: {}; readonly id: {}; readonly imports: { readonly length: {}; item: {}; }; readonly isAlternate: {}; readonly isPrefAlternate: {}; readonly ownerRule: {}; readonly owningElement: {}; readonly pages: { readonly length: {}; item: {}; }; readonly readOnly: {}; readonly rules: {}; addImport: {}; addPageRule: {}; addRule: {}; deleteRule: {}; insertRule: {}; removeImport: {}; removeRule: {}; disabled: {}; readonly href: {}; readonly media: { readonly length: {}; mediaText: {}; appendMedium: {}; deleteMedium: {}; item: {}; toString: {}; }; readonly ownerNode: { readonly attributes: { readonly length: {}; getNamedItem: {}; getNamedItemNS: {}; item: {}; removeNamedItem: {}; removeNamedItemNS: {}; setNamedItem: {}; setNamedItemNS: {}; }; readonly baseURI: {}; readonly childNodes: { readonly length: {}; item: {}; }; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: { accessKey: {}; readonly children: {}; contentEditable: {}; readonly dataset: {}; dir: {}; draggable: {}; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: {}; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; addEventListener: {}; removeEventListener: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: { readonly host: {}; innerHTML: {}; readonly activeElement: {}; readonly stylesheets: {}; getSelection: {}; elementFromPoint: {}; elementsFromPoint: {}; getElementById: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; querySelector: {}; querySelectorAll: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; }; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; }; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; }; readonly parentStyleSheet: { disabled: {}; readonly href: {}; readonly media: {}; readonly ownerNode: {}; readonly parentStyleSheet: {}; readonly title: {}; readonly type: {}; }; readonly title: {}; readonly type: {}; }; readonly type: {}; readonly CHARSET_RULE: {}; readonly FONT_FACE_RULE: {}; readonly IMPORT_RULE: {}; readonly KEYFRAME_RULE: {}; readonly KEYFRAMES_RULE: {}; readonly MEDIA_RULE: {}; readonly NAMESPACE_RULE: {}; readonly PAGE_RULE: {}; readonly STYLE_RULE: {}; readonly SUPPORTS_RULE: {}; readonly UNKNOWN_RULE: {}; readonly VIEWPORT_RULE: {}; }; perspective: {}; perspectiveOrigin: {}; pointerEvents: {}; position: {}; quotes: {}; right: {}; rotate: {}; rubyAlign: {}; rubyOverhang: {}; rubyPosition: {}; scale: {}; stopColor: {}; stopOpacity: {}; stroke: {}; strokeDasharray: {}; strokeDashoffset: {}; strokeLinecap: {}; strokeLinejoin: {}; strokeMiterlimit: {}; strokeOpacity: {}; strokeWidth: {}; tableLayout: {}; textAlign: {}; textAlignLast: {}; textAnchor: {}; textDecoration: {}; textIndent: {}; textJustify: {}; textKashida: {}; textKashidaSpace: {}; textOverflow: {}; textShadow: {}; textTransform: {}; textUnderlinePosition: {}; top: {}; touchAction: {}; transform: {}; transformOrigin: {}; transformStyle: {}; transition: {}; transitionDelay: {}; transitionDuration: {}; transitionProperty: {}; transitionTimingFunction: {}; translate: {}; unicodeBidi: {}; verticalAlign: {}; visibility: {}; webkitAlignContent: {}; webkitAlignItems: {}; webkitAlignSelf: {}; webkitAnimation: {}; webkitAnimationDelay: {}; webkitAnimationDirection: {}; webkitAnimationDuration: {}; webkitAnimationFillMode: {}; webkitAnimationIterationCount: {}; webkitAnimationName: {}; webkitAnimationPlayState: {}; webkitAnimationTimingFunction: {}; webkitAppearance: {}; webkitBackfaceVisibility: {}; webkitBackgroundClip: {}; webkitBackgroundOrigin: {}; webkitBackgroundSize: {}; webkitBorderBottomLeftRadius: {}; webkitBorderBottomRightRadius: {}; webkitBorderImage: {}; webkitBorderRadius: {}; webkitBorderTopLeftRadius: {}; webkitBorderTopRightRadius: {}; webkitBoxAlign: {}; webkitBoxDirection: {}; webkitBoxFlex: {}; webkitBoxOrdinalGroup: {}; webkitBoxOrient: {}; webkitBoxPack: {}; webkitBoxSizing: {}; webkitColumnBreakAfter: {}; webkitColumnBreakBefore: {}; webkitColumnBreakInside: {}; webkitColumnCount: {}; webkitColumnGap: {}; webkitColumnRule: {}; webkitColumnRuleColor: {}; webkitColumnRuleStyle: {}; webkitColumnRuleWidth: {}; webkitColumns: {}; webkitColumnSpan: {}; webkitColumnWidth: {}; webkitFilter: {}; webkitFlex: {}; webkitFlexBasis: {}; webkitFlexDirection: {}; webkitFlexFlow: {}; webkitFlexGrow: {}; webkitFlexShrink: {}; webkitFlexWrap: {}; webkitJustifyContent: {}; webkitOrder: {}; webkitPerspective: {}; webkitPerspectiveOrigin: {}; webkitTapHighlightColor: {}; webkitTextFillColor: {}; webkitTextSizeAdjust: {}; webkitTextStroke: {}; webkitTextStrokeColor: {}; webkitTextStrokeWidth: {}; webkitTransform: {}; webkitTransformOrigin: {}; webkitTransformStyle: {}; webkitTransition: {}; webkitTransitionDelay: {}; webkitTransitionDuration: {}; webkitTransitionProperty: {}; webkitTransitionTimingFunction: {}; webkitUserModify: {}; webkitUserSelect: {}; webkitWritingMode: {}; whiteSpace: {}; widows: {}; width: {}; wordBreak: {}; wordSpacing: {}; wordWrap: {}; writingMode: {}; zIndex: {}; zoom: {}; resize: {}; userSelect: {}; getPropertyPriority: {}; getPropertyValue: {}; item: {}; removeProperty: {}; setProperty: {}; }; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; addEventListener: {}; removeEventListener: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; }; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; }; alinkColor: {}; readonly all: { readonly length: {}; item: {}; namedItem: {}; }; anchors: { item: {}; namedItem: {}; readonly length: {}; }; applets: {}; bgColor: {}; body: {}; readonly characterSet: {}; charset: {}; readonly compatMode: {}; cookie: {}; readonly currentScript: { async: {}; charset: {}; crossOrigin: {}; defer: {}; event: {}; htmlFor: {}; src: {}; text: {}; type: {}; integrity: {}; addEventListener: {}; removeEventListener: {}; accessKey: {}; readonly children: {}; contentEditable: {}; readonly dataset: {}; dir: {}; draggable: {}; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: {}; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; } | { type: {}; addEventListener: {}; removeEventListener: {}; className: {}; onclick: {}; ondblclick: {}; onfocusin: {}; onfocusout: {}; onload: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; readonly ownerSVGElement: { contentScriptType: {}; contentStyleType: {}; currentScale: {}; readonly currentTranslate: { x: {}; y: {}; matrixTransform: {}; }; readonly height: { readonly animVal: { readonly unitType: {}; value: {}; valueAsString: {}; valueInSpecifiedUnits: {}; convertToSpecifiedUnits: {}; newValueSpecifiedUnits: {}; readonly SVG_LENGTHTYPE_CM: {}; readonly SVG_LENGTHTYPE_EMS: {}; readonly SVG_LENGTHTYPE_EXS: {}; readonly SVG_LENGTHTYPE_IN: {}; readonly SVG_LENGTHTYPE_MM: {}; readonly SVG_LENGTHTYPE_NUMBER: {}; readonly SVG_LENGTHTYPE_PC: {}; readonly SVG_LENGTHTYPE_PERCENTAGE: {}; readonly SVG_LENGTHTYPE_PT: {}; readonly SVG_LENGTHTYPE_PX: {}; readonly SVG_LENGTHTYPE_UNKNOWN: {}; }; readonly baseVal: {}; }; onabort: {}; onerror: {}; onresize: {}; onscroll: {}; onunload: {}; onzoom: {}; readonly pixelUnitToMillimeterX: {}; readonly pixelUnitToMillimeterY: {}; readonly screenPixelToMillimeterX: {}; readonly screenPixelToMillimeterY: {}; readonly viewport: { height: {}; width: {}; x: {}; y: {}; }; readonly width: {}; readonly x: {}; readonly y: {}; checkEnclosure: {}; checkIntersection: {}; createSVGAngle: {}; createSVGLength: {}; createSVGMatrix: {}; createSVGNumber: {}; createSVGPoint: {}; createSVGRect: {}; createSVGTransform: {}; createSVGTransformFromMatrix: {}; deselectAll: {}; forceRedraw: {}; getComputedStyle: {}; getCurrentTime: {}; getElementById: {}; getEnclosureList: {}; getIntersectionList: {}; pauseAnimations: {}; setCurrentTime: {}; suspendRedraw: {}; unpauseAnimations: {}; unsuspendRedraw: {}; unsuspendRedrawAll: {}; addEventListener: {}; removeEventListener: {}; readonly farthestViewportElement: { className: {}; onclick: {}; ondblclick: {}; onfocusin: {}; onfocusout: {}; onload: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; readonly ownerSVGElement: {}; readonly style: {}; readonly viewportElement: {}; xmlbase: {}; addEventListener: {}; removeEventListener: {}; readonly classList: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; }; readonly nearestViewportElement: {}; readonly transform: { readonly animVal: { readonly numberOfItems: {}; appendItem: {}; clear: {}; consolidate: {}; createSVGTransformFromMatrix: {}; getItem: {}; initialize: {}; insertItemBefore: {}; removeItem: {}; replaceItem: {}; }; readonly baseVal: {}; }; getBBox: {}; getCTM: {}; getScreenCTM: {}; getTransformToElement: {}; className: {}; onclick: {}; ondblclick: {}; onfocusin: {}; onfocusout: {}; onload: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; readonly ownerSVGElement: {}; readonly style: {}; readonly viewportElement: {}; xmlbase: {}; readonly classList: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; readonly requiredExtensions: { readonly numberOfItems: {}; appendItem: {}; clear: {}; getItem: {}; initialize: {}; insertItemBefore: {}; removeItem: {}; replaceItem: {}; }; readonly requiredFeatures: {}; readonly systemLanguage: {}; hasExtension: {}; createEvent: {}; readonly preserveAspectRatio: { readonly animVal: { align: {}; meetOrSlice: {}; readonly SVG_MEETORSLICE_MEET: {}; readonly SVG_MEETORSLICE_SLICE: {}; readonly SVG_MEETORSLICE_UNKNOWN: {}; readonly SVG_PRESERVEASPECTRATIO_NONE: {}; readonly SVG_PRESERVEASPECTRATIO_UNKNOWN: {}; readonly SVG_PRESERVEASPECTRATIO_XMAXYMAX: {}; readonly SVG_PRESERVEASPECTRATIO_XMAXYMID: {}; readonly SVG_PRESERVEASPECTRATIO_XMAXYMIN: {}; readonly SVG_PRESERVEASPECTRATIO_XMIDYMAX: {}; readonly SVG_PRESERVEASPECTRATIO_XMIDYMID: {}; readonly SVG_PRESERVEASPECTRATIO_XMIDYMIN: {}; readonly SVG_PRESERVEASPECTRATIO_XMINYMAX: {}; readonly SVG_PRESERVEASPECTRATIO_XMINYMID: {}; readonly SVG_PRESERVEASPECTRATIO_XMINYMIN: {}; }; readonly baseVal: {}; }; readonly viewBox: { readonly animVal: {}; readonly baseVal: {}; }; readonly zoomAndPan: {}; }; readonly style: {}; readonly viewportElement: {}; xmlbase: {}; readonly classList: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; readonly href: { readonly animVal: {}; baseVal: {}; }; }; readonly defaultView: { readonly applicationCache: { oncached: {}; onchecking: {}; ondownloading: {}; onerror: {}; onnoupdate: {}; onobsolete: {}; onprogress: {}; onupdateready: {}; readonly status: {}; abort: {}; swapCache: {}; update: {}; readonly CHECKING: {}; readonly DOWNLOADING: {}; readonly IDLE: {}; readonly OBSOLETE: {}; readonly UNCACHED: {}; readonly UPDATEREADY: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; readonly caches: { delete: {}; has: {}; keys: {}; match: {}; open: {}; }; readonly clientInformation: { readonly authentication: { getAssertion: {}; makeCredential: {}; }; readonly cookieEnabled: {}; gamepadInputEmulation: {}; readonly language: {}; readonly maxTouchPoints: {}; readonly mimeTypes: { readonly length: {}; item: {}; namedItem: {}; }; readonly msManipulationViewsEnabled: {}; readonly msMaxTouchPoints: {}; readonly msPointerEnabled: {}; readonly plugins: { readonly length: {}; item: {}; namedItem: {}; refresh: {}; }; readonly pointerEnabled: {}; readonly serviceWorker: { readonly controller: { onstatechange: {}; readonly scriptURL: {}; readonly state: {}; postMessage: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onerror: {}; }; oncontrollerchange: {}; onmessage: {}; readonly ready: { then: {}; catch: {}; readonly [Symbol.toStringTag]: {}; }; getRegistration: {}; getRegistrations: {}; register: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; readonly webdriver: {}; readonly doNotTrack: {}; readonly hardwareConcurrency: {}; readonly languages: { length: {}; toString: {}; toLocaleString: {}; push: {}; pop: {}; concat: {}; join: {}; reverse: {}; shift: {}; slice: {}; sort: {}; splice: {}; unshift: {}; indexOf: {}; lastIndexOf: {}; every: {}; some: {}; forEach: {}; map: {}; filter: {}; reduce: {}; reduceRight: {}; [Symbol.unscopables]: {}; [Symbol.iterator]: {}; entries: {}; keys: {}; values: {}; find: {}; findIndex: {}; fill: {}; copyWithin: {}; }; getGamepads: {}; javaEnabled: {}; msLaunchUri: {}; requestMediaKeySystemAccess: {}; vibrate: {}; constructor: { apply: {}; call: {}; bind: {}; toString: {}; prototype: {}; readonly length: {}; arguments: {}; caller: {}; [Symbol.hasInstance]: {}; readonly name: {}; }; toString: {}; toLocaleString: {}; valueOf: {}; hasOwnProperty: {}; isPrototypeOf: {}; propertyIsEnumerable: {}; readonly appCodeName: {}; readonly appName: {}; readonly appVersion: {}; readonly platform: {}; readonly product: {}; readonly productSub: {}; readonly userAgent: {}; readonly vendor: {}; readonly vendorSub: {}; readonly onLine: {}; readonly geolocation: { clearWatch: {}; getCurrentPosition: {}; watchPosition: {}; }; confirmSiteSpecificTrackingException: {}; confirmWebWideTrackingException: {}; removeSiteSpecificTrackingException: {}; removeWebWideTrackingException: {}; storeSiteSpecificTrackingException: {}; storeWebWideTrackingException: {}; msSaveBlob: {}; msSaveOrOpenBlob: {}; sendBeacon: {}; readonly mediaDevices: { ondevicechange: {}; enumerateDevices: {}; getSupportedConstraints: {}; getUserMedia: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; getUserMedia: {}; }; readonly closed: {}; readonly crypto: { readonly subtle: { decrypt: {}; deriveBits: {}; deriveKey: {}; digest: {}; encrypt: {}; exportKey: {}; generateKey: {}; importKey: {}; sign: {}; unwrapKey: {}; verify: {}; wrapKey: {}; }; constructor: {}; toString: {}; toLocaleString: {}; valueOf: {}; hasOwnProperty: {}; isPrototypeOf: {}; propertyIsEnumerable: {}; getRandomValues: {}; }; defaultStatus: {}; readonly devicePixelRatio: {}; readonly document: {}; readonly doNotTrack: {}; event: { readonly bubbles: {}; readonly cancelable: {}; cancelBubble: {}; readonly currentTarget: { addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; }; readonly defaultPrevented: {}; readonly eventPhase: {}; readonly isTrusted: {}; returnValue: {}; readonly srcElement: {}; readonly target: {}; readonly timeStamp: {}; readonly type: {}; readonly scoped: {}; initEvent: {}; preventDefault: {}; stopImmediatePropagation: {}; stopPropagation: {}; deepPath: {}; readonly AT_TARGET: {}; readonly BUBBLING_PHASE: {}; readonly CAPTURING_PHASE: {}; }; readonly external: {}; readonly frameElement: {}; readonly frames: {}; readonly history: { readonly length: {}; readonly state: {}; scrollRestoration: {}; back: {}; forward: {}; go: {}; pushState: {}; replaceState: {}; }; readonly innerHeight: {}; readonly innerWidth: {}; readonly isSecureContext: {}; readonly length: {}; readonly location: { hash: {}; host: {}; hostname: {}; href: {}; readonly origin: {}; pathname: {}; port: {}; protocol: {}; search: {}; assign: {}; reload: {}; replace: {}; toString: {}; }; readonly locationbar: { readonly visible: {}; }; readonly menubar: {}; readonly msContentScript: { extensionIdToShortId: {}; fireExtensionApiTelemetry: {}; genericFunction: {}; genericSynchronousFunction: {}; getExtensionId: {}; registerGenericFunctionCallbackHandler: {}; registerGenericPersistentCallbackHandler: {}; }; readonly msCredentials: { getAssertion: {}; makeCredential: {}; }; name: {}; readonly navigator: {}; offscreenBuffering: {}; onabort: {}; onafterprint: {}; onbeforeprint: {}; onbeforeunload: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncompassneedscalibration: {}; oncontextmenu: {}; ondblclick: {}; ondevicelight: {}; ondevicemotion: {}; ondeviceorientation: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onhashchange: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmessage: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onoffline: {}; ononline: {}; onorientationchange: {}; onpagehide: {}; onpageshow: {}; onpause: {}; onplay: {}; onplaying: {}; onpopstate: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onresize: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onstalled: {}; onstorage: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onunload: {}; onvolumechange: {}; onwaiting: {}; opener: {}; orientation: {}; readonly outerHeight: {}; readonly outerWidth: {}; readonly pageXOffset: {}; readonly pageYOffset: {}; readonly parent: {}; readonly performance: { readonly navigation: { readonly redirectCount: {}; readonly type: {}; toJSON: {}; readonly TYPE_BACK_FORWARD: {}; readonly TYPE_NAVIGATE: {}; readonly TYPE_RELOAD: {}; readonly TYPE_RESERVED: {}; }; readonly timing: { readonly connectEnd: {}; readonly connectStart: {}; readonly domainLookupEnd: {}; readonly domainLookupStart: {}; readonly domComplete: {}; readonly domContentLoadedEventEnd: {}; readonly domContentLoadedEventStart: {}; readonly domInteractive: {}; readonly domLoading: {}; readonly fetchStart: {}; readonly loadEventEnd: {}; readonly loadEventStart: {}; readonly msFirstPaint: {}; readonly navigationStart: {}; readonly redirectEnd: {}; readonly redirectStart: {}; readonly requestStart: {}; readonly responseEnd: {}; readonly responseStart: {}; readonly unloadEventEnd: {}; readonly unloadEventStart: {}; readonly secureConnectionStart: {}; toJSON: {}; }; clearMarks: {}; clearMeasures: {}; clearResourceTimings: {}; getEntries: {}; getEntriesByName: {}; getEntriesByType: {}; getMarks: {}; getMeasures: {}; mark: {}; measure: {}; now: {}; setResourceTimingBufferSize: {}; toJSON: {}; }; readonly personalbar: {}; readonly screen: { readonly availHeight: {}; readonly availWidth: {}; bufferDepth: {}; readonly colorDepth: {}; readonly deviceXDPI: {}; readonly deviceYDPI: {}; readonly fontSmoothingEnabled: {}; readonly height: {}; readonly logicalXDPI: {}; readonly logicalYDPI: {}; readonly msOrientation: {}; onmsorientationchange: {}; readonly pixelDepth: {}; readonly systemXDPI: {}; readonly systemYDPI: {}; readonly width: {}; msLockOrientation: {}; msUnlockOrientation: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; readonly screenLeft: {}; readonly screenTop: {}; readonly screenX: {}; readonly screenY: {}; readonly scrollbars: {}; readonly scrollX: {}; readonly scrollY: {}; readonly self: {}; readonly speechSynthesis: { onvoiceschanged: {}; readonly paused: {}; readonly pending: {}; readonly speaking: {}; cancel: {}; getVoices: {}; pause: {}; resume: {}; speak: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; status: {}; readonly statusbar: {}; readonly styleMedia: { readonly type: {}; matchMedium: {}; }; readonly toolbar: {}; readonly top: {}; readonly window: {}; URL: { prototype: { hash: {}; host: {}; hostname: {}; href: {}; readonly origin: {}; password: {}; pathname: {}; port: {}; protocol: {}; search: {}; username: {}; readonly searchParams: { append: {}; delete: {}; get: {}; getAll: {}; has: {}; set: {}; }; toString: {}; }; createObjectURL: {}; revokeObjectURL: {}; }; URLSearchParams: { prototype: {}; }; Blob: { prototype: { readonly size: {}; readonly type: {}; msClose: {}; msDetachStream: {}; slice: {}; }; }; customElements: { define: {}; get: {}; whenDefined: {}; }; alert: {}; blur: {}; cancelAnimationFrame: {}; captureEvents: {}; close: {}; confirm: {}; departFocus: {}; focus: {}; getComputedStyle: {}; getMatchedCSSRules: {}; getSelection: {}; matchMedia: {}; moveBy: {}; moveTo: {}; msWriteProfilerMark: {}; open: {}; postMessage: {}; print: {}; prompt: {}; releaseEvents: {}; requestAnimationFrame: {}; resizeBy: {}; resizeTo: {}; scroll: {}; scrollBy: {}; scrollTo: {}; stop: {}; webkitCancelAnimationFrame: {}; webkitConvertPointFromNodeToPage: {}; webkitConvertPointFromPageToNode: {}; webkitRequestAnimationFrame: {}; createImageBitmap: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; clearInterval: {}; clearTimeout: {}; setInterval: {}; setTimeout: {}; constructor: {}; toString: {}; toLocaleString: {}; valueOf: {}; hasOwnProperty: {}; isPrototypeOf: {}; propertyIsEnumerable: {}; clearImmediate: {}; setImmediate: {}; readonly sessionStorage: { [x: string]: {}; readonly length: {}; clear: {}; getItem: {}; key: {}; removeItem: {}; setItem: {}; }; readonly localStorage: {}; readonly console: { assert: {}; clear: {}; count: {}; debug: {}; dir: {}; dirxml: {}; error: {}; exception: {}; group: {}; groupCollapsed: {}; groupEnd: {}; info: {}; log: {}; msIsIndependentlyComposed: {}; profile: {}; profileEnd: {}; select: {}; table: {}; time: {}; timeEnd: {}; trace: {}; warn: {}; }; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly indexedDB: { cmp: {}; deleteDatabase: {}; open: {}; }; atob: {}; btoa: {}; fetch: {}; }; designMode: {}; dir: {}; readonly doctype: { readonly entities: {}; readonly internalSubset: {}; readonly name: {}; readonly notations: {}; readonly publicId: {}; readonly systemId: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; remove: {}; }; documentElement: {}; domain: {}; embeds: {}; fgColor: {}; forms: {}; readonly fullscreenElement: {}; readonly fullscreenEnabled: {}; readonly head: { profile: {}; addEventListener: {}; removeEventListener: {}; accessKey: {}; readonly children: {}; contentEditable: {}; readonly dataset: {}; dir: {}; draggable: {}; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: {}; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; }; readonly hidden: {}; images: {}; readonly implementation: { createDocument: {}; createDocumentType: {}; createHTMLDocument: {}; hasFeature: {}; }; readonly inputEncoding: {}; readonly lastModified: {}; linkColor: {}; links: {}; readonly location: {}; msCapsLockWarningOff: {}; msCSSOMElementFloatMetrics: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforedeactivate: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onfullscreenchange: {}; onfullscreenerror: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmsmanipulationstatechanged: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onmssitemodejumplistitemremoved: {}; onmsthumbnailclick: {}; onpause: {}; onplay: {}; onplaying: {}; onpointerlockchange: {}; onpointerlockerror: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectionchange: {}; onselectstart: {}; onstalled: {}; onstop: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onvolumechange: {}; onwaiting: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; plugins: {}; readonly pointerLockElement: {}; readonly readyState: {}; readonly referrer: {}; readonly rootElement: {}; scripts: {}; readonly scrollingElement: {}; readonly styleSheets: {}; title: {}; readonly URL: {}; readonly URLUnencoded: {}; readonly visibilityState: {}; vlinkColor: {}; readonly webkitCurrentFullScreenElement: {}; readonly webkitFullscreenElement: {}; readonly webkitFullscreenEnabled: {}; readonly webkitIsFullScreen: {}; readonly xmlEncoding: {}; xmlStandalone: {}; xmlVersion: {}; adoptNode: {}; captureEvents: {}; caretRangeFromPoint: {}; clear: {}; close: {}; createAttribute: {}; createAttributeNS: {}; createCDATASection: {}; createComment: {}; createDocumentFragment: {}; createElement: {}; createElementNS: {}; createExpression: {}; createNodeIterator: {}; createNSResolver: {}; createProcessingInstruction: {}; createRange: {}; createTextNode: {}; createTouch: {}; createTouchList: {}; createTreeWalker: {}; elementFromPoint: {}; evaluate: {}; execCommand: {}; execCommandShowHelp: {}; exitFullscreen: {}; exitPointerLock: {}; focus: {}; getElementById: {}; getElementsByClassName: {}; getElementsByName: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; getSelection: {}; hasFocus: {}; importNode: {}; msElementsFromPoint: {}; msElementsFromRect: {}; open: {}; queryCommandEnabled: {}; queryCommandIndeterm: {}; queryCommandState: {}; queryCommandSupported: {}; queryCommandText: {}; queryCommandValue: {}; releaseEvents: {}; updateSettings: {}; webkitCancelFullScreen: {}; webkitExitFullscreen: {}; write: {}; writeln: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; querySelector: {}; querySelectorAll: {}; createEvent: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; readonly stylesheets: {}; elementsFromPoint: {}; }; readonly status: {}; readonly statusText: {}; timeout: {}; readonly upload: { addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; }; withCredentials: {}; msCaching?: {}; abort: {}; getAllResponseHeaders: {}; getResponseHeader: {}; msCachingEnabled: {}; open: {}; overrideMimeType: {}; send: {}; setRequestHeader: {}; readonly DONE: {}; readonly HEADERS_RECEIVED: {}; readonly LOADING: {}; readonly OPENED: {}; readonly UNSENT: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; } +>foo(xhr) : { onreadystatechange: {}; readonly readyState: { toString: {}; toFixed: {}; toExponential: {}; toPrecision: {}; valueOf: {}; toLocaleString: {}; }; readonly response: {}; readonly responseText: { toString: {}; charAt: {}; charCodeAt: {}; concat: {}; indexOf: {}; lastIndexOf: {}; localeCompare: {}; match: {}; replace: {}; search: {}; slice: {}; split: {}; substring: {}; toLowerCase: {}; toLocaleLowerCase: {}; toUpperCase: {}; toLocaleUpperCase: {}; trim: {}; readonly length: {}; substr: {}; valueOf: {}; [Symbol.iterator]: {}; codePointAt: {}; includes: {}; endsWith: {}; normalize: {}; repeat: {}; startsWith: {}; anchor: {}; big: {}; blink: {}; bold: {}; fixed: {}; fontcolor: {}; fontsize: {}; italics: {}; link: {}; small: {}; strike: {}; sub: {}; sup: {}; }; responseType: {}; readonly responseURL: {}; readonly responseXML: { readonly activeElement: { readonly classList: { readonly length: {}; add: {}; contains: {}; item: {}; remove: {}; toggle: {}; toString: {}; }; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: { name: {}; assignedNodes: {}; accessKey: {}; readonly children: { namedItem: {}; readonly length: {}; item: {}; }; contentEditable: {}; readonly dataset: { [x: string]: {}; }; dir: {}; draggable: { valueOf: {}; }; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: { alignContent: {}; alignItems: {}; alignmentBaseline: {}; alignSelf: {}; animation: {}; animationDelay: {}; animationDirection: {}; animationDuration: {}; animationFillMode: {}; animationIterationCount: {}; animationName: {}; animationPlayState: {}; animationTimingFunction: {}; backfaceVisibility: {}; background: {}; backgroundAttachment: {}; backgroundClip: {}; backgroundColor: {}; backgroundImage: {}; backgroundOrigin: {}; backgroundPosition: {}; backgroundPositionX: {}; backgroundPositionY: {}; backgroundRepeat: {}; backgroundSize: {}; baselineShift: {}; border: {}; borderBottom: {}; borderBottomColor: {}; borderBottomLeftRadius: {}; borderBottomRightRadius: {}; borderBottomStyle: {}; borderBottomWidth: {}; borderCollapse: {}; borderColor: {}; borderImage: {}; borderImageOutset: {}; borderImageRepeat: {}; borderImageSlice: {}; borderImageSource: {}; borderImageWidth: {}; borderLeft: {}; borderLeftColor: {}; borderLeftStyle: {}; borderLeftWidth: {}; borderRadius: {}; borderRight: {}; borderRightColor: {}; borderRightStyle: {}; borderRightWidth: {}; borderSpacing: {}; borderStyle: {}; borderTop: {}; borderTopColor: {}; borderTopLeftRadius: {}; borderTopRightRadius: {}; borderTopStyle: {}; borderTopWidth: {}; borderWidth: {}; bottom: {}; boxShadow: {}; boxSizing: {}; breakAfter: {}; breakBefore: {}; breakInside: {}; captionSide: {}; clear: {}; clip: {}; clipPath: {}; clipRule: {}; color: {}; colorInterpolationFilters: {}; columnCount: {}; columnFill: {}; columnGap: {}; columnRule: {}; columnRuleColor: {}; columnRuleStyle: {}; columnRuleWidth: {}; columns: {}; columnSpan: {}; columnWidth: {}; content: {}; counterIncrement: {}; counterReset: {}; cssFloat: {}; cssText: {}; cursor: {}; direction: {}; display: {}; dominantBaseline: {}; emptyCells: {}; enableBackground: {}; fill: {}; fillOpacity: {}; fillRule: {}; filter: {}; flex: {}; flexBasis: {}; flexDirection: {}; flexFlow: {}; flexGrow: {}; flexShrink: {}; flexWrap: {}; floodColor: {}; floodOpacity: {}; font: {}; fontFamily: {}; fontFeatureSettings: {}; fontSize: {}; fontSizeAdjust: {}; fontStretch: {}; fontStyle: {}; fontVariant: {}; fontWeight: {}; glyphOrientationHorizontal: {}; glyphOrientationVertical: {}; height: {}; imeMode: {}; justifyContent: {}; kerning: {}; layoutGrid: {}; layoutGridChar: {}; layoutGridLine: {}; layoutGridMode: {}; layoutGridType: {}; left: {}; readonly length: {}; letterSpacing: {}; lightingColor: {}; lineBreak: {}; lineHeight: {}; listStyle: {}; listStyleImage: {}; listStylePosition: {}; listStyleType: {}; margin: {}; marginBottom: {}; marginLeft: {}; marginRight: {}; marginTop: {}; marker: {}; markerEnd: {}; markerMid: {}; markerStart: {}; mask: {}; maxHeight: {}; maxWidth: {}; minHeight: {}; minWidth: {}; msContentZoomChaining: {}; msContentZooming: {}; msContentZoomLimit: {}; msContentZoomLimitMax: {}; msContentZoomLimitMin: {}; msContentZoomSnap: {}; msContentZoomSnapPoints: {}; msContentZoomSnapType: {}; msFlowFrom: {}; msFlowInto: {}; msFontFeatureSettings: {}; msGridColumn: {}; msGridColumnAlign: {}; msGridColumns: {}; msGridColumnSpan: {}; msGridRow: {}; msGridRowAlign: {}; msGridRows: {}; msGridRowSpan: {}; msHighContrastAdjust: {}; msHyphenateLimitChars: {}; msHyphenateLimitLines: {}; msHyphenateLimitZone: {}; msHyphens: {}; msImeAlign: {}; msOverflowStyle: {}; msScrollChaining: {}; msScrollLimit: {}; msScrollLimitXMax: {}; msScrollLimitXMin: {}; msScrollLimitYMax: {}; msScrollLimitYMin: {}; msScrollRails: {}; msScrollSnapPointsX: {}; msScrollSnapPointsY: {}; msScrollSnapType: {}; msScrollSnapX: {}; msScrollSnapY: {}; msScrollTranslation: {}; msTextCombineHorizontal: {}; msTextSizeAdjust: {}; msTouchAction: {}; msTouchSelect: {}; msUserSelect: {}; msWrapFlow: {}; msWrapMargin: {}; msWrapThrough: {}; opacity: {}; order: {}; orphans: {}; outline: {}; outlineColor: {}; outlineOffset: {}; outlineStyle: {}; outlineWidth: {}; overflow: {}; overflowX: {}; overflowY: {}; padding: {}; paddingBottom: {}; paddingLeft: {}; paddingRight: {}; paddingTop: {}; pageBreakAfter: {}; pageBreakBefore: {}; pageBreakInside: {}; readonly parentRule: { cssText: {}; readonly parentRule: {}; readonly parentStyleSheet: { readonly cssRules: { readonly length: {}; item: {}; }; cssText: {}; readonly id: {}; readonly imports: { readonly length: {}; item: {}; }; readonly isAlternate: {}; readonly isPrefAlternate: {}; readonly ownerRule: {}; readonly owningElement: {}; readonly pages: { readonly length: {}; item: {}; }; readonly readOnly: {}; readonly rules: {}; addImport: {}; addPageRule: {}; addRule: {}; deleteRule: {}; insertRule: {}; removeImport: {}; removeRule: {}; disabled: {}; readonly href: {}; readonly media: { readonly length: {}; mediaText: {}; appendMedium: {}; deleteMedium: {}; item: {}; toString: {}; }; readonly ownerNode: { readonly attributes: { readonly length: {}; getNamedItem: {}; getNamedItemNS: {}; item: {}; removeNamedItem: {}; removeNamedItemNS: {}; setNamedItem: {}; setNamedItemNS: {}; }; readonly baseURI: {}; readonly childNodes: { readonly length: {}; item: {}; }; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: { accessKey: {}; readonly children: {}; contentEditable: {}; readonly dataset: {}; dir: {}; draggable: {}; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: {}; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; addEventListener: {}; removeEventListener: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: { readonly host: {}; innerHTML: {}; readonly activeElement: {}; readonly stylesheets: {}; getSelection: {}; elementFromPoint: {}; elementsFromPoint: {}; getElementById: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; querySelector: {}; querySelectorAll: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; }; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; }; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; }; readonly parentStyleSheet: { disabled: {}; readonly href: {}; readonly media: {}; readonly ownerNode: {}; readonly parentStyleSheet: {}; readonly title: {}; readonly type: {}; }; readonly title: {}; readonly type: {}; }; readonly type: {}; readonly CHARSET_RULE: {}; readonly FONT_FACE_RULE: {}; readonly IMPORT_RULE: {}; readonly KEYFRAME_RULE: {}; readonly KEYFRAMES_RULE: {}; readonly MEDIA_RULE: {}; readonly NAMESPACE_RULE: {}; readonly PAGE_RULE: {}; readonly STYLE_RULE: {}; readonly SUPPORTS_RULE: {}; readonly UNKNOWN_RULE: {}; readonly VIEWPORT_RULE: {}; }; perspective: {}; perspectiveOrigin: {}; pointerEvents: {}; position: {}; quotes: {}; right: {}; rotate: {}; rubyAlign: {}; rubyOverhang: {}; rubyPosition: {}; scale: {}; stopColor: {}; stopOpacity: {}; stroke: {}; strokeDasharray: {}; strokeDashoffset: {}; strokeLinecap: {}; strokeLinejoin: {}; strokeMiterlimit: {}; strokeOpacity: {}; strokeWidth: {}; tableLayout: {}; textAlign: {}; textAlignLast: {}; textAnchor: {}; textDecoration: {}; textIndent: {}; textJustify: {}; textKashida: {}; textKashidaSpace: {}; textOverflow: {}; textShadow: {}; textTransform: {}; textUnderlinePosition: {}; top: {}; touchAction: {}; transform: {}; transformOrigin: {}; transformStyle: {}; transition: {}; transitionDelay: {}; transitionDuration: {}; transitionProperty: {}; transitionTimingFunction: {}; translate: {}; unicodeBidi: {}; verticalAlign: {}; visibility: {}; webkitAlignContent: {}; webkitAlignItems: {}; webkitAlignSelf: {}; webkitAnimation: {}; webkitAnimationDelay: {}; webkitAnimationDirection: {}; webkitAnimationDuration: {}; webkitAnimationFillMode: {}; webkitAnimationIterationCount: {}; webkitAnimationName: {}; webkitAnimationPlayState: {}; webkitAnimationTimingFunction: {}; webkitAppearance: {}; webkitBackfaceVisibility: {}; webkitBackgroundClip: {}; webkitBackgroundOrigin: {}; webkitBackgroundSize: {}; webkitBorderBottomLeftRadius: {}; webkitBorderBottomRightRadius: {}; webkitBorderImage: {}; webkitBorderRadius: {}; webkitBorderTopLeftRadius: {}; webkitBorderTopRightRadius: {}; webkitBoxAlign: {}; webkitBoxDirection: {}; webkitBoxFlex: {}; webkitBoxOrdinalGroup: {}; webkitBoxOrient: {}; webkitBoxPack: {}; webkitBoxSizing: {}; webkitColumnBreakAfter: {}; webkitColumnBreakBefore: {}; webkitColumnBreakInside: {}; webkitColumnCount: {}; webkitColumnGap: {}; webkitColumnRule: {}; webkitColumnRuleColor: {}; webkitColumnRuleStyle: {}; webkitColumnRuleWidth: {}; webkitColumns: {}; webkitColumnSpan: {}; webkitColumnWidth: {}; webkitFilter: {}; webkitFlex: {}; webkitFlexBasis: {}; webkitFlexDirection: {}; webkitFlexFlow: {}; webkitFlexGrow: {}; webkitFlexShrink: {}; webkitFlexWrap: {}; webkitJustifyContent: {}; webkitOrder: {}; webkitPerspective: {}; webkitPerspectiveOrigin: {}; webkitTapHighlightColor: {}; webkitTextFillColor: {}; webkitTextSizeAdjust: {}; webkitTextStroke: {}; webkitTextStrokeColor: {}; webkitTextStrokeWidth: {}; webkitTransform: {}; webkitTransformOrigin: {}; webkitTransformStyle: {}; webkitTransition: {}; webkitTransitionDelay: {}; webkitTransitionDuration: {}; webkitTransitionProperty: {}; webkitTransitionTimingFunction: {}; webkitUserModify: {}; webkitUserSelect: {}; webkitWritingMode: {}; whiteSpace: {}; widows: {}; width: {}; wordBreak: {}; wordSpacing: {}; wordWrap: {}; writingMode: {}; zIndex: {}; zoom: {}; resize: {}; userSelect: {}; getPropertyPriority: {}; getPropertyValue: {}; item: {}; removeProperty: {}; setProperty: {}; }; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; addEventListener: {}; removeEventListener: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; }; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; }; alinkColor: {}; readonly all: { readonly length: {}; item: {}; namedItem: {}; }; anchors: { item: {}; namedItem: {}; readonly length: {}; }; applets: {}; bgColor: {}; body: {}; readonly characterSet: {}; charset: {}; readonly compatMode: {}; cookie: {}; readonly currentScript: { async: {}; charset: {}; crossOrigin: {}; defer: {}; event: {}; htmlFor: {}; src: {}; text: {}; type: {}; integrity: {}; addEventListener: {}; removeEventListener: {}; accessKey: {}; readonly children: {}; contentEditable: {}; readonly dataset: {}; dir: {}; draggable: {}; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: {}; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; } | { type: {}; addEventListener: {}; removeEventListener: {}; className: {}; onclick: {}; ondblclick: {}; onfocusin: {}; onfocusout: {}; onload: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; readonly ownerSVGElement: { contentScriptType: {}; contentStyleType: {}; currentScale: {}; readonly currentTranslate: { x: {}; y: {}; matrixTransform: {}; }; readonly height: { readonly animVal: { readonly unitType: {}; value: {}; valueAsString: {}; valueInSpecifiedUnits: {}; convertToSpecifiedUnits: {}; newValueSpecifiedUnits: {}; readonly SVG_LENGTHTYPE_CM: {}; readonly SVG_LENGTHTYPE_EMS: {}; readonly SVG_LENGTHTYPE_EXS: {}; readonly SVG_LENGTHTYPE_IN: {}; readonly SVG_LENGTHTYPE_MM: {}; readonly SVG_LENGTHTYPE_NUMBER: {}; readonly SVG_LENGTHTYPE_PC: {}; readonly SVG_LENGTHTYPE_PERCENTAGE: {}; readonly SVG_LENGTHTYPE_PT: {}; readonly SVG_LENGTHTYPE_PX: {}; readonly SVG_LENGTHTYPE_UNKNOWN: {}; }; readonly baseVal: {}; }; onabort: {}; onerror: {}; onresize: {}; onscroll: {}; onunload: {}; onzoom: {}; readonly pixelUnitToMillimeterX: {}; readonly pixelUnitToMillimeterY: {}; readonly screenPixelToMillimeterX: {}; readonly screenPixelToMillimeterY: {}; readonly viewport: { height: {}; width: {}; x: {}; y: {}; }; readonly width: {}; readonly x: {}; readonly y: {}; checkEnclosure: {}; checkIntersection: {}; createSVGAngle: {}; createSVGLength: {}; createSVGMatrix: {}; createSVGNumber: {}; createSVGPoint: {}; createSVGRect: {}; createSVGTransform: {}; createSVGTransformFromMatrix: {}; deselectAll: {}; forceRedraw: {}; getComputedStyle: {}; getCurrentTime: {}; getElementById: {}; getEnclosureList: {}; getIntersectionList: {}; pauseAnimations: {}; setCurrentTime: {}; suspendRedraw: {}; unpauseAnimations: {}; unsuspendRedraw: {}; unsuspendRedrawAll: {}; addEventListener: {}; removeEventListener: {}; readonly farthestViewportElement: { className: {}; onclick: {}; ondblclick: {}; onfocusin: {}; onfocusout: {}; onload: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; readonly ownerSVGElement: {}; readonly style: {}; readonly viewportElement: {}; xmlbase: {}; addEventListener: {}; removeEventListener: {}; readonly classList: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; }; readonly nearestViewportElement: {}; readonly transform: { readonly animVal: { readonly numberOfItems: {}; appendItem: {}; clear: {}; consolidate: {}; createSVGTransformFromMatrix: {}; getItem: {}; initialize: {}; insertItemBefore: {}; removeItem: {}; replaceItem: {}; }; readonly baseVal: {}; }; getBBox: {}; getCTM: {}; getScreenCTM: {}; getTransformToElement: {}; className: {}; onclick: {}; ondblclick: {}; onfocusin: {}; onfocusout: {}; onload: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; readonly ownerSVGElement: {}; readonly style: {}; readonly viewportElement: {}; xmlbase: {}; readonly classList: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; readonly requiredExtensions: { readonly numberOfItems: {}; appendItem: {}; clear: {}; getItem: {}; initialize: {}; insertItemBefore: {}; removeItem: {}; replaceItem: {}; }; readonly requiredFeatures: {}; readonly systemLanguage: {}; hasExtension: {}; createEvent: {}; readonly preserveAspectRatio: { readonly animVal: { align: {}; meetOrSlice: {}; readonly SVG_MEETORSLICE_MEET: {}; readonly SVG_MEETORSLICE_SLICE: {}; readonly SVG_MEETORSLICE_UNKNOWN: {}; readonly SVG_PRESERVEASPECTRATIO_NONE: {}; readonly SVG_PRESERVEASPECTRATIO_UNKNOWN: {}; readonly SVG_PRESERVEASPECTRATIO_XMAXYMAX: {}; readonly SVG_PRESERVEASPECTRATIO_XMAXYMID: {}; readonly SVG_PRESERVEASPECTRATIO_XMAXYMIN: {}; readonly SVG_PRESERVEASPECTRATIO_XMIDYMAX: {}; readonly SVG_PRESERVEASPECTRATIO_XMIDYMID: {}; readonly SVG_PRESERVEASPECTRATIO_XMIDYMIN: {}; readonly SVG_PRESERVEASPECTRATIO_XMINYMAX: {}; readonly SVG_PRESERVEASPECTRATIO_XMINYMID: {}; readonly SVG_PRESERVEASPECTRATIO_XMINYMIN: {}; }; readonly baseVal: {}; }; readonly viewBox: { readonly animVal: {}; readonly baseVal: {}; }; readonly zoomAndPan: {}; }; readonly style: {}; readonly viewportElement: {}; xmlbase: {}; readonly classList: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; readonly href: { readonly animVal: {}; baseVal: {}; }; }; readonly defaultView: { readonly applicationCache: { oncached: {}; onchecking: {}; ondownloading: {}; onerror: {}; onnoupdate: {}; onobsolete: {}; onprogress: {}; onupdateready: {}; readonly status: {}; abort: {}; swapCache: {}; update: {}; readonly CHECKING: {}; readonly DOWNLOADING: {}; readonly IDLE: {}; readonly OBSOLETE: {}; readonly UNCACHED: {}; readonly UPDATEREADY: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; readonly caches: { delete: {}; has: {}; keys: {}; match: {}; open: {}; }; readonly clientInformation: { readonly authentication: { getAssertion: {}; makeCredential: {}; }; readonly cookieEnabled: {}; gamepadInputEmulation: {}; readonly language: {}; readonly maxTouchPoints: {}; readonly mimeTypes: { readonly length: {}; item: {}; namedItem: {}; }; readonly msManipulationViewsEnabled: {}; readonly msMaxTouchPoints: {}; readonly msPointerEnabled: {}; readonly plugins: { readonly length: {}; item: {}; namedItem: {}; refresh: {}; }; readonly pointerEnabled: {}; readonly serviceWorker: { readonly controller: { onstatechange: {}; readonly scriptURL: {}; readonly state: {}; postMessage: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onerror: {}; }; oncontrollerchange: {}; onmessage: {}; readonly ready: { then: {}; catch: {}; readonly [Symbol.toStringTag]: {}; }; getRegistration: {}; getRegistrations: {}; register: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; readonly webdriver: {}; readonly doNotTrack: {}; readonly hardwareConcurrency: {}; readonly languages: { length: {}; toString: {}; toLocaleString: {}; push: {}; pop: {}; concat: {}; join: {}; reverse: {}; shift: {}; slice: {}; sort: {}; splice: {}; unshift: {}; indexOf: {}; lastIndexOf: {}; every: {}; some: {}; forEach: {}; map: {}; filter: {}; reduce: {}; reduceRight: {}; [Symbol.unscopables]: {}; [Symbol.iterator]: {}; entries: {}; keys: {}; values: {}; find: {}; findIndex: {}; fill: {}; copyWithin: {}; }; getGamepads: {}; javaEnabled: {}; msLaunchUri: {}; requestMediaKeySystemAccess: {}; vibrate: {}; constructor: { apply: {}; call: {}; bind: {}; toString: {}; prototype: {}; readonly length: {}; arguments: {}; caller: {}; [Symbol.hasInstance]: {}; readonly name: {}; }; toString: {}; toLocaleString: {}; valueOf: {}; hasOwnProperty: {}; isPrototypeOf: {}; propertyIsEnumerable: {}; readonly appCodeName: {}; readonly appName: {}; readonly appVersion: {}; readonly platform: {}; readonly product: {}; readonly productSub: {}; readonly userAgent: {}; readonly vendor: {}; readonly vendorSub: {}; readonly onLine: {}; readonly geolocation: { clearWatch: {}; getCurrentPosition: {}; watchPosition: {}; }; confirmSiteSpecificTrackingException: {}; confirmWebWideTrackingException: {}; removeSiteSpecificTrackingException: {}; removeWebWideTrackingException: {}; storeSiteSpecificTrackingException: {}; storeWebWideTrackingException: {}; msSaveBlob: {}; msSaveOrOpenBlob: {}; sendBeacon: {}; readonly mediaDevices: { ondevicechange: {}; enumerateDevices: {}; getSupportedConstraints: {}; getUserMedia: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; getUserMedia: {}; }; readonly closed: {}; readonly crypto: { readonly subtle: { decrypt: {}; deriveBits: {}; deriveKey: {}; digest: {}; encrypt: {}; exportKey: {}; generateKey: {}; importKey: {}; sign: {}; unwrapKey: {}; verify: {}; wrapKey: {}; }; constructor: {}; toString: {}; toLocaleString: {}; valueOf: {}; hasOwnProperty: {}; isPrototypeOf: {}; propertyIsEnumerable: {}; getRandomValues: {}; }; defaultStatus: {}; readonly devicePixelRatio: {}; readonly document: {}; readonly doNotTrack: {}; event: { readonly bubbles: {}; readonly cancelable: {}; cancelBubble: {}; readonly currentTarget: { addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; }; readonly defaultPrevented: {}; readonly eventPhase: {}; readonly isTrusted: {}; returnValue: {}; readonly srcElement: {}; readonly target: {}; readonly timeStamp: {}; readonly type: {}; readonly scoped: {}; initEvent: {}; preventDefault: {}; stopImmediatePropagation: {}; stopPropagation: {}; deepPath: {}; readonly AT_TARGET: {}; readonly BUBBLING_PHASE: {}; readonly CAPTURING_PHASE: {}; }; readonly external: {}; readonly frameElement: {}; readonly frames: {}; readonly history: { readonly length: {}; readonly state: {}; scrollRestoration: {}; back: {}; forward: {}; go: {}; pushState: {}; replaceState: {}; }; readonly innerHeight: {}; readonly innerWidth: {}; readonly isSecureContext: {}; readonly length: {}; readonly location: { hash: {}; host: {}; hostname: {}; href: {}; readonly origin: {}; pathname: {}; port: {}; protocol: {}; search: {}; assign: {}; reload: {}; replace: {}; toString: {}; }; readonly locationbar: { readonly visible: {}; }; readonly menubar: {}; readonly msContentScript: { extensionIdToShortId: {}; fireExtensionApiTelemetry: {}; genericFunction: {}; genericSynchronousFunction: {}; getExtensionId: {}; registerGenericFunctionCallbackHandler: {}; registerGenericPersistentCallbackHandler: {}; }; readonly msCredentials: { getAssertion: {}; makeCredential: {}; }; name: {}; readonly navigator: {}; offscreenBuffering: {}; onabort: {}; onafterprint: {}; onbeforeprint: {}; onbeforeunload: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncompassneedscalibration: {}; oncontextmenu: {}; ondblclick: {}; ondevicelight: {}; ondevicemotion: {}; ondeviceorientation: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onhashchange: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmessage: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onoffline: {}; ononline: {}; onorientationchange: {}; onpagehide: {}; onpageshow: {}; onpause: {}; onplay: {}; onplaying: {}; onpopstate: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onresize: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onstalled: {}; onstorage: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onunload: {}; onvolumechange: {}; onwaiting: {}; opener: {}; orientation: {}; readonly outerHeight: {}; readonly outerWidth: {}; readonly pageXOffset: {}; readonly pageYOffset: {}; readonly parent: {}; readonly performance: { readonly navigation: { readonly redirectCount: {}; readonly type: {}; toJSON: {}; readonly TYPE_BACK_FORWARD: {}; readonly TYPE_NAVIGATE: {}; readonly TYPE_RELOAD: {}; readonly TYPE_RESERVED: {}; }; readonly timing: { readonly connectEnd: {}; readonly connectStart: {}; readonly domainLookupEnd: {}; readonly domainLookupStart: {}; readonly domComplete: {}; readonly domContentLoadedEventEnd: {}; readonly domContentLoadedEventStart: {}; readonly domInteractive: {}; readonly domLoading: {}; readonly fetchStart: {}; readonly loadEventEnd: {}; readonly loadEventStart: {}; readonly msFirstPaint: {}; readonly navigationStart: {}; readonly redirectEnd: {}; readonly redirectStart: {}; readonly requestStart: {}; readonly responseEnd: {}; readonly responseStart: {}; readonly unloadEventEnd: {}; readonly unloadEventStart: {}; readonly secureConnectionStart: {}; toJSON: {}; }; clearMarks: {}; clearMeasures: {}; clearResourceTimings: {}; getEntries: {}; getEntriesByName: {}; getEntriesByType: {}; getMarks: {}; getMeasures: {}; mark: {}; measure: {}; now: {}; setResourceTimingBufferSize: {}; toJSON: {}; }; readonly personalbar: {}; readonly screen: { readonly availHeight: {}; readonly availWidth: {}; bufferDepth: {}; readonly colorDepth: {}; readonly deviceXDPI: {}; readonly deviceYDPI: {}; readonly fontSmoothingEnabled: {}; readonly height: {}; readonly logicalXDPI: {}; readonly logicalYDPI: {}; readonly msOrientation: {}; onmsorientationchange: {}; readonly pixelDepth: {}; readonly systemXDPI: {}; readonly systemYDPI: {}; readonly width: {}; msLockOrientation: {}; msUnlockOrientation: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; readonly screenLeft: {}; readonly screenTop: {}; readonly screenX: {}; readonly screenY: {}; readonly scrollbars: {}; readonly scrollX: {}; readonly scrollY: {}; readonly self: {}; readonly speechSynthesis: { onvoiceschanged: {}; readonly paused: {}; readonly pending: {}; readonly speaking: {}; cancel: {}; getVoices: {}; pause: {}; resume: {}; speak: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; status: {}; readonly statusbar: {}; readonly styleMedia: { readonly type: {}; matchMedium: {}; }; readonly toolbar: {}; readonly top: {}; readonly window: {}; URL: { prototype: { hash: {}; host: {}; hostname: {}; href: {}; readonly origin: {}; password: {}; pathname: {}; port: {}; protocol: {}; search: {}; username: {}; readonly searchParams: { append: {}; delete: {}; get: {}; getAll: {}; has: {}; set: {}; }; toString: {}; }; createObjectURL: {}; revokeObjectURL: {}; }; URLSearchParams: { prototype: {}; }; Blob: { prototype: { readonly size: {}; readonly type: {}; msClose: {}; msDetachStream: {}; slice: {}; }; }; customElements: { define: {}; get: {}; whenDefined: {}; }; alert: {}; blur: {}; cancelAnimationFrame: {}; captureEvents: {}; close: {}; confirm: {}; departFocus: {}; focus: {}; getComputedStyle: {}; getMatchedCSSRules: {}; getSelection: {}; matchMedia: {}; moveBy: {}; moveTo: {}; msWriteProfilerMark: {}; open: {}; postMessage: {}; print: {}; prompt: {}; releaseEvents: {}; requestAnimationFrame: {}; resizeBy: {}; resizeTo: {}; scroll: {}; scrollBy: {}; scrollTo: {}; stop: {}; webkitCancelAnimationFrame: {}; webkitConvertPointFromNodeToPage: {}; webkitConvertPointFromPageToNode: {}; webkitRequestAnimationFrame: {}; createImageBitmap: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; clearInterval: {}; clearTimeout: {}; setInterval: {}; setTimeout: {}; constructor: {}; toString: {}; toLocaleString: {}; valueOf: {}; hasOwnProperty: {}; isPrototypeOf: {}; propertyIsEnumerable: {}; clearImmediate: {}; setImmediate: {}; readonly sessionStorage: { [x: string]: {}; readonly length: {}; clear: {}; getItem: {}; key: {}; removeItem: {}; setItem: {}; }; readonly localStorage: {}; readonly console: { assert: {}; clear: {}; count: {}; debug: {}; dir: {}; dirxml: {}; error: {}; exception: {}; group: {}; groupCollapsed: {}; groupEnd: {}; info: {}; log: {}; msIsIndependentlyComposed: {}; profile: {}; profileEnd: {}; select: {}; table: {}; time: {}; timeEnd: {}; trace: {}; warn: {}; }; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly indexedDB: { cmp: {}; deleteDatabase: {}; open: {}; }; atob: {}; btoa: {}; fetch: {}; }; designMode: {}; dir: {}; readonly doctype: { readonly entities: {}; readonly internalSubset: {}; readonly name: {}; readonly notations: {}; readonly publicId: {}; readonly systemId: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; remove: {}; }; documentElement: {}; domain: {}; embeds: {}; fgColor: {}; forms: {}; readonly fullscreenElement: {}; readonly fullscreenEnabled: {}; readonly head: { profile: {}; addEventListener: {}; removeEventListener: {}; accessKey: {}; readonly children: {}; contentEditable: {}; readonly dataset: {}; dir: {}; draggable: {}; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: {}; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; }; readonly hidden: {}; images: {}; readonly implementation: { createDocument: {}; createDocumentType: {}; createHTMLDocument: {}; hasFeature: {}; }; readonly inputEncoding: {}; readonly lastModified: {}; linkColor: {}; links: {}; readonly location: {}; msCapsLockWarningOff: {}; msCSSOMElementFloatMetrics: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforedeactivate: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onfullscreenchange: {}; onfullscreenerror: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmsmanipulationstatechanged: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onmssitemodejumplistitemremoved: {}; onmsthumbnailclick: {}; onpause: {}; onplay: {}; onplaying: {}; onpointerlockchange: {}; onpointerlockerror: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectionchange: {}; onselectstart: {}; onstalled: {}; onstop: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onvolumechange: {}; onwaiting: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; plugins: {}; readonly pointerLockElement: {}; readonly readyState: {}; readonly referrer: {}; readonly rootElement: {}; scripts: {}; readonly scrollingElement: {}; readonly styleSheets: {}; title: {}; readonly URL: {}; readonly URLUnencoded: {}; readonly visibilityState: {}; vlinkColor: {}; readonly webkitCurrentFullScreenElement: {}; readonly webkitFullscreenElement: {}; readonly webkitFullscreenEnabled: {}; readonly webkitIsFullScreen: {}; readonly xmlEncoding: {}; xmlStandalone: {}; xmlVersion: {}; adoptNode: {}; captureEvents: {}; caretRangeFromPoint: {}; clear: {}; close: {}; createAttribute: {}; createAttributeNS: {}; createCDATASection: {}; createComment: {}; createDocumentFragment: {}; createElement: {}; createElementNS: {}; createExpression: {}; createNodeIterator: {}; createNSResolver: {}; createProcessingInstruction: {}; createRange: {}; createTextNode: {}; createTouch: {}; createTouchList: {}; createTreeWalker: {}; elementFromPoint: {}; evaluate: {}; execCommand: {}; execCommandShowHelp: {}; exitFullscreen: {}; exitPointerLock: {}; focus: {}; getElementById: {}; getElementsByClassName: {}; getElementsByName: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; getSelection: {}; hasFocus: {}; importNode: {}; msElementsFromPoint: {}; msElementsFromRect: {}; open: {}; queryCommandEnabled: {}; queryCommandIndeterm: {}; queryCommandState: {}; queryCommandSupported: {}; queryCommandText: {}; queryCommandValue: {}; releaseEvents: {}; updateSettings: {}; webkitCancelFullScreen: {}; webkitExitFullscreen: {}; write: {}; writeln: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; querySelector: {}; querySelectorAll: {}; createEvent: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; readonly stylesheets: {}; elementsFromPoint: {}; }; readonly status: {}; readonly statusText: {}; timeout: {}; readonly upload: { addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; }; withCredentials: {}; msCaching?: {}; abort: {}; getAllResponseHeaders: {}; getResponseHeader: {}; msCachingEnabled: {}; open: {}; overrideMimeType: {}; send: {}; setRequestHeader: {}; readonly DONE: {}; readonly HEADERS_RECEIVED: {}; readonly LOADING: {}; readonly OPENED: {}; readonly UNSENT: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; } +>foo : (deep: Deep) => T +>xhr : XMLHttpRequest + diff --git a/tests/cases/compiler/mappedTypeRecursiveInference.ts b/tests/cases/compiler/mappedTypeRecursiveInference.ts index d7a9cf3a0be..e264244095d 100644 --- a/tests/cases/compiler/mappedTypeRecursiveInference.ts +++ b/tests/cases/compiler/mappedTypeRecursiveInference.ts @@ -1,5 +1,9 @@ +// @lib: es6, dom interface A { a: A } declare let a: A; type Deep = { [K in keyof T]: Deep } declare function foo(deep: Deep): T; const out = foo(a); + +let xhr: XMLHttpRequest; +const out2 = foo(xhr); From 955db84f2c556fddc459bab28440c681fa3d7d81 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 14 Dec 2017 15:03:12 -0800 Subject: [PATCH 010/189] Simplify printing of deferred mapped types Just print {} for the type of deferred symbols. This is simple although it loses fidelity pretty badly. It will not be sufficient for projects that want to export the result of an inference. I don't think any such projects exist right now, though. --- src/compiler/checker.ts | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index dbc12b1461a..6fc9ae48ae2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -335,7 +335,6 @@ namespace ts { const globals = createSymbolTable(); const deferredInferenceCache = createMap(); - const deferredMappedTypeInstantiationStack: string[] = []; let ambientModulesCache: Symbol[] | undefined; /** * List of every ambient module with a "*" wildcard. @@ -2868,23 +2867,7 @@ namespace ts { } for (const propertySymbol of properties) { - let propertyType: Type; - if (getCheckFlags(propertySymbol) & CheckFlags.DeferredInferred) { - const deferred = propertySymbol as DeferredTransientSymbol; - const key = deferred.propertyType.id + "," + (deferred.mappedType.symbol ? deferred.mappedType.symbol.id : ""); - // Temporary solution to recursive printing: zero out repeated types. - if (contains(deferredMappedTypeInstantiationStack, key)) { - // TODO: Could probably be an actual cache that returns {} when it contains undefined. - propertyType = emptyObjectType; - } - else { - deferredMappedTypeInstantiationStack.push(key) - propertyType = getTypeOfSymbol(propertySymbol); - } - } - else { - propertyType = getTypeOfSymbol(propertySymbol); - } + const propertyType = getCheckFlags(propertySymbol) & CheckFlags.DeferredInferred ? emptyObjectType : getTypeOfSymbol(propertySymbol); const saveEnclosingDeclaration = context.enclosingDeclaration; context.enclosingDeclaration = undefined; const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true); @@ -2911,9 +2894,6 @@ namespace ts { /*initializer*/ undefined); typeElements.push(propertySignature); } - if (getCheckFlags(propertySymbol) & CheckFlags.DeferredInferred) { - deferredMappedTypeInstantiationStack.pop(); - } } return typeElements.length ? typeElements : undefined; } @@ -11278,7 +11258,7 @@ namespace ts { const checkFlags = CheckFlags.DeferredInferred | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as DeferredTransientSymbol; inferredProp.declarations = prop.declarations; - inferredProp.propertyType = propType; // not sure I need this. + inferredProp.propertyType = propType; inferredProp.mappedType = target; members.set(prop.escapedName, inferredProp); } @@ -11295,7 +11275,6 @@ namespace ts { const typeParameter = getIndexedAccessType((getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target)); const templateType = getTemplateTypeFromMappedType(target); const inference = createInferenceInfo(typeParameter); - inference.candidates = undefined; inferTypes([inference], sourceType, templateType); return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : emptyObjectType; } From 5b45cf3db17e592b7415536b1b09e24c94ae08e1 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 14 Dec 2017 15:11:29 -0800 Subject: [PATCH 011/189] Update spelling --- src/compiler/checker.ts | 6 +++--- src/compiler/types.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6fc9ae48ae2..8833afbf32c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2867,7 +2867,7 @@ namespace ts { } for (const propertySymbol of properties) { - const propertyType = getCheckFlags(propertySymbol) & CheckFlags.DeferredInferred ? emptyObjectType : getTypeOfSymbol(propertySymbol); + const propertyType = getCheckFlags(propertySymbol) & CheckFlags.Deferred ? emptyObjectType : getTypeOfSymbol(propertySymbol); const saveEnclosingDeclaration = context.enclosingDeclaration; context.enclosingDeclaration = undefined; const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true); @@ -4868,7 +4868,7 @@ namespace ts { if (getCheckFlags(symbol) & CheckFlags.Instantiated) { return getTypeOfInstantiatedSymbol(symbol); } - if (getCheckFlags(symbol) & CheckFlags.DeferredInferred) { + if (getCheckFlags(symbol) & CheckFlags.Deferred) { return inferDeferredMappedType((symbol as DeferredTransientSymbol).propertyType, (symbol as DeferredTransientSymbol).mappedType); } if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) { @@ -11255,7 +11255,7 @@ namespace ts { if (propType.flags & TypeFlags.ContainsAnyFunctionType) { return undefined; } - const checkFlags = CheckFlags.DeferredInferred | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); + const checkFlags = CheckFlags.Deferred | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as DeferredTransientSymbol; inferredProp.declarations = prop.declarations; inferredProp.propertyType = propType; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index dc8c6d71618..afa62c0a382 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3217,7 +3217,7 @@ namespace ts { ContainsPrivate = 1 << 8, // Synthetic property with private constituent(s) ContainsStatic = 1 << 9, // Synthetic property with static constituent(s) Late = 1 << 10, // Late-bound symbol for a computed property with a dynamic name - DeferredInferred = 1 << 11, // Deferred inferred property of homomorphic mapped type. It is HILARIOUS. + Deferred = 1 << 11, // Deferred inferred property of homomorphic mapped type. Synthetic = SyntheticProperty | SyntheticMethod } From dd941e5665a8dd5742217fd255e7fc560001f967 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 14 Dec 2017 15:11:49 -0800 Subject: [PATCH 012/189] Add more tests of deferred mapped types --- .../isomorphicMappedTypeInference.types | 38 ++++++------- .../reference/keyofAndIndexedAccess.types | 4 +- .../mappedTypeInferenceErrors.errors.txt | 12 ++--- .../reference/mappedTypeRecursiveInference.js | 10 ++++ .../mappedTypeRecursiveInference.symbols | 51 ++++++++++++++++-- .../mappedTypeRecursiveInference.types | 53 +++++++++++++++++-- .../reference/thisTypeInObjectLiterals2.types | 30 +++++------ .../compiler/mappedTypeRecursiveInference.ts | 5 ++ 8 files changed, 154 insertions(+), 49 deletions(-) diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.types b/tests/baselines/reference/isomorphicMappedTypeInference.types index e60e1fb7b4c..a7e4011109a 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.types +++ b/tests/baselines/reference/isomorphicMappedTypeInference.types @@ -203,15 +203,15 @@ function f2() { }; let v = unboxify(b); ->v : { a: number; b: string; c: boolean; } ->unboxify(b) : { a: number; b: string; c: boolean; } +>v : { a: {}; b: {}; c: {}; } +>unboxify(b) : { a: {}; b: {}; c: {}; } >unboxify : (obj: Boxified) => T >b : { a: Box; b: Box; c: Box; } let x: number = v.a; >x : number >v.a : number ->v : { a: number; b: string; c: boolean; } +>v : { a: {}; b: {}; c: {}; } >a : number } @@ -277,11 +277,11 @@ function f4() { }; b = boxify(unboxify(b)); ->b = boxify(unboxify(b)) : Boxified<{ a: number; b: string; c: boolean; }> +>b = boxify(unboxify(b)) : Boxified<{ a: {}; b: {}; c: {}; }> >b : { a: Box; b: Box; c: Box; } ->boxify(unboxify(b)) : Boxified<{ a: number; b: string; c: boolean; }> +>boxify(unboxify(b)) : Boxified<{ a: {}; b: {}; c: {}; }> >boxify : (obj: T) => Boxified ->unboxify(b) : { a: number; b: string; c: boolean; } +>unboxify(b) : { a: {}; b: {}; c: {}; } >unboxify : (obj: Boxified) => T >b : { a: Box; b: Box; c: Box; } @@ -338,15 +338,15 @@ function f5(s: string) { }); let v = unboxify(b); ->v : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; } ->unboxify(b) : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; } +>v : { a: {}; b: {}; c: {}; } +>unboxify(b) : { a: {}; b: {}; c: {}; } >unboxify : (obj: Boxified) => T >b : { a: Box | Box | Box; b: Box | Box | Box; c: Box | Box | Box; } let x: string | number | boolean = v.a; >x : string | number | boolean >v.a : string | number | boolean ->v : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; } +>v : { a: {}; b: {}; c: {}; } >a : string | number | boolean } @@ -449,20 +449,20 @@ function f10(foo: Foo) { >Foo : Foo let x = validate(foo); // { a: number, readonly b: string } ->x : { a: number; readonly b: string; } ->validate(foo) : { a: number; readonly b: string; } +>x : { a: {}; readonly b: {}; } +>validate(foo) : { a: {}; readonly b: {}; } >validate : (obj: { [P in keyof T]?: T[P] | undefined; }) => T >foo : Foo let y = clone(foo); // { a?: number, b: string } ->y : { a?: number | undefined; b: string; } ->clone(foo) : { a?: number | undefined; b: string; } +>y : { a?: {}; b: {}; } +>clone(foo) : { a?: {}; b: {}; } >clone : (obj: { readonly [P in keyof T]: T[P]; }) => T >foo : Foo let z = validateAndClone(foo); // { a: number, b: string } ->z : { a: number; b: string; } ->validateAndClone(foo) : { a: number; b: string; } +>z : { a: {}; b: {}; } +>validateAndClone(foo) : { a: {}; b: {}; } >validateAndClone : (obj: { readonly [P in keyof T]?: T[P] | undefined; }) => T >foo : Foo } @@ -507,8 +507,8 @@ declare function applySpec(obj: Spec): (...args: any[]) => T; // Infers g1: (...args: any[]) => { sum: number, nested: { mul: string } } var g1 = applySpec({ ->g1 : (...args: any[]) => { sum: number; nested: { mul: string; }; } ->applySpec({ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }}) : (...args: any[]) => { sum: number; nested: { mul: string; }; } +>g1 : (...args: any[]) => { sum: {}; nested: {}; } +>applySpec({ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }}) : (...args: any[]) => { sum: {}; nested: {}; } >applySpec : (obj: Spec) => (...args: any[]) => T >{ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }} : { sum: (a: any) => number; nested: { mul: (b: any) => string; }; } @@ -532,8 +532,8 @@ var g1 = applySpec({ // Infers g2: (...args: any[]) => { foo: { bar: { baz: boolean } } } var g2 = applySpec({ foo: { bar: { baz: (x: any) => true } } }); ->g2 : (...args: any[]) => { foo: { bar: { baz: boolean; }; }; } ->applySpec({ foo: { bar: { baz: (x: any) => true } } }) : (...args: any[]) => { foo: { bar: { baz: boolean; }; }; } +>g2 : (...args: any[]) => { foo: {}; } +>applySpec({ foo: { bar: { baz: (x: any) => true } } }) : (...args: any[]) => { foo: {}; } >applySpec : (obj: Spec) => (...args: any[]) => T >{ foo: { bar: { baz: (x: any) => true } } } : { foo: { bar: { baz: (x: any) => boolean; }; }; } >foo : { bar: { baz: (x: any) => boolean; }; } diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index bf95972be76..9e09c2a3c35 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -1801,8 +1801,8 @@ var hashOfEmpty1 = on({ test: () => {} }); // {} >() => {} : () => void var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean } ->hashOfEmpty2 : { test: boolean; } ->on({ test: (x: boolean) => {} }) : { test: boolean; } +>hashOfEmpty2 : { test: {}; } +>on({ test: (x: boolean) => {} }) : { test: {}; } >on : (handlerHash: Handlers) => T >{ test: (x: boolean) => {} } : { test: (x: boolean) => void; } >test : (x: boolean) => void diff --git a/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt b/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt index 28bc188f7b6..2293fd6bfd5 100644 --- a/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt +++ b/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: number; baz: {}; }>'. - Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; }'. +tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: {}; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: {}; baz: {}; }>'. + Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: {}; baz: {}; }>; }'. Types of property 'computed' are incompatible. - Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: number; baz: {}; }>'. + Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: {}; baz: {}; }>'. Types of property 'baz' are incompatible. Type 'number' is not assignable to type '() => {}'. @@ -35,10 +35,10 @@ tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS ~~~~~ }); ~ -!!! error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: number; baz: {}; }>'. -!!! error TS2345: Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; }'. +!!! error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: {}; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: {}; baz: {}; }>'. +!!! error TS2345: Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: {}; baz: {}; }>; }'. !!! error TS2345: Types of property 'computed' are incompatible. -!!! error TS2345: Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: number; baz: {}; }>'. +!!! error TS2345: Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: {}; baz: {}; }>'. !!! error TS2345: Types of property 'baz' are incompatible. !!! error TS2345: Type 'number' is not assignable to type '() => {}'. \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.js b/tests/baselines/reference/mappedTypeRecursiveInference.js index eda4d0b618e..c1b5bc6f7bf 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.js +++ b/tests/baselines/reference/mappedTypeRecursiveInference.js @@ -4,12 +4,22 @@ declare let a: A; type Deep = { [K in keyof T]: Deep } declare function foo(deep: Deep): T; const out = foo(a); +out.a +out.a.a +out.a.a.a.a.a.a.a let xhr: XMLHttpRequest; const out2 = foo(xhr); +out2.responseXML +out2.responseXML.activeElement.className.length //// [mappedTypeRecursiveInference.js] var out = foo(a); +out.a; +out.a.a; +out.a.a.a.a.a.a.a; var xhr; var out2 = foo(xhr); +out2.responseXML; +out2.responseXML.activeElement.className.length; diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.symbols b/tests/baselines/reference/mappedTypeRecursiveInference.symbols index 96ed980c4c2..089468d4aa8 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.symbols +++ b/tests/baselines/reference/mappedTypeRecursiveInference.symbols @@ -30,12 +30,57 @@ const out = foo(a); >foo : Symbol(foo, Decl(mappedTypeRecursiveInference.ts, 2, 45)) >a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 1, 11)) +out.a +>out.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out : Symbol(out, Decl(mappedTypeRecursiveInference.ts, 4, 5)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) + +out.a.a +>out.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out : Symbol(out, Decl(mappedTypeRecursiveInference.ts, 4, 5)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) + +out.a.a.a.a.a.a.a +>out.a.a.a.a.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a.a.a.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a.a.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out : Symbol(out, Decl(mappedTypeRecursiveInference.ts, 4, 5)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) + let xhr: XMLHttpRequest; ->xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 6, 3)) +>xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 9, 3)) >XMLHttpRequest : Symbol(XMLHttpRequest, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) const out2 = foo(xhr); ->out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 7, 5)) +>out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 10, 5)) >foo : Symbol(foo, Decl(mappedTypeRecursiveInference.ts, 2, 45)) ->xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 6, 3)) +>xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 9, 3)) + +out2.responseXML +>out2.responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --)) +>out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 10, 5)) +>responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --)) + +out2.responseXML.activeElement.className.length +>out2.responseXML.activeElement.className.length : Symbol(length, Decl(lib.es5.d.ts, --, --)) +>out2.responseXML.activeElement.className : Symbol(className, Decl(lib.dom.d.ts, --, --)) +>out2.responseXML.activeElement : Symbol(activeElement, Decl(lib.dom.d.ts, --, --)) +>out2.responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --)) +>out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 10, 5)) +>responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --)) +>activeElement : Symbol(activeElement, Decl(lib.dom.d.ts, --, --)) +>className : Symbol(className, Decl(lib.dom.d.ts, --, --)) +>length : Symbol(length, Decl(lib.es5.d.ts, --, --)) diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.types b/tests/baselines/reference/mappedTypeRecursiveInference.types index 8dbc33e0b2a..eccb4ff65a1 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.types +++ b/tests/baselines/reference/mappedTypeRecursiveInference.types @@ -26,18 +26,63 @@ declare function foo(deep: Deep): T; >T : T const out = foo(a); ->out : { a: { a: {}; }; } ->foo(a) : { a: { a: {}; }; } +>out : { a: {}; } +>foo(a) : { a: {}; } >foo : (deep: Deep) => T >a : A +out.a +>out.a : { a: {}; } +>out : { a: {}; } +>a : { a: {}; } + +out.a.a +>out.a.a : { a: {}; } +>out.a : { a: {}; } +>out : { a: {}; } +>a : { a: {}; } +>a : { a: {}; } + +out.a.a.a.a.a.a.a +>out.a.a.a.a.a.a.a : { a: {}; } +>out.a.a.a.a.a.a : { a: {}; } +>out.a.a.a.a.a : { a: {}; } +>out.a.a.a.a : { a: {}; } +>out.a.a.a : { a: {}; } +>out.a.a : { a: {}; } +>out.a : { a: {}; } +>out : { a: {}; } +>a : { a: {}; } +>a : { a: {}; } +>a : { a: {}; } +>a : { a: {}; } +>a : { a: {}; } +>a : { a: {}; } +>a : { a: {}; } + let xhr: XMLHttpRequest; >xhr : XMLHttpRequest >XMLHttpRequest : XMLHttpRequest const out2 = foo(xhr); ->out2 : { onreadystatechange: {}; readonly readyState: { toString: {}; toFixed: {}; toExponential: {}; toPrecision: {}; valueOf: {}; toLocaleString: {}; }; readonly response: {}; readonly responseText: { toString: {}; charAt: {}; charCodeAt: {}; concat: {}; indexOf: {}; lastIndexOf: {}; localeCompare: {}; match: {}; replace: {}; search: {}; slice: {}; split: {}; substring: {}; toLowerCase: {}; toLocaleLowerCase: {}; toUpperCase: {}; toLocaleUpperCase: {}; trim: {}; readonly length: {}; substr: {}; valueOf: {}; [Symbol.iterator]: {}; codePointAt: {}; includes: {}; endsWith: {}; normalize: {}; repeat: {}; startsWith: {}; anchor: {}; big: {}; blink: {}; bold: {}; fixed: {}; fontcolor: {}; fontsize: {}; italics: {}; link: {}; small: {}; strike: {}; sub: {}; sup: {}; }; responseType: {}; readonly responseURL: {}; readonly responseXML: { readonly activeElement: { readonly classList: { readonly length: {}; add: {}; contains: {}; item: {}; remove: {}; toggle: {}; toString: {}; }; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: { name: {}; assignedNodes: {}; accessKey: {}; readonly children: { namedItem: {}; readonly length: {}; item: {}; }; contentEditable: {}; readonly dataset: { [x: string]: {}; }; dir: {}; draggable: { valueOf: {}; }; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: { alignContent: {}; alignItems: {}; alignmentBaseline: {}; alignSelf: {}; animation: {}; animationDelay: {}; animationDirection: {}; animationDuration: {}; animationFillMode: {}; animationIterationCount: {}; animationName: {}; animationPlayState: {}; animationTimingFunction: {}; backfaceVisibility: {}; background: {}; backgroundAttachment: {}; backgroundClip: {}; backgroundColor: {}; backgroundImage: {}; backgroundOrigin: {}; backgroundPosition: {}; backgroundPositionX: {}; backgroundPositionY: {}; backgroundRepeat: {}; backgroundSize: {}; baselineShift: {}; border: {}; borderBottom: {}; borderBottomColor: {}; borderBottomLeftRadius: {}; borderBottomRightRadius: {}; borderBottomStyle: {}; borderBottomWidth: {}; borderCollapse: {}; borderColor: {}; borderImage: {}; borderImageOutset: {}; borderImageRepeat: {}; borderImageSlice: {}; borderImageSource: {}; borderImageWidth: {}; borderLeft: {}; borderLeftColor: {}; borderLeftStyle: {}; borderLeftWidth: {}; borderRadius: {}; borderRight: {}; borderRightColor: {}; borderRightStyle: {}; borderRightWidth: {}; borderSpacing: {}; borderStyle: {}; borderTop: {}; borderTopColor: {}; borderTopLeftRadius: {}; borderTopRightRadius: {}; borderTopStyle: {}; borderTopWidth: {}; borderWidth: {}; bottom: {}; boxShadow: {}; boxSizing: {}; breakAfter: {}; breakBefore: {}; breakInside: {}; captionSide: {}; clear: {}; clip: {}; clipPath: {}; clipRule: {}; color: {}; colorInterpolationFilters: {}; columnCount: {}; columnFill: {}; columnGap: {}; columnRule: {}; columnRuleColor: {}; columnRuleStyle: {}; columnRuleWidth: {}; columns: {}; columnSpan: {}; columnWidth: {}; content: {}; counterIncrement: {}; counterReset: {}; cssFloat: {}; cssText: {}; cursor: {}; direction: {}; display: {}; dominantBaseline: {}; emptyCells: {}; enableBackground: {}; fill: {}; fillOpacity: {}; fillRule: {}; filter: {}; flex: {}; flexBasis: {}; flexDirection: {}; flexFlow: {}; flexGrow: {}; flexShrink: {}; flexWrap: {}; floodColor: {}; floodOpacity: {}; font: {}; fontFamily: {}; fontFeatureSettings: {}; fontSize: {}; fontSizeAdjust: {}; fontStretch: {}; fontStyle: {}; fontVariant: {}; fontWeight: {}; glyphOrientationHorizontal: {}; glyphOrientationVertical: {}; height: {}; imeMode: {}; justifyContent: {}; kerning: {}; layoutGrid: {}; layoutGridChar: {}; layoutGridLine: {}; layoutGridMode: {}; layoutGridType: {}; left: {}; readonly length: {}; letterSpacing: {}; lightingColor: {}; lineBreak: {}; lineHeight: {}; listStyle: {}; listStyleImage: {}; listStylePosition: {}; listStyleType: {}; margin: {}; marginBottom: {}; marginLeft: {}; marginRight: {}; marginTop: {}; marker: {}; markerEnd: {}; markerMid: {}; markerStart: {}; mask: {}; maxHeight: {}; maxWidth: {}; minHeight: {}; minWidth: {}; msContentZoomChaining: {}; msContentZooming: {}; msContentZoomLimit: {}; msContentZoomLimitMax: {}; msContentZoomLimitMin: {}; msContentZoomSnap: {}; msContentZoomSnapPoints: {}; msContentZoomSnapType: {}; msFlowFrom: {}; msFlowInto: {}; msFontFeatureSettings: {}; msGridColumn: {}; msGridColumnAlign: {}; msGridColumns: {}; msGridColumnSpan: {}; msGridRow: {}; msGridRowAlign: {}; msGridRows: {}; msGridRowSpan: {}; msHighContrastAdjust: {}; msHyphenateLimitChars: {}; msHyphenateLimitLines: {}; msHyphenateLimitZone: {}; msHyphens: {}; msImeAlign: {}; msOverflowStyle: {}; msScrollChaining: {}; msScrollLimit: {}; msScrollLimitXMax: {}; msScrollLimitXMin: {}; msScrollLimitYMax: {}; msScrollLimitYMin: {}; msScrollRails: {}; msScrollSnapPointsX: {}; msScrollSnapPointsY: {}; msScrollSnapType: {}; msScrollSnapX: {}; msScrollSnapY: {}; msScrollTranslation: {}; msTextCombineHorizontal: {}; msTextSizeAdjust: {}; msTouchAction: {}; msTouchSelect: {}; msUserSelect: {}; msWrapFlow: {}; msWrapMargin: {}; msWrapThrough: {}; opacity: {}; order: {}; orphans: {}; outline: {}; outlineColor: {}; outlineOffset: {}; outlineStyle: {}; outlineWidth: {}; overflow: {}; overflowX: {}; overflowY: {}; padding: {}; paddingBottom: {}; paddingLeft: {}; paddingRight: {}; paddingTop: {}; pageBreakAfter: {}; pageBreakBefore: {}; pageBreakInside: {}; readonly parentRule: { cssText: {}; readonly parentRule: {}; readonly parentStyleSheet: { readonly cssRules: { readonly length: {}; item: {}; }; cssText: {}; readonly id: {}; readonly imports: { readonly length: {}; item: {}; }; readonly isAlternate: {}; readonly isPrefAlternate: {}; readonly ownerRule: {}; readonly owningElement: {}; readonly pages: { readonly length: {}; item: {}; }; readonly readOnly: {}; readonly rules: {}; addImport: {}; addPageRule: {}; addRule: {}; deleteRule: {}; insertRule: {}; removeImport: {}; removeRule: {}; disabled: {}; readonly href: {}; readonly media: { readonly length: {}; mediaText: {}; appendMedium: {}; deleteMedium: {}; item: {}; toString: {}; }; readonly ownerNode: { readonly attributes: { readonly length: {}; getNamedItem: {}; getNamedItemNS: {}; item: {}; removeNamedItem: {}; removeNamedItemNS: {}; setNamedItem: {}; setNamedItemNS: {}; }; readonly baseURI: {}; readonly childNodes: { readonly length: {}; item: {}; }; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: { accessKey: {}; readonly children: {}; contentEditable: {}; readonly dataset: {}; dir: {}; draggable: {}; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: {}; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; addEventListener: {}; removeEventListener: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: { readonly host: {}; innerHTML: {}; readonly activeElement: {}; readonly stylesheets: {}; getSelection: {}; elementFromPoint: {}; elementsFromPoint: {}; getElementById: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; querySelector: {}; querySelectorAll: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; }; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; }; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; }; readonly parentStyleSheet: { disabled: {}; readonly href: {}; readonly media: {}; readonly ownerNode: {}; readonly parentStyleSheet: {}; readonly title: {}; readonly type: {}; }; readonly title: {}; readonly type: {}; }; readonly type: {}; readonly CHARSET_RULE: {}; readonly FONT_FACE_RULE: {}; readonly IMPORT_RULE: {}; readonly KEYFRAME_RULE: {}; readonly KEYFRAMES_RULE: {}; readonly MEDIA_RULE: {}; readonly NAMESPACE_RULE: {}; readonly PAGE_RULE: {}; readonly STYLE_RULE: {}; readonly SUPPORTS_RULE: {}; readonly UNKNOWN_RULE: {}; readonly VIEWPORT_RULE: {}; }; perspective: {}; perspectiveOrigin: {}; pointerEvents: {}; position: {}; quotes: {}; right: {}; rotate: {}; rubyAlign: {}; rubyOverhang: {}; rubyPosition: {}; scale: {}; stopColor: {}; stopOpacity: {}; stroke: {}; strokeDasharray: {}; strokeDashoffset: {}; strokeLinecap: {}; strokeLinejoin: {}; strokeMiterlimit: {}; strokeOpacity: {}; strokeWidth: {}; tableLayout: {}; textAlign: {}; textAlignLast: {}; textAnchor: {}; textDecoration: {}; textIndent: {}; textJustify: {}; textKashida: {}; textKashidaSpace: {}; textOverflow: {}; textShadow: {}; textTransform: {}; textUnderlinePosition: {}; top: {}; touchAction: {}; transform: {}; transformOrigin: {}; transformStyle: {}; transition: {}; transitionDelay: {}; transitionDuration: {}; transitionProperty: {}; transitionTimingFunction: {}; translate: {}; unicodeBidi: {}; verticalAlign: {}; visibility: {}; webkitAlignContent: {}; webkitAlignItems: {}; webkitAlignSelf: {}; webkitAnimation: {}; webkitAnimationDelay: {}; webkitAnimationDirection: {}; webkitAnimationDuration: {}; webkitAnimationFillMode: {}; webkitAnimationIterationCount: {}; webkitAnimationName: {}; webkitAnimationPlayState: {}; webkitAnimationTimingFunction: {}; webkitAppearance: {}; webkitBackfaceVisibility: {}; webkitBackgroundClip: {}; webkitBackgroundOrigin: {}; webkitBackgroundSize: {}; webkitBorderBottomLeftRadius: {}; webkitBorderBottomRightRadius: {}; webkitBorderImage: {}; webkitBorderRadius: {}; webkitBorderTopLeftRadius: {}; webkitBorderTopRightRadius: {}; webkitBoxAlign: {}; webkitBoxDirection: {}; webkitBoxFlex: {}; webkitBoxOrdinalGroup: {}; webkitBoxOrient: {}; webkitBoxPack: {}; webkitBoxSizing: {}; webkitColumnBreakAfter: {}; webkitColumnBreakBefore: {}; webkitColumnBreakInside: {}; webkitColumnCount: {}; webkitColumnGap: {}; webkitColumnRule: {}; webkitColumnRuleColor: {}; webkitColumnRuleStyle: {}; webkitColumnRuleWidth: {}; webkitColumns: {}; webkitColumnSpan: {}; webkitColumnWidth: {}; webkitFilter: {}; webkitFlex: {}; webkitFlexBasis: {}; webkitFlexDirection: {}; webkitFlexFlow: {}; webkitFlexGrow: {}; webkitFlexShrink: {}; webkitFlexWrap: {}; webkitJustifyContent: {}; webkitOrder: {}; webkitPerspective: {}; webkitPerspectiveOrigin: {}; webkitTapHighlightColor: {}; webkitTextFillColor: {}; webkitTextSizeAdjust: {}; webkitTextStroke: {}; webkitTextStrokeColor: {}; webkitTextStrokeWidth: {}; webkitTransform: {}; webkitTransformOrigin: {}; webkitTransformStyle: {}; webkitTransition: {}; webkitTransitionDelay: {}; webkitTransitionDuration: {}; webkitTransitionProperty: {}; webkitTransitionTimingFunction: {}; webkitUserModify: {}; webkitUserSelect: {}; webkitWritingMode: {}; whiteSpace: {}; widows: {}; width: {}; wordBreak: {}; wordSpacing: {}; wordWrap: {}; writingMode: {}; zIndex: {}; zoom: {}; resize: {}; userSelect: {}; getPropertyPriority: {}; getPropertyValue: {}; item: {}; removeProperty: {}; setProperty: {}; }; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; addEventListener: {}; removeEventListener: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; }; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; }; alinkColor: {}; readonly all: { readonly length: {}; item: {}; namedItem: {}; }; anchors: { item: {}; namedItem: {}; readonly length: {}; }; applets: {}; bgColor: {}; body: {}; readonly characterSet: {}; charset: {}; readonly compatMode: {}; cookie: {}; readonly currentScript: { async: {}; charset: {}; crossOrigin: {}; defer: {}; event: {}; htmlFor: {}; src: {}; text: {}; type: {}; integrity: {}; addEventListener: {}; removeEventListener: {}; accessKey: {}; readonly children: {}; contentEditable: {}; readonly dataset: {}; dir: {}; draggable: {}; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: {}; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; } | { type: {}; addEventListener: {}; removeEventListener: {}; className: {}; onclick: {}; ondblclick: {}; onfocusin: {}; onfocusout: {}; onload: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; readonly ownerSVGElement: { contentScriptType: {}; contentStyleType: {}; currentScale: {}; readonly currentTranslate: { x: {}; y: {}; matrixTransform: {}; }; readonly height: { readonly animVal: { readonly unitType: {}; value: {}; valueAsString: {}; valueInSpecifiedUnits: {}; convertToSpecifiedUnits: {}; newValueSpecifiedUnits: {}; readonly SVG_LENGTHTYPE_CM: {}; readonly SVG_LENGTHTYPE_EMS: {}; readonly SVG_LENGTHTYPE_EXS: {}; readonly SVG_LENGTHTYPE_IN: {}; readonly SVG_LENGTHTYPE_MM: {}; readonly SVG_LENGTHTYPE_NUMBER: {}; readonly SVG_LENGTHTYPE_PC: {}; readonly SVG_LENGTHTYPE_PERCENTAGE: {}; readonly SVG_LENGTHTYPE_PT: {}; readonly SVG_LENGTHTYPE_PX: {}; readonly SVG_LENGTHTYPE_UNKNOWN: {}; }; readonly baseVal: {}; }; onabort: {}; onerror: {}; onresize: {}; onscroll: {}; onunload: {}; onzoom: {}; readonly pixelUnitToMillimeterX: {}; readonly pixelUnitToMillimeterY: {}; readonly screenPixelToMillimeterX: {}; readonly screenPixelToMillimeterY: {}; readonly viewport: { height: {}; width: {}; x: {}; y: {}; }; readonly width: {}; readonly x: {}; readonly y: {}; checkEnclosure: {}; checkIntersection: {}; createSVGAngle: {}; createSVGLength: {}; createSVGMatrix: {}; createSVGNumber: {}; createSVGPoint: {}; createSVGRect: {}; createSVGTransform: {}; createSVGTransformFromMatrix: {}; deselectAll: {}; forceRedraw: {}; getComputedStyle: {}; getCurrentTime: {}; getElementById: {}; getEnclosureList: {}; getIntersectionList: {}; pauseAnimations: {}; setCurrentTime: {}; suspendRedraw: {}; unpauseAnimations: {}; unsuspendRedraw: {}; unsuspendRedrawAll: {}; addEventListener: {}; removeEventListener: {}; readonly farthestViewportElement: { className: {}; onclick: {}; ondblclick: {}; onfocusin: {}; onfocusout: {}; onload: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; readonly ownerSVGElement: {}; readonly style: {}; readonly viewportElement: {}; xmlbase: {}; addEventListener: {}; removeEventListener: {}; readonly classList: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; }; readonly nearestViewportElement: {}; readonly transform: { readonly animVal: { readonly numberOfItems: {}; appendItem: {}; clear: {}; consolidate: {}; createSVGTransformFromMatrix: {}; getItem: {}; initialize: {}; insertItemBefore: {}; removeItem: {}; replaceItem: {}; }; readonly baseVal: {}; }; getBBox: {}; getCTM: {}; getScreenCTM: {}; getTransformToElement: {}; className: {}; onclick: {}; ondblclick: {}; onfocusin: {}; onfocusout: {}; onload: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; readonly ownerSVGElement: {}; readonly style: {}; readonly viewportElement: {}; xmlbase: {}; readonly classList: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; readonly requiredExtensions: { readonly numberOfItems: {}; appendItem: {}; clear: {}; getItem: {}; initialize: {}; insertItemBefore: {}; removeItem: {}; replaceItem: {}; }; readonly requiredFeatures: {}; readonly systemLanguage: {}; hasExtension: {}; createEvent: {}; readonly preserveAspectRatio: { readonly animVal: { align: {}; meetOrSlice: {}; readonly SVG_MEETORSLICE_MEET: {}; readonly SVG_MEETORSLICE_SLICE: {}; readonly SVG_MEETORSLICE_UNKNOWN: {}; readonly SVG_PRESERVEASPECTRATIO_NONE: {}; readonly SVG_PRESERVEASPECTRATIO_UNKNOWN: {}; readonly SVG_PRESERVEASPECTRATIO_XMAXYMAX: {}; readonly SVG_PRESERVEASPECTRATIO_XMAXYMID: {}; readonly SVG_PRESERVEASPECTRATIO_XMAXYMIN: {}; readonly SVG_PRESERVEASPECTRATIO_XMIDYMAX: {}; readonly SVG_PRESERVEASPECTRATIO_XMIDYMID: {}; readonly SVG_PRESERVEASPECTRATIO_XMIDYMIN: {}; readonly SVG_PRESERVEASPECTRATIO_XMINYMAX: {}; readonly SVG_PRESERVEASPECTRATIO_XMINYMID: {}; readonly SVG_PRESERVEASPECTRATIO_XMINYMIN: {}; }; readonly baseVal: {}; }; readonly viewBox: { readonly animVal: {}; readonly baseVal: {}; }; readonly zoomAndPan: {}; }; readonly style: {}; readonly viewportElement: {}; xmlbase: {}; readonly classList: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; readonly href: { readonly animVal: {}; baseVal: {}; }; }; readonly defaultView: { readonly applicationCache: { oncached: {}; onchecking: {}; ondownloading: {}; onerror: {}; onnoupdate: {}; onobsolete: {}; onprogress: {}; onupdateready: {}; readonly status: {}; abort: {}; swapCache: {}; update: {}; readonly CHECKING: {}; readonly DOWNLOADING: {}; readonly IDLE: {}; readonly OBSOLETE: {}; readonly UNCACHED: {}; readonly UPDATEREADY: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; readonly caches: { delete: {}; has: {}; keys: {}; match: {}; open: {}; }; readonly clientInformation: { readonly authentication: { getAssertion: {}; makeCredential: {}; }; readonly cookieEnabled: {}; gamepadInputEmulation: {}; readonly language: {}; readonly maxTouchPoints: {}; readonly mimeTypes: { readonly length: {}; item: {}; namedItem: {}; }; readonly msManipulationViewsEnabled: {}; readonly msMaxTouchPoints: {}; readonly msPointerEnabled: {}; readonly plugins: { readonly length: {}; item: {}; namedItem: {}; refresh: {}; }; readonly pointerEnabled: {}; readonly serviceWorker: { readonly controller: { onstatechange: {}; readonly scriptURL: {}; readonly state: {}; postMessage: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onerror: {}; }; oncontrollerchange: {}; onmessage: {}; readonly ready: { then: {}; catch: {}; readonly [Symbol.toStringTag]: {}; }; getRegistration: {}; getRegistrations: {}; register: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; readonly webdriver: {}; readonly doNotTrack: {}; readonly hardwareConcurrency: {}; readonly languages: { length: {}; toString: {}; toLocaleString: {}; push: {}; pop: {}; concat: {}; join: {}; reverse: {}; shift: {}; slice: {}; sort: {}; splice: {}; unshift: {}; indexOf: {}; lastIndexOf: {}; every: {}; some: {}; forEach: {}; map: {}; filter: {}; reduce: {}; reduceRight: {}; [Symbol.unscopables]: {}; [Symbol.iterator]: {}; entries: {}; keys: {}; values: {}; find: {}; findIndex: {}; fill: {}; copyWithin: {}; }; getGamepads: {}; javaEnabled: {}; msLaunchUri: {}; requestMediaKeySystemAccess: {}; vibrate: {}; constructor: { apply: {}; call: {}; bind: {}; toString: {}; prototype: {}; readonly length: {}; arguments: {}; caller: {}; [Symbol.hasInstance]: {}; readonly name: {}; }; toString: {}; toLocaleString: {}; valueOf: {}; hasOwnProperty: {}; isPrototypeOf: {}; propertyIsEnumerable: {}; readonly appCodeName: {}; readonly appName: {}; readonly appVersion: {}; readonly platform: {}; readonly product: {}; readonly productSub: {}; readonly userAgent: {}; readonly vendor: {}; readonly vendorSub: {}; readonly onLine: {}; readonly geolocation: { clearWatch: {}; getCurrentPosition: {}; watchPosition: {}; }; confirmSiteSpecificTrackingException: {}; confirmWebWideTrackingException: {}; removeSiteSpecificTrackingException: {}; removeWebWideTrackingException: {}; storeSiteSpecificTrackingException: {}; storeWebWideTrackingException: {}; msSaveBlob: {}; msSaveOrOpenBlob: {}; sendBeacon: {}; readonly mediaDevices: { ondevicechange: {}; enumerateDevices: {}; getSupportedConstraints: {}; getUserMedia: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; getUserMedia: {}; }; readonly closed: {}; readonly crypto: { readonly subtle: { decrypt: {}; deriveBits: {}; deriveKey: {}; digest: {}; encrypt: {}; exportKey: {}; generateKey: {}; importKey: {}; sign: {}; unwrapKey: {}; verify: {}; wrapKey: {}; }; constructor: {}; toString: {}; toLocaleString: {}; valueOf: {}; hasOwnProperty: {}; isPrototypeOf: {}; propertyIsEnumerable: {}; getRandomValues: {}; }; defaultStatus: {}; readonly devicePixelRatio: {}; readonly document: {}; readonly doNotTrack: {}; event: { readonly bubbles: {}; readonly cancelable: {}; cancelBubble: {}; readonly currentTarget: { addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; }; readonly defaultPrevented: {}; readonly eventPhase: {}; readonly isTrusted: {}; returnValue: {}; readonly srcElement: {}; readonly target: {}; readonly timeStamp: {}; readonly type: {}; readonly scoped: {}; initEvent: {}; preventDefault: {}; stopImmediatePropagation: {}; stopPropagation: {}; deepPath: {}; readonly AT_TARGET: {}; readonly BUBBLING_PHASE: {}; readonly CAPTURING_PHASE: {}; }; readonly external: {}; readonly frameElement: {}; readonly frames: {}; readonly history: { readonly length: {}; readonly state: {}; scrollRestoration: {}; back: {}; forward: {}; go: {}; pushState: {}; replaceState: {}; }; readonly innerHeight: {}; readonly innerWidth: {}; readonly isSecureContext: {}; readonly length: {}; readonly location: { hash: {}; host: {}; hostname: {}; href: {}; readonly origin: {}; pathname: {}; port: {}; protocol: {}; search: {}; assign: {}; reload: {}; replace: {}; toString: {}; }; readonly locationbar: { readonly visible: {}; }; readonly menubar: {}; readonly msContentScript: { extensionIdToShortId: {}; fireExtensionApiTelemetry: {}; genericFunction: {}; genericSynchronousFunction: {}; getExtensionId: {}; registerGenericFunctionCallbackHandler: {}; registerGenericPersistentCallbackHandler: {}; }; readonly msCredentials: { getAssertion: {}; makeCredential: {}; }; name: {}; readonly navigator: {}; offscreenBuffering: {}; onabort: {}; onafterprint: {}; onbeforeprint: {}; onbeforeunload: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncompassneedscalibration: {}; oncontextmenu: {}; ondblclick: {}; ondevicelight: {}; ondevicemotion: {}; ondeviceorientation: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onhashchange: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmessage: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onoffline: {}; ononline: {}; onorientationchange: {}; onpagehide: {}; onpageshow: {}; onpause: {}; onplay: {}; onplaying: {}; onpopstate: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onresize: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onstalled: {}; onstorage: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onunload: {}; onvolumechange: {}; onwaiting: {}; opener: {}; orientation: {}; readonly outerHeight: {}; readonly outerWidth: {}; readonly pageXOffset: {}; readonly pageYOffset: {}; readonly parent: {}; readonly performance: { readonly navigation: { readonly redirectCount: {}; readonly type: {}; toJSON: {}; readonly TYPE_BACK_FORWARD: {}; readonly TYPE_NAVIGATE: {}; readonly TYPE_RELOAD: {}; readonly TYPE_RESERVED: {}; }; readonly timing: { readonly connectEnd: {}; readonly connectStart: {}; readonly domainLookupEnd: {}; readonly domainLookupStart: {}; readonly domComplete: {}; readonly domContentLoadedEventEnd: {}; readonly domContentLoadedEventStart: {}; readonly domInteractive: {}; readonly domLoading: {}; readonly fetchStart: {}; readonly loadEventEnd: {}; readonly loadEventStart: {}; readonly msFirstPaint: {}; readonly navigationStart: {}; readonly redirectEnd: {}; readonly redirectStart: {}; readonly requestStart: {}; readonly responseEnd: {}; readonly responseStart: {}; readonly unloadEventEnd: {}; readonly unloadEventStart: {}; readonly secureConnectionStart: {}; toJSON: {}; }; clearMarks: {}; clearMeasures: {}; clearResourceTimings: {}; getEntries: {}; getEntriesByName: {}; getEntriesByType: {}; getMarks: {}; getMeasures: {}; mark: {}; measure: {}; now: {}; setResourceTimingBufferSize: {}; toJSON: {}; }; readonly personalbar: {}; readonly screen: { readonly availHeight: {}; readonly availWidth: {}; bufferDepth: {}; readonly colorDepth: {}; readonly deviceXDPI: {}; readonly deviceYDPI: {}; readonly fontSmoothingEnabled: {}; readonly height: {}; readonly logicalXDPI: {}; readonly logicalYDPI: {}; readonly msOrientation: {}; onmsorientationchange: {}; readonly pixelDepth: {}; readonly systemXDPI: {}; readonly systemYDPI: {}; readonly width: {}; msLockOrientation: {}; msUnlockOrientation: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; readonly screenLeft: {}; readonly screenTop: {}; readonly screenX: {}; readonly screenY: {}; readonly scrollbars: {}; readonly scrollX: {}; readonly scrollY: {}; readonly self: {}; readonly speechSynthesis: { onvoiceschanged: {}; readonly paused: {}; readonly pending: {}; readonly speaking: {}; cancel: {}; getVoices: {}; pause: {}; resume: {}; speak: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; status: {}; readonly statusbar: {}; readonly styleMedia: { readonly type: {}; matchMedium: {}; }; readonly toolbar: {}; readonly top: {}; readonly window: {}; URL: { prototype: { hash: {}; host: {}; hostname: {}; href: {}; readonly origin: {}; password: {}; pathname: {}; port: {}; protocol: {}; search: {}; username: {}; readonly searchParams: { append: {}; delete: {}; get: {}; getAll: {}; has: {}; set: {}; }; toString: {}; }; createObjectURL: {}; revokeObjectURL: {}; }; URLSearchParams: { prototype: {}; }; Blob: { prototype: { readonly size: {}; readonly type: {}; msClose: {}; msDetachStream: {}; slice: {}; }; }; customElements: { define: {}; get: {}; whenDefined: {}; }; alert: {}; blur: {}; cancelAnimationFrame: {}; captureEvents: {}; close: {}; confirm: {}; departFocus: {}; focus: {}; getComputedStyle: {}; getMatchedCSSRules: {}; getSelection: {}; matchMedia: {}; moveBy: {}; moveTo: {}; msWriteProfilerMark: {}; open: {}; postMessage: {}; print: {}; prompt: {}; releaseEvents: {}; requestAnimationFrame: {}; resizeBy: {}; resizeTo: {}; scroll: {}; scrollBy: {}; scrollTo: {}; stop: {}; webkitCancelAnimationFrame: {}; webkitConvertPointFromNodeToPage: {}; webkitConvertPointFromPageToNode: {}; webkitRequestAnimationFrame: {}; createImageBitmap: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; clearInterval: {}; clearTimeout: {}; setInterval: {}; setTimeout: {}; constructor: {}; toString: {}; toLocaleString: {}; valueOf: {}; hasOwnProperty: {}; isPrototypeOf: {}; propertyIsEnumerable: {}; clearImmediate: {}; setImmediate: {}; readonly sessionStorage: { [x: string]: {}; readonly length: {}; clear: {}; getItem: {}; key: {}; removeItem: {}; setItem: {}; }; readonly localStorage: {}; readonly console: { assert: {}; clear: {}; count: {}; debug: {}; dir: {}; dirxml: {}; error: {}; exception: {}; group: {}; groupCollapsed: {}; groupEnd: {}; info: {}; log: {}; msIsIndependentlyComposed: {}; profile: {}; profileEnd: {}; select: {}; table: {}; time: {}; timeEnd: {}; trace: {}; warn: {}; }; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly indexedDB: { cmp: {}; deleteDatabase: {}; open: {}; }; atob: {}; btoa: {}; fetch: {}; }; designMode: {}; dir: {}; readonly doctype: { readonly entities: {}; readonly internalSubset: {}; readonly name: {}; readonly notations: {}; readonly publicId: {}; readonly systemId: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; remove: {}; }; documentElement: {}; domain: {}; embeds: {}; fgColor: {}; forms: {}; readonly fullscreenElement: {}; readonly fullscreenEnabled: {}; readonly head: { profile: {}; addEventListener: {}; removeEventListener: {}; accessKey: {}; readonly children: {}; contentEditable: {}; readonly dataset: {}; dir: {}; draggable: {}; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: {}; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; }; readonly hidden: {}; images: {}; readonly implementation: { createDocument: {}; createDocumentType: {}; createHTMLDocument: {}; hasFeature: {}; }; readonly inputEncoding: {}; readonly lastModified: {}; linkColor: {}; links: {}; readonly location: {}; msCapsLockWarningOff: {}; msCSSOMElementFloatMetrics: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforedeactivate: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onfullscreenchange: {}; onfullscreenerror: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmsmanipulationstatechanged: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onmssitemodejumplistitemremoved: {}; onmsthumbnailclick: {}; onpause: {}; onplay: {}; onplaying: {}; onpointerlockchange: {}; onpointerlockerror: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectionchange: {}; onselectstart: {}; onstalled: {}; onstop: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onvolumechange: {}; onwaiting: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; plugins: {}; readonly pointerLockElement: {}; readonly readyState: {}; readonly referrer: {}; readonly rootElement: {}; scripts: {}; readonly scrollingElement: {}; readonly styleSheets: {}; title: {}; readonly URL: {}; readonly URLUnencoded: {}; readonly visibilityState: {}; vlinkColor: {}; readonly webkitCurrentFullScreenElement: {}; readonly webkitFullscreenElement: {}; readonly webkitFullscreenEnabled: {}; readonly webkitIsFullScreen: {}; readonly xmlEncoding: {}; xmlStandalone: {}; xmlVersion: {}; adoptNode: {}; captureEvents: {}; caretRangeFromPoint: {}; clear: {}; close: {}; createAttribute: {}; createAttributeNS: {}; createCDATASection: {}; createComment: {}; createDocumentFragment: {}; createElement: {}; createElementNS: {}; createExpression: {}; createNodeIterator: {}; createNSResolver: {}; createProcessingInstruction: {}; createRange: {}; createTextNode: {}; createTouch: {}; createTouchList: {}; createTreeWalker: {}; elementFromPoint: {}; evaluate: {}; execCommand: {}; execCommandShowHelp: {}; exitFullscreen: {}; exitPointerLock: {}; focus: {}; getElementById: {}; getElementsByClassName: {}; getElementsByName: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; getSelection: {}; hasFocus: {}; importNode: {}; msElementsFromPoint: {}; msElementsFromRect: {}; open: {}; queryCommandEnabled: {}; queryCommandIndeterm: {}; queryCommandState: {}; queryCommandSupported: {}; queryCommandText: {}; queryCommandValue: {}; releaseEvents: {}; updateSettings: {}; webkitCancelFullScreen: {}; webkitExitFullscreen: {}; write: {}; writeln: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; querySelector: {}; querySelectorAll: {}; createEvent: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; readonly stylesheets: {}; elementsFromPoint: {}; }; readonly status: {}; readonly statusText: {}; timeout: {}; readonly upload: { addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; }; withCredentials: {}; msCaching?: {}; abort: {}; getAllResponseHeaders: {}; getResponseHeader: {}; msCachingEnabled: {}; open: {}; overrideMimeType: {}; send: {}; setRequestHeader: {}; readonly DONE: {}; readonly HEADERS_RECEIVED: {}; readonly LOADING: {}; readonly OPENED: {}; readonly UNSENT: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; } ->foo(xhr) : { onreadystatechange: {}; readonly readyState: { toString: {}; toFixed: {}; toExponential: {}; toPrecision: {}; valueOf: {}; toLocaleString: {}; }; readonly response: {}; readonly responseText: { toString: {}; charAt: {}; charCodeAt: {}; concat: {}; indexOf: {}; lastIndexOf: {}; localeCompare: {}; match: {}; replace: {}; search: {}; slice: {}; split: {}; substring: {}; toLowerCase: {}; toLocaleLowerCase: {}; toUpperCase: {}; toLocaleUpperCase: {}; trim: {}; readonly length: {}; substr: {}; valueOf: {}; [Symbol.iterator]: {}; codePointAt: {}; includes: {}; endsWith: {}; normalize: {}; repeat: {}; startsWith: {}; anchor: {}; big: {}; blink: {}; bold: {}; fixed: {}; fontcolor: {}; fontsize: {}; italics: {}; link: {}; small: {}; strike: {}; sub: {}; sup: {}; }; responseType: {}; readonly responseURL: {}; readonly responseXML: { readonly activeElement: { readonly classList: { readonly length: {}; add: {}; contains: {}; item: {}; remove: {}; toggle: {}; toString: {}; }; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: { name: {}; assignedNodes: {}; accessKey: {}; readonly children: { namedItem: {}; readonly length: {}; item: {}; }; contentEditable: {}; readonly dataset: { [x: string]: {}; }; dir: {}; draggable: { valueOf: {}; }; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: { alignContent: {}; alignItems: {}; alignmentBaseline: {}; alignSelf: {}; animation: {}; animationDelay: {}; animationDirection: {}; animationDuration: {}; animationFillMode: {}; animationIterationCount: {}; animationName: {}; animationPlayState: {}; animationTimingFunction: {}; backfaceVisibility: {}; background: {}; backgroundAttachment: {}; backgroundClip: {}; backgroundColor: {}; backgroundImage: {}; backgroundOrigin: {}; backgroundPosition: {}; backgroundPositionX: {}; backgroundPositionY: {}; backgroundRepeat: {}; backgroundSize: {}; baselineShift: {}; border: {}; borderBottom: {}; borderBottomColor: {}; borderBottomLeftRadius: {}; borderBottomRightRadius: {}; borderBottomStyle: {}; borderBottomWidth: {}; borderCollapse: {}; borderColor: {}; borderImage: {}; borderImageOutset: {}; borderImageRepeat: {}; borderImageSlice: {}; borderImageSource: {}; borderImageWidth: {}; borderLeft: {}; borderLeftColor: {}; borderLeftStyle: {}; borderLeftWidth: {}; borderRadius: {}; borderRight: {}; borderRightColor: {}; borderRightStyle: {}; borderRightWidth: {}; borderSpacing: {}; borderStyle: {}; borderTop: {}; borderTopColor: {}; borderTopLeftRadius: {}; borderTopRightRadius: {}; borderTopStyle: {}; borderTopWidth: {}; borderWidth: {}; bottom: {}; boxShadow: {}; boxSizing: {}; breakAfter: {}; breakBefore: {}; breakInside: {}; captionSide: {}; clear: {}; clip: {}; clipPath: {}; clipRule: {}; color: {}; colorInterpolationFilters: {}; columnCount: {}; columnFill: {}; columnGap: {}; columnRule: {}; columnRuleColor: {}; columnRuleStyle: {}; columnRuleWidth: {}; columns: {}; columnSpan: {}; columnWidth: {}; content: {}; counterIncrement: {}; counterReset: {}; cssFloat: {}; cssText: {}; cursor: {}; direction: {}; display: {}; dominantBaseline: {}; emptyCells: {}; enableBackground: {}; fill: {}; fillOpacity: {}; fillRule: {}; filter: {}; flex: {}; flexBasis: {}; flexDirection: {}; flexFlow: {}; flexGrow: {}; flexShrink: {}; flexWrap: {}; floodColor: {}; floodOpacity: {}; font: {}; fontFamily: {}; fontFeatureSettings: {}; fontSize: {}; fontSizeAdjust: {}; fontStretch: {}; fontStyle: {}; fontVariant: {}; fontWeight: {}; glyphOrientationHorizontal: {}; glyphOrientationVertical: {}; height: {}; imeMode: {}; justifyContent: {}; kerning: {}; layoutGrid: {}; layoutGridChar: {}; layoutGridLine: {}; layoutGridMode: {}; layoutGridType: {}; left: {}; readonly length: {}; letterSpacing: {}; lightingColor: {}; lineBreak: {}; lineHeight: {}; listStyle: {}; listStyleImage: {}; listStylePosition: {}; listStyleType: {}; margin: {}; marginBottom: {}; marginLeft: {}; marginRight: {}; marginTop: {}; marker: {}; markerEnd: {}; markerMid: {}; markerStart: {}; mask: {}; maxHeight: {}; maxWidth: {}; minHeight: {}; minWidth: {}; msContentZoomChaining: {}; msContentZooming: {}; msContentZoomLimit: {}; msContentZoomLimitMax: {}; msContentZoomLimitMin: {}; msContentZoomSnap: {}; msContentZoomSnapPoints: {}; msContentZoomSnapType: {}; msFlowFrom: {}; msFlowInto: {}; msFontFeatureSettings: {}; msGridColumn: {}; msGridColumnAlign: {}; msGridColumns: {}; msGridColumnSpan: {}; msGridRow: {}; msGridRowAlign: {}; msGridRows: {}; msGridRowSpan: {}; msHighContrastAdjust: {}; msHyphenateLimitChars: {}; msHyphenateLimitLines: {}; msHyphenateLimitZone: {}; msHyphens: {}; msImeAlign: {}; msOverflowStyle: {}; msScrollChaining: {}; msScrollLimit: {}; msScrollLimitXMax: {}; msScrollLimitXMin: {}; msScrollLimitYMax: {}; msScrollLimitYMin: {}; msScrollRails: {}; msScrollSnapPointsX: {}; msScrollSnapPointsY: {}; msScrollSnapType: {}; msScrollSnapX: {}; msScrollSnapY: {}; msScrollTranslation: {}; msTextCombineHorizontal: {}; msTextSizeAdjust: {}; msTouchAction: {}; msTouchSelect: {}; msUserSelect: {}; msWrapFlow: {}; msWrapMargin: {}; msWrapThrough: {}; opacity: {}; order: {}; orphans: {}; outline: {}; outlineColor: {}; outlineOffset: {}; outlineStyle: {}; outlineWidth: {}; overflow: {}; overflowX: {}; overflowY: {}; padding: {}; paddingBottom: {}; paddingLeft: {}; paddingRight: {}; paddingTop: {}; pageBreakAfter: {}; pageBreakBefore: {}; pageBreakInside: {}; readonly parentRule: { cssText: {}; readonly parentRule: {}; readonly parentStyleSheet: { readonly cssRules: { readonly length: {}; item: {}; }; cssText: {}; readonly id: {}; readonly imports: { readonly length: {}; item: {}; }; readonly isAlternate: {}; readonly isPrefAlternate: {}; readonly ownerRule: {}; readonly owningElement: {}; readonly pages: { readonly length: {}; item: {}; }; readonly readOnly: {}; readonly rules: {}; addImport: {}; addPageRule: {}; addRule: {}; deleteRule: {}; insertRule: {}; removeImport: {}; removeRule: {}; disabled: {}; readonly href: {}; readonly media: { readonly length: {}; mediaText: {}; appendMedium: {}; deleteMedium: {}; item: {}; toString: {}; }; readonly ownerNode: { readonly attributes: { readonly length: {}; getNamedItem: {}; getNamedItemNS: {}; item: {}; removeNamedItem: {}; removeNamedItemNS: {}; setNamedItem: {}; setNamedItemNS: {}; }; readonly baseURI: {}; readonly childNodes: { readonly length: {}; item: {}; }; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: { accessKey: {}; readonly children: {}; contentEditable: {}; readonly dataset: {}; dir: {}; draggable: {}; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: {}; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; addEventListener: {}; removeEventListener: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: { readonly host: {}; innerHTML: {}; readonly activeElement: {}; readonly stylesheets: {}; getSelection: {}; elementFromPoint: {}; elementsFromPoint: {}; getElementById: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; querySelector: {}; querySelectorAll: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; }; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; }; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; }; readonly parentStyleSheet: { disabled: {}; readonly href: {}; readonly media: {}; readonly ownerNode: {}; readonly parentStyleSheet: {}; readonly title: {}; readonly type: {}; }; readonly title: {}; readonly type: {}; }; readonly type: {}; readonly CHARSET_RULE: {}; readonly FONT_FACE_RULE: {}; readonly IMPORT_RULE: {}; readonly KEYFRAME_RULE: {}; readonly KEYFRAMES_RULE: {}; readonly MEDIA_RULE: {}; readonly NAMESPACE_RULE: {}; readonly PAGE_RULE: {}; readonly STYLE_RULE: {}; readonly SUPPORTS_RULE: {}; readonly UNKNOWN_RULE: {}; readonly VIEWPORT_RULE: {}; }; perspective: {}; perspectiveOrigin: {}; pointerEvents: {}; position: {}; quotes: {}; right: {}; rotate: {}; rubyAlign: {}; rubyOverhang: {}; rubyPosition: {}; scale: {}; stopColor: {}; stopOpacity: {}; stroke: {}; strokeDasharray: {}; strokeDashoffset: {}; strokeLinecap: {}; strokeLinejoin: {}; strokeMiterlimit: {}; strokeOpacity: {}; strokeWidth: {}; tableLayout: {}; textAlign: {}; textAlignLast: {}; textAnchor: {}; textDecoration: {}; textIndent: {}; textJustify: {}; textKashida: {}; textKashidaSpace: {}; textOverflow: {}; textShadow: {}; textTransform: {}; textUnderlinePosition: {}; top: {}; touchAction: {}; transform: {}; transformOrigin: {}; transformStyle: {}; transition: {}; transitionDelay: {}; transitionDuration: {}; transitionProperty: {}; transitionTimingFunction: {}; translate: {}; unicodeBidi: {}; verticalAlign: {}; visibility: {}; webkitAlignContent: {}; webkitAlignItems: {}; webkitAlignSelf: {}; webkitAnimation: {}; webkitAnimationDelay: {}; webkitAnimationDirection: {}; webkitAnimationDuration: {}; webkitAnimationFillMode: {}; webkitAnimationIterationCount: {}; webkitAnimationName: {}; webkitAnimationPlayState: {}; webkitAnimationTimingFunction: {}; webkitAppearance: {}; webkitBackfaceVisibility: {}; webkitBackgroundClip: {}; webkitBackgroundOrigin: {}; webkitBackgroundSize: {}; webkitBorderBottomLeftRadius: {}; webkitBorderBottomRightRadius: {}; webkitBorderImage: {}; webkitBorderRadius: {}; webkitBorderTopLeftRadius: {}; webkitBorderTopRightRadius: {}; webkitBoxAlign: {}; webkitBoxDirection: {}; webkitBoxFlex: {}; webkitBoxOrdinalGroup: {}; webkitBoxOrient: {}; webkitBoxPack: {}; webkitBoxSizing: {}; webkitColumnBreakAfter: {}; webkitColumnBreakBefore: {}; webkitColumnBreakInside: {}; webkitColumnCount: {}; webkitColumnGap: {}; webkitColumnRule: {}; webkitColumnRuleColor: {}; webkitColumnRuleStyle: {}; webkitColumnRuleWidth: {}; webkitColumns: {}; webkitColumnSpan: {}; webkitColumnWidth: {}; webkitFilter: {}; webkitFlex: {}; webkitFlexBasis: {}; webkitFlexDirection: {}; webkitFlexFlow: {}; webkitFlexGrow: {}; webkitFlexShrink: {}; webkitFlexWrap: {}; webkitJustifyContent: {}; webkitOrder: {}; webkitPerspective: {}; webkitPerspectiveOrigin: {}; webkitTapHighlightColor: {}; webkitTextFillColor: {}; webkitTextSizeAdjust: {}; webkitTextStroke: {}; webkitTextStrokeColor: {}; webkitTextStrokeWidth: {}; webkitTransform: {}; webkitTransformOrigin: {}; webkitTransformStyle: {}; webkitTransition: {}; webkitTransitionDelay: {}; webkitTransitionDuration: {}; webkitTransitionProperty: {}; webkitTransitionTimingFunction: {}; webkitUserModify: {}; webkitUserSelect: {}; webkitWritingMode: {}; whiteSpace: {}; widows: {}; width: {}; wordBreak: {}; wordSpacing: {}; wordWrap: {}; writingMode: {}; zIndex: {}; zoom: {}; resize: {}; userSelect: {}; getPropertyPriority: {}; getPropertyValue: {}; item: {}; removeProperty: {}; setProperty: {}; }; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; addEventListener: {}; removeEventListener: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; }; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; }; alinkColor: {}; readonly all: { readonly length: {}; item: {}; namedItem: {}; }; anchors: { item: {}; namedItem: {}; readonly length: {}; }; applets: {}; bgColor: {}; body: {}; readonly characterSet: {}; charset: {}; readonly compatMode: {}; cookie: {}; readonly currentScript: { async: {}; charset: {}; crossOrigin: {}; defer: {}; event: {}; htmlFor: {}; src: {}; text: {}; type: {}; integrity: {}; addEventListener: {}; removeEventListener: {}; accessKey: {}; readonly children: {}; contentEditable: {}; readonly dataset: {}; dir: {}; draggable: {}; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: {}; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; } | { type: {}; addEventListener: {}; removeEventListener: {}; className: {}; onclick: {}; ondblclick: {}; onfocusin: {}; onfocusout: {}; onload: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; readonly ownerSVGElement: { contentScriptType: {}; contentStyleType: {}; currentScale: {}; readonly currentTranslate: { x: {}; y: {}; matrixTransform: {}; }; readonly height: { readonly animVal: { readonly unitType: {}; value: {}; valueAsString: {}; valueInSpecifiedUnits: {}; convertToSpecifiedUnits: {}; newValueSpecifiedUnits: {}; readonly SVG_LENGTHTYPE_CM: {}; readonly SVG_LENGTHTYPE_EMS: {}; readonly SVG_LENGTHTYPE_EXS: {}; readonly SVG_LENGTHTYPE_IN: {}; readonly SVG_LENGTHTYPE_MM: {}; readonly SVG_LENGTHTYPE_NUMBER: {}; readonly SVG_LENGTHTYPE_PC: {}; readonly SVG_LENGTHTYPE_PERCENTAGE: {}; readonly SVG_LENGTHTYPE_PT: {}; readonly SVG_LENGTHTYPE_PX: {}; readonly SVG_LENGTHTYPE_UNKNOWN: {}; }; readonly baseVal: {}; }; onabort: {}; onerror: {}; onresize: {}; onscroll: {}; onunload: {}; onzoom: {}; readonly pixelUnitToMillimeterX: {}; readonly pixelUnitToMillimeterY: {}; readonly screenPixelToMillimeterX: {}; readonly screenPixelToMillimeterY: {}; readonly viewport: { height: {}; width: {}; x: {}; y: {}; }; readonly width: {}; readonly x: {}; readonly y: {}; checkEnclosure: {}; checkIntersection: {}; createSVGAngle: {}; createSVGLength: {}; createSVGMatrix: {}; createSVGNumber: {}; createSVGPoint: {}; createSVGRect: {}; createSVGTransform: {}; createSVGTransformFromMatrix: {}; deselectAll: {}; forceRedraw: {}; getComputedStyle: {}; getCurrentTime: {}; getElementById: {}; getEnclosureList: {}; getIntersectionList: {}; pauseAnimations: {}; setCurrentTime: {}; suspendRedraw: {}; unpauseAnimations: {}; unsuspendRedraw: {}; unsuspendRedrawAll: {}; addEventListener: {}; removeEventListener: {}; readonly farthestViewportElement: { className: {}; onclick: {}; ondblclick: {}; onfocusin: {}; onfocusout: {}; onload: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; readonly ownerSVGElement: {}; readonly style: {}; readonly viewportElement: {}; xmlbase: {}; addEventListener: {}; removeEventListener: {}; readonly classList: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; }; readonly nearestViewportElement: {}; readonly transform: { readonly animVal: { readonly numberOfItems: {}; appendItem: {}; clear: {}; consolidate: {}; createSVGTransformFromMatrix: {}; getItem: {}; initialize: {}; insertItemBefore: {}; removeItem: {}; replaceItem: {}; }; readonly baseVal: {}; }; getBBox: {}; getCTM: {}; getScreenCTM: {}; getTransformToElement: {}; className: {}; onclick: {}; ondblclick: {}; onfocusin: {}; onfocusout: {}; onload: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; readonly ownerSVGElement: {}; readonly style: {}; readonly viewportElement: {}; xmlbase: {}; readonly classList: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; readonly requiredExtensions: { readonly numberOfItems: {}; appendItem: {}; clear: {}; getItem: {}; initialize: {}; insertItemBefore: {}; removeItem: {}; replaceItem: {}; }; readonly requiredFeatures: {}; readonly systemLanguage: {}; hasExtension: {}; createEvent: {}; readonly preserveAspectRatio: { readonly animVal: { align: {}; meetOrSlice: {}; readonly SVG_MEETORSLICE_MEET: {}; readonly SVG_MEETORSLICE_SLICE: {}; readonly SVG_MEETORSLICE_UNKNOWN: {}; readonly SVG_PRESERVEASPECTRATIO_NONE: {}; readonly SVG_PRESERVEASPECTRATIO_UNKNOWN: {}; readonly SVG_PRESERVEASPECTRATIO_XMAXYMAX: {}; readonly SVG_PRESERVEASPECTRATIO_XMAXYMID: {}; readonly SVG_PRESERVEASPECTRATIO_XMAXYMIN: {}; readonly SVG_PRESERVEASPECTRATIO_XMIDYMAX: {}; readonly SVG_PRESERVEASPECTRATIO_XMIDYMID: {}; readonly SVG_PRESERVEASPECTRATIO_XMIDYMIN: {}; readonly SVG_PRESERVEASPECTRATIO_XMINYMAX: {}; readonly SVG_PRESERVEASPECTRATIO_XMINYMID: {}; readonly SVG_PRESERVEASPECTRATIO_XMINYMIN: {}; }; readonly baseVal: {}; }; readonly viewBox: { readonly animVal: {}; readonly baseVal: {}; }; readonly zoomAndPan: {}; }; readonly style: {}; readonly viewportElement: {}; xmlbase: {}; readonly classList: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; readonly href: { readonly animVal: {}; baseVal: {}; }; }; readonly defaultView: { readonly applicationCache: { oncached: {}; onchecking: {}; ondownloading: {}; onerror: {}; onnoupdate: {}; onobsolete: {}; onprogress: {}; onupdateready: {}; readonly status: {}; abort: {}; swapCache: {}; update: {}; readonly CHECKING: {}; readonly DOWNLOADING: {}; readonly IDLE: {}; readonly OBSOLETE: {}; readonly UNCACHED: {}; readonly UPDATEREADY: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; readonly caches: { delete: {}; has: {}; keys: {}; match: {}; open: {}; }; readonly clientInformation: { readonly authentication: { getAssertion: {}; makeCredential: {}; }; readonly cookieEnabled: {}; gamepadInputEmulation: {}; readonly language: {}; readonly maxTouchPoints: {}; readonly mimeTypes: { readonly length: {}; item: {}; namedItem: {}; }; readonly msManipulationViewsEnabled: {}; readonly msMaxTouchPoints: {}; readonly msPointerEnabled: {}; readonly plugins: { readonly length: {}; item: {}; namedItem: {}; refresh: {}; }; readonly pointerEnabled: {}; readonly serviceWorker: { readonly controller: { onstatechange: {}; readonly scriptURL: {}; readonly state: {}; postMessage: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onerror: {}; }; oncontrollerchange: {}; onmessage: {}; readonly ready: { then: {}; catch: {}; readonly [Symbol.toStringTag]: {}; }; getRegistration: {}; getRegistrations: {}; register: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; readonly webdriver: {}; readonly doNotTrack: {}; readonly hardwareConcurrency: {}; readonly languages: { length: {}; toString: {}; toLocaleString: {}; push: {}; pop: {}; concat: {}; join: {}; reverse: {}; shift: {}; slice: {}; sort: {}; splice: {}; unshift: {}; indexOf: {}; lastIndexOf: {}; every: {}; some: {}; forEach: {}; map: {}; filter: {}; reduce: {}; reduceRight: {}; [Symbol.unscopables]: {}; [Symbol.iterator]: {}; entries: {}; keys: {}; values: {}; find: {}; findIndex: {}; fill: {}; copyWithin: {}; }; getGamepads: {}; javaEnabled: {}; msLaunchUri: {}; requestMediaKeySystemAccess: {}; vibrate: {}; constructor: { apply: {}; call: {}; bind: {}; toString: {}; prototype: {}; readonly length: {}; arguments: {}; caller: {}; [Symbol.hasInstance]: {}; readonly name: {}; }; toString: {}; toLocaleString: {}; valueOf: {}; hasOwnProperty: {}; isPrototypeOf: {}; propertyIsEnumerable: {}; readonly appCodeName: {}; readonly appName: {}; readonly appVersion: {}; readonly platform: {}; readonly product: {}; readonly productSub: {}; readonly userAgent: {}; readonly vendor: {}; readonly vendorSub: {}; readonly onLine: {}; readonly geolocation: { clearWatch: {}; getCurrentPosition: {}; watchPosition: {}; }; confirmSiteSpecificTrackingException: {}; confirmWebWideTrackingException: {}; removeSiteSpecificTrackingException: {}; removeWebWideTrackingException: {}; storeSiteSpecificTrackingException: {}; storeWebWideTrackingException: {}; msSaveBlob: {}; msSaveOrOpenBlob: {}; sendBeacon: {}; readonly mediaDevices: { ondevicechange: {}; enumerateDevices: {}; getSupportedConstraints: {}; getUserMedia: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; getUserMedia: {}; }; readonly closed: {}; readonly crypto: { readonly subtle: { decrypt: {}; deriveBits: {}; deriveKey: {}; digest: {}; encrypt: {}; exportKey: {}; generateKey: {}; importKey: {}; sign: {}; unwrapKey: {}; verify: {}; wrapKey: {}; }; constructor: {}; toString: {}; toLocaleString: {}; valueOf: {}; hasOwnProperty: {}; isPrototypeOf: {}; propertyIsEnumerable: {}; getRandomValues: {}; }; defaultStatus: {}; readonly devicePixelRatio: {}; readonly document: {}; readonly doNotTrack: {}; event: { readonly bubbles: {}; readonly cancelable: {}; cancelBubble: {}; readonly currentTarget: { addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; }; readonly defaultPrevented: {}; readonly eventPhase: {}; readonly isTrusted: {}; returnValue: {}; readonly srcElement: {}; readonly target: {}; readonly timeStamp: {}; readonly type: {}; readonly scoped: {}; initEvent: {}; preventDefault: {}; stopImmediatePropagation: {}; stopPropagation: {}; deepPath: {}; readonly AT_TARGET: {}; readonly BUBBLING_PHASE: {}; readonly CAPTURING_PHASE: {}; }; readonly external: {}; readonly frameElement: {}; readonly frames: {}; readonly history: { readonly length: {}; readonly state: {}; scrollRestoration: {}; back: {}; forward: {}; go: {}; pushState: {}; replaceState: {}; }; readonly innerHeight: {}; readonly innerWidth: {}; readonly isSecureContext: {}; readonly length: {}; readonly location: { hash: {}; host: {}; hostname: {}; href: {}; readonly origin: {}; pathname: {}; port: {}; protocol: {}; search: {}; assign: {}; reload: {}; replace: {}; toString: {}; }; readonly locationbar: { readonly visible: {}; }; readonly menubar: {}; readonly msContentScript: { extensionIdToShortId: {}; fireExtensionApiTelemetry: {}; genericFunction: {}; genericSynchronousFunction: {}; getExtensionId: {}; registerGenericFunctionCallbackHandler: {}; registerGenericPersistentCallbackHandler: {}; }; readonly msCredentials: { getAssertion: {}; makeCredential: {}; }; name: {}; readonly navigator: {}; offscreenBuffering: {}; onabort: {}; onafterprint: {}; onbeforeprint: {}; onbeforeunload: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncompassneedscalibration: {}; oncontextmenu: {}; ondblclick: {}; ondevicelight: {}; ondevicemotion: {}; ondeviceorientation: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onhashchange: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmessage: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onoffline: {}; ononline: {}; onorientationchange: {}; onpagehide: {}; onpageshow: {}; onpause: {}; onplay: {}; onplaying: {}; onpopstate: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onresize: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onstalled: {}; onstorage: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onunload: {}; onvolumechange: {}; onwaiting: {}; opener: {}; orientation: {}; readonly outerHeight: {}; readonly outerWidth: {}; readonly pageXOffset: {}; readonly pageYOffset: {}; readonly parent: {}; readonly performance: { readonly navigation: { readonly redirectCount: {}; readonly type: {}; toJSON: {}; readonly TYPE_BACK_FORWARD: {}; readonly TYPE_NAVIGATE: {}; readonly TYPE_RELOAD: {}; readonly TYPE_RESERVED: {}; }; readonly timing: { readonly connectEnd: {}; readonly connectStart: {}; readonly domainLookupEnd: {}; readonly domainLookupStart: {}; readonly domComplete: {}; readonly domContentLoadedEventEnd: {}; readonly domContentLoadedEventStart: {}; readonly domInteractive: {}; readonly domLoading: {}; readonly fetchStart: {}; readonly loadEventEnd: {}; readonly loadEventStart: {}; readonly msFirstPaint: {}; readonly navigationStart: {}; readonly redirectEnd: {}; readonly redirectStart: {}; readonly requestStart: {}; readonly responseEnd: {}; readonly responseStart: {}; readonly unloadEventEnd: {}; readonly unloadEventStart: {}; readonly secureConnectionStart: {}; toJSON: {}; }; clearMarks: {}; clearMeasures: {}; clearResourceTimings: {}; getEntries: {}; getEntriesByName: {}; getEntriesByType: {}; getMarks: {}; getMeasures: {}; mark: {}; measure: {}; now: {}; setResourceTimingBufferSize: {}; toJSON: {}; }; readonly personalbar: {}; readonly screen: { readonly availHeight: {}; readonly availWidth: {}; bufferDepth: {}; readonly colorDepth: {}; readonly deviceXDPI: {}; readonly deviceYDPI: {}; readonly fontSmoothingEnabled: {}; readonly height: {}; readonly logicalXDPI: {}; readonly logicalYDPI: {}; readonly msOrientation: {}; onmsorientationchange: {}; readonly pixelDepth: {}; readonly systemXDPI: {}; readonly systemYDPI: {}; readonly width: {}; msLockOrientation: {}; msUnlockOrientation: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; readonly screenLeft: {}; readonly screenTop: {}; readonly screenX: {}; readonly screenY: {}; readonly scrollbars: {}; readonly scrollX: {}; readonly scrollY: {}; readonly self: {}; readonly speechSynthesis: { onvoiceschanged: {}; readonly paused: {}; readonly pending: {}; readonly speaking: {}; cancel: {}; getVoices: {}; pause: {}; resume: {}; speak: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; }; status: {}; readonly statusbar: {}; readonly styleMedia: { readonly type: {}; matchMedium: {}; }; readonly toolbar: {}; readonly top: {}; readonly window: {}; URL: { prototype: { hash: {}; host: {}; hostname: {}; href: {}; readonly origin: {}; password: {}; pathname: {}; port: {}; protocol: {}; search: {}; username: {}; readonly searchParams: { append: {}; delete: {}; get: {}; getAll: {}; has: {}; set: {}; }; toString: {}; }; createObjectURL: {}; revokeObjectURL: {}; }; URLSearchParams: { prototype: {}; }; Blob: { prototype: { readonly size: {}; readonly type: {}; msClose: {}; msDetachStream: {}; slice: {}; }; }; customElements: { define: {}; get: {}; whenDefined: {}; }; alert: {}; blur: {}; cancelAnimationFrame: {}; captureEvents: {}; close: {}; confirm: {}; departFocus: {}; focus: {}; getComputedStyle: {}; getMatchedCSSRules: {}; getSelection: {}; matchMedia: {}; moveBy: {}; moveTo: {}; msWriteProfilerMark: {}; open: {}; postMessage: {}; print: {}; prompt: {}; releaseEvents: {}; requestAnimationFrame: {}; resizeBy: {}; resizeTo: {}; scroll: {}; scrollBy: {}; scrollTo: {}; stop: {}; webkitCancelAnimationFrame: {}; webkitConvertPointFromNodeToPage: {}; webkitConvertPointFromPageToNode: {}; webkitRequestAnimationFrame: {}; createImageBitmap: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; clearInterval: {}; clearTimeout: {}; setInterval: {}; setTimeout: {}; constructor: {}; toString: {}; toLocaleString: {}; valueOf: {}; hasOwnProperty: {}; isPrototypeOf: {}; propertyIsEnumerable: {}; clearImmediate: {}; setImmediate: {}; readonly sessionStorage: { [x: string]: {}; readonly length: {}; clear: {}; getItem: {}; key: {}; removeItem: {}; setItem: {}; }; readonly localStorage: {}; readonly console: { assert: {}; clear: {}; count: {}; debug: {}; dir: {}; dirxml: {}; error: {}; exception: {}; group: {}; groupCollapsed: {}; groupEnd: {}; info: {}; log: {}; msIsIndependentlyComposed: {}; profile: {}; profileEnd: {}; select: {}; table: {}; time: {}; timeEnd: {}; trace: {}; warn: {}; }; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly indexedDB: { cmp: {}; deleteDatabase: {}; open: {}; }; atob: {}; btoa: {}; fetch: {}; }; designMode: {}; dir: {}; readonly doctype: { readonly entities: {}; readonly internalSubset: {}; readonly name: {}; readonly notations: {}; readonly publicId: {}; readonly systemId: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; addEventListener: {}; dispatchEvent: {}; removeEventListener: {}; remove: {}; }; documentElement: {}; domain: {}; embeds: {}; fgColor: {}; forms: {}; readonly fullscreenElement: {}; readonly fullscreenEnabled: {}; readonly head: { profile: {}; addEventListener: {}; removeEventListener: {}; accessKey: {}; readonly children: {}; contentEditable: {}; readonly dataset: {}; dir: {}; draggable: {}; hidden: {}; hideFocus: {}; innerText: {}; readonly isContentEditable: {}; lang: {}; readonly offsetHeight: {}; readonly offsetLeft: {}; readonly offsetParent: {}; readonly offsetTop: {}; readonly offsetWidth: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforecopy: {}; onbeforecut: {}; onbeforedeactivate: {}; onbeforepaste: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; oncopy: {}; oncuechange: {}; oncut: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmouseenter: {}; onmouseleave: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsmanipulationstatechanged: {}; onpaste: {}; onpause: {}; onplay: {}; onplaying: {}; onprogress: {}; onratechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectstart: {}; onstalled: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; onvolumechange: {}; onwaiting: {}; outerText: {}; spellcheck: {}; readonly style: {}; tabIndex: {}; title: {}; blur: {}; click: {}; dragDrop: {}; focus: {}; msGetInputContext: {}; readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; }; readonly hidden: {}; images: {}; readonly implementation: { createDocument: {}; createDocumentType: {}; createHTMLDocument: {}; hasFeature: {}; }; readonly inputEncoding: {}; readonly lastModified: {}; linkColor: {}; links: {}; readonly location: {}; msCapsLockWarningOff: {}; msCSSOMElementFloatMetrics: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforedeactivate: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onfullscreenchange: {}; onfullscreenerror: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmsmanipulationstatechanged: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onmssitemodejumplistitemremoved: {}; onmsthumbnailclick: {}; onpause: {}; onplay: {}; onplaying: {}; onpointerlockchange: {}; onpointerlockerror: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectionchange: {}; onselectstart: {}; onstalled: {}; onstop: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onvolumechange: {}; onwaiting: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; plugins: {}; readonly pointerLockElement: {}; readonly readyState: {}; readonly referrer: {}; readonly rootElement: {}; scripts: {}; readonly scrollingElement: {}; readonly styleSheets: {}; title: {}; readonly URL: {}; readonly URLUnencoded: {}; readonly visibilityState: {}; vlinkColor: {}; readonly webkitCurrentFullScreenElement: {}; readonly webkitFullscreenElement: {}; readonly webkitFullscreenEnabled: {}; readonly webkitIsFullScreen: {}; readonly xmlEncoding: {}; xmlStandalone: {}; xmlVersion: {}; adoptNode: {}; captureEvents: {}; caretRangeFromPoint: {}; clear: {}; close: {}; createAttribute: {}; createAttributeNS: {}; createCDATASection: {}; createComment: {}; createDocumentFragment: {}; createElement: {}; createElementNS: {}; createExpression: {}; createNodeIterator: {}; createNSResolver: {}; createProcessingInstruction: {}; createRange: {}; createTextNode: {}; createTouch: {}; createTouchList: {}; createTreeWalker: {}; elementFromPoint: {}; evaluate: {}; execCommand: {}; execCommandShowHelp: {}; exitFullscreen: {}; exitPointerLock: {}; focus: {}; getElementById: {}; getElementsByClassName: {}; getElementsByName: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; getSelection: {}; hasFocus: {}; importNode: {}; msElementsFromPoint: {}; msElementsFromRect: {}; open: {}; queryCommandEnabled: {}; queryCommandIndeterm: {}; queryCommandState: {}; queryCommandSupported: {}; queryCommandText: {}; queryCommandValue: {}; releaseEvents: {}; updateSettings: {}; webkitCancelFullScreen: {}; webkitExitFullscreen: {}; write: {}; writeln: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; querySelector: {}; querySelectorAll: {}; createEvent: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; readonly stylesheets: {}; elementsFromPoint: {}; }; readonly status: {}; readonly statusText: {}; timeout: {}; readonly upload: { addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; }; withCredentials: {}; msCaching?: {}; abort: {}; getAllResponseHeaders: {}; getResponseHeader: {}; msCachingEnabled: {}; open: {}; overrideMimeType: {}; send: {}; setRequestHeader: {}; readonly DONE: {}; readonly HEADERS_RECEIVED: {}; readonly LOADING: {}; readonly OPENED: {}; readonly UNSENT: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; } +>out2 : { onreadystatechange: {}; readonly readyState: {}; readonly response: {}; readonly responseText: {}; responseType: {}; readonly responseURL: {}; readonly responseXML: {}; readonly status: {}; readonly statusText: {}; timeout: {}; readonly upload: {}; withCredentials: {}; msCaching?: {}; abort: {}; getAllResponseHeaders: {}; getResponseHeader: {}; msCachingEnabled: {}; open: {}; overrideMimeType: {}; send: {}; setRequestHeader: {}; readonly DONE: {}; readonly HEADERS_RECEIVED: {}; readonly LOADING: {}; readonly OPENED: {}; readonly UNSENT: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; } +>foo(xhr) : { onreadystatechange: {}; readonly readyState: {}; readonly response: {}; readonly responseText: {}; responseType: {}; readonly responseURL: {}; readonly responseXML: {}; readonly status: {}; readonly statusText: {}; timeout: {}; readonly upload: {}; withCredentials: {}; msCaching?: {}; abort: {}; getAllResponseHeaders: {}; getResponseHeader: {}; msCachingEnabled: {}; open: {}; overrideMimeType: {}; send: {}; setRequestHeader: {}; readonly DONE: {}; readonly HEADERS_RECEIVED: {}; readonly LOADING: {}; readonly OPENED: {}; readonly UNSENT: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; } >foo : (deep: Deep) => T >xhr : XMLHttpRequest +out2.responseXML +>out2.responseXML : { readonly activeElement: {}; alinkColor: {}; readonly all: {}; anchors: {}; applets: {}; bgColor: {}; body: {}; readonly characterSet: {}; charset: {}; readonly compatMode: {}; cookie: {}; readonly currentScript: {}; readonly defaultView: {}; designMode: {}; dir: {}; readonly doctype: {}; documentElement: {}; domain: {}; embeds: {}; fgColor: {}; forms: {}; readonly fullscreenElement: {}; readonly fullscreenEnabled: {}; readonly head: {}; readonly hidden: {}; images: {}; readonly implementation: {}; readonly inputEncoding: {}; readonly lastModified: {}; linkColor: {}; links: {}; readonly location: {}; msCapsLockWarningOff: {}; msCSSOMElementFloatMetrics: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforedeactivate: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onfullscreenchange: {}; onfullscreenerror: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmsmanipulationstatechanged: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onmssitemodejumplistitemremoved: {}; onmsthumbnailclick: {}; onpause: {}; onplay: {}; onplaying: {}; onpointerlockchange: {}; onpointerlockerror: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectionchange: {}; onselectstart: {}; onstalled: {}; onstop: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onvolumechange: {}; onwaiting: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; plugins: {}; readonly pointerLockElement: {}; readonly readyState: {}; readonly referrer: {}; readonly rootElement: {}; scripts: {}; readonly scrollingElement: {}; readonly styleSheets: {}; title: {}; readonly URL: {}; readonly URLUnencoded: {}; readonly visibilityState: {}; vlinkColor: {}; readonly webkitCurrentFullScreenElement: {}; readonly webkitFullscreenElement: {}; readonly webkitFullscreenEnabled: {}; readonly webkitIsFullScreen: {}; readonly xmlEncoding: {}; xmlStandalone: {}; xmlVersion: {}; adoptNode: {}; captureEvents: {}; caretRangeFromPoint: {}; clear: {}; close: {}; createAttribute: {}; createAttributeNS: {}; createCDATASection: {}; createComment: {}; createDocumentFragment: {}; createElement: {}; createElementNS: {}; createExpression: {}; createNodeIterator: {}; createNSResolver: {}; createProcessingInstruction: {}; createRange: {}; createTextNode: {}; createTouch: {}; createTouchList: {}; createTreeWalker: {}; elementFromPoint: {}; evaluate: {}; execCommand: {}; execCommandShowHelp: {}; exitFullscreen: {}; exitPointerLock: {}; focus: {}; getElementById: {}; getElementsByClassName: {}; getElementsByName: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; getSelection: {}; hasFocus: {}; importNode: {}; msElementsFromPoint: {}; msElementsFromRect: {}; open: {}; queryCommandEnabled: {}; queryCommandIndeterm: {}; queryCommandState: {}; queryCommandSupported: {}; queryCommandText: {}; queryCommandValue: {}; releaseEvents: {}; updateSettings: {}; webkitCancelFullScreen: {}; webkitExitFullscreen: {}; write: {}; writeln: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; querySelector: {}; querySelectorAll: {}; createEvent: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; readonly stylesheets: {}; elementsFromPoint: {}; } +>out2 : { onreadystatechange: {}; readonly readyState: {}; readonly response: {}; readonly responseText: {}; responseType: {}; readonly responseURL: {}; readonly responseXML: {}; readonly status: {}; readonly statusText: {}; timeout: {}; readonly upload: {}; withCredentials: {}; msCaching?: {}; abort: {}; getAllResponseHeaders: {}; getResponseHeader: {}; msCachingEnabled: {}; open: {}; overrideMimeType: {}; send: {}; setRequestHeader: {}; readonly DONE: {}; readonly HEADERS_RECEIVED: {}; readonly LOADING: {}; readonly OPENED: {}; readonly UNSENT: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; } +>responseXML : { readonly activeElement: {}; alinkColor: {}; readonly all: {}; anchors: {}; applets: {}; bgColor: {}; body: {}; readonly characterSet: {}; charset: {}; readonly compatMode: {}; cookie: {}; readonly currentScript: {}; readonly defaultView: {}; designMode: {}; dir: {}; readonly doctype: {}; documentElement: {}; domain: {}; embeds: {}; fgColor: {}; forms: {}; readonly fullscreenElement: {}; readonly fullscreenEnabled: {}; readonly head: {}; readonly hidden: {}; images: {}; readonly implementation: {}; readonly inputEncoding: {}; readonly lastModified: {}; linkColor: {}; links: {}; readonly location: {}; msCapsLockWarningOff: {}; msCSSOMElementFloatMetrics: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforedeactivate: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onfullscreenchange: {}; onfullscreenerror: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmsmanipulationstatechanged: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onmssitemodejumplistitemremoved: {}; onmsthumbnailclick: {}; onpause: {}; onplay: {}; onplaying: {}; onpointerlockchange: {}; onpointerlockerror: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectionchange: {}; onselectstart: {}; onstalled: {}; onstop: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onvolumechange: {}; onwaiting: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; plugins: {}; readonly pointerLockElement: {}; readonly readyState: {}; readonly referrer: {}; readonly rootElement: {}; scripts: {}; readonly scrollingElement: {}; readonly styleSheets: {}; title: {}; readonly URL: {}; readonly URLUnencoded: {}; readonly visibilityState: {}; vlinkColor: {}; readonly webkitCurrentFullScreenElement: {}; readonly webkitFullscreenElement: {}; readonly webkitFullscreenEnabled: {}; readonly webkitIsFullScreen: {}; readonly xmlEncoding: {}; xmlStandalone: {}; xmlVersion: {}; adoptNode: {}; captureEvents: {}; caretRangeFromPoint: {}; clear: {}; close: {}; createAttribute: {}; createAttributeNS: {}; createCDATASection: {}; createComment: {}; createDocumentFragment: {}; createElement: {}; createElementNS: {}; createExpression: {}; createNodeIterator: {}; createNSResolver: {}; createProcessingInstruction: {}; createRange: {}; createTextNode: {}; createTouch: {}; createTouchList: {}; createTreeWalker: {}; elementFromPoint: {}; evaluate: {}; execCommand: {}; execCommandShowHelp: {}; exitFullscreen: {}; exitPointerLock: {}; focus: {}; getElementById: {}; getElementsByClassName: {}; getElementsByName: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; getSelection: {}; hasFocus: {}; importNode: {}; msElementsFromPoint: {}; msElementsFromRect: {}; open: {}; queryCommandEnabled: {}; queryCommandIndeterm: {}; queryCommandState: {}; queryCommandSupported: {}; queryCommandText: {}; queryCommandValue: {}; releaseEvents: {}; updateSettings: {}; webkitCancelFullScreen: {}; webkitExitFullscreen: {}; write: {}; writeln: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; querySelector: {}; querySelectorAll: {}; createEvent: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; readonly stylesheets: {}; elementsFromPoint: {}; } + +out2.responseXML.activeElement.className.length +>out2.responseXML.activeElement.className.length : { toString: {}; toFixed: {}; toExponential: {}; toPrecision: {}; valueOf: {}; toLocaleString: {}; } +>out2.responseXML.activeElement.className : { toString: {}; charAt: {}; charCodeAt: {}; concat: {}; indexOf: {}; lastIndexOf: {}; localeCompare: {}; match: {}; replace: {}; search: {}; slice: {}; split: {}; substring: {}; toLowerCase: {}; toLocaleLowerCase: {}; toUpperCase: {}; toLocaleUpperCase: {}; trim: {}; readonly length: {}; substr: {}; valueOf: {}; [Symbol.iterator]: {}; codePointAt: {}; includes: {}; endsWith: {}; normalize: {}; repeat: {}; startsWith: {}; anchor: {}; big: {}; blink: {}; bold: {}; fixed: {}; fontcolor: {}; fontsize: {}; italics: {}; link: {}; small: {}; strike: {}; sub: {}; sup: {}; } +>out2.responseXML.activeElement : { readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; } +>out2.responseXML : { readonly activeElement: {}; alinkColor: {}; readonly all: {}; anchors: {}; applets: {}; bgColor: {}; body: {}; readonly characterSet: {}; charset: {}; readonly compatMode: {}; cookie: {}; readonly currentScript: {}; readonly defaultView: {}; designMode: {}; dir: {}; readonly doctype: {}; documentElement: {}; domain: {}; embeds: {}; fgColor: {}; forms: {}; readonly fullscreenElement: {}; readonly fullscreenEnabled: {}; readonly head: {}; readonly hidden: {}; images: {}; readonly implementation: {}; readonly inputEncoding: {}; readonly lastModified: {}; linkColor: {}; links: {}; readonly location: {}; msCapsLockWarningOff: {}; msCSSOMElementFloatMetrics: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforedeactivate: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onfullscreenchange: {}; onfullscreenerror: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmsmanipulationstatechanged: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onmssitemodejumplistitemremoved: {}; onmsthumbnailclick: {}; onpause: {}; onplay: {}; onplaying: {}; onpointerlockchange: {}; onpointerlockerror: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectionchange: {}; onselectstart: {}; onstalled: {}; onstop: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onvolumechange: {}; onwaiting: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; plugins: {}; readonly pointerLockElement: {}; readonly readyState: {}; readonly referrer: {}; readonly rootElement: {}; scripts: {}; readonly scrollingElement: {}; readonly styleSheets: {}; title: {}; readonly URL: {}; readonly URLUnencoded: {}; readonly visibilityState: {}; vlinkColor: {}; readonly webkitCurrentFullScreenElement: {}; readonly webkitFullscreenElement: {}; readonly webkitFullscreenEnabled: {}; readonly webkitIsFullScreen: {}; readonly xmlEncoding: {}; xmlStandalone: {}; xmlVersion: {}; adoptNode: {}; captureEvents: {}; caretRangeFromPoint: {}; clear: {}; close: {}; createAttribute: {}; createAttributeNS: {}; createCDATASection: {}; createComment: {}; createDocumentFragment: {}; createElement: {}; createElementNS: {}; createExpression: {}; createNodeIterator: {}; createNSResolver: {}; createProcessingInstruction: {}; createRange: {}; createTextNode: {}; createTouch: {}; createTouchList: {}; createTreeWalker: {}; elementFromPoint: {}; evaluate: {}; execCommand: {}; execCommandShowHelp: {}; exitFullscreen: {}; exitPointerLock: {}; focus: {}; getElementById: {}; getElementsByClassName: {}; getElementsByName: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; getSelection: {}; hasFocus: {}; importNode: {}; msElementsFromPoint: {}; msElementsFromRect: {}; open: {}; queryCommandEnabled: {}; queryCommandIndeterm: {}; queryCommandState: {}; queryCommandSupported: {}; queryCommandText: {}; queryCommandValue: {}; releaseEvents: {}; updateSettings: {}; webkitCancelFullScreen: {}; webkitExitFullscreen: {}; write: {}; writeln: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; querySelector: {}; querySelectorAll: {}; createEvent: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; readonly stylesheets: {}; elementsFromPoint: {}; } +>out2 : { onreadystatechange: {}; readonly readyState: {}; readonly response: {}; readonly responseText: {}; responseType: {}; readonly responseURL: {}; readonly responseXML: {}; readonly status: {}; readonly statusText: {}; timeout: {}; readonly upload: {}; withCredentials: {}; msCaching?: {}; abort: {}; getAllResponseHeaders: {}; getResponseHeader: {}; msCachingEnabled: {}; open: {}; overrideMimeType: {}; send: {}; setRequestHeader: {}; readonly DONE: {}; readonly HEADERS_RECEIVED: {}; readonly LOADING: {}; readonly OPENED: {}; readonly UNSENT: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; } +>responseXML : { readonly activeElement: {}; alinkColor: {}; readonly all: {}; anchors: {}; applets: {}; bgColor: {}; body: {}; readonly characterSet: {}; charset: {}; readonly compatMode: {}; cookie: {}; readonly currentScript: {}; readonly defaultView: {}; designMode: {}; dir: {}; readonly doctype: {}; documentElement: {}; domain: {}; embeds: {}; fgColor: {}; forms: {}; readonly fullscreenElement: {}; readonly fullscreenEnabled: {}; readonly head: {}; readonly hidden: {}; images: {}; readonly implementation: {}; readonly inputEncoding: {}; readonly lastModified: {}; linkColor: {}; links: {}; readonly location: {}; msCapsLockWarningOff: {}; msCSSOMElementFloatMetrics: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforedeactivate: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onfullscreenchange: {}; onfullscreenerror: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmsmanipulationstatechanged: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onmssitemodejumplistitemremoved: {}; onmsthumbnailclick: {}; onpause: {}; onplay: {}; onplaying: {}; onpointerlockchange: {}; onpointerlockerror: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectionchange: {}; onselectstart: {}; onstalled: {}; onstop: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onvolumechange: {}; onwaiting: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; plugins: {}; readonly pointerLockElement: {}; readonly readyState: {}; readonly referrer: {}; readonly rootElement: {}; scripts: {}; readonly scrollingElement: {}; readonly styleSheets: {}; title: {}; readonly URL: {}; readonly URLUnencoded: {}; readonly visibilityState: {}; vlinkColor: {}; readonly webkitCurrentFullScreenElement: {}; readonly webkitFullscreenElement: {}; readonly webkitFullscreenEnabled: {}; readonly webkitIsFullScreen: {}; readonly xmlEncoding: {}; xmlStandalone: {}; xmlVersion: {}; adoptNode: {}; captureEvents: {}; caretRangeFromPoint: {}; clear: {}; close: {}; createAttribute: {}; createAttributeNS: {}; createCDATASection: {}; createComment: {}; createDocumentFragment: {}; createElement: {}; createElementNS: {}; createExpression: {}; createNodeIterator: {}; createNSResolver: {}; createProcessingInstruction: {}; createRange: {}; createTextNode: {}; createTouch: {}; createTouchList: {}; createTreeWalker: {}; elementFromPoint: {}; evaluate: {}; execCommand: {}; execCommandShowHelp: {}; exitFullscreen: {}; exitPointerLock: {}; focus: {}; getElementById: {}; getElementsByClassName: {}; getElementsByName: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; getSelection: {}; hasFocus: {}; importNode: {}; msElementsFromPoint: {}; msElementsFromRect: {}; open: {}; queryCommandEnabled: {}; queryCommandIndeterm: {}; queryCommandState: {}; queryCommandSupported: {}; queryCommandText: {}; queryCommandValue: {}; releaseEvents: {}; updateSettings: {}; webkitCancelFullScreen: {}; webkitExitFullscreen: {}; write: {}; writeln: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; querySelector: {}; querySelectorAll: {}; createEvent: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; readonly stylesheets: {}; elementsFromPoint: {}; } +>activeElement : { readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; } +>className : { toString: {}; charAt: {}; charCodeAt: {}; concat: {}; indexOf: {}; lastIndexOf: {}; localeCompare: {}; match: {}; replace: {}; search: {}; slice: {}; split: {}; substring: {}; toLowerCase: {}; toLocaleLowerCase: {}; toUpperCase: {}; toLocaleUpperCase: {}; trim: {}; readonly length: {}; substr: {}; valueOf: {}; [Symbol.iterator]: {}; codePointAt: {}; includes: {}; endsWith: {}; normalize: {}; repeat: {}; startsWith: {}; anchor: {}; big: {}; blink: {}; bold: {}; fixed: {}; fontcolor: {}; fontsize: {}; italics: {}; link: {}; small: {}; strike: {}; sub: {}; sup: {}; } +>length : { toString: {}; toFixed: {}; toExponential: {}; toPrecision: {}; valueOf: {}; toLocaleString: {}; } + diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.types b/tests/baselines/reference/thisTypeInObjectLiterals2.types index 746ca0eb264..4a9ab16f9ea 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals2.types +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.types @@ -672,8 +672,8 @@ p11.bar = p11.bar + 1; >1 : 1 let p12 = defineProps(p1, { ->p12 : Point & { foo: number; bar: number; } ->defineProps(p1, { foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }}) : Point & { foo: number; bar: number; } +>p12 : Point & { foo: {}; bar: {}; } +>defineProps(p1, { foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }}) : Point & { foo: {}; bar: {}; } >defineProps : (obj: T, descs: PropDescMap & ThisType) => T & U >p1 : Point >{ foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }} : { foo: { value: number; }; bar: { get(): number; set(value: number): void; }; } @@ -716,22 +716,22 @@ let p12 = defineProps(p1, { p12.foo = p12.foo + 1; >p12.foo = p12.foo + 1 : number >p12.foo : number ->p12 : Point & { foo: number; bar: number; } +>p12 : Point & { foo: {}; bar: {}; } >foo : number >p12.foo + 1 : number >p12.foo : number ->p12 : Point & { foo: number; bar: number; } +>p12 : Point & { foo: {}; bar: {}; } >foo : number >1 : 1 p12.bar = p12.bar + 1; >p12.bar = p12.bar + 1 : number >p12.bar : number ->p12 : Point & { foo: number; bar: number; } +>p12 : Point & { foo: {}; bar: {}; } >bar : number >p12.bar + 1 : number >p12.bar : number ->p12 : Point & { foo: number; bar: number; } +>p12 : Point & { foo: {}; bar: {}; } >bar : number >1 : 1 @@ -808,8 +808,8 @@ declare const Vue: new (options: VueOptions) => D & M & P; >P : P let vue = new Vue({ ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } ->new Vue({ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }}) : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } +>new Vue({ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }}) : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } >Vue : new (options: VueOptions) => D & M & P >{ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }} : { data: () => { x: number; y: number; }; methods: { f(x: string): number; }; computed: { test(): number; hello: { get(): string; set(value: string): void; }; }; } @@ -833,7 +833,7 @@ let vue = new Vue({ return this.x; >this.x : number ->this : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>this : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } >x : number } }, @@ -846,7 +846,7 @@ let vue = new Vue({ return this.x; >this.x : number ->this : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>this : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } >x : number }, @@ -870,27 +870,27 @@ let vue = new Vue({ }); vue; ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } vue.x; >vue.x : number ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } >x : number vue.f("abc"); >vue.f("abc") : number >vue.f : (x: string) => number ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } >f : (x: string) => number >"abc" : "abc" vue.test; >vue.test : number ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } >test : number vue.hello; >vue.hello : string ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } >hello : string diff --git a/tests/cases/compiler/mappedTypeRecursiveInference.ts b/tests/cases/compiler/mappedTypeRecursiveInference.ts index e264244095d..37b5b09d8a3 100644 --- a/tests/cases/compiler/mappedTypeRecursiveInference.ts +++ b/tests/cases/compiler/mappedTypeRecursiveInference.ts @@ -4,6 +4,11 @@ declare let a: A; type Deep = { [K in keyof T]: Deep } declare function foo(deep: Deep): T; const out = foo(a); +out.a +out.a.a +out.a.a.a.a.a.a.a let xhr: XMLHttpRequest; const out2 = foo(xhr); +out2.responseXML +out2.responseXML.activeElement.className.length From 0c089d8d666b7e0540069b51fd9966c32e279b0f Mon Sep 17 00:00:00 2001 From: kujon Date: Fri, 15 Dec 2017 21:25:16 +0000 Subject: [PATCH 013/189] Better error messages for aliased index types --- src/compiler/checker.ts | 6 +++ src/compiler/diagnosticMessages.json | 4 ++ .../reference/indexerConstraints2.errors.txt | 30 ++++++++++++++- .../reference/indexerConstraints2.js | 19 ++++++++++ .../reference/indexerConstraints2.symbols | 37 +++++++++++++++++++ .../reference/indexerConstraints2.types | 37 +++++++++++++++++++ tests/cases/compiler/indexerConstraints2.ts | 19 ++++++++++ 7 files changed, 151 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ca73d92e0c0..a2e0c490642 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25775,6 +25775,12 @@ namespace ts { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_must_have_a_type_annotation); } if (parameter.type.kind !== SyntaxKind.StringKeyword && parameter.type.kind !== SyntaxKind.NumberKeyword) { + const type = getTypeFromTypeNode(parameter.type); + + if (type.flags & TypeFlags.String || type.flags & TypeFlags.Number) { + return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Use_index_Colon_0_instead, typeToString(type)); + } + return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_or_number); } if (!node.type) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 336def7ea52..083396e51d2 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -939,6 +939,10 @@ "category": "Error", "code": 1335 }, + "An index signature parameter type cannot be a type alias. Use '[index: {0}]' instead.": { + "category": "Error", + "code": 1336 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/tests/baselines/reference/indexerConstraints2.errors.txt b/tests/baselines/reference/indexerConstraints2.errors.txt index 316486e709f..7e13c2ba399 100644 --- a/tests/baselines/reference/indexerConstraints2.errors.txt +++ b/tests/baselines/reference/indexerConstraints2.errors.txt @@ -1,9 +1,12 @@ tests/cases/compiler/indexerConstraints2.ts(9,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. tests/cases/compiler/indexerConstraints2.ts(17,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. tests/cases/compiler/indexerConstraints2.ts(26,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. +tests/cases/compiler/indexerConstraints2.ts(34,6): error TS1336: An index signature parameter type cannot be a type alias. Use '[index: number]' instead. +tests/cases/compiler/indexerConstraints2.ts(40,6): error TS1336: An index signature parameter type cannot be a type alias. Use '[index: string]' instead. +tests/cases/compiler/indexerConstraints2.ts(46,6): error TS1023: An index signature parameter type must be 'string' or 'number'. -==== tests/cases/compiler/indexerConstraints2.ts (3 errors) ==== +==== tests/cases/compiler/indexerConstraints2.ts (6 errors) ==== class A { a: number; } class B extends A { b: number; } @@ -37,4 +40,29 @@ tests/cases/compiler/indexerConstraints2.ts(26,5): error TS2413: Numeric index t ~~~~~~~~~~~~~~~ !!! error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. [s: string]: B; + } + + + type AliasedNumber = number; + + interface L { + [n: AliasedNumber]: A; + ~ +!!! error TS1336: An index signature parameter type cannot be a type alias. Use '[index: number]' instead. + } + + type AliasedString = string; + + interface M { + [s: AliasedString]: A; + ~ +!!! error TS1336: An index signature parameter type cannot be a type alias. Use '[index: string]' instead. + } + + type AliasedBoolean = boolean; + + interface N { + [b: AliasedBoolean]: A; + ~ +!!! error TS1023: An index signature parameter type must be 'string' or 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/indexerConstraints2.js b/tests/baselines/reference/indexerConstraints2.js index f5bfc3c64d8..56da818e37d 100644 --- a/tests/baselines/reference/indexerConstraints2.js +++ b/tests/baselines/reference/indexerConstraints2.js @@ -26,6 +26,25 @@ class J { class K extends J { [n: number]: A; [s: string]: B; +} + + +type AliasedNumber = number; + +interface L { + [n: AliasedNumber]: A; +} + +type AliasedString = string; + +interface M { + [s: AliasedString]: A; +} + +type AliasedBoolean = boolean; + +interface N { + [b: AliasedBoolean]: A; } //// [indexerConstraints2.js] diff --git a/tests/baselines/reference/indexerConstraints2.symbols b/tests/baselines/reference/indexerConstraints2.symbols index de606a2c2e4..96f2b84127e 100644 --- a/tests/baselines/reference/indexerConstraints2.symbols +++ b/tests/baselines/reference/indexerConstraints2.symbols @@ -62,3 +62,40 @@ class K extends J { >s : Symbol(s, Decl(indexerConstraints2.ts, 26, 5)) >B : Symbol(B, Decl(indexerConstraints2.ts, 0, 22)) } + + +type AliasedNumber = number; +>AliasedNumber : Symbol(AliasedNumber, Decl(indexerConstraints2.ts, 27, 1)) + +interface L { +>L : Symbol(L, Decl(indexerConstraints2.ts, 30, 28)) + + [n: AliasedNumber]: A; +>n : Symbol(n, Decl(indexerConstraints2.ts, 33, 5)) +>AliasedNumber : Symbol(AliasedNumber, Decl(indexerConstraints2.ts, 27, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +type AliasedString = string; +>AliasedString : Symbol(AliasedString, Decl(indexerConstraints2.ts, 34, 1)) + +interface M { +>M : Symbol(M, Decl(indexerConstraints2.ts, 36, 28)) + + [s: AliasedString]: A; +>s : Symbol(s, Decl(indexerConstraints2.ts, 39, 5)) +>AliasedString : Symbol(AliasedString, Decl(indexerConstraints2.ts, 34, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +type AliasedBoolean = boolean; +>AliasedBoolean : Symbol(AliasedBoolean, Decl(indexerConstraints2.ts, 40, 1)) + +interface N { +>N : Symbol(N, Decl(indexerConstraints2.ts, 42, 30)) + + [b: AliasedBoolean]: A; +>b : Symbol(b, Decl(indexerConstraints2.ts, 45, 5)) +>AliasedBoolean : Symbol(AliasedBoolean, Decl(indexerConstraints2.ts, 40, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} diff --git a/tests/baselines/reference/indexerConstraints2.types b/tests/baselines/reference/indexerConstraints2.types index 2a52f0e41db..29fb2526e84 100644 --- a/tests/baselines/reference/indexerConstraints2.types +++ b/tests/baselines/reference/indexerConstraints2.types @@ -62,3 +62,40 @@ class K extends J { >s : string >B : B } + + +type AliasedNumber = number; +>AliasedNumber : number + +interface L { +>L : L + + [n: AliasedNumber]: A; +>n : number +>AliasedNumber : number +>A : A +} + +type AliasedString = string; +>AliasedString : string + +interface M { +>M : M + + [s: AliasedString]: A; +>s : string +>AliasedString : string +>A : A +} + +type AliasedBoolean = boolean; +>AliasedBoolean : boolean + +interface N { +>N : N + + [b: AliasedBoolean]: A; +>b : boolean +>AliasedBoolean : boolean +>A : A +} diff --git a/tests/cases/compiler/indexerConstraints2.ts b/tests/cases/compiler/indexerConstraints2.ts index a7439b018e7..9a2e21cc4a1 100644 --- a/tests/cases/compiler/indexerConstraints2.ts +++ b/tests/cases/compiler/indexerConstraints2.ts @@ -25,4 +25,23 @@ class J { class K extends J { [n: number]: A; [s: string]: B; +} + + +type AliasedNumber = number; + +interface L { + [n: AliasedNumber]: A; +} + +type AliasedString = string; + +interface M { + [s: AliasedString]: A; +} + +type AliasedBoolean = boolean; + +interface N { + [b: AliasedBoolean]: A; } \ No newline at end of file From a0d827cfdf0cb0a0398b579eb3b2359ecf2f1c8a Mon Sep 17 00:00:00 2001 From: kujon Date: Fri, 15 Dec 2017 21:44:37 +0000 Subject: [PATCH 014/189] Improved error messages for Union index signature params --- src/compiler/checker.ts | 4 +++ src/compiler/diagnosticMessages.json | 4 +++ .../reference/indexerConstraints2.errors.txt | 29 ++++++++++++++- .../reference/indexerConstraints2.js | 18 ++++++++++ .../reference/indexerConstraints2.symbols | 36 +++++++++++++++++++ .../reference/indexerConstraints2.types | 36 +++++++++++++++++++ tests/cases/compiler/indexerConstraints2.ts | 18 ++++++++++ 7 files changed, 144 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a2e0c490642..4a06ff23c95 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25781,6 +25781,10 @@ namespace ts { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Use_index_Colon_0_instead, typeToString(type)); } + if (type.flags & TypeFlags.Union && forEach((type).types, t => !!(t.flags & TypeFlags.StringOrNumberLiteral))) { + return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Use_K_in_0_instead, symbolName(type.aliasSymbol)); + } + return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_or_number); } if (!node.type) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 083396e51d2..9ff6a591a02 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -943,6 +943,10 @@ "category": "Error", "code": 1336 }, + "An index signature parameter type cannot be a union type. Use '[K in {0}]' instead.": { + "category": "Error", + "code": 1337 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/tests/baselines/reference/indexerConstraints2.errors.txt b/tests/baselines/reference/indexerConstraints2.errors.txt index 7e13c2ba399..b8b76a69f71 100644 --- a/tests/baselines/reference/indexerConstraints2.errors.txt +++ b/tests/baselines/reference/indexerConstraints2.errors.txt @@ -4,9 +4,12 @@ tests/cases/compiler/indexerConstraints2.ts(26,5): error TS2413: Numeric index t tests/cases/compiler/indexerConstraints2.ts(34,6): error TS1336: An index signature parameter type cannot be a type alias. Use '[index: number]' instead. tests/cases/compiler/indexerConstraints2.ts(40,6): error TS1336: An index signature parameter type cannot be a type alias. Use '[index: string]' instead. tests/cases/compiler/indexerConstraints2.ts(46,6): error TS1023: An index signature parameter type must be 'string' or 'number'. +tests/cases/compiler/indexerConstraints2.ts(52,6): error TS1337: An index signature parameter type cannot be a union type. Use '[K in IndexableUnion]' instead. +tests/cases/compiler/indexerConstraints2.ts(58,6): error TS1023: An index signature parameter type must be 'string' or 'number'. +tests/cases/compiler/indexerConstraints2.ts(64,6): error TS1023: An index signature parameter type must be 'string' or 'number'. -==== tests/cases/compiler/indexerConstraints2.ts (6 errors) ==== +==== tests/cases/compiler/indexerConstraints2.ts (9 errors) ==== class A { a: number; } class B extends A { b: number; } @@ -64,5 +67,29 @@ tests/cases/compiler/indexerConstraints2.ts(46,6): error TS1023: An index signat interface N { [b: AliasedBoolean]: A; ~ +!!! error TS1023: An index signature parameter type must be 'string' or 'number'. + } + + type IndexableUnion = "foo" | 42; + + interface O { + [u: IndexableUnion]: A; + ~ +!!! error TS1337: An index signature parameter type cannot be a union type. Use '[K in IndexableUnion]' instead. + } + + type NonIndexableUnion = boolean | {}; + + interface P { + [u: NonIndexableUnion]: A; + ~ +!!! error TS1023: An index signature parameter type must be 'string' or 'number'. + } + + type NonIndexableUnion2 = string | number; + + interface Q { + [u: NonIndexableUnion2]: A; + ~ !!! error TS1023: An index signature parameter type must be 'string' or 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/indexerConstraints2.js b/tests/baselines/reference/indexerConstraints2.js index 56da818e37d..ec7b2ca0646 100644 --- a/tests/baselines/reference/indexerConstraints2.js +++ b/tests/baselines/reference/indexerConstraints2.js @@ -45,6 +45,24 @@ type AliasedBoolean = boolean; interface N { [b: AliasedBoolean]: A; +} + +type IndexableUnion = "foo" | 42; + +interface O { + [u: IndexableUnion]: A; +} + +type NonIndexableUnion = boolean | {}; + +interface P { + [u: NonIndexableUnion]: A; +} + +type NonIndexableUnion2 = string | number; + +interface Q { + [u: NonIndexableUnion2]: A; } //// [indexerConstraints2.js] diff --git a/tests/baselines/reference/indexerConstraints2.symbols b/tests/baselines/reference/indexerConstraints2.symbols index 96f2b84127e..63e0423074e 100644 --- a/tests/baselines/reference/indexerConstraints2.symbols +++ b/tests/baselines/reference/indexerConstraints2.symbols @@ -99,3 +99,39 @@ interface N { >AliasedBoolean : Symbol(AliasedBoolean, Decl(indexerConstraints2.ts, 40, 1)) >A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) } + +type IndexableUnion = "foo" | 42; +>IndexableUnion : Symbol(IndexableUnion, Decl(indexerConstraints2.ts, 46, 1)) + +interface O { +>O : Symbol(O, Decl(indexerConstraints2.ts, 48, 33)) + + [u: IndexableUnion]: A; +>u : Symbol(u, Decl(indexerConstraints2.ts, 51, 5)) +>IndexableUnion : Symbol(IndexableUnion, Decl(indexerConstraints2.ts, 46, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +type NonIndexableUnion = boolean | {}; +>NonIndexableUnion : Symbol(NonIndexableUnion, Decl(indexerConstraints2.ts, 52, 1)) + +interface P { +>P : Symbol(P, Decl(indexerConstraints2.ts, 54, 38)) + + [u: NonIndexableUnion]: A; +>u : Symbol(u, Decl(indexerConstraints2.ts, 57, 5)) +>NonIndexableUnion : Symbol(NonIndexableUnion, Decl(indexerConstraints2.ts, 52, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +type NonIndexableUnion2 = string | number; +>NonIndexableUnion2 : Symbol(NonIndexableUnion2, Decl(indexerConstraints2.ts, 58, 1)) + +interface Q { +>Q : Symbol(Q, Decl(indexerConstraints2.ts, 60, 42)) + + [u: NonIndexableUnion2]: A; +>u : Symbol(u, Decl(indexerConstraints2.ts, 63, 5)) +>NonIndexableUnion2 : Symbol(NonIndexableUnion2, Decl(indexerConstraints2.ts, 58, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} diff --git a/tests/baselines/reference/indexerConstraints2.types b/tests/baselines/reference/indexerConstraints2.types index 29fb2526e84..d3abcdceaed 100644 --- a/tests/baselines/reference/indexerConstraints2.types +++ b/tests/baselines/reference/indexerConstraints2.types @@ -99,3 +99,39 @@ interface N { >AliasedBoolean : boolean >A : A } + +type IndexableUnion = "foo" | 42; +>IndexableUnion : IndexableUnion + +interface O { +>O : O + + [u: IndexableUnion]: A; +>u : IndexableUnion +>IndexableUnion : IndexableUnion +>A : A +} + +type NonIndexableUnion = boolean | {}; +>NonIndexableUnion : NonIndexableUnion + +interface P { +>P : P + + [u: NonIndexableUnion]: A; +>u : NonIndexableUnion +>NonIndexableUnion : NonIndexableUnion +>A : A +} + +type NonIndexableUnion2 = string | number; +>NonIndexableUnion2 : NonIndexableUnion2 + +interface Q { +>Q : Q + + [u: NonIndexableUnion2]: A; +>u : NonIndexableUnion2 +>NonIndexableUnion2 : NonIndexableUnion2 +>A : A +} diff --git a/tests/cases/compiler/indexerConstraints2.ts b/tests/cases/compiler/indexerConstraints2.ts index 9a2e21cc4a1..6e790c29883 100644 --- a/tests/cases/compiler/indexerConstraints2.ts +++ b/tests/cases/compiler/indexerConstraints2.ts @@ -44,4 +44,22 @@ type AliasedBoolean = boolean; interface N { [b: AliasedBoolean]: A; +} + +type IndexableUnion = "foo" | 42; + +interface O { + [u: IndexableUnion]: A; +} + +type NonIndexableUnion = boolean | {}; + +interface P { + [u: NonIndexableUnion]: A; +} + +type NonIndexableUnion2 = string | number; + +interface Q { + [u: NonIndexableUnion2]: A; } \ No newline at end of file From 92bffe43c5f67c0862eb6934a69bf9b2a2a520a9 Mon Sep 17 00:00:00 2001 From: kujon Date: Fri, 15 Dec 2017 22:04:24 +0000 Subject: [PATCH 015/189] Fixed a mistake, whereby the check for the literal type was satisfied when any (not every) was a literal --- src/compiler/checker.ts | 2 +- .../reference/indexerConstraints2.errors.txt | 20 +++++++++++++++- .../reference/indexerConstraints2.js | 12 ++++++++++ .../reference/indexerConstraints2.symbols | 24 +++++++++++++++++++ .../reference/indexerConstraints2.types | 24 +++++++++++++++++++ tests/cases/compiler/indexerConstraints2.ts | 12 ++++++++++ 6 files changed, 92 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4a06ff23c95..611b1bac6be 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25781,7 +25781,7 @@ namespace ts { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Use_index_Colon_0_instead, typeToString(type)); } - if (type.flags & TypeFlags.Union && forEach((type).types, t => !!(t.flags & TypeFlags.StringOrNumberLiteral))) { + if (type.flags & TypeFlags.Union && every((type).types, t => !!(t.flags & TypeFlags.StringOrNumberLiteral))) { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Use_K_in_0_instead, symbolName(type.aliasSymbol)); } diff --git a/tests/baselines/reference/indexerConstraints2.errors.txt b/tests/baselines/reference/indexerConstraints2.errors.txt index b8b76a69f71..f6ffcb25c7b 100644 --- a/tests/baselines/reference/indexerConstraints2.errors.txt +++ b/tests/baselines/reference/indexerConstraints2.errors.txt @@ -7,9 +7,11 @@ tests/cases/compiler/indexerConstraints2.ts(46,6): error TS1023: An index signat tests/cases/compiler/indexerConstraints2.ts(52,6): error TS1337: An index signature parameter type cannot be a union type. Use '[K in IndexableUnion]' instead. tests/cases/compiler/indexerConstraints2.ts(58,6): error TS1023: An index signature parameter type must be 'string' or 'number'. tests/cases/compiler/indexerConstraints2.ts(64,6): error TS1023: An index signature parameter type must be 'string' or 'number'. +tests/cases/compiler/indexerConstraints2.ts(70,6): error TS1023: An index signature parameter type must be 'string' or 'number'. +tests/cases/compiler/indexerConstraints2.ts(76,6): error TS1023: An index signature parameter type must be 'string' or 'number'. -==== tests/cases/compiler/indexerConstraints2.ts (9 errors) ==== +==== tests/cases/compiler/indexerConstraints2.ts (11 errors) ==== class A { a: number; } class B extends A { b: number; } @@ -91,5 +93,21 @@ tests/cases/compiler/indexerConstraints2.ts(64,6): error TS1023: An index signat interface Q { [u: NonIndexableUnion2]: A; ~ +!!! error TS1023: An index signature parameter type must be 'string' or 'number'. + } + + type NonIndexableUnion3 = 42 | string; + + interface R { + [u: NonIndexableUnion3]: A; + ~ +!!! error TS1023: An index signature parameter type must be 'string' or 'number'. + } + + type NonIndexableUnion4 = "foo" | number; + + interface S { + [u: NonIndexableUnion4]: A; + ~ !!! error TS1023: An index signature parameter type must be 'string' or 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/indexerConstraints2.js b/tests/baselines/reference/indexerConstraints2.js index ec7b2ca0646..52df32907d5 100644 --- a/tests/baselines/reference/indexerConstraints2.js +++ b/tests/baselines/reference/indexerConstraints2.js @@ -63,6 +63,18 @@ type NonIndexableUnion2 = string | number; interface Q { [u: NonIndexableUnion2]: A; +} + +type NonIndexableUnion3 = 42 | string; + +interface R { + [u: NonIndexableUnion3]: A; +} + +type NonIndexableUnion4 = "foo" | number; + +interface S { + [u: NonIndexableUnion4]: A; } //// [indexerConstraints2.js] diff --git a/tests/baselines/reference/indexerConstraints2.symbols b/tests/baselines/reference/indexerConstraints2.symbols index 63e0423074e..571f29fafb9 100644 --- a/tests/baselines/reference/indexerConstraints2.symbols +++ b/tests/baselines/reference/indexerConstraints2.symbols @@ -135,3 +135,27 @@ interface Q { >NonIndexableUnion2 : Symbol(NonIndexableUnion2, Decl(indexerConstraints2.ts, 58, 1)) >A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) } + +type NonIndexableUnion3 = 42 | string; +>NonIndexableUnion3 : Symbol(NonIndexableUnion3, Decl(indexerConstraints2.ts, 64, 1)) + +interface R { +>R : Symbol(R, Decl(indexerConstraints2.ts, 66, 38)) + + [u: NonIndexableUnion3]: A; +>u : Symbol(u, Decl(indexerConstraints2.ts, 69, 5)) +>NonIndexableUnion3 : Symbol(NonIndexableUnion3, Decl(indexerConstraints2.ts, 64, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +type NonIndexableUnion4 = "foo" | number; +>NonIndexableUnion4 : Symbol(NonIndexableUnion4, Decl(indexerConstraints2.ts, 70, 1)) + +interface S { +>S : Symbol(S, Decl(indexerConstraints2.ts, 72, 41)) + + [u: NonIndexableUnion4]: A; +>u : Symbol(u, Decl(indexerConstraints2.ts, 75, 5)) +>NonIndexableUnion4 : Symbol(NonIndexableUnion4, Decl(indexerConstraints2.ts, 70, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} diff --git a/tests/baselines/reference/indexerConstraints2.types b/tests/baselines/reference/indexerConstraints2.types index d3abcdceaed..a7c830fe7ba 100644 --- a/tests/baselines/reference/indexerConstraints2.types +++ b/tests/baselines/reference/indexerConstraints2.types @@ -135,3 +135,27 @@ interface Q { >NonIndexableUnion2 : NonIndexableUnion2 >A : A } + +type NonIndexableUnion3 = 42 | string; +>NonIndexableUnion3 : NonIndexableUnion3 + +interface R { +>R : R + + [u: NonIndexableUnion3]: A; +>u : NonIndexableUnion3 +>NonIndexableUnion3 : NonIndexableUnion3 +>A : A +} + +type NonIndexableUnion4 = "foo" | number; +>NonIndexableUnion4 : NonIndexableUnion4 + +interface S { +>S : S + + [u: NonIndexableUnion4]: A; +>u : NonIndexableUnion4 +>NonIndexableUnion4 : NonIndexableUnion4 +>A : A +} diff --git a/tests/cases/compiler/indexerConstraints2.ts b/tests/cases/compiler/indexerConstraints2.ts index 6e790c29883..ac259df29d6 100644 --- a/tests/cases/compiler/indexerConstraints2.ts +++ b/tests/cases/compiler/indexerConstraints2.ts @@ -62,4 +62,16 @@ type NonIndexableUnion2 = string | number; interface Q { [u: NonIndexableUnion2]: A; +} + +type NonIndexableUnion3 = 42 | string; + +interface R { + [u: NonIndexableUnion3]: A; +} + +type NonIndexableUnion4 = "foo" | number; + +interface S { + [u: NonIndexableUnion4]: A; } \ No newline at end of file From 8755d4da47aa6ae3b054e27b8f4fa1ac83fb8bf9 Mon Sep 17 00:00:00 2001 From: kujon Date: Fri, 15 Dec 2017 22:28:29 +0000 Subject: [PATCH 016/189] Fixed an incorrect assumption K in Union works with numeric literals --- src/compiler/checker.ts | 2 +- .../reference/indexerConstraints2.errors.txt | 15 +++----------- .../reference/indexerConstraints2.js | 10 ++-------- .../reference/indexerConstraints2.symbols | 20 ++++--------------- .../reference/indexerConstraints2.types | 16 ++------------- tests/cases/compiler/indexerConstraints2.ts | 10 ++-------- 6 files changed, 14 insertions(+), 59 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 611b1bac6be..6c27a67c1d1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25781,7 +25781,7 @@ namespace ts { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Use_index_Colon_0_instead, typeToString(type)); } - if (type.flags & TypeFlags.Union && every((type).types, t => !!(t.flags & TypeFlags.StringOrNumberLiteral))) { + if (type.flags & TypeFlags.Union && every((type).types, t => !!(t.flags & TypeFlags.StringLiteral))) { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Use_K_in_0_instead, symbolName(type.aliasSymbol)); } diff --git a/tests/baselines/reference/indexerConstraints2.errors.txt b/tests/baselines/reference/indexerConstraints2.errors.txt index f6ffcb25c7b..804ca4eafb5 100644 --- a/tests/baselines/reference/indexerConstraints2.errors.txt +++ b/tests/baselines/reference/indexerConstraints2.errors.txt @@ -8,10 +8,9 @@ tests/cases/compiler/indexerConstraints2.ts(52,6): error TS1337: An index signat tests/cases/compiler/indexerConstraints2.ts(58,6): error TS1023: An index signature parameter type must be 'string' or 'number'. tests/cases/compiler/indexerConstraints2.ts(64,6): error TS1023: An index signature parameter type must be 'string' or 'number'. tests/cases/compiler/indexerConstraints2.ts(70,6): error TS1023: An index signature parameter type must be 'string' or 'number'. -tests/cases/compiler/indexerConstraints2.ts(76,6): error TS1023: An index signature parameter type must be 'string' or 'number'. -==== tests/cases/compiler/indexerConstraints2.ts (11 errors) ==== +==== tests/cases/compiler/indexerConstraints2.ts (10 errors) ==== class A { a: number; } class B extends A { b: number; } @@ -72,7 +71,7 @@ tests/cases/compiler/indexerConstraints2.ts(76,6): error TS1023: An index signat !!! error TS1023: An index signature parameter type must be 'string' or 'number'. } - type IndexableUnion = "foo" | 42; + type IndexableUnion = "foo" | "bar"; interface O { [u: IndexableUnion]: A; @@ -96,18 +95,10 @@ tests/cases/compiler/indexerConstraints2.ts(76,6): error TS1023: An index signat !!! error TS1023: An index signature parameter type must be 'string' or 'number'. } - type NonIndexableUnion3 = 42 | string; + type NonIndexableUnion3 = "foo" | 42; interface R { [u: NonIndexableUnion3]: A; ~ -!!! error TS1023: An index signature parameter type must be 'string' or 'number'. - } - - type NonIndexableUnion4 = "foo" | number; - - interface S { - [u: NonIndexableUnion4]: A; - ~ !!! error TS1023: An index signature parameter type must be 'string' or 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/indexerConstraints2.js b/tests/baselines/reference/indexerConstraints2.js index 52df32907d5..7fae4839e3f 100644 --- a/tests/baselines/reference/indexerConstraints2.js +++ b/tests/baselines/reference/indexerConstraints2.js @@ -47,7 +47,7 @@ interface N { [b: AliasedBoolean]: A; } -type IndexableUnion = "foo" | 42; +type IndexableUnion = "foo" | "bar"; interface O { [u: IndexableUnion]: A; @@ -65,16 +65,10 @@ interface Q { [u: NonIndexableUnion2]: A; } -type NonIndexableUnion3 = 42 | string; +type NonIndexableUnion3 = "foo" | 42; interface R { [u: NonIndexableUnion3]: A; -} - -type NonIndexableUnion4 = "foo" | number; - -interface S { - [u: NonIndexableUnion4]: A; } //// [indexerConstraints2.js] diff --git a/tests/baselines/reference/indexerConstraints2.symbols b/tests/baselines/reference/indexerConstraints2.symbols index 571f29fafb9..fe171479ec1 100644 --- a/tests/baselines/reference/indexerConstraints2.symbols +++ b/tests/baselines/reference/indexerConstraints2.symbols @@ -100,11 +100,11 @@ interface N { >A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) } -type IndexableUnion = "foo" | 42; +type IndexableUnion = "foo" | "bar"; >IndexableUnion : Symbol(IndexableUnion, Decl(indexerConstraints2.ts, 46, 1)) interface O { ->O : Symbol(O, Decl(indexerConstraints2.ts, 48, 33)) +>O : Symbol(O, Decl(indexerConstraints2.ts, 48, 36)) [u: IndexableUnion]: A; >u : Symbol(u, Decl(indexerConstraints2.ts, 51, 5)) @@ -136,26 +136,14 @@ interface Q { >A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) } -type NonIndexableUnion3 = 42 | string; +type NonIndexableUnion3 = "foo" | 42; >NonIndexableUnion3 : Symbol(NonIndexableUnion3, Decl(indexerConstraints2.ts, 64, 1)) interface R { ->R : Symbol(R, Decl(indexerConstraints2.ts, 66, 38)) +>R : Symbol(R, Decl(indexerConstraints2.ts, 66, 37)) [u: NonIndexableUnion3]: A; >u : Symbol(u, Decl(indexerConstraints2.ts, 69, 5)) >NonIndexableUnion3 : Symbol(NonIndexableUnion3, Decl(indexerConstraints2.ts, 64, 1)) >A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) } - -type NonIndexableUnion4 = "foo" | number; ->NonIndexableUnion4 : Symbol(NonIndexableUnion4, Decl(indexerConstraints2.ts, 70, 1)) - -interface S { ->S : Symbol(S, Decl(indexerConstraints2.ts, 72, 41)) - - [u: NonIndexableUnion4]: A; ->u : Symbol(u, Decl(indexerConstraints2.ts, 75, 5)) ->NonIndexableUnion4 : Symbol(NonIndexableUnion4, Decl(indexerConstraints2.ts, 70, 1)) ->A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) -} diff --git a/tests/baselines/reference/indexerConstraints2.types b/tests/baselines/reference/indexerConstraints2.types index a7c830fe7ba..a41dda6ed35 100644 --- a/tests/baselines/reference/indexerConstraints2.types +++ b/tests/baselines/reference/indexerConstraints2.types @@ -100,7 +100,7 @@ interface N { >A : A } -type IndexableUnion = "foo" | 42; +type IndexableUnion = "foo" | "bar"; >IndexableUnion : IndexableUnion interface O { @@ -136,7 +136,7 @@ interface Q { >A : A } -type NonIndexableUnion3 = 42 | string; +type NonIndexableUnion3 = "foo" | 42; >NonIndexableUnion3 : NonIndexableUnion3 interface R { @@ -147,15 +147,3 @@ interface R { >NonIndexableUnion3 : NonIndexableUnion3 >A : A } - -type NonIndexableUnion4 = "foo" | number; ->NonIndexableUnion4 : NonIndexableUnion4 - -interface S { ->S : S - - [u: NonIndexableUnion4]: A; ->u : NonIndexableUnion4 ->NonIndexableUnion4 : NonIndexableUnion4 ->A : A -} diff --git a/tests/cases/compiler/indexerConstraints2.ts b/tests/cases/compiler/indexerConstraints2.ts index ac259df29d6..26cf94fbbc0 100644 --- a/tests/cases/compiler/indexerConstraints2.ts +++ b/tests/cases/compiler/indexerConstraints2.ts @@ -46,7 +46,7 @@ interface N { [b: AliasedBoolean]: A; } -type IndexableUnion = "foo" | 42; +type IndexableUnion = "foo" | "bar"; interface O { [u: IndexableUnion]: A; @@ -64,14 +64,8 @@ interface Q { [u: NonIndexableUnion2]: A; } -type NonIndexableUnion3 = 42 | string; +type NonIndexableUnion3 = "foo" | 42; interface R { [u: NonIndexableUnion3]: A; -} - -type NonIndexableUnion4 = "foo" | number; - -interface S { - [u: NonIndexableUnion4]: A; } \ No newline at end of file From 8c2eeb215ffa62d47a4db57dc446feb2ad93a36a Mon Sep 17 00:00:00 2001 From: Oussama Ben Brahim Date: Mon, 4 Dec 2017 03:04:34 +0100 Subject: [PATCH 017/189] bug(esnext): add definitions for flatten and flatMap Fixes #20410 --- Gulpfile.ts | 3 +- Jakefile.js | 3 +- src/compiler/commandLineParser.ts | 1 + src/harness/unittests/commandLineParsing.ts | 6 +-- .../convertCompilerOptionsFromJson.ts | 8 +-- src/lib/es2018.d.ts | 2 +- src/lib/esnext.array.d.ts | 51 +++++++++++++++++++ src/lib/esnext.d.ts | 3 +- 8 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 src/lib/esnext.array.d.ts diff --git a/Gulpfile.ts b/Gulpfile.ts index 4d90d5cf24a..602a689f9a2 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -150,7 +150,8 @@ const es2018LibrarySourceMap = es2018LibrarySource.map(source => ({ target: "lib." + source, sources: ["header.d.ts", source] })); const esnextLibrarySource = [ - "esnext.asynciterable.d.ts" + "esnext.asynciterable.d.ts", + "esnext.array.d.ts" ]; const esnextLibrarySourceMap = esnextLibrarySource.map(source => diff --git a/Jakefile.js b/Jakefile.js index e016c1bd0bd..f653e77ff3d 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -213,7 +213,8 @@ var es2018LibrarySourceMap = es2018LibrarySource.map(function (source) { }); var esnextLibrarySource = [ - "esnext.asynciterable.d.ts" + "esnext.asynciterable.d.ts", + "esnext.array.d.ts" ]; var esnextLibrarySourceMap = esnextLibrarySource.map(function (source) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index a0f91e3d0e9..6dfa829c9f2 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -144,6 +144,7 @@ namespace ts { "es2017.string": "lib.es2017.string.d.ts", "es2017.intl": "lib.es2017.intl.d.ts", "es2017.typedarrays": "lib.es2017.typedarrays.d.ts", + "esnext.array": "lib.esnext.array.d.ts", "esnext.asynciterable": "lib.esnext.asynciterable.d.ts", }), }, diff --git a/src/harness/unittests/commandLineParsing.ts b/src/harness/unittests/commandLineParsing.ts index 82c2af7f64e..ade4718c3fe 100644 --- a/src/harness/unittests/commandLineParsing.ts +++ b/src/harness/unittests/commandLineParsing.ts @@ -60,7 +60,7 @@ namespace ts { assertParseResult(["--lib", "es5,invalidOption", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -263,7 +263,7 @@ namespace ts { assertParseResult(["--lib", "es5,", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -283,7 +283,7 @@ namespace ts { assertParseResult(["--lib", "es5, ", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index 2a8f1fe3a89..526731313b1 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -266,7 +266,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -297,7 +297,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -328,7 +328,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -359,7 +359,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] diff --git a/src/lib/es2018.d.ts b/src/lib/es2018.d.ts index 71d6e190b15..90f6d4931f4 100644 --- a/src/lib/es2018.d.ts +++ b/src/lib/es2018.d.ts @@ -1 +1 @@ -/// \ No newline at end of file +/// diff --git a/src/lib/esnext.array.d.ts b/src/lib/esnext.array.d.ts new file mode 100644 index 00000000000..d2fbf5e290f --- /dev/null +++ b/src/lib/esnext.array.d.ts @@ -0,0 +1,51 @@ +interface ReadonlyArray { + + /** + * Calls a defined callback function on each element of an array. Then, flattens the result into + * a new array. + * This is identical to a map followed by a flatten of depth 1. + * + * @param callback A function that accepts up to three arguments. The flatMap method calls the + * callback function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callback function. If + * thisArg is omitted, undefined is used as the this value. + */ + flatMap ( + callback: (this: This, value: T, index: number, array: T[]) => U|U[], + thisArg?: This + ): U[] + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. If no depth is provided, flatten method defaults to the depth of 1. + * + * @param depth The maximum recursion depth + */ + flatten(this: ReadonlyArray, depth?: number): U[]; + } + +interface Array { + + /** + * Calls a defined callback function on each element of an array. Then, flattens the result into + * a new array. + * This is identical to a map followed by a flatten of depth 1. + * + * @param callback A function that accepts up to three arguments. The flatMap method calls the + * callback function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callback function. If + * thisArg is omitted, undefined is used as the this value. + */ + flatMap ( + callback: (this: This, value: T, index: number, array: T[]) => U|U[], + thisArg?: This + ): U[] + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. If no depth is provided, flatten method defaults to the depth of 1. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[], depth?: number): U[]; +} diff --git a/src/lib/esnext.d.ts b/src/lib/esnext.d.ts index 71fab82a866..831d241cc3c 100644 --- a/src/lib/esnext.d.ts +++ b/src/lib/esnext.d.ts @@ -1,2 +1,3 @@ -/// +/// /// +/// From ae6bf9c7333f35641b0fea16f76cf8d4b42cc443 Mon Sep 17 00:00:00 2001 From: Oussama Ben Brahim Date: Sat, 16 Dec 2017 19:51:47 +0100 Subject: [PATCH 018/189] bug(esnext) add overloads for flatten --- src/lib/esnext.array.d.ts | 156 +++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 2 deletions(-) diff --git a/src/lib/esnext.array.d.ts b/src/lib/esnext.array.d.ts index d2fbf5e290f..ddba47badaa 100644 --- a/src/lib/esnext.array.d.ts +++ b/src/lib/esnext.array.d.ts @@ -15,13 +15,101 @@ interface ReadonlyArray { thisArg?: This ): U[] + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray | + + ReadonlyArray> | + ReadonlyArray[]> | + ReadonlyArray[][]> | + ReadonlyArray[][][]> | + + ReadonlyArray>> | + ReadonlyArray[][]>> | + ReadonlyArray>[][]> | + ReadonlyArray[]>[]> | + ReadonlyArray>[]> | + ReadonlyArray[]>> | + + ReadonlyArray>>> | + ReadonlyArray[]>>> | + ReadonlyArray>[]>> | + ReadonlyArray>>[]> | + + ReadonlyArray>>>>, + depth: 4): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray | + + ReadonlyArray[][]> | + ReadonlyArray[]> | + ReadonlyArray> | + + ReadonlyArray>> | + ReadonlyArray[]>> | + ReadonlyArray>[]> | + + ReadonlyArray>>>, + depth: 3): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray | + + ReadonlyArray> | + ReadonlyArray[]> | + + ReadonlyArray>>, + depth: 2): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray | + ReadonlyArray>, + depth?: 1 + ): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray, + depth: 0 + ): U[]; + /** * Returns a new array with all sub-array elements concatenated into it recursively up to the * specified depth. If no depth is provided, flatten method defaults to the depth of 1. * * @param depth The maximum recursion depth */ - flatten(this: ReadonlyArray, depth?: number): U[]; + flatten(depth?: number): any[]; } interface Array { @@ -41,11 +129,75 @@ interface Array { thisArg?: This ): U[] + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][][][][][], depth: 7): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][][][][], depth: 6): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][][][], depth: 5): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][][], depth: 4): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][], depth: 3): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][], depth: 2): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][], depth?: 1): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[], depth: 0): U[]; + /** * Returns a new array with all sub-array elements concatenated into it recursively up to the * specified depth. If no depth is provided, flatten method defaults to the depth of 1. * * @param depth The maximum recursion depth */ - flatten(this: U[], depth?: number): U[]; + flatten(depth?: number): any[]; } From c92c7a5b100a3b13168b8a2e0d2b9281a42a396a Mon Sep 17 00:00:00 2001 From: kujon Date: Tue, 19 Dec 2017 21:29:03 +0000 Subject: [PATCH 019/189] Addressed the suggestions --- src/compiler/checker.ts | 11 +++++++--- src/compiler/diagnosticMessages.json | 4 ++-- .../reference/indexerConstraints2.errors.txt | 21 ++++++++++++------- .../reference/indexerConstraints2.js | 4 ++++ .../reference/indexerConstraints2.symbols | 8 +++++++ .../reference/indexerConstraints2.types | 8 +++++++ tests/cases/compiler/indexerConstraints2.ts | 4 ++++ 7 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6c27a67c1d1..d49acffbff4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25778,11 +25778,16 @@ namespace ts { const type = getTypeFromTypeNode(parameter.type); if (type.flags & TypeFlags.String || type.flags & TypeFlags.Number) { - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Use_index_Colon_0_instead, typeToString(type)); + return grammarErrorOnNode(parameter.name, + Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead, + getTextOfNode(parameter.name), + typeToString(type), + typeToString(getTypeFromTypeNode(node.type))); } - if (type.flags & TypeFlags.Union && every((type).types, t => !!(t.flags & TypeFlags.StringLiteral))) { - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Use_K_in_0_instead, symbolName(type.aliasSymbol)); + if (allTypesAssignableToKind(type, TypeFlags.StringLiteral, /*strict*/ true)) { + return grammarErrorOnNode(parameter.name, + Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead); } return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_or_number); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 9ff6a591a02..b5758675eb9 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -939,11 +939,11 @@ "category": "Error", "code": 1335 }, - "An index signature parameter type cannot be a type alias. Use '[index: {0}]' instead.": { + "An index signature parameter type cannot be a type alias. Consider writing '[{0}: {1}]: {2}' instead.": { "category": "Error", "code": 1336 }, - "An index signature parameter type cannot be a union type. Use '[K in {0}]' instead.": { + "An index signature parameter type cannot be a union type. Consider using a mapped object type instead.": { "category": "Error", "code": 1337 }, diff --git a/tests/baselines/reference/indexerConstraints2.errors.txt b/tests/baselines/reference/indexerConstraints2.errors.txt index 804ca4eafb5..7e104e77f98 100644 --- a/tests/baselines/reference/indexerConstraints2.errors.txt +++ b/tests/baselines/reference/indexerConstraints2.errors.txt @@ -1,16 +1,17 @@ tests/cases/compiler/indexerConstraints2.ts(9,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. tests/cases/compiler/indexerConstraints2.ts(17,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. tests/cases/compiler/indexerConstraints2.ts(26,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. -tests/cases/compiler/indexerConstraints2.ts(34,6): error TS1336: An index signature parameter type cannot be a type alias. Use '[index: number]' instead. -tests/cases/compiler/indexerConstraints2.ts(40,6): error TS1336: An index signature parameter type cannot be a type alias. Use '[index: string]' instead. +tests/cases/compiler/indexerConstraints2.ts(34,6): error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[n: number]: A' instead. +tests/cases/compiler/indexerConstraints2.ts(40,6): error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[s: string]: A' instead. tests/cases/compiler/indexerConstraints2.ts(46,6): error TS1023: An index signature parameter type must be 'string' or 'number'. -tests/cases/compiler/indexerConstraints2.ts(52,6): error TS1337: An index signature parameter type cannot be a union type. Use '[K in IndexableUnion]' instead. +tests/cases/compiler/indexerConstraints2.ts(52,6): error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. tests/cases/compiler/indexerConstraints2.ts(58,6): error TS1023: An index signature parameter type must be 'string' or 'number'. tests/cases/compiler/indexerConstraints2.ts(64,6): error TS1023: An index signature parameter type must be 'string' or 'number'. tests/cases/compiler/indexerConstraints2.ts(70,6): error TS1023: An index signature parameter type must be 'string' or 'number'. +tests/cases/compiler/indexerConstraints2.ts(74,6): error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. -==== tests/cases/compiler/indexerConstraints2.ts (10 errors) ==== +==== tests/cases/compiler/indexerConstraints2.ts (11 errors) ==== class A { a: number; } class B extends A { b: number; } @@ -52,7 +53,7 @@ tests/cases/compiler/indexerConstraints2.ts(70,6): error TS1023: An index signat interface L { [n: AliasedNumber]: A; ~ -!!! error TS1336: An index signature parameter type cannot be a type alias. Use '[index: number]' instead. +!!! error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[n: number]: A' instead. } type AliasedString = string; @@ -60,7 +61,7 @@ tests/cases/compiler/indexerConstraints2.ts(70,6): error TS1023: An index signat interface M { [s: AliasedString]: A; ~ -!!! error TS1336: An index signature parameter type cannot be a type alias. Use '[index: string]' instead. +!!! error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[s: string]: A' instead. } type AliasedBoolean = boolean; @@ -76,7 +77,7 @@ tests/cases/compiler/indexerConstraints2.ts(70,6): error TS1023: An index signat interface O { [u: IndexableUnion]: A; ~ -!!! error TS1337: An index signature parameter type cannot be a union type. Use '[K in IndexableUnion]' instead. +!!! error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. } type NonIndexableUnion = boolean | {}; @@ -101,4 +102,10 @@ tests/cases/compiler/indexerConstraints2.ts(70,6): error TS1023: An index signat [u: NonIndexableUnion3]: A; ~ !!! error TS1023: An index signature parameter type must be 'string' or 'number'. + } + + interface S { + [u: "foo" | "bar"]: A; + ~ +!!! error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. } \ No newline at end of file diff --git a/tests/baselines/reference/indexerConstraints2.js b/tests/baselines/reference/indexerConstraints2.js index 7fae4839e3f..d6fb40ba22d 100644 --- a/tests/baselines/reference/indexerConstraints2.js +++ b/tests/baselines/reference/indexerConstraints2.js @@ -69,6 +69,10 @@ type NonIndexableUnion3 = "foo" | 42; interface R { [u: NonIndexableUnion3]: A; +} + +interface S { + [u: "foo" | "bar"]: A; } //// [indexerConstraints2.js] diff --git a/tests/baselines/reference/indexerConstraints2.symbols b/tests/baselines/reference/indexerConstraints2.symbols index fe171479ec1..4cb5558a8ce 100644 --- a/tests/baselines/reference/indexerConstraints2.symbols +++ b/tests/baselines/reference/indexerConstraints2.symbols @@ -147,3 +147,11 @@ interface R { >NonIndexableUnion3 : Symbol(NonIndexableUnion3, Decl(indexerConstraints2.ts, 64, 1)) >A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) } + +interface S { +>S : Symbol(S, Decl(indexerConstraints2.ts, 70, 1)) + + [u: "foo" | "bar"]: A; +>u : Symbol(u, Decl(indexerConstraints2.ts, 73, 5)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} diff --git a/tests/baselines/reference/indexerConstraints2.types b/tests/baselines/reference/indexerConstraints2.types index a41dda6ed35..e2db782d788 100644 --- a/tests/baselines/reference/indexerConstraints2.types +++ b/tests/baselines/reference/indexerConstraints2.types @@ -147,3 +147,11 @@ interface R { >NonIndexableUnion3 : NonIndexableUnion3 >A : A } + +interface S { +>S : S + + [u: "foo" | "bar"]: A; +>u : IndexableUnion +>A : A +} diff --git a/tests/cases/compiler/indexerConstraints2.ts b/tests/cases/compiler/indexerConstraints2.ts index 26cf94fbbc0..38b4ddec41a 100644 --- a/tests/cases/compiler/indexerConstraints2.ts +++ b/tests/cases/compiler/indexerConstraints2.ts @@ -68,4 +68,8 @@ type NonIndexableUnion3 = "foo" | 42; interface R { [u: NonIndexableUnion3]: A; +} + +interface S { + [u: "foo" | "bar"]: A; } \ No newline at end of file From 993a21e4e2caa80085459a2f1967c0d2cac04123 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 21 Dec 2017 17:04:27 -0800 Subject: [PATCH 020/189] Load global plugins for inferred projects Fixes #18322 Ensure that we also try to load global plugins for inferred projects. Moves global plugin loading logic to base `Project` class from `ConfigureProject` . --- src/server/project.ts | 174 ++++++++++++++++++++++-------------------- 1 file changed, 93 insertions(+), 81 deletions(-) diff --git a/src/server/project.ts b/src/server/project.ts index 11c023415ef..ebc93ae3e1e 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -121,6 +121,7 @@ namespace ts.server { private program: Program; private externalFiles: SortedReadonlyArray; private missingFilesMap: Map; + private plugins: PluginModule[] = []; private cachedUnresolvedImportsPerFile = new UnresolvedImportsMap(); private lastCachedUnresolvedImportsList: SortedReadonlyArray; @@ -515,7 +516,18 @@ namespace ts.server { } getExternalFiles(): SortedReadonlyArray { - return emptyArray as SortedReadonlyArray; + return toSortedArray(flatMap(this.plugins, plugin => { + if (typeof plugin.getExternalFiles !== "function") return; + try { + return plugin.getExternalFiles(this); + } + catch (e) { + this.projectService.logger.info(`A plugin threw an exception in getExternalFiles: ${e}`); + if (e.stack) { + this.projectService.logger.info(e.stack); + } + } + })); } getSourceFile(path: Path) { @@ -1029,6 +1041,84 @@ namespace ts.server { orderedRemoveItem(this.rootFiles, info); this.rootFilesMap.delete(info.path); } + + protected enableGlobalPlugins() { + const host = this.projectService.host; + const options = this.getCompilationSettings(); + + if (!host.require) { + this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); + return; + } + + // Search our peer node_modules, then any globally-specified probe paths + // ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/ + const searchPaths = [combinePaths(this.projectService.getExecutingFilePath(), "../../.."), ...this.projectService.pluginProbeLocations]; + + if (this.projectService.globalPlugins) { + // Enable global plugins with synthetic configuration entries + for (const globalPluginName of this.projectService.globalPlugins) { + // Skip empty names from odd commandline parses + if (!globalPluginName) continue; + + // Skip already-locally-loaded plugins + if (options.plugins && options.plugins.some(p => p.name === globalPluginName)) continue; + + // Provide global: true so plugins can detect why they can't find their config + this.projectService.logger.info(`Loading global plugin ${globalPluginName}`); + this.enablePlugin({ name: globalPluginName, global: true } as PluginImport, searchPaths); + } + } + } + + protected enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[]) { + this.projectService.logger.info(`Enabling plugin ${pluginConfigEntry.name} from candidate paths: ${searchPaths.join(",")}`); + + const log = (message: string) => { + this.projectService.logger.info(message); + }; + + for (const searchPath of searchPaths) { + const resolvedModule = Project.resolveModule(pluginConfigEntry.name, searchPath, this.projectService.host, log); + if (resolvedModule) { + this.enableProxy(resolvedModule, pluginConfigEntry); + return; + } + } + this.projectService.logger.info(`Couldn't find ${pluginConfigEntry.name}`); + } + + private enableProxy(pluginModuleFactory: PluginModuleFactory, configEntry: PluginImport) { + try { + if (typeof pluginModuleFactory !== "function") { + this.projectService.logger.info(`Skipped loading plugin ${configEntry.name} because it did expose a proper factory function`); + return; + } + + const info: PluginCreateInfo = { + config: configEntry, + project: this, + languageService: this.languageService, + languageServiceHost: this, + serverHost: this.projectService.host + }; + + const pluginModule = pluginModuleFactory({ typescript: ts }); + const newLS = pluginModule.create(info); + for (const k of Object.keys(this.languageService)) { + if (!(k in newLS)) { + this.projectService.logger.info(`Plugin activation warning: Missing proxied method ${k} in created LS. Patching.`); + (newLS as any)[k] = (this.languageService as any)[k]; + } + } + this.projectService.logger.info(`Plugin validation succeded`); + this.languageService = newLS; + this.plugins.push(pluginModule); + } + catch (e) { + this.projectService.logger.info(`Plugin activation failed: ${e}`); + } + } } /** @@ -1092,6 +1182,7 @@ namespace ts.server { projectService.host, currentDirectory); this.projectRootPath = projectRootPath && projectService.toCanonicalFileName(projectRootPath); + this.enableGlobalPlugins(); } addRoot(info: ScriptInfo) { @@ -1153,8 +1244,6 @@ namespace ts.server { /*@internal*/ configFileSpecs: ConfigFileSpecs; - private plugins: PluginModule[] = []; - /** Ref count to the project when opened from external project */ private externalProjectRefCount = 0; @@ -1236,69 +1325,7 @@ namespace ts.server { } } - if (this.projectService.globalPlugins) { - // Enable global plugins with synthetic configuration entries - for (const globalPluginName of this.projectService.globalPlugins) { - // Skip empty names from odd commandline parses - if (!globalPluginName) continue; - - // Skip already-locally-loaded plugins - if (options.plugins && options.plugins.some(p => p.name === globalPluginName)) continue; - - // Provide global: true so plugins can detect why they can't find their config - this.projectService.logger.info(`Loading global plugin ${globalPluginName}`); - this.enablePlugin({ name: globalPluginName, global: true } as PluginImport, searchPaths); - } - } - } - - private enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[]) { - this.projectService.logger.info(`Enabling plugin ${pluginConfigEntry.name} from candidate paths: ${searchPaths.join(",")}`); - - const log = (message: string) => { - this.projectService.logger.info(message); - }; - - for (const searchPath of searchPaths) { - const resolvedModule = Project.resolveModule(pluginConfigEntry.name, searchPath, this.projectService.host, log); - if (resolvedModule) { - this.enableProxy(resolvedModule, pluginConfigEntry); - return; - } - } - this.projectService.logger.info(`Couldn't find ${pluginConfigEntry.name}`); - } - - private enableProxy(pluginModuleFactory: PluginModuleFactory, configEntry: PluginImport) { - try { - if (typeof pluginModuleFactory !== "function") { - this.projectService.logger.info(`Skipped loading plugin ${configEntry.name} because it did expose a proper factory function`); - return; - } - - const info: PluginCreateInfo = { - config: configEntry, - project: this, - languageService: this.languageService, - languageServiceHost: this, - serverHost: this.projectService.host - }; - - const pluginModule = pluginModuleFactory({ typescript: ts }); - const newLS = pluginModule.create(info); - for (const k of Object.keys(this.languageService)) { - if (!(k in newLS)) { - this.projectService.logger.info(`Plugin activation warning: Missing proxied method ${k} in created LS. Patching.`); - (newLS as any)[k] = (this.languageService as any)[k]; - } - } - this.projectService.logger.info(`Plugin validation succeded`); - this.languageService = newLS; - this.plugins.push(pluginModule); - } - catch (e) { - this.projectService.logger.info(`Plugin activation failed: ${e}`); - } + this.enableGlobalPlugins(); } /** @@ -1327,21 +1354,6 @@ namespace ts.server { return this.typeAcquisition; } - getExternalFiles(): SortedReadonlyArray { - return toSortedArray(flatMap(this.plugins, plugin => { - if (typeof plugin.getExternalFiles !== "function") return; - try { - return plugin.getExternalFiles(this); - } - catch (e) { - this.projectService.logger.info(`A plugin threw an exception in getExternalFiles: ${e}`); - if (e.stack) { - this.projectService.logger.info(e.stack); - } - } - })); - } - /*@internal*/ watchWildcards(wildcardDirectories: Map) { updateWatchingWildcardDirectories( From a5e77074f70d0fd13c31032d12769e29f95a0e2e Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 21 Dec 2017 17:11:58 -0800 Subject: [PATCH 021/189] Baseline --- tests/baselines/reference/api/tsserverlibrary.d.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index ad34924a097..d7d06fd9adc 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7230,6 +7230,7 @@ declare namespace ts.server { private program; private externalFiles; private missingFilesMap; + private plugins; private cachedUnresolvedImportsPerFile; private lastCachedUnresolvedImportsList; protected languageService: LanguageService; @@ -7345,6 +7346,9 @@ declare namespace ts.server { filesToString(writeProjectFileNames: boolean): string; setCompilerOptions(compilerOptions: CompilerOptions): void; protected removeRoot(info: ScriptInfo): void; + protected enableGlobalPlugins(): void; + protected enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[]): void; + private enableProxy(pluginModuleFactory, configEntry); } /** * If a file is opened and no tsconfig (or jsconfig) is found, @@ -7373,7 +7377,6 @@ declare namespace ts.server { private typeAcquisition; private directoriesWatchedForWildcards; readonly canonicalConfigFilePath: NormalizedPath; - private plugins; /** Ref count to the project when opened from external project */ private externalProjectRefCount; private projectErrors; @@ -7384,8 +7387,6 @@ declare namespace ts.server { updateGraph(): boolean; getConfigFilePath(): NormalizedPath; enablePlugins(): void; - private enablePlugin(pluginConfigEntry, searchPaths); - private enableProxy(pluginModuleFactory, configEntry); /** * Get the errors that dont have any file name associated */ @@ -7397,7 +7398,6 @@ declare namespace ts.server { setProjectErrors(projectErrors: Diagnostic[]): void; setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void; getTypeAcquisition(): TypeAcquisition; - getExternalFiles(): SortedReadonlyArray; close(): void; getEffectiveTypeRoots(): string[]; } From 303786a3b81de49cea4297b0dd9c8382cef0e526 Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Sun, 24 Dec 2017 17:05:05 +0800 Subject: [PATCH 022/189] fix #20018, allow skip constraint when merging interfaces --- src/compiler/checker.ts | 8 +-- ...erfacesWithDifferentConstraints.errors.txt | 31 ++++++++++- ...nericInterfacesWithDifferentConstraints.js | 23 ++++++++- ...InterfacesWithDifferentConstraints.symbols | 51 +++++++++++++++++++ ...icInterfacesWithDifferentConstraints.types | 51 +++++++++++++++++++ ...nericInterfacesWithDifferentConstraints.ts | 22 +++++++- 6 files changed, 179 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 813e09f97ca..f9c40d74638 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22633,9 +22633,11 @@ namespace ts { // type parameter at this position, we report an error. const sourceConstraint = source.constraint && getTypeFromTypeNode(source.constraint); const targetConstraint = getConstraintFromTypeParameter(target); - if ((sourceConstraint || targetConstraint) && - (!sourceConstraint || !targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint))) { - return false; + if (sourceConstraint) { + // relax check if later interface augmentation has no constraint + if (!targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint)) { + return false; + } } // If the type parameter node has a default and it is not identical to the default diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt index 71d6f73d864..21a35e0553b 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt @@ -4,9 +4,11 @@ tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDi tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(14,15): error TS2428: All declarations of 'B' must have identical type parameters. tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(32,22): error TS2428: All declarations of 'A' must have identical type parameters. tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(38,22): error TS2428: All declarations of 'A' must have identical type parameters. +tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(53,11): error TS2428: All declarations of 'C' must have identical type parameters. +tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(57,11): error TS2428: All declarations of 'C' must have identical type parameters. -==== tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts (6 errors) ==== +==== tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts (8 errors) ==== interface A { ~ !!! error TS2428: All declarations of 'A' must have identical type parameters. @@ -59,4 +61,29 @@ tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDi !!! error TS2428: All declarations of 'A' must have identical type parameters. y: T; } - } \ No newline at end of file + } + + interface B { + u: T; + v: Constraint; // ok + } + + interface B { // ok + x: T; + y: Constraint; // ok + } + + interface C { + ~ +!!! error TS2428: All declarations of 'C' must have identical type parameters. + x: T; + } + + interface C { // error + ~ +!!! error TS2428: All declarations of 'C' must have identical type parameters. + y: T; + } + + interface Constraint {} + \ No newline at end of file diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js index 245da303d73..5b1964b2891 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js @@ -39,6 +39,27 @@ module M3 { export interface A { // error y: T; } -} +} + +interface B { + u: T; + v: Constraint; // ok +} + +interface B { // ok + x: T; + y: Constraint; // ok +} + +interface C { + x: T; +} + +interface C { // error + y: T; +} + +interface Constraint {} + //// [twoGenericInterfacesWithDifferentConstraints.js] diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols index 46b0d397e09..6d802b9ff2c 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols @@ -99,3 +99,54 @@ module M3 { >T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 31, 23), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 37, 23)) } } + +interface B { +>B : Symbol(B, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 40, 1), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 45, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) + + u: T; +>u : Symbol(B.u, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 31)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) + + v: Constraint; // ok +>v : Symbol(B.v, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 43, 7)) +>Constraint : Symbol(Constraint, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 58, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) +} + +interface B { // ok +>B : Symbol(B, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 40, 1), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 45, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) + + x: T; +>x : Symbol(B.x, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 16)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) + + y: Constraint; // ok +>y : Symbol(B.y, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 48, 7)) +>Constraint : Symbol(Constraint, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 58, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) +} + +interface C { +>C : Symbol(C, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 50, 1), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 54, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) + + x: T; +>x : Symbol(C.x, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 16)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) +} + +interface C { // error +>C : Symbol(C, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 50, 1), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 54, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) + + y: T; +>y : Symbol(C.y, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 31)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) +} + +interface Constraint {} +>Constraint : Symbol(Constraint, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 58, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 60, 21)) + diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types index ca56778032b..8f7899549fc 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types @@ -99,3 +99,54 @@ module M3 { >T : T } } + +interface B { +>B : B +>T : T + + u: T; +>u : T +>T : T + + v: Constraint; // ok +>v : Constraint +>Constraint : Constraint +>T : T +} + +interface B { // ok +>B : B +>T : T + + x: T; +>x : T +>T : T + + y: Constraint; // ok +>y : Constraint +>Constraint : Constraint +>T : T +} + +interface C { +>C : C +>T : T + + x: T; +>x : T +>T : T +} + +interface C { // error +>C : C +>T : T + + y: T; +>y : T +>T : T +} + +interface Constraint {} +>Constraint : Constraint +>T : T + diff --git a/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts b/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts index 181252c0721..4c698626eb0 100644 --- a/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts +++ b/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts @@ -38,4 +38,24 @@ module M3 { export interface A { // error y: T; } -} \ No newline at end of file +} + +interface B { + u: T; + v: Constraint; // ok +} + +interface B { // ok + x: T; + y: Constraint; // ok +} + +interface C { + x: T; +} + +interface C { // error + y: T; +} + +interface Constraint {} From ec7a667e4b017e3301bd367a212cf4695c88d160 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Wed, 27 Dec 2017 14:43:23 -0800 Subject: [PATCH 023/189] Update rules to match JSXElement --- src/services/formatting/rules.ts | 10 +++++----- src/services/formatting/smartIndenter.ts | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 91c133ca352..bf1c57b2188 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -231,8 +231,8 @@ namespace ts.formatting { rule("SpaceAfterConstructor", SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], RuleAction.Space), rule("NoSpaceAfterConstructor", SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], RuleAction.Delete), - rule("SpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionEnabled("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementContext, isNextTokenNotCloseBracket], RuleAction.Space), - rule("NoSpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementContext], RuleAction.Delete), + rule("SpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionEnabled("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNextTokenNotCloseBracket], RuleAction.Space), + rule("NoSpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext], RuleAction.Delete), // Insert space after function keyword for anonymous functions rule("SpaceAfterAnonymousFunctionKeyword", SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], RuleAction.Space), @@ -319,7 +319,7 @@ namespace ts.formatting { "SpaceBetweenStatements", [SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword], anyToken, - [isNonJsxSameLineTokenContext, isNonJsxElementContext, isNotForContext], + [isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNotForContext], RuleAction.Space), // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter. rule("SpaceAfterTryFinally", [SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword], SyntaxKind.OpenBraceToken, [isNonJsxSameLineTokenContext], RuleAction.Space), @@ -614,8 +614,8 @@ namespace ts.formatting { return context.TokensAreOnSameLine() && context.contextNode.kind !== SyntaxKind.JsxText; } - function isNonJsxElementContext(context: FormattingContext): boolean { - return context.contextNode.kind !== SyntaxKind.JsxElement; + function isNonJsxElementOrFragmentContext(context: FormattingContext): boolean { + return context.contextNode.kind !== SyntaxKind.JsxElement && context.contextNode.kind !== SyntaxKind.JsxFragment; } function isJsxExpressionContext(context: FormattingContext): boolean { diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 0a444a7280a..443a63a2042 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -508,6 +508,7 @@ namespace ts.formatting { case SyntaxKind.ArrayBindingPattern: case SyntaxKind.ObjectBindingPattern: case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxOpeningFragment: case SyntaxKind.JsxSelfClosingElement: case SyntaxKind.JsxExpression: case SyntaxKind.MethodSignature: @@ -554,6 +555,8 @@ namespace ts.formatting { (!!(child).namedBindings && (child).namedBindings.kind !== SyntaxKind.NamedImports); case SyntaxKind.JsxElement: return childKind !== SyntaxKind.JsxClosingElement; + case SyntaxKind.JsxFragment: + return childKind !== SyntaxKind.JsxClosingFragment; } // No explicit rule for given nodes so the result will follow the default value argument return indentByDefault; From 80b7983d2cf7f9bdccdaf75e8943560c07038a3c Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Wed, 27 Dec 2017 16:56:03 -0800 Subject: [PATCH 024/189] Add formatting tests --- .../cases/fourslash/formattingJsxElements.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/cases/fourslash/formattingJsxElements.ts b/tests/cases/fourslash/formattingJsxElements.ts index a27bc809456..58326c5a9e9 100644 --- a/tests/cases/fourslash/formattingJsxElements.ts +++ b/tests/cases/fourslash/formattingJsxElements.ts @@ -47,6 +47,16 @@ //// ) ////} //// +////const bar = ( +//// <> +//// /*fragmentChildIndent*/

text

+//// +////); +//// +////const bar2 = <> +////

text

+//// /*fragmentClosingTagIndent*/; +//// ////(function () { //// return
,{integer}
;/*commaInJsxElement*/ ////
, {integer}
;/*commaInJsxElement2*/ +////<>,{integer};/*commaInJsxFragment*/ +////<>, {integer};/*commaInJsxFragment2*/ ////);/*closingParenInJsxElement*/ ////) ;/*closingParenInJsxElement2*/ +////<>);/*closingParenInJsxFragment*/ +////<>) ;/*closingParenInJsxFragment2*/ ////;/*jsxExpressionSpaces*/ ////;/*jsxExpressionSpaces2*/ //// {}}/*jsxExpressionSpaces3*/ @@ -111,6 +125,10 @@ verify.currentLineContentIs(' class3={'); goTo.marker("6"); verify.currentLineContentIs(' } />'); +goTo.marker("fragmentChildIndent"); +verify.currentLineContentIs("

text

"); +goTo.marker("fragmentClosingTagIndent"); +verify.currentLineContentIs(";"); goTo.marker("attrAutoformat"); verify.currentLineContentIs(' className=""'); @@ -139,10 +157,18 @@ goTo.marker("commaInJsxElement"); verify.currentLineContentIs("
,{integer}
;"); goTo.marker("commaInJsxElement2"); verify.currentLineContentIs("
, {integer}
;"); +goTo.marker("commaInJsxFragment"); +verify.currentLineContentIs("<>,{integer};"); +goTo.marker("commaInJsxFragment2"); +verify.currentLineContentIs("<>, {integer};"); goTo.marker("closingParenInJsxElement"); verify.currentLineContentIs(");"); goTo.marker("closingParenInJsxElement2"); verify.currentLineContentIs(") ;"); +goTo.marker("closingParenInJsxFragment"); +verify.currentLineContentIs("<>);"); +goTo.marker("closingParenInJsxFragment2"); +verify.currentLineContentIs("<>) ;"); goTo.marker("jsxExpressionSpaces"); verify.currentLineContentIs(";"); goTo.marker("jsxExpressionSpaces2"); From 3f8203449851ed64673ff432ee7321e85a51251b Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Thu, 28 Dec 2017 12:42:06 -0800 Subject: [PATCH 025/189] Ensure spread attribute formatting options match jsxexpression --- src/services/formatting/rules.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 91c133ca352..8303770d00d 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -619,7 +619,7 @@ namespace ts.formatting { } function isJsxExpressionContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.JsxExpression; + return context.contextNode.kind === SyntaxKind.JsxExpression || context.contextNode.kind === SyntaxKind.JsxSpreadAttribute; } function isNextTokenParentJsxAttribute(context: FormattingContext): boolean { From 05a6f343f71ae234ccfd72f83050abaf2ee1f0b7 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Thu, 28 Dec 2017 13:10:32 -0800 Subject: [PATCH 026/189] Update test --- tests/cases/fourslash/formattingOptionsChangeJsx.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/cases/fourslash/formattingOptionsChangeJsx.ts b/tests/cases/fourslash/formattingOptionsChangeJsx.ts index a3c7e28a1ef..067f0b882f2 100644 --- a/tests/cases/fourslash/formattingOptionsChangeJsx.ts +++ b/tests/cases/fourslash/formattingOptionsChangeJsx.ts @@ -1,9 +1,14 @@ /// //@Filename: file.tsx -/////*InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces*/; +/////*InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces1*/; +//// +//// -runTest("InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces", ";", ";"); +runTest("InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces1", ";", ";"); +runTest("InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces2", " { ...this._getButtonProps() }", " {...this._getButtonProps()}"); function runTest(propertyName: string, expectedStringWhenTrue: string, expectedStringWhenFalse: string) { @@ -11,7 +16,7 @@ function runTest(propertyName: string, expectedStringWhenTrue: string, expectedS goTo.marker(propertyName); // Set the option to false first - format.setOption(propertyName, false); + format.setOption(propertyName.slice(0, -1), false); // Format format.document(); @@ -21,7 +26,7 @@ function runTest(propertyName: string, expectedStringWhenTrue: string, expectedS verify.currentLineContentIs(expectedStringWhenFalse); // Set the option to true - format.setOption(propertyName, true); + format.setOption(propertyName.slice(0, -1), true); // Format format.document(); From e0f20334d2c5682bcb7a76f8091726c5c38fb18b Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 3 Jan 2018 11:30:41 -0800 Subject: [PATCH 027/189] Use inference for filling JSX attributes in getJsxElementInstanceType (#20973) * Add simple type inference for JSX elements * Small cleanups from PR feedback --- src/compiler/checker.ts | 55 ++++++++++++------- .../tsxGenericAttributesType4.errors.txt | 19 ------- .../reference/tsxGenericAttributesType4.js | 2 - .../tsxGenericAttributesType4.symbols | 3 +- .../reference/tsxGenericAttributesType4.types | 1 - .../tsxGenericAttributesType5.errors.txt | 20 ------- .../reference/tsxGenericAttributesType5.js | 2 - .../tsxGenericAttributesType5.symbols | 3 +- .../reference/tsxGenericAttributesType5.types | 1 - ...ponentWithDefaultTypeParameter2.errors.txt | 31 ----------- ...ReactComponentWithDefaultTypeParameter2.js | 2 - ...ComponentWithDefaultTypeParameter2.symbols | 7 +-- ...ctComponentWithDefaultTypeParameter2.types | 1 - ...ponentWithDefaultTypeParameter3.errors.txt | 24 +++++--- ...ReactComponentWithDefaultTypeParameter3.js | 11 ++-- ...ComponentWithDefaultTypeParameter3.symbols | 9 +-- ...ctComponentWithDefaultTypeParameter3.types | 5 +- .../jsx/tsxGenericAttributesType4.tsx | 1 - .../jsx/tsxGenericAttributesType5.tsx | 1 - ...eactComponentWithDefaultTypeParameter2.tsx | 1 - ...eactComponentWithDefaultTypeParameter3.tsx | 6 +- 21 files changed, 77 insertions(+), 128 deletions(-) delete mode 100644 tests/baselines/reference/tsxGenericAttributesType4.errors.txt delete mode 100644 tests/baselines/reference/tsxGenericAttributesType5.errors.txt delete mode 100644 tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b3566cae702..caa5a55c0c8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15043,7 +15043,7 @@ namespace ts { * element is not a class element, or the class element type cannot be determined, returns 'undefined'. * For example, in the element , the element instance type is `MyClass` (not `typeof MyClass`). */ - function getJsxElementInstanceType(node: JsxOpeningLikeElement, valueType: Type) { + function getJsxElementInstanceType(node: JsxOpeningLikeElement, valueType: Type, sourceAttributesType: Type) { Debug.assert(!(valueType.flags & TypeFlags.Union)); if (isTypeAny(valueType)) { // Short-circuit if the class tag is using an element type 'any' @@ -15066,7 +15066,8 @@ namespace ts { for (const signature of signatures) { if (signature.typeParameters) { const isJavascript = isInJavaScriptFile(node); - const typeArguments = fillMissingTypeArguments(/*typeArguments*/ undefined, signature.typeParameters, /*minTypeArgumentCount*/ 0, isJavascript); + const inferenceContext = createInferenceContext(signature, /*flags*/ isJavascript ? InferenceFlags.AnyDefault : 0); + const typeArguments = inferJsxTypeArguments(signature, sourceAttributesType, inferenceContext); instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript)); } else { @@ -15251,6 +15252,7 @@ namespace ts { * * @param openingLikeElement a non-intrinsic JSXOPeningLikeElement * @param shouldIncludeAllStatelessAttributesType a boolean indicating whether to include all attributes types from all stateless function signature + * @param sourceAttributesType Is the attributes type the user passed, and is used to create inferences in the target type if present * @param elementType an instance type of the given opening-like element. If undefined, the function will check type openinglikeElement's tagname. * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global (imported from react.d.ts) * @return attributes type if able to resolve the type of node @@ -15259,13 +15261,14 @@ namespace ts { */ function resolveCustomJsxElementAttributesType(openingLikeElement: JsxOpeningLikeElement, shouldIncludeAllStatelessAttributesType: boolean, - elementType: Type = checkExpression(openingLikeElement.tagName), + sourceAttributesType: Type | undefined, + elementType: Type, elementClassType?: Type): Type { if (elementType.flags & TypeFlags.Union) { const types = (elementType as UnionType).types; return getUnionType(types.map(type => { - return resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, type, elementClassType); + return resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, sourceAttributesType, type, elementClassType); }), UnionReduction.Subtype); } @@ -15296,7 +15299,7 @@ namespace ts { } // Get the element instance type (the result of newing or invoking this tag) - const elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType); + const elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType, sourceAttributesType || emptyObjectType); // If we should include all stateless attributes type, then get all attributes type from all stateless function signature. // Otherwise get only attributes type from the signature picked by choose-overload logic. @@ -15309,7 +15312,7 @@ namespace ts { } // Issue an error if this return type isn't assignable to JSX.ElementClass - if (elementClassType) { + if (elementClassType && sourceAttributesType) { checkTypeRelatedTo(elemInstanceType, elementClassType, assignableRelation, openingLikeElement, Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements); } @@ -15392,14 +15395,20 @@ namespace ts { * @param node a custom JSX opening-like element * @param shouldIncludeAllStatelessAttributesType a boolean value used by language service to get all possible attributes type from an overload stateless function component */ - function getCustomJsxElementAttributesType(node: JsxOpeningLikeElement, shouldIncludeAllStatelessAttributesType: boolean): Type { - const links = getNodeLinks(node); - const linkLocation = shouldIncludeAllStatelessAttributesType ? "resolvedJsxElementAllAttributesType" : "resolvedJsxElementAttributesType"; - if (!links[linkLocation]) { - const elemClassType = getJsxGlobalElementClassType(); - return links[linkLocation] = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, /*elementType*/ undefined, elemClassType); + function getCustomJsxElementAttributesType(node: JsxOpeningLikeElement, sourceAttributesType: Type, shouldIncludeAllStatelessAttributesType: boolean): Type { + if (!sourceAttributesType) { + // This ensures we cache non-inference uses of this calculation (ie, contextual types or services) + const links = getNodeLinks(node); + const linkLocation = shouldIncludeAllStatelessAttributesType ? "resolvedJsxElementAllAttributesType" : "resolvedJsxElementAttributesType"; + if (!links[linkLocation]) { + const elemClassType = getJsxGlobalElementClassType(); + return links[linkLocation] = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, sourceAttributesType, checkExpression(node.tagName), elemClassType); + } + return links[linkLocation]; + } + else { + return resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, sourceAttributesType, checkExpression(node.tagName), getJsxGlobalElementClassType()); } - return links[linkLocation]; } /** @@ -15414,7 +15423,7 @@ namespace ts { else { // Because in language service, the given JSX opening-like element may be incomplete and therefore, // we can't resolve to exact signature if the element is a stateless function component so the best thing to do is return all attributes type from all overloads. - return getCustomJsxElementAttributesType(node, /*shouldIncludeAllStatelessAttributesType*/ true); + return getCustomJsxElementAttributesType(node, /*sourceAttributesType*/ undefined, /*shouldIncludeAllStatelessAttributesType*/ true); } } @@ -15428,7 +15437,7 @@ namespace ts { return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node); } else { - return getCustomJsxElementAttributesType(node, /*shouldIncludeAllStatelessAttributesType*/ false); + return getCustomJsxElementAttributesType(node, /*sourceAttributesType*/ undefined, /*shouldIncludeAllStatelessAttributesType*/ false); } } @@ -15567,16 +15576,17 @@ namespace ts { // 2. Solved JSX attributes type given by users, sourceAttributesType, which is by resolving "attributes" property of the JSX opening-like element. // 3. Check if the two are assignable to each other - // targetAttributesType is a type of an attributes from resolving tagName of an opening-like JSX element. - const targetAttributesType = isJsxIntrinsicIdentifier(openingLikeElement.tagName) ? - getIntrinsicAttributesTypeFromJsxOpeningLikeElement(openingLikeElement) : - getCustomJsxElementAttributesType(openingLikeElement, /*shouldIncludeAllStatelessAttributesType*/ false); // sourceAttributesType is a type of an attributes properties. // i.e
// attr1 and attr2 are treated as JSXAttributes attached in the JsxOpeningLikeElement as "attributes". const sourceAttributesType = createJsxAttributesTypeFromAttributesProperty(openingLikeElement, checkMode); + // targetAttributesType is a type of an attributes from resolving tagName of an opening-like JSX element. + const targetAttributesType = isJsxIntrinsicIdentifier(openingLikeElement.tagName) ? + getIntrinsicAttributesTypeFromJsxOpeningLikeElement(openingLikeElement) : + getCustomJsxElementAttributesType(openingLikeElement, sourceAttributesType, /*shouldIncludeAllStatelessAttributesType*/ false); + // If the targetAttributesType is an emptyObjectType, indicating that there is no property named 'props' on this instance type. // but there exists a sourceAttributesType, we need to explicitly give an error as normal assignability check allow excess properties and will pass. if (targetAttributesType === emptyObjectType && (isTypeAny(sourceAttributesType) || (sourceAttributesType).properties.length > 0)) { @@ -16434,6 +16444,13 @@ namespace ts { return getSignatureInstantiation(signature, getInferredTypes(context), isInJavaScriptFile(contextualSignature.declaration)); } + function inferJsxTypeArguments(signature: Signature, sourceAttributesType: Type, context: InferenceContext): Type[] { + const paramType = getTypeAtPosition(signature, 0); + inferTypes(context.inferences, sourceAttributesType, paramType); + + return getInferredTypes(context); + } + function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray, excludeArgument: boolean[], context: InferenceContext): Type[] { // Clear out all the inference results from the last time inferTypeArguments was called on this context for (const inference of context.inferences) { diff --git a/tests/baselines/reference/tsxGenericAttributesType4.errors.txt b/tests/baselines/reference/tsxGenericAttributesType4.errors.txt deleted file mode 100644 index ee91f938b9f..00000000000 --- a/tests/baselines/reference/tsxGenericAttributesType4.errors.txt +++ /dev/null @@ -1,19 +0,0 @@ -tests/cases/conformance/jsx/file.tsx(11,36): error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. - - -==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== - import React = require('react'); - - class B1 extends React.Component { - render() { - return
hi
; - } - } - class B extends React.Component { - render() { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object - return ; - ~~~~~~ -!!! error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. - } - } \ No newline at end of file diff --git a/tests/baselines/reference/tsxGenericAttributesType4.js b/tests/baselines/reference/tsxGenericAttributesType4.js index 1f8c9a631c0..3fad8aaccde 100644 --- a/tests/baselines/reference/tsxGenericAttributesType4.js +++ b/tests/baselines/reference/tsxGenericAttributesType4.js @@ -8,7 +8,6 @@ class B1 extends React.Component { } class B extends React.Component { render() { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; } } @@ -43,7 +42,6 @@ var B = /** @class */ (function (_super) { return _super !== null && _super.apply(this, arguments) || this; } B.prototype.render = function () { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; }; return B; diff --git a/tests/baselines/reference/tsxGenericAttributesType4.symbols b/tests/baselines/reference/tsxGenericAttributesType4.symbols index ab64844e0fd..0d01dec93ca 100644 --- a/tests/baselines/reference/tsxGenericAttributesType4.symbols +++ b/tests/baselines/reference/tsxGenericAttributesType4.symbols @@ -30,12 +30,11 @@ class B extends React.Component { render() { >render : Symbol(B.render, Decl(file.tsx, 7, 43)) - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; >B1 : Symbol(B1, Decl(file.tsx, 0, 32)) >this.props : Symbol(React.Component.props, Decl(react.d.ts, 167, 37)) >this : Symbol(B, Decl(file.tsx, 6, 1)) >props : Symbol(React.Component.props, Decl(react.d.ts, 167, 37)) ->x : Symbol(x, Decl(file.tsx, 10, 34)) +>x : Symbol(x, Decl(file.tsx, 9, 34)) } } diff --git a/tests/baselines/reference/tsxGenericAttributesType4.types b/tests/baselines/reference/tsxGenericAttributesType4.types index ede5a874a42..874d77d8325 100644 --- a/tests/baselines/reference/tsxGenericAttributesType4.types +++ b/tests/baselines/reference/tsxGenericAttributesType4.types @@ -31,7 +31,6 @@ class B extends React.Component { render() { >render : () => JSX.Element - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; > : JSX.Element >B1 : typeof B1 diff --git a/tests/baselines/reference/tsxGenericAttributesType5.errors.txt b/tests/baselines/reference/tsxGenericAttributesType5.errors.txt deleted file mode 100644 index 83f07326f92..00000000000 --- a/tests/baselines/reference/tsxGenericAttributesType5.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -tests/cases/conformance/jsx/file.tsx(12,36): error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. - - -==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== - import React = require('react'); - - class B1 extends React.Component { - render() { - return
hi
; - } - } - class B extends React.Component { - props: U; - render() { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object - return ; - ~~~~~~ -!!! error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. - } - } \ No newline at end of file diff --git a/tests/baselines/reference/tsxGenericAttributesType5.js b/tests/baselines/reference/tsxGenericAttributesType5.js index 402ed461a4f..240f2bf95c2 100644 --- a/tests/baselines/reference/tsxGenericAttributesType5.js +++ b/tests/baselines/reference/tsxGenericAttributesType5.js @@ -9,7 +9,6 @@ class B1 extends React.Component { class B extends React.Component { props: U; render() { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; } } @@ -44,7 +43,6 @@ var B = /** @class */ (function (_super) { return _super !== null && _super.apply(this, arguments) || this; } B.prototype.render = function () { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; }; return B; diff --git a/tests/baselines/reference/tsxGenericAttributesType5.symbols b/tests/baselines/reference/tsxGenericAttributesType5.symbols index 972e19f2e3c..18252ea5d1b 100644 --- a/tests/baselines/reference/tsxGenericAttributesType5.symbols +++ b/tests/baselines/reference/tsxGenericAttributesType5.symbols @@ -34,12 +34,11 @@ class B extends React.Component { render() { >render : Symbol(B.render, Decl(file.tsx, 8, 13)) - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; >B1 : Symbol(B1, Decl(file.tsx, 0, 32)) >this.props : Symbol(B.props, Decl(file.tsx, 7, 43)) >this : Symbol(B, Decl(file.tsx, 6, 1)) >props : Symbol(B.props, Decl(file.tsx, 7, 43)) ->x : Symbol(x, Decl(file.tsx, 11, 34)) +>x : Symbol(x, Decl(file.tsx, 10, 34)) } } diff --git a/tests/baselines/reference/tsxGenericAttributesType5.types b/tests/baselines/reference/tsxGenericAttributesType5.types index c5320a5a8c4..11b10ae6a88 100644 --- a/tests/baselines/reference/tsxGenericAttributesType5.types +++ b/tests/baselines/reference/tsxGenericAttributesType5.types @@ -35,7 +35,6 @@ class B extends React.Component { render() { >render : () => JSX.Element - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; > : JSX.Element >B1 : typeof B1 diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.errors.txt b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.errors.txt deleted file mode 100644 index 95749802ced..00000000000 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.errors.txt +++ /dev/null @@ -1,31 +0,0 @@ -tests/cases/conformance/jsx/file.tsx(13,9): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. - Type '{}' is not assignable to type 'Prop'. - Property 'a' is missing in type '{}'. -tests/cases/conformance/jsx/file.tsx(14,18): error TS2322: Type '{ a: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. - Type '{ a: string; }' is not assignable to type 'Prop'. - Property 'b' is missing in type '{ a: string; }'. - - -==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== - import React = require('react'); - - interface Prop { - a: number, - b: string - } - - declare class MyComp

extends React.Component { - internalProp: P; - } - - // Error - let x = - ~~~~~~~~~~ -!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. -!!! error TS2322: Type '{}' is not assignable to type 'Prop'. -!!! error TS2322: Property 'a' is missing in type '{}'. - let x1 = - ~~~~~~ -!!! error TS2322: Type '{ a: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. -!!! error TS2322: Type '{ a: string; }' is not assignable to type 'Prop'. -!!! error TS2322: Property 'b' is missing in type '{ a: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.js b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.js index 469adbee4b7..5959f527539 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.js +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.js @@ -10,7 +10,6 @@ declare class MyComp

extends React.Component { internalProp: P; } -// Error let x = let x1 = @@ -18,6 +17,5 @@ let x1 = "use strict"; exports.__esModule = true; var React = require("react"); -// Error var x = ; var x1 = ; diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.symbols b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.symbols index 9c9ca8c419f..6c4e407fc61 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.symbols +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.symbols @@ -26,13 +26,12 @@ declare class MyComp

extends React.Component { >P : Symbol(P, Decl(file.tsx, 7, 21)) } -// Error let x = ->x : Symbol(x, Decl(file.tsx, 12, 3)) +>x : Symbol(x, Decl(file.tsx, 11, 3)) >MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1)) let x1 = ->x1 : Symbol(x1, Decl(file.tsx, 13, 3)) +>x1 : Symbol(x1, Decl(file.tsx, 12, 3)) >MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1)) ->a : Symbol(a, Decl(file.tsx, 13, 16)) +>a : Symbol(a, Decl(file.tsx, 12, 16)) diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.types b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.types index 0dc264c2720..a5d9212ce83 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.types +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.types @@ -26,7 +26,6 @@ declare class MyComp

extends React.Component { >P : P } -// Error let x = >x : JSX.Element > : JSX.Element diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.errors.txt b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.errors.txt index 2fc79a30ade..dd38d89662f 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.errors.txt +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.errors.txt @@ -1,5 +1,9 @@ -tests/cases/conformance/jsx/file.tsx(16,17): error TS2559: Type '{ a: number; b: string; }' has no properties in common with type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. -tests/cases/conformance/jsx/file.tsx(17,18): error TS2559: Type '{ a: string; }' has no properties in common with type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(13,10): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. + Type '{}' is not assignable to type 'Prop'. + Property 'a' is missing in type '{}'. +tests/cases/conformance/jsx/file.tsx(19,18): error TS2322: Type '{ a: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. + Type '{ a: string; }' is not assignable to type 'Prop'. + Property 'b' is missing in type '{ a: string; }'. ==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== @@ -14,13 +18,19 @@ tests/cases/conformance/jsx/file.tsx(17,18): error TS2559: Type '{ a: string; }' internalProp: P; } - // OK: we fille in missing type argument with empty object + // Error let x1 = + ~~~~~~~~~~ +!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. +!!! error TS2322: Type '{}' is not assignable to type 'Prop'. +!!! error TS2322: Property 'a' is missing in type '{}'. + + // OK + let x = // Error - let x = - ~~~~~~~~~~~~~ -!!! error TS2559: Type '{ a: number; b: string; }' has no properties in common with type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. let x2 = ~~~~~~ -!!! error TS2559: Type '{ a: string; }' has no properties in common with type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. \ No newline at end of file +!!! error TS2322: Type '{ a: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. +!!! error TS2322: Type '{ a: string; }' is not assignable to type 'Prop'. +!!! error TS2322: Property 'b' is missing in type '{ a: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.js b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.js index 3eed9e5fb17..8e4dae1b2e9 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.js +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.js @@ -10,19 +10,22 @@ declare class MyComp

extends React.Component { internalProp: P; } -// OK: we fille in missing type argument with empty object +// Error let x1 = -// Error +// OK let x = + +// Error let x2 = //// [file.jsx] "use strict"; exports.__esModule = true; var React = require("react"); -// OK: we fille in missing type argument with empty object -var x1 = ; // Error +var x1 = ; +// OK var x = ; +// Error var x2 = ; diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.symbols b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.symbols index 8d0ea3cb8e2..9305e503cc7 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.symbols +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.symbols @@ -26,20 +26,21 @@ declare class MyComp

extends React.Component { >P : Symbol(P, Decl(file.tsx, 7, 21)) } -// OK: we fille in missing type argument with empty object +// Error let x1 = >x1 : Symbol(x1, Decl(file.tsx, 12, 3)) >MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1)) -// Error +// OK let x = >x : Symbol(x, Decl(file.tsx, 15, 3)) >MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1)) >a : Symbol(a, Decl(file.tsx, 15, 15)) >b : Symbol(b, Decl(file.tsx, 15, 22)) +// Error let x2 = ->x2 : Symbol(x2, Decl(file.tsx, 16, 3)) +>x2 : Symbol(x2, Decl(file.tsx, 18, 3)) >MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1)) ->a : Symbol(a, Decl(file.tsx, 16, 16)) +>a : Symbol(a, Decl(file.tsx, 18, 16)) diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.types b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.types index 5463e2fe4b0..03301a17710 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.types +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.types @@ -26,13 +26,13 @@ declare class MyComp

extends React.Component { >P : P } -// OK: we fille in missing type argument with empty object +// Error let x1 = >x1 : JSX.Element > : JSX.Element >MyComp : typeof MyComp -// Error +// OK let x = >x : JSX.Element > : JSX.Element @@ -41,6 +41,7 @@ let x = >10 : 10 >b : string +// Error let x2 = >x2 : JSX.Element > : JSX.Element diff --git a/tests/cases/conformance/jsx/tsxGenericAttributesType4.tsx b/tests/cases/conformance/jsx/tsxGenericAttributesType4.tsx index 2c134d4e20e..de918e6bb77 100644 --- a/tests/cases/conformance/jsx/tsxGenericAttributesType4.tsx +++ b/tests/cases/conformance/jsx/tsxGenericAttributesType4.tsx @@ -13,7 +13,6 @@ class B1 extends React.Component { } class B extends React.Component { render() { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; } } \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxGenericAttributesType5.tsx b/tests/cases/conformance/jsx/tsxGenericAttributesType5.tsx index ba8d9a284ca..5e4da2e46f7 100644 --- a/tests/cases/conformance/jsx/tsxGenericAttributesType5.tsx +++ b/tests/cases/conformance/jsx/tsxGenericAttributesType5.tsx @@ -14,7 +14,6 @@ class B1 extends React.Component { class B extends React.Component { props: U; render() { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; } } \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter2.tsx b/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter2.tsx index 84c4ffcef45..7b96a88a382 100644 --- a/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter2.tsx +++ b/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter2.tsx @@ -15,6 +15,5 @@ declare class MyComp

extends React.Component { internalProp: P; } -// Error let x = let x1 = \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter3.tsx b/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter3.tsx index abae7e36853..57b9a9e0a8e 100644 --- a/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter3.tsx +++ b/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter3.tsx @@ -15,9 +15,11 @@ declare class MyComp

extends React.Component { internalProp: P; } -// OK: we fille in missing type argument with empty object +// Error let x1 = -// Error +// OK let x = + +// Error let x2 = \ No newline at end of file From a33f229d82f5ff27938c58892d23182c77668cdb Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 3 Jan 2018 13:51:33 -0800 Subject: [PATCH 028/189] Support completions contextual types in more places (#20768) * Support completions contextual types in more places * Adjust formatting --- src/compiler/checker.ts | 20 +---- src/harness/fourslash.ts | 16 ++-- src/services/completions.ts | 85 +++++++++++++------ src/services/pathCompletions.ts | 2 +- .../completionsRecommended_equals.ts | 12 +-- .../completionsRecommended_import.ts | 39 ++++++--- .../fourslash/completionsRecommended_local.ts | 45 +++++++--- .../completionsRecommended_namespace.ts | 42 +++++---- .../completionsRecommended_switch.ts | 12 +-- tests/cases/fourslash/fourslash.ts | 3 +- 10 files changed, 167 insertions(+), 109 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index caa5a55c0c8..49dde4ea6e4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13943,7 +13943,7 @@ namespace ts { // the contextual type of an initializer expression is the type annotation of the containing declaration, if present. function getContextualTypeForInitializerExpression(node: Expression): Type { const declaration = node.parent; - if (hasInitializer(declaration) && node === declaration.initializer || node.kind === SyntaxKind.EqualsToken) { + if (hasInitializer(declaration) && node === declaration.initializer) { const typeNode = getEffectiveTypeAnnotationNode(declaration); if (typeNode) { return getTypeFromTypeNode(typeNode); @@ -14075,12 +14075,6 @@ namespace ts { case SyntaxKind.AmpersandAmpersandToken: case SyntaxKind.CommaToken: return node === right ? getContextualType(binaryExpression) : undefined; - case SyntaxKind.EqualsEqualsEqualsToken: - case SyntaxKind.EqualsEqualsToken: - case SyntaxKind.ExclamationEqualsEqualsToken: - case SyntaxKind.ExclamationEqualsToken: - // For completions after `x === ` - return node === operatorToken ? getTypeOfExpression(binaryExpression.left) : undefined; default: return undefined; } @@ -14296,12 +14290,8 @@ namespace ts { return getContextualTypeForReturnExpression(node); case SyntaxKind.YieldExpression: return getContextualTypeForYieldOperand(parent); + case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: - if (node.kind === SyntaxKind.NewKeyword) { // for completions after `new ` - return getContextualType(parent as NewExpression); - } - // falls through - case SyntaxKind.CallExpression: return getContextualTypeForArgument(parent, node); case SyntaxKind.TypeAssertionExpression: case SyntaxKind.AsExpression: @@ -14336,12 +14326,6 @@ namespace ts { case SyntaxKind.JsxOpeningElement: case SyntaxKind.JsxSelfClosingElement: return getAttributesTypeFromJsxOpeningLikeElement(parent); - case SyntaxKind.CaseClause: { - if (node.kind === SyntaxKind.CaseKeyword) { // for completions after `case ` - const switchStatement = (parent as CaseClause).parent.parent; - return getTypeOfExpression(switchStatement.expression); - } - } } return undefined; } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index fefee7ca3bd..99d643ec438 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -441,12 +441,11 @@ namespace FourSlash { this.goToPosition(marker.position); } - public goToEachMarker(action: () => void) { - const markers = this.getMarkers(); + public goToEachMarker(markers: ReadonlyArray, action: (marker: FourSlash.Marker, index: number) => void) { assert(markers.length); - for (const marker of markers) { - this.goToMarker(marker); - action(); + for (let i = 0; i < markers.length; i++) { + this.goToMarker(markers[i]); + action(markers[i], i); } } @@ -3764,8 +3763,11 @@ namespace FourSlashInterface { this.state.goToMarker(name); } - public eachMarker(action: () => void) { - this.state.goToEachMarker(action); + public eachMarker(markers: ReadonlyArray, action: (marker: FourSlash.Marker, index: number) => void): void; + public eachMarker(action: (marker: FourSlash.Marker, index: number) => void): void; + public eachMarker(a: ReadonlyArray | ((marker: FourSlash.Marker, index: number) => void), b?: (marker: FourSlash.Marker, index: number) => void): void { + const markers = typeof a === "function" ? this.state.getMarkers() : a.map(m => this.state.getMarkerByName(m)); + this.state.goToEachMarker(markers, typeof a === "function" ? a : b); } public rangeStart(range: FourSlash.Range) { diff --git a/src/services/completions.ts b/src/services/completions.ts index 11119503d36..2b24309d1c1 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -238,7 +238,7 @@ namespace ts.Completions { function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined { const node = findPrecedingToken(position, sourceFile); - if (!node || (node.kind !== SyntaxKind.StringLiteral && node.kind !== SyntaxKind.NoSubstitutionTemplateLiteral)) { + if (!node || !isStringLiteral(node) && !isNoSubstitutionTemplateLiteral(node)) { return undefined; } @@ -277,21 +277,9 @@ namespace ts.Completions { // import x = require("/*completion position*/"); // var y = require("/*completion position*/"); // export * from "/*completion position*/"; - const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(node, compilerOptions, host, typeChecker); + const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(node, compilerOptions, host, typeChecker); return pathCompletionsInfo(entries); } - else if (isEqualityExpression(node.parent)) { - // Get completions from the type of the other operand - // i.e. switch (a) { - // case '/*completion position*/' - // } - return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.left === node ? node.parent.right : node.parent.left), typeChecker); - } - else if (isCaseOrDefaultClause(node.parent)) { - // Get completions from the type of the switch expression - // i.e. x === '/*completion position' - return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation((node.parent.parent.parent).expression), typeChecker); - } else { const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile); if (argumentInfo) { @@ -303,7 +291,7 @@ namespace ts.Completions { // Get completion for string literal from string literal type // i.e. var x: "hi" | "hello" = "/*completion position*/" - return getStringLiteralCompletionEntriesFromType(typeChecker.getContextualType(node), typeChecker); + return getStringLiteralCompletionEntriesFromType(getContextualTypeFromParent(node, typeChecker), typeChecker); } } @@ -602,8 +590,8 @@ namespace ts.Completions { } type Request = { kind: "JsDocTagName" } | { kind: "JsDocTag" } | { kind: "JsDocParameterName", tag: JSDocParameterTag }; - function getRecommendedCompletion(currentToken: Node, checker: TypeChecker/*, symbolToOriginInfoMap: SymbolOriginInfoMap*/): Symbol | undefined { - const ty = checker.getContextualType(currentToken as Expression); + function getRecommendedCompletion(currentToken: Node, checker: TypeChecker): Symbol | undefined { + const ty = getContextualType(currentToken, checker); const symbol = ty && ty.symbol; // Don't include make a recommended completion for an abstract class return symbol && (symbol.flags & SymbolFlags.Enum || symbol.flags & SymbolFlags.Class && !isAbstractConstructorSymbol(symbol)) @@ -611,6 +599,48 @@ namespace ts.Completions { : undefined; } + function getContextualType(currentToken: Node, checker: ts.TypeChecker): Type | undefined { + const { parent } = currentToken; + switch (currentToken.kind) { + case ts.SyntaxKind.Identifier: + return getContextualTypeFromParent(currentToken as ts.Identifier, checker); + case ts.SyntaxKind.EqualsToken: + return ts.isVariableDeclaration(parent) ? checker.getContextualType(parent.initializer) : + ts.isBinaryExpression(parent) ? checker.getTypeAtLocation(parent.left) : undefined; + case ts.SyntaxKind.NewKeyword: + return checker.getContextualType(parent as ts.Expression); + case ts.SyntaxKind.CaseKeyword: + return getSwitchedType(cast(currentToken.parent, isCaseClause), checker); + default: + return isEqualityOperatorKind(currentToken.kind) && ts.isBinaryExpression(parent) && isEqualityOperatorKind(parent.operatorToken.kind) + // completion at `x ===/**/` should be for the right side + ? checker.getTypeAtLocation(parent.left) + : checker.getContextualType(currentToken as ts.Expression); + } + } + + function getContextualTypeFromParent(node: ts.Expression, checker: ts.TypeChecker): Type | undefined { + const { parent } = node; + switch (parent.kind) { + case ts.SyntaxKind.NewExpression: + return checker.getContextualType(parent as ts.NewExpression); + case ts.SyntaxKind.BinaryExpression: { + const { left, operatorToken, right } = parent as ts.BinaryExpression; + return isEqualityOperatorKind(operatorToken.kind) + ? checker.getTypeAtLocation(node === right ? left : right) + : checker.getContextualType(node); + } + case ts.SyntaxKind.CaseClause: + return (parent as ts.CaseClause).expression === node ? getSwitchedType(parent as ts.CaseClause, checker) : undefined; + default: + return checker.getContextualType(node); + } + } + + function getSwitchedType(caseClause: ts.CaseClause, checker: ts.TypeChecker): ts.Type { + return checker.getTypeAtLocation(caseClause.parent.parent.expression); + } + function getFirstSymbolInChain(symbol: Symbol, enclosingDeclaration: Node, checker: TypeChecker): Symbol | undefined { const chain = checker.getAccessibleSymbolChain(symbol, enclosingDeclaration, /*meaning*/ SymbolFlags.All, /*useOnlyExternalAliasing*/ false); if (chain) return first(chain); @@ -851,7 +881,7 @@ namespace ts.Completions { log("getCompletionData: Semantic work: " + (timestamp() - semanticStart)); - const recommendedCompletion = getRecommendedCompletion(previousToken, typeChecker); + const recommendedCompletion = previousToken && getRecommendedCompletion(previousToken, typeChecker); return { symbols, isGlobalCompletion, isMemberCompletion, allowStringLiteral, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), request, keywordFilters, symbolToOriginInfoMap, recommendedCompletion, previousToken }; type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag; @@ -2081,15 +2111,16 @@ namespace ts.Completions { return isConstructorParameterCompletionKeyword(stringToToken(text)); } - function isEqualityExpression(node: Node): node is BinaryExpression { - return isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind); - } - - function isEqualityOperatorKind(kind: SyntaxKind) { - return kind === SyntaxKind.EqualsEqualsToken || - kind === SyntaxKind.ExclamationEqualsToken || - kind === SyntaxKind.EqualsEqualsEqualsToken || - kind === SyntaxKind.ExclamationEqualsEqualsToken; + function isEqualityOperatorKind(kind: ts.SyntaxKind): kind is EqualityOperator { + switch (kind) { + case ts.SyntaxKind.EqualsEqualsEqualsToken: + case ts.SyntaxKind.EqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsToken: + return true; + default: + return false; + } } /** Get the corresponding JSDocTag node if the position is in a jsDoc comment */ diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 15c1ff99758..cb285d46417 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -1,6 +1,6 @@ /* @internal */ namespace ts.Completions.PathCompletions { - export function getStringLiteralCompletionsFromModuleNames(node: StringLiteral, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionEntry[] { + export function getStringLiteralCompletionsFromModuleNames(node: LiteralExpression, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionEntry[] { const literalValue = normalizeSlashes(node.text); const scriptPath = node.getSourceFile().path; diff --git a/tests/cases/fourslash/completionsRecommended_equals.ts b/tests/cases/fourslash/completionsRecommended_equals.ts index 21b17677ccc..37e4c931359 100644 --- a/tests/cases/fourslash/completionsRecommended_equals.ts +++ b/tests/cases/fourslash/completionsRecommended_equals.ts @@ -1,8 +1,10 @@ /// -////enum E {} -////declare const e: E; -////e === /**/ +////enum Enu {} +////declare const e: Enu; +////e === /*a*/; +////e === E/*b*/ -goTo.marker(); -verify.completionListContains("E", "enum E", "", "enum", undefined, undefined, { isRecommended: true }); +goTo.eachMarker(["a", "b"], () => { + verify.completionListContains("Enu", "enum Enu", "", "enum", undefined, undefined, { isRecommended: true }); +}); diff --git a/tests/cases/fourslash/completionsRecommended_import.ts b/tests/cases/fourslash/completionsRecommended_import.ts index dc8066d246e..158221f03a8 100644 --- a/tests/cases/fourslash/completionsRecommended_import.ts +++ b/tests/cases/fourslash/completionsRecommended_import.ts @@ -3,25 +3,36 @@ // @noLib: true // @Filename: /a.ts -////export class C {} -////export function f(c: C) {} +////export class Cls {} +////export function f(c: Cls) {} // @Filename: /b.ts ////import { f } from "./a"; -// Here we will recommend a new import of 'C' -////f(new /*b*/); +// Here we will recommend a new import of 'Cls' +////f(new C/*b0*/); +////f(new /*b1*/); // @Filename: /c.ts -////import * as a from "./a"; -// Here we will recommend 'a' because it contains 'C'. -////a.f(new /*c*/); +////import * as alpha from "./a"; +// Here we will recommend 'alpha' because it contains 'Cls'. +////alpha.f(new al/*c0*/); +////alpha.f(new /*c1*/); -goTo.marker("b"); -verify.completionListContains({ name: "C", source: "/a" }, "class C", "", "class", undefined, /*hasAction*/ true, { - includeExternalModuleExports: true, - isRecommended: true, - sourceDisplay: "./a", +goTo.eachMarker(["b0", "b1"], (_, idx) => { + verify.completionListContains( + { name: "Cls", source: "/a" }, + idx === 0 ? "constructor Cls(): Cls" : "class Cls", + "", + "class", + undefined, + /*hasAction*/ true, { + includeExternalModuleExports: true, + isRecommended: true, + sourceDisplay: "./a", + }); +}); + +goTo.eachMarker(["c0", "c1"], (_, idx) => { + verify.completionListContains("alpha", "import alpha", "", "alias", undefined, undefined, { isRecommended: true }) }); -goTo.marker("c"); -verify.completionListContains("a", "import a", "", "alias", undefined, undefined, { isRecommended: true }); diff --git a/tests/cases/fourslash/completionsRecommended_local.ts b/tests/cases/fourslash/completionsRecommended_local.ts index fad660761fa..768db8c0c91 100644 --- a/tests/cases/fourslash/completionsRecommended_local.ts +++ b/tests/cases/fourslash/completionsRecommended_local.ts @@ -1,18 +1,37 @@ /// -////enum E {} -////class C {} -////abstract class A {} -////const e: E = /*e*/ -////const c: C = new /*c*/ -////const a: A = new /*a*/ +////enum Enu {} +////class Cls {} +////abstract class Abs {} +////const e: Enu = E/*e0*/; +////const e: Enu = /*e1*/; +////const c: Cls = new C/*c0*/; +////const c: Cls = new /*c1*/; +////const a: Abs = new A/*a0*/; +////const a: Abs = new /*a1*/; -goTo.marker("e"); -verify.completionListContains("E", "enum E", "", "enum", undefined, undefined, { isRecommended: true }); +// Also works on mutations +////let enu: Enu; +////enu = E/*let0*/; +////enu = E/*let1*/; -goTo.marker("c"); -verify.completionListContains("C", "class C", "", "class", undefined, undefined, { isRecommended: true }); +goTo.eachMarker(["e0"], () => {//, "e1", "let0", "let1" + verify.completionListContains("Enu", "enum Enu", "", "enum", undefined, undefined, { isRecommended: true }); +}); -goTo.marker("a"); -// Not recommended, because it's an abstract class -verify.completionListContains("A", "class A", "", "class"); +goTo.eachMarker(["c0", "c1"], (_, idx) => { + verify.completionListContains( + "Cls", + idx === 0 ? "constructor Cls(): Cls" : "class Cls", + "", + "class", + undefined, + undefined, { + isRecommended: true, + }); +}); + +goTo.eachMarker(["a0", "a1"], (_, idx) => { + // Not recommended, because it's an abstract class + verify.completionListContains("Abs", idx == 0 ? "constructor Abs(): Abs" : "class Abs", "", "class"); +}); diff --git a/tests/cases/fourslash/completionsRecommended_namespace.ts b/tests/cases/fourslash/completionsRecommended_namespace.ts index 3ea8d597210..d3fe9c2a54b 100644 --- a/tests/cases/fourslash/completionsRecommended_namespace.ts +++ b/tests/cases/fourslash/completionsRecommended_namespace.ts @@ -3,31 +3,37 @@ // @noLib: true // @Filename: /a.ts -////export namespace N { +////export namespace Name { //// export class C {} ////} -////export function f(c: N.C) {} -////f(new /*a*/); +////export function f(c: Name.C) {} +////f(new N/*a0*/); +////f(new /*a1*/); // @Filename: /b.ts ////import { f } from "./a"; -// Here we will recommend a new import of 'N' -////f(new /*b*/); +// Here we will recommend a new import of 'Name' +////f(new N/*b0*/); +////f(new /*b1*/); // @Filename: /c.ts -////import * as a from "./a"; -// Here we will recommend 'a' because it contains 'N' which contains 'C'. -////a.f(new /*c*/); +////import * as alpha from "./a"; +// Here we will recommend 'a' because it contains 'Name' which contains 'C'. +////alpha.f(new a/*c0*/); +////alpha.f(new /*c1*/); -goTo.marker("a"); -verify.completionListContains("N", "namespace N", "", "module", undefined, undefined, { isRecommended: true }); - -goTo.marker("b"); -verify.completionListContains({ name: "N", source: "/a" }, "namespace N", "", "module", undefined, /*hasAction*/ true, { - includeExternalModuleExports: true, - isRecommended: true, - sourceDisplay: "./a", +goTo.eachMarker(["a0", "a1"], () => { + verify.completionListContains("Name", "namespace Name", "", "module", undefined, undefined, { isRecommended: true }); }); -goTo.marker("c"); -verify.completionListContains("a", "import a", "", "alias", undefined, undefined, { isRecommended: true }); +goTo.eachMarker(["b0", "b1"], () => { + verify.completionListContains({ name: "Name", source: "/a" }, "namespace Name", "", "module", undefined, /*hasAction*/ true, { + includeExternalModuleExports: true, + isRecommended: true, + sourceDisplay: "./a", + }); +}); + +goTo.eachMarker(["c0", "c1"], () => { + verify.completionListContains("alpha", "import alpha", "", "alias", undefined, undefined, { isRecommended: true }); +}); diff --git a/tests/cases/fourslash/completionsRecommended_switch.ts b/tests/cases/fourslash/completionsRecommended_switch.ts index b73d0be632b..a8941ac53ea 100644 --- a/tests/cases/fourslash/completionsRecommended_switch.ts +++ b/tests/cases/fourslash/completionsRecommended_switch.ts @@ -1,10 +1,12 @@ /// -////enum E {} -////declare const e: E; +////enum Enu {} +////declare const e: Enu; ////switch (e) { -//// case /**/ +//// case E/*0*/: +//// case /*1*/: ////} -goTo.marker(); -verify.completionListContains("E", "enum E", "", "enum", undefined, undefined, { isRecommended: true }); +goTo.eachMarker((_, idx) => { + verify.completionListContains("Enu", "enum Enu", "", "enum", undefined, undefined, { isRecommended: true }); +}); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index acebb9dfc05..8b581e62e6c 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -122,7 +122,8 @@ declare namespace FourSlashInterface { } class goTo { marker(name?: string | Marker): void; - eachMarker(action: () => void): void; + eachMarker(markers: ReadonlyArray, action: (marker: Marker, index: number) => void): void; + eachMarker(action: (marker: Marker, index: number) => void): void; rangeStart(range: Range): void; eachRange(action: () => void): void; bof(): void; From 35244230d5ac8cbf02eaa7063d8f9dd4e9d6ef1f Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 3 Jan 2018 14:20:14 -0800 Subject: [PATCH 029/189] Add deferred mapped types This allows index signature inference to be inferred as well. --- src/compiler/checker.ts | 62 +++++++++++++++++++++++------------------ src/compiler/types.ts | 8 ++++++ 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6e6bb0fb9a4..9a95a3300ca 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6114,6 +6114,23 @@ namespace ts { } } + function resolveDeferredMappedTypeMembers(type: DeferredMappedType) { + const indexInfo = type.targetIndexInfo; + const readonlyMask = type.mappedType.declaration.readonlyToken ? false : true; + const optionalMask = type.mappedType.declaration.questionToken ? 0 : SymbolFlags.Optional; + const stringIndexInfo = indexInfo && createIndexInfo(inferDeferredMappedType(indexInfo.type, type.mappedType), readonlyMask && indexInfo.isReadonly); + const members = createSymbolTable(); + for (const prop of type.sourceProperties) { + const checkFlags = CheckFlags.Deferred | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); + const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as DeferredTransientSymbol; + inferredProp.declarations = prop.declarations; + inferredProp.propertyType = getTypeOfSymbol(prop); + inferredProp.mappedType = type.mappedType; + members.set(prop.escapedName, inferredProp); + } + setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined); + } + /** Resolve the members of a mapped type { [P in K]: T } */ function resolveMappedTypeMembers(type: MappedType) { const members: SymbolTable = createSymbolTable(); @@ -6253,6 +6270,9 @@ namespace ts { else if ((type).objectFlags & ObjectFlags.ClassOrInterface) { resolveClassOrInterfaceMembers(type); } + else if ((type).objectFlags & ObjectFlags.Deferred) { + resolveDeferredMappedTypeMembers(type as DeferredMappedType); + } else if ((type).objectFlags & ObjectFlags.Anonymous) { resolveAnonymousTypeMembers(type); } @@ -11291,35 +11311,23 @@ namespace ts { } function createDeferredMappedType(source: Type, target: MappedType) { - const properties = getPropertiesOfType(source); - let indexInfo = getIndexInfoOfType(source, IndexKind.String); - if (properties.length === 0 && !indexInfo) { + const properties = getPropertiesOfType(source); + let indexInfo = getIndexInfoOfType(source, IndexKind.String); + if (properties.length === 0 && !indexInfo) { + return undefined; + } + // If any property contains context sensitive functions that have been skipped, the source type + // is incomplete and we can't infer a meaningful input type. + for (const prop of properties) { + if (getTypeOfSymbol(prop).flags & TypeFlags.ContainsAnyFunctionType) { return undefined; } - const readonlyMask = target.declaration.readonlyToken ? false : true; - const optionalMask = target.declaration.questionToken ? 0 : SymbolFlags.Optional; - const members = createSymbolTable(); - for (const prop of properties) { - const propType = getTypeOfSymbol(prop); - // If any property contains context sensitive functions that have been skipped, the source type - // is incomplete and we can't infer a meaningful input type. - if (propType.flags & TypeFlags.ContainsAnyFunctionType) { - return undefined; - } - const checkFlags = CheckFlags.Deferred | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); - const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as DeferredTransientSymbol; - inferredProp.declarations = prop.declarations; - inferredProp.propertyType = propType; - inferredProp.mappedType = target; - members.set(prop.escapedName, inferredProp); - } - if (indexInfo) { - // TODO: Defer this too. - // (probably the simplest way is to have a special type that defers the creation of (at least) its index info in - // resolveStructuredTypeMembers - indexInfo = createIndexInfo(inferDeferredMappedType(indexInfo.type, target), readonlyMask && indexInfo.isReadonly); - } - return createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfo, undefined); + } + const deferred = createObjectType(ObjectFlags.Deferred | ObjectFlags.Anonymous, undefined) as DeferredMappedType; + deferred.mappedType = target; + deferred.sourceProperties = properties; + deferred.targetIndexInfo = indexInfo; + return deferred; } function inferDeferredMappedType(sourceType: Type, target: MappedType): Type { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b8ac1c67e8d..6c4b9c0658e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3501,6 +3501,7 @@ namespace ts { EvolvingArray = 1 << 8, // Evolving array type ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties ContainsSpread = 1 << 10, // Object literal contains spread operation + Deferred = 1 << 11, // Object contains a deferred inferred property ClassOrInterface = Class | Interface } @@ -3608,6 +3609,13 @@ namespace ts { finalArrayType?: Type; // Final array type of evolving array type } + /* @internal */ + export interface DeferredMappedType extends ObjectType { + targetIndexInfo?: IndexInfo; + mappedType: MappedType; + sourceProperties: Symbol[]; + } + /* @internal */ // Resolved object, union, or intersection type export interface ResolvedType extends ObjectType, UnionOrIntersectionType { From a43adad080158ac5fa8a5ff6aa43f74f4d1a6f8c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 3 Jan 2018 14:44:34 -0800 Subject: [PATCH 030/189] Simplify DeferredMappedType construction --- src/compiler/checker.ts | 10 ++++------ src/compiler/types.ts | 3 +-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9a95a3300ca..2e7f1f0186f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6115,12 +6115,12 @@ namespace ts { } function resolveDeferredMappedTypeMembers(type: DeferredMappedType) { - const indexInfo = type.targetIndexInfo; + const indexInfo = getIndexInfoOfType(type.source, IndexKind.String); const readonlyMask = type.mappedType.declaration.readonlyToken ? false : true; const optionalMask = type.mappedType.declaration.questionToken ? 0 : SymbolFlags.Optional; const stringIndexInfo = indexInfo && createIndexInfo(inferDeferredMappedType(indexInfo.type, type.mappedType), readonlyMask && indexInfo.isReadonly); const members = createSymbolTable(); - for (const prop of type.sourceProperties) { + for (const prop of getPropertiesOfType(type.source)) { const checkFlags = CheckFlags.Deferred | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as DeferredTransientSymbol; inferredProp.declarations = prop.declarations; @@ -11312,8 +11312,7 @@ namespace ts { function createDeferredMappedType(source: Type, target: MappedType) { const properties = getPropertiesOfType(source); - let indexInfo = getIndexInfoOfType(source, IndexKind.String); - if (properties.length === 0 && !indexInfo) { + if (properties.length === 0 && !getIndexInfoOfType(source, IndexKind.String)) { return undefined; } // If any property contains context sensitive functions that have been skipped, the source type @@ -11324,9 +11323,8 @@ namespace ts { } } const deferred = createObjectType(ObjectFlags.Deferred | ObjectFlags.Anonymous, undefined) as DeferredMappedType; + deferred.source = source; deferred.mappedType = target; - deferred.sourceProperties = properties; - deferred.targetIndexInfo = indexInfo; return deferred; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6c4b9c0658e..bd49ce9f90c 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3611,9 +3611,8 @@ namespace ts { /* @internal */ export interface DeferredMappedType extends ObjectType { - targetIndexInfo?: IndexInfo; + source: Type; mappedType: MappedType; - sourceProperties: Symbol[]; } /* @internal */ From 7de8c6bcaa164ea478b450da84e135dfdf3860bb Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 3 Jan 2018 14:56:59 -0800 Subject: [PATCH 031/189] For `export default foo`, use 'foo' for the completion identifier name, not the module name (#20987) --- src/services/completions.ts | 20 +++++--------- ...sImport_default_exportDefaultIdentifier.ts | 26 +++++++++++++++++++ 2 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 tests/cases/fourslash/completionsImport_default_exportDefaultIdentifier.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index 2b24309d1c1..15a99942c85 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -444,7 +444,9 @@ namespace ts.Completions { function getSymbolName(symbol: Symbol, origin: SymbolOriginInfo | undefined, target: ScriptTarget): string { return origin && origin.isDefaultExport && symbol.escapedName === InternalSymbolName.Default - ? codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target) + // Name of "export default foo;" is "foo". Name of "export default 0" is the filename converted to camelCase. + ? firstDefined(symbol.declarations, d => isExportAssignment(d) && isIdentifier(d.expression) ? d.expression.text : undefined) + || codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target) : symbol.name; } @@ -1143,8 +1145,6 @@ namespace ts.Completions { codefix.forEachExternalModuleToImportFrom(typeChecker, sourceFile, allSourceFiles, moduleSymbol => { for (let symbol of typeChecker.getExportsOfModule(moduleSymbol)) { - let { name } = symbol; - // Don't add a completion for a re-export, only for the original. // If `symbol.parent !== moduleSymbol`, this comes from an `export * from "foo"` re-export. Those don't create new symbols. // If `some(...)`, this comes from an `export { foo } from "foo"` re-export, which creates a new symbol (thus isn't caught by the first check). @@ -1152,19 +1152,13 @@ namespace ts.Completions { continue; } - const isDefaultExport = name === InternalSymbolName.Default; + const isDefaultExport = symbol.name === InternalSymbolName.Default; if (isDefaultExport) { - const localSymbol = getLocalSymbolForExportDefault(symbol); - if (localSymbol) { - symbol = localSymbol; - name = localSymbol.name; - } - else { - name = codefix.moduleSymbolToValidIdentifier(moduleSymbol, target); - } + symbol = getLocalSymbolForExportDefault(symbol) || symbol; } - if (stringContainsCharactersInOrder(name.toLowerCase(), tokenTextLowerCase)) { + const origin: SymbolOriginInfo = { moduleSymbol, isDefaultExport }; + if (stringContainsCharactersInOrder(getSymbolName(symbol, origin, target).toLowerCase(), tokenTextLowerCase)) { symbols.push(symbol); symbolToOriginInfoMap[getSymbolId(symbol)] = { moduleSymbol, isDefaultExport }; } diff --git a/tests/cases/fourslash/completionsImport_default_exportDefaultIdentifier.ts b/tests/cases/fourslash/completionsImport_default_exportDefaultIdentifier.ts new file mode 100644 index 00000000000..042da2fee39 --- /dev/null +++ b/tests/cases/fourslash/completionsImport_default_exportDefaultIdentifier.ts @@ -0,0 +1,26 @@ +/// + +// Tests that we use the name "foo". + +// @Filename: /a.ts +////const foo = 0; +////export default foo; + +// @Filename: /b.ts +////f/**/; + +goTo.marker(""); +verify.completionListContains({ name: "foo", source: "/a" }, "export default foo", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ true, { + includeExternalModuleExports: true, + sourceDisplay: "./a", +}); + +verify.applyCodeActionFromCompletion("", { + name: "foo", + source: "/a", + description: `Import 'foo' from module "./a"`, + // TODO: GH#18445 + newFileContent: `import foo from "./a";\r +\r +f;`, +}); From 861617006046bbd9b687f584eb09b46124ec30a5 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 3 Jan 2018 15:49:09 -0800 Subject: [PATCH 032/189] Fix printing of deferred mapped types A deferred mapped type with a source that has an index signature now prints {} as the type of the index signature. This avoids an infinite recursion. --- src/compiler/checker.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2e7f1f0186f..770a31e9435 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2860,8 +2860,11 @@ namespace ts { for (const signature of resolvedType.constructSignatures) { typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructSignature, context)); } - if (resolvedType.stringIndexInfo) { - typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, IndexKind.String, context)); + if (resolvedType.stringIndexInfo && !(resolvedType.objectFlags & ObjectFlags.Deferred)) { + const indexInfo = resolvedType.objectFlags & ObjectFlags.Deferred ? + createIndexInfo(emptyObjectType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration) : + resolvedType.stringIndexInfo; + typeElements.push(indexInfoToIndexSignatureDeclarationHelper(indexInfo, IndexKind.String, context)); } if (resolvedType.numberIndexInfo) { typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, IndexKind.Number, context)); From 81a601bb4963ed5495a33171f4b11e45c596f0a0 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 3 Jan 2018 15:54:43 -0800 Subject: [PATCH 033/189] Test:deferred mapped types --- .../reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + .../isomorphicMappedTypeInference.types | 6 +-- .../reference/mappedTypeRecursiveInference.js | 12 ++++++ .../mappedTypeRecursiveInference.symbols | 34 ++++++++++++--- .../mappedTypeRecursiveInference.types | 43 +++++++++++++++++++ .../compiler/mappedTypeRecursiveInference.ts | 8 ++++ 7 files changed, 97 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index ad34924a097..926e715aaf3 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2066,6 +2066,7 @@ declare namespace ts { EvolvingArray = 256, ObjectLiteralPatternWithComputedProperties = 512, ContainsSpread = 1024, + Deferred = 2048, ClassOrInterface = 3, } interface ObjectType extends Type { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 4d06e48dc25..2709e0c5294 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2066,6 +2066,7 @@ declare namespace ts { EvolvingArray = 256, ObjectLiteralPatternWithComputedProperties = 512, ContainsSpread = 1024, + Deferred = 2048, ClassOrInterface = 3, } interface ObjectType extends Type { diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.types b/tests/baselines/reference/isomorphicMappedTypeInference.types index a7e4011109a..23306d30313 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.types +++ b/tests/baselines/reference/isomorphicMappedTypeInference.types @@ -391,15 +391,15 @@ function f6(s: string) { }); let v = unboxify(b); ->v : { [x: string]: string | number | boolean; } ->unboxify(b) : { [x: string]: string | number | boolean; } +>v : {} +>unboxify(b) : {} >unboxify : (obj: Boxified) => T >b : { [x: string]: Box | Box | Box; } let x: string | number | boolean = v[s]; >x : string | number | boolean >v[s] : string | number | boolean ->v : { [x: string]: string | number | boolean; } +>v : {} >s : string } diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.js b/tests/baselines/reference/mappedTypeRecursiveInference.js index c1b5bc6f7bf..914eb2f16b6 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.js +++ b/tests/baselines/reference/mappedTypeRecursiveInference.js @@ -8,6 +8,14 @@ out.a out.a.a out.a.a.a.a.a.a.a + +interface B { [s: string]: B } +declare let b: B; +const oub = foo(b); +oub.b +oub.b.b +oub.b.a.n.a.n.a + let xhr: XMLHttpRequest; const out2 = foo(xhr); out2.responseXML @@ -19,6 +27,10 @@ var out = foo(a); out.a; out.a.a; out.a.a.a.a.a.a.a; +var oub = foo(b); +oub.b; +oub.b.b; +oub.b.a.n.a.n.a; var xhr; var out2 = foo(xhr); out2.responseXML; diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.symbols b/tests/baselines/reference/mappedTypeRecursiveInference.symbols index 089468d4aa8..59109f15f91 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.symbols +++ b/tests/baselines/reference/mappedTypeRecursiveInference.symbols @@ -59,18 +59,42 @@ out.a.a.a.a.a.a.a >a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) >a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) + +interface B { [s: string]: B } +>B : Symbol(B, Decl(mappedTypeRecursiveInference.ts, 7, 17)) +>s : Symbol(s, Decl(mappedTypeRecursiveInference.ts, 10, 15)) +>B : Symbol(B, Decl(mappedTypeRecursiveInference.ts, 7, 17)) + +declare let b: B; +>b : Symbol(b, Decl(mappedTypeRecursiveInference.ts, 11, 11)) +>B : Symbol(B, Decl(mappedTypeRecursiveInference.ts, 7, 17)) + +const oub = foo(b); +>oub : Symbol(oub, Decl(mappedTypeRecursiveInference.ts, 12, 5)) +>foo : Symbol(foo, Decl(mappedTypeRecursiveInference.ts, 2, 45)) +>b : Symbol(b, Decl(mappedTypeRecursiveInference.ts, 11, 11)) + +oub.b +>oub : Symbol(oub, Decl(mappedTypeRecursiveInference.ts, 12, 5)) + +oub.b.b +>oub : Symbol(oub, Decl(mappedTypeRecursiveInference.ts, 12, 5)) + +oub.b.a.n.a.n.a +>oub : Symbol(oub, Decl(mappedTypeRecursiveInference.ts, 12, 5)) + let xhr: XMLHttpRequest; ->xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 9, 3)) +>xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 17, 3)) >XMLHttpRequest : Symbol(XMLHttpRequest, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) const out2 = foo(xhr); ->out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 10, 5)) +>out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 18, 5)) >foo : Symbol(foo, Decl(mappedTypeRecursiveInference.ts, 2, 45)) ->xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 9, 3)) +>xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 17, 3)) out2.responseXML >out2.responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --)) ->out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 10, 5)) +>out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 18, 5)) >responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --)) out2.responseXML.activeElement.className.length @@ -78,7 +102,7 @@ out2.responseXML.activeElement.className.length >out2.responseXML.activeElement.className : Symbol(className, Decl(lib.dom.d.ts, --, --)) >out2.responseXML.activeElement : Symbol(activeElement, Decl(lib.dom.d.ts, --, --)) >out2.responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --)) ->out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 10, 5)) +>out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 18, 5)) >responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --)) >activeElement : Symbol(activeElement, Decl(lib.dom.d.ts, --, --)) >className : Symbol(className, Decl(lib.dom.d.ts, --, --)) diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.types b/tests/baselines/reference/mappedTypeRecursiveInference.types index eccb4ff65a1..ca2761ac964 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.types +++ b/tests/baselines/reference/mappedTypeRecursiveInference.types @@ -60,6 +60,49 @@ out.a.a.a.a.a.a.a >a : { a: {}; } >a : { a: {}; } + +interface B { [s: string]: B } +>B : B +>s : string +>B : B + +declare let b: B; +>b : B +>B : B + +const oub = foo(b); +>oub : {} +>foo(b) : {} +>foo : (deep: Deep) => T +>b : B + +oub.b +>oub.b : {} +>oub : {} +>b : {} + +oub.b.b +>oub.b.b : {} +>oub.b : {} +>oub : {} +>b : {} +>b : {} + +oub.b.a.n.a.n.a +>oub.b.a.n.a.n.a : {} +>oub.b.a.n.a.n : {} +>oub.b.a.n.a : {} +>oub.b.a.n : {} +>oub.b.a : {} +>oub.b : {} +>oub : {} +>b : {} +>a : {} +>n : {} +>a : {} +>n : {} +>a : {} + let xhr: XMLHttpRequest; >xhr : XMLHttpRequest >XMLHttpRequest : XMLHttpRequest diff --git a/tests/cases/compiler/mappedTypeRecursiveInference.ts b/tests/cases/compiler/mappedTypeRecursiveInference.ts index 37b5b09d8a3..1b2e34837f6 100644 --- a/tests/cases/compiler/mappedTypeRecursiveInference.ts +++ b/tests/cases/compiler/mappedTypeRecursiveInference.ts @@ -8,6 +8,14 @@ out.a out.a.a out.a.a.a.a.a.a.a + +interface B { [s: string]: B } +declare let b: B; +const oub = foo(b); +oub.b +oub.b.b +oub.b.a.n.a.n.a + let xhr: XMLHttpRequest; const out2 = foo(xhr); out2.responseXML From 9aa5443bbc2587dba2b2ffeb7860c100659256e1 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 3 Jan 2018 16:10:26 -0800 Subject: [PATCH 034/189] Fix printing of deferred mapped types' index signatures --- src/compiler/checker.ts | 2 +- .../isomorphicMappedTypeInference.types | 6 +-- .../mappedTypeRecursiveInference.types | 46 +++++++++---------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 770a31e9435..93f3428ba73 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2860,7 +2860,7 @@ namespace ts { for (const signature of resolvedType.constructSignatures) { typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructSignature, context)); } - if (resolvedType.stringIndexInfo && !(resolvedType.objectFlags & ObjectFlags.Deferred)) { + if (resolvedType.stringIndexInfo) { const indexInfo = resolvedType.objectFlags & ObjectFlags.Deferred ? createIndexInfo(emptyObjectType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration) : resolvedType.stringIndexInfo; diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.types b/tests/baselines/reference/isomorphicMappedTypeInference.types index 23306d30313..1a78dff0e78 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.types +++ b/tests/baselines/reference/isomorphicMappedTypeInference.types @@ -391,15 +391,15 @@ function f6(s: string) { }); let v = unboxify(b); ->v : {} ->unboxify(b) : {} +>v : { [x: string]: {}; } +>unboxify(b) : { [x: string]: {}; } >unboxify : (obj: Boxified) => T >b : { [x: string]: Box | Box | Box; } let x: string | number | boolean = v[s]; >x : string | number | boolean >v[s] : string | number | boolean ->v : {} +>v : { [x: string]: {}; } >s : string } diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.types b/tests/baselines/reference/mappedTypeRecursiveInference.types index ca2761ac964..c48dda05f31 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.types +++ b/tests/baselines/reference/mappedTypeRecursiveInference.types @@ -71,37 +71,37 @@ declare let b: B; >B : B const oub = foo(b); ->oub : {} ->foo(b) : {} +>oub : { [x: string]: {}; } +>foo(b) : { [x: string]: {}; } >foo : (deep: Deep) => T >b : B oub.b ->oub.b : {} ->oub : {} ->b : {} +>oub.b : { [x: string]: {}; } +>oub : { [x: string]: {}; } +>b : { [x: string]: {}; } oub.b.b ->oub.b.b : {} ->oub.b : {} ->oub : {} ->b : {} ->b : {} +>oub.b.b : { [x: string]: {}; } +>oub.b : { [x: string]: {}; } +>oub : { [x: string]: {}; } +>b : { [x: string]: {}; } +>b : { [x: string]: {}; } oub.b.a.n.a.n.a ->oub.b.a.n.a.n.a : {} ->oub.b.a.n.a.n : {} ->oub.b.a.n.a : {} ->oub.b.a.n : {} ->oub.b.a : {} ->oub.b : {} ->oub : {} ->b : {} ->a : {} ->n : {} ->a : {} ->n : {} ->a : {} +>oub.b.a.n.a.n.a : { [x: string]: {}; } +>oub.b.a.n.a.n : { [x: string]: {}; } +>oub.b.a.n.a : { [x: string]: {}; } +>oub.b.a.n : { [x: string]: {}; } +>oub.b.a : { [x: string]: {}; } +>oub.b : { [x: string]: {}; } +>oub : { [x: string]: {}; } +>b : { [x: string]: {}; } +>a : { [x: string]: {}; } +>n : { [x: string]: {}; } +>a : { [x: string]: {}; } +>n : { [x: string]: {}; } +>a : { [x: string]: {}; } let xhr: XMLHttpRequest; >xhr : XMLHttpRequest From b9fb4cce8809cc746c12cfd5bbd75cfe6500ccfd Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 3 Jan 2018 16:26:23 -0800 Subject: [PATCH 035/189] Fix quickinfo display of deferred mapped types --- src/compiler/checker.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 93f3428ba73..bb30894d613 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3685,7 +3685,10 @@ namespace ts { writePunctuation(writer, SyntaxKind.SemicolonToken); writer.writeLine(); } - buildIndexSignatureDisplay(resolved.stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack); + const stringIndexInfo = resolved.objectFlags & ObjectFlags.Deferred && resolved.stringIndexInfo ? + createIndexInfo(emptyObjectType, resolved.stringIndexInfo.isReadonly, resolved.stringIndexInfo.declaration) : + resolved.stringIndexInfo; + buildIndexSignatureDisplay(stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack); buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, IndexKind.Number, enclosingDeclaration, globalFlags, symbolStack); for (const p of resolved.properties) { if (globalFlags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral) { @@ -3696,7 +3699,7 @@ namespace ts { writer.reportPrivateInBaseOfClassExpression(symbolName(p)); } } - const t = getTypeOfSymbol(p); + const t = getCheckFlags(p) & CheckFlags.Deferred ? emptyObjectType : getTypeOfSymbol(p); if (p.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) { const signatures = getSignaturesOfType(t, SignatureKind.Call); for (const signature of signatures) { @@ -11325,7 +11328,7 @@ namespace ts { return undefined; } } - const deferred = createObjectType(ObjectFlags.Deferred | ObjectFlags.Anonymous, undefined) as DeferredMappedType; + const deferred = createObjectType(ObjectFlags.Deferred | ObjectFlags.Anonymous, /*symbol*/ undefined) as DeferredMappedType; deferred.source = source; deferred.mappedType = target; return deferred; From e3a20e7f0aa9cd76104f45c5a6997ff59ea39ebc Mon Sep 17 00:00:00 2001 From: Martin Hiller Date: Thu, 4 Jan 2018 02:18:15 +0100 Subject: [PATCH 036/189] Do not redefine __asyncValues if it already exists (#20460) The emitted declaration for the __asyncValues variable checked for the global property __asyncIterable instead of its actual declared name __asyncValues. Now the __asyncValues variable is not redefined if it is already present as global variable. This commit fixes issue #20408. --- src/compiler/transformers/esnext.ts | 2 +- .../emitter.asyncGenerators.classMethods.es2015.js | 4 ++-- .../reference/emitter.asyncGenerators.classMethods.es5.js | 4 ++-- ...emitter.asyncGenerators.functionDeclarations.es2015.js | 4 ++-- .../emitter.asyncGenerators.functionDeclarations.es5.js | 4 ++-- .../emitter.asyncGenerators.functionExpressions.es2015.js | 4 ++-- .../emitter.asyncGenerators.functionExpressions.es5.js | 4 ++-- ...emitter.asyncGenerators.objectLiteralMethods.es2015.js | 4 ++-- .../emitter.asyncGenerators.objectLiteralMethods.es5.js | 4 ++-- tests/baselines/reference/emitter.forAwait.es2015.js | 8 ++++---- tests/baselines/reference/emitter.forAwait.es2017.js | 8 ++++---- tests/baselines/reference/emitter.forAwait.es5.js | 8 ++++---- 12 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 5b4c12b4f23..5d46c8430d2 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -968,7 +968,7 @@ namespace ts { name: "typescript:asyncValues", scoped: false, text: ` - var __asyncValues = (this && this.__asyncIterator) || function (o) { + var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.js b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.js index d91571f93ad..2de9f939ba1 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.js +++ b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.js @@ -120,7 +120,7 @@ class C3 { } } //// [C4.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -162,7 +162,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js index 1119d6b06e3..a91120c4079 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js @@ -256,7 +256,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -347,7 +347,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.js b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.js index 4ca8322da9f..d0bf1c902c0 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.js @@ -83,7 +83,7 @@ function f3() { }); } //// [F4.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -123,7 +123,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js index 410a25d2e16..70cfee32542 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js @@ -210,7 +210,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -296,7 +296,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.js b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.js index 602fd47d38b..909196952f0 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.js @@ -83,7 +83,7 @@ const f3 = function () { }); }; //// [F4.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -123,7 +123,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js index 45d17737cef..c9dff58c7ce 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js @@ -210,7 +210,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -296,7 +296,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.js b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.js index 760931a4342..99caa9d3ad3 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.js +++ b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.js @@ -103,7 +103,7 @@ const o3 = { } }; //// [O4.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -145,7 +145,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js index b5069bcea2c..76d74351923 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js @@ -230,7 +230,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -318,7 +318,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.forAwait.es2015.js b/tests/baselines/reference/emitter.forAwait.es2015.js index d88ed8d1a06..323d62f0ac8 100644 --- a/tests/baselines/reference/emitter.forAwait.es2015.js +++ b/tests/baselines/reference/emitter.forAwait.es2015.js @@ -34,7 +34,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -66,7 +66,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -90,7 +90,7 @@ function f2() { }); } //// [file3.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -126,7 +126,7 @@ function f3() { }); } //// [file4.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.forAwait.es2017.js b/tests/baselines/reference/emitter.forAwait.es2017.js index eb953781ab3..4b3770f02af 100644 --- a/tests/baselines/reference/emitter.forAwait.es2017.js +++ b/tests/baselines/reference/emitter.forAwait.es2017.js @@ -26,7 +26,7 @@ async function* f4() { } //// [file1.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -48,7 +48,7 @@ async function f1() { var e_1, _a; } //// [file2.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -70,7 +70,7 @@ async function f2() { var e_1, _a; } //// [file3.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -106,7 +106,7 @@ function f3() { }); } //// [file4.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.forAwait.es5.js b/tests/baselines/reference/emitter.forAwait.es5.js index fc8f5fd321d..2b073a3f43a 100644 --- a/tests/baselines/reference/emitter.forAwait.es5.js +++ b/tests/baselines/reference/emitter.forAwait.es5.js @@ -61,7 +61,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -141,7 +141,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -213,7 +213,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -297,7 +297,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); From 56fc112d8dcfe53327af4d347b7351dd0a7884c5 Mon Sep 17 00:00:00 2001 From: Justin Bay Date: Wed, 25 Oct 2017 20:50:11 -0400 Subject: [PATCH 037/189] add more information to quickinfo for imported symbols --- .gitignore | 1 + src/services/symbolDisplay.ts | 66 +- ...foDisplayPartsInternalModuleAlias.baseline | 722 ++++++++++++++++++ .../fourslash/ambientShorthandFindAllRefs.ts | 4 +- .../ambientShorthandGotoDefinition.ts | 8 +- .../fourslash/completionListOnAliases.ts | 2 +- ...mpletionsImport_named_didNotExistBefore.ts | 2 +- .../fourslash/completionsImport_ofAlias.ts | 2 +- .../fourslash/duplicatePackageServices.ts | 4 +- tests/cases/fourslash/exportEqualTypes.ts | 2 +- .../externalModuleWithExportAssignment.ts | 18 +- .../findAllReferencesOfConstructor.ts | 4 +- .../fourslash/findAllRefsClassExpression2.ts | 2 +- .../fourslash/findAllRefsExportAsNamespace.ts | 2 +- .../findAllRefsExportConstEqualToClass.ts | 2 +- .../fourslash/findAllRefsForDefaultExport.ts | 4 +- .../findAllRefsForDefaultExport04.ts | 10 +- .../findAllRefsForDefaultExport_reExport.ts | 12 +- ...t_reExport_allowSyntheticDefaultImports.ts | 12 +- .../findAllRefsImportStarOfExportEquals.ts | 16 +- .../fourslash/findAllRefsOnImportAliases.ts | 4 +- .../fourslash/findAllRefsOnImportAliases2.ts | 4 +- .../fourslash/findAllRefsReExportLocal.ts | 6 +- ...findAllRefsReExportRightNameWrongSymbol.ts | 6 +- .../fourslash/findAllRefsReExportStar.ts | 2 +- tests/cases/fourslash/findAllRefsReExports.ts | 14 +- .../cases/fourslash/findAllRefsReExports2.ts | 2 +- .../findAllRefsRenameImportWithSameName.ts | 2 +- .../fourslash/findReferencesJSXTagName.ts | 2 +- .../getOccurrencesIsDefinitionOfExport.ts | 2 +- ...mergedDeclarationsWithExportAssignment1.ts | 6 +- ...uickInfoDisplayPartsInternalModuleAlias.ts | 31 +- .../cases/fourslash/quickInfoImportedTypes.ts | 34 + ...uickInfoImportedTypesWithMergedMeanings.ts | 28 + tests/cases/fourslash/quickInfoMeaning.ts | 4 +- .../fourslash/quickInfoOnInternalAliases.ts | 8 +- .../cases/fourslash/referencesForAmbients.ts | 2 +- .../cases/fourslash/referencesForGlobals5.ts | 2 +- .../referencesForMergedDeclarations2.ts | 6 +- tests/cases/fourslash/renameDefaultImport.ts | 2 +- .../renameDefaultImportDifferentName.ts | 2 +- .../renameImportAndExportInDiffFiles.ts | 2 +- .../fourslash/renameImportOfExportEquals.ts | 4 +- .../fourslash/renameImportOfExportEquals2.ts | 6 +- .../cases/fourslash/renameImportOfReExport.ts | 4 +- .../fourslash/renameImportOfReExport2.ts | 4 +- .../fourslash/transitiveExportImports.ts | 2 +- .../fourslash/transitiveExportImports2.ts | 4 +- .../fourslash/transitiveExportImports3.ts | 6 +- 49 files changed, 958 insertions(+), 138 deletions(-) create mode 100644 tests/baselines/reference/quickInfoDisplayPartsInternalModuleAlias.baseline create mode 100644 tests/cases/fourslash/quickInfoImportedTypes.ts create mode 100644 tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts diff --git a/.gitignore b/.gitignore index 19d96d0b046..5125de360b8 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,7 @@ internal/ !tests/baselines/reference/project/nodeModules*/**/* .idea yarn.lock +yarn-error.log .parallelperf.* tests/cases/user/*/package-lock.json tests/cases/user/*/node_modules/ diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index caf38306bec..600a269e2cb 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -105,7 +105,7 @@ namespace ts.SymbolDisplay { // TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: TypeChecker, symbol: Symbol, sourceFile: SourceFile, enclosingDeclaration: Node, - location: Node, semanticMeaning = getMeaningFromLocation(location)): SymbolDisplayPartsDocumentationAndSymbolKind { + location: Node, semanticMeaning = getMeaningFromLocation(location), alias?: Symbol): SymbolDisplayPartsDocumentationAndSymbolKind { const displayParts: SymbolDisplayPart[] = []; let documentation: SymbolDisplayPart[]; @@ -115,6 +115,7 @@ namespace ts.SymbolDisplay { let hasAddedSymbolInfo: boolean; const isThisExpression = location.kind === SyntaxKind.ThisKeyword && isExpression(location); let type: Type; + let documentationFromAlias: SymbolDisplayPart[]; // 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) { @@ -243,6 +244,7 @@ namespace ts.SymbolDisplay { } } if (symbolFlags & SymbolFlags.Class && !hasAddedSymbolInfo && !isThisExpression) { + addAliasPrefixIfNecessary(); if (getDeclarationOfKind(symbol, SyntaxKind.ClassExpression)) { // 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) @@ -258,14 +260,14 @@ namespace ts.SymbolDisplay { writeTypeParametersOfSymbol(symbol, sourceFile); } if ((symbolFlags & SymbolFlags.Interface) && (semanticMeaning & SemanticMeaning.Type)) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); displayParts.push(keywordPart(SyntaxKind.InterfaceKeyword)); displayParts.push(spacePart()); addFullSymbolName(symbol); writeTypeParametersOfSymbol(symbol, sourceFile); } if (symbolFlags & SymbolFlags.TypeAlias) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); displayParts.push(keywordPart(SyntaxKind.TypeKeyword)); displayParts.push(spacePart()); addFullSymbolName(symbol); @@ -276,7 +278,7 @@ namespace ts.SymbolDisplay { addRange(displayParts, typeToDisplayParts(typeChecker, typeChecker.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration, TypeFormatFlags.InTypeAlias)); } if (symbolFlags & SymbolFlags.Enum) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); if (forEach(symbol.declarations, isConstEnumDeclaration)) { displayParts.push(keywordPart(SyntaxKind.ConstKeyword)); displayParts.push(spacePart()); @@ -286,7 +288,7 @@ namespace ts.SymbolDisplay { addFullSymbolName(symbol); } if (symbolFlags & SymbolFlags.Module) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); const declaration = getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration); const isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier; displayParts.push(keywordPart(isNamespace ? SyntaxKind.NamespaceKeyword : SyntaxKind.ModuleKeyword)); @@ -294,7 +296,7 @@ namespace ts.SymbolDisplay { addFullSymbolName(symbol); } if ((symbolFlags & SymbolFlags.TypeParameter) && (semanticMeaning & SemanticMeaning.Type)) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); displayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); displayParts.push(textPart("type parameter")); displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); @@ -354,7 +356,32 @@ namespace ts.SymbolDisplay { } } if (symbolFlags & SymbolFlags.Alias) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); + if (!hasAddedSymbolInfo) { + const resolvedSymbol = typeChecker.getAliasedSymbol(symbol); + if (resolvedSymbol !== symbol && resolvedSymbol.declarations && resolvedSymbol.declarations.length > 0) { + const resolvedNode = resolvedSymbol.declarations[0]; + const declarationName = ts.getNameOfDeclaration(resolvedNode); + if (declarationName) { + const isExternalModuleDeclaration = + ts.isModuleWithStringLiteralName(resolvedNode) && + ts.hasModifier(resolvedNode, ModifierFlags.Ambient); + const shouldUseAliasName = symbol.name !== "default" && !isExternalModuleDeclaration; + const resolvedInfo = getSymbolDisplayPartsDocumentationAndSymbolKind( + typeChecker, + resolvedSymbol, + ts.getSourceFileOfNode(resolvedNode), + resolvedNode, + declarationName, + semanticMeaning, + shouldUseAliasName ? symbol : resolvedSymbol); + displayParts.push(...resolvedInfo.displayParts); + displayParts.push(lineBreakPart()); + documentationFromAlias = resolvedInfo.documentation; + } + } + } + switch (symbol.declarations[0].kind) { case SyntaxKind.NamespaceExportDeclaration: displayParts.push(keywordPart(SyntaxKind.ExportKeyword)); @@ -400,7 +427,7 @@ namespace ts.SymbolDisplay { if (symbolKind !== ScriptElementKind.unknown) { if (type) { if (isThisExpression) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); displayParts.push(keywordPart(SyntaxKind.ThisKeyword)); } else { @@ -472,12 +499,24 @@ namespace ts.SymbolDisplay { } } + if (documentation.length === 0 && documentationFromAlias) { + documentation = documentationFromAlias; + } + return { displayParts, documentation, symbolKind, tags }; - function addNewLineIfDisplayPartsExist() { + function prefixNextMeaning() { if (displayParts.length) { displayParts.push(lineBreakPart()); } + addAliasPrefixIfNecessary(); + } + + function addAliasPrefixIfNecessary() { + if (alias) { + pushTypePart(ScriptElementKind.alias); + displayParts.push(spacePart()); + } } function addInPrefix() { @@ -486,14 +525,17 @@ namespace ts.SymbolDisplay { displayParts.push(spacePart()); } - function addFullSymbolName(symbol: Symbol, enclosingDeclaration?: Node) { - const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, + function addFullSymbolName(symbolToDisplay: Symbol, enclosingDeclaration?: Node) { + if (alias && symbolToDisplay === symbol) { + symbolToDisplay = alias; + } + const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing); addRange(displayParts, fullSymbolDisplayParts); } function addPrefixForAnyFunctionOrVar(symbol: Symbol, symbolKind: string) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); if (symbolKind) { pushTypePart(symbolKind); if (symbol && !some(symbol.declarations, d => isArrowFunction(d) || (isFunctionExpression(d) || isClassExpression(d)) && !d.name)) { diff --git a/tests/baselines/reference/quickInfoDisplayPartsInternalModuleAlias.baseline b/tests/baselines/reference/quickInfoDisplayPartsInternalModuleAlias.baseline new file mode 100644 index 00000000000..c476abad356 --- /dev/null +++ b/tests/baselines/reference/quickInfoDisplayPartsInternalModuleAlias.baseline @@ -0,0 +1,722 @@ +[ + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 66 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "", + "textSpan": { + "start": 66, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a1", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a1", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 82 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "", + "textSpan": { + "start": 82, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a1", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a1", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 104 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "", + "textSpan": { + "start": 104, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a2", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a2", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "m1", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 123 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "", + "textSpan": { + "start": 123, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a2", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a2", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "m1", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 149 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "export", + "textSpan": { + "start": 149, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a3", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a3", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 165 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "export", + "textSpan": { + "start": 165, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a3", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a3", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 194 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "export", + "textSpan": { + "start": 194, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a4", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a4", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "m1", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 213 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "export", + "textSpan": { + "start": 213, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a4", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a4", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "m1", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + } +] \ No newline at end of file diff --git a/tests/cases/fourslash/ambientShorthandFindAllRefs.ts b/tests/cases/fourslash/ambientShorthandFindAllRefs.ts index 3f325a546c2..14918f4a449 100644 --- a/tests/cases/fourslash/ambientShorthandFindAllRefs.ts +++ b/tests/cases/fourslash/ambientShorthandFindAllRefs.ts @@ -12,5 +12,5 @@ const ranges = test.ranges(); const [r0, r1] = ranges; // TODO: Want these to be in the same group, but that would require creating a symbol for `x`. -verify.singleReferenceGroup("import x", [r0]); -verify.singleReferenceGroup("import x", [r1]); \ No newline at end of file +verify.singleReferenceGroup("(alias) module \"jquery\"\nimport x", [r0]); +verify.singleReferenceGroup("(alias) module \"jquery\"\nimport x", [r1]); \ No newline at end of file diff --git a/tests/cases/fourslash/ambientShorthandGotoDefinition.ts b/tests/cases/fourslash/ambientShorthandGotoDefinition.ts index f0e717999cf..6530a0e0c99 100644 --- a/tests/cases/fourslash/ambientShorthandGotoDefinition.ts +++ b/tests/cases/fourslash/ambientShorthandGotoDefinition.ts @@ -10,22 +10,22 @@ ////import [|/*importBang*/bang|] = require("jquery"); ////[|foo/*useFoo*/|]([|bar/*useBar*/|], [|baz/*useBaz*/|], [|bang/*useBang*/|]); -verify.quickInfoAt("useFoo", "import foo"); +verify.quickInfoAt("useFoo", "(alias) module \"jquery\"\nimport foo"); verify.goToDefinition({ useFoo: "module", importFoo: "module" }); -verify.quickInfoAt("useBar", "import bar"); +verify.quickInfoAt("useBar", "(alias) module \"jquery\"\nimport bar"); verify.goToDefinition("useBar", "module"); -verify.quickInfoAt("useBaz", "import baz"); +verify.quickInfoAt("useBaz", "(alias) module \"jquery\"\nimport baz"); verify.goToDefinition({ useBaz: "importBaz", importBaz: "module" }); -verify.quickInfoAt("useBang", "import bang = require(\"jquery\")"); +verify.quickInfoAt("useBang", "(alias) module \"jquery\"\nimport bang = require(\"jquery\")"); verify.goToDefinition({ useBang: "module", importBang: "module" diff --git a/tests/cases/fourslash/completionListOnAliases.ts b/tests/cases/fourslash/completionListOnAliases.ts index c15e5284c06..0c5b7adcd50 100644 --- a/tests/cases/fourslash/completionListOnAliases.ts +++ b/tests/cases/fourslash/completionListOnAliases.ts @@ -9,7 +9,7 @@ ////} goTo.marker("1"); -verify.completionListContains("x", "import x = M", undefined); +verify.completionListContains("x", "(alias) namespace x\nimport x = M", undefined); goTo.marker("2"); verify.completionListContains("value"); diff --git a/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts b/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts index c793a5f06ad..a69c0ab19ca 100644 --- a/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts +++ b/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts @@ -11,7 +11,7 @@ goTo.marker(""); const options = { includeExternalModuleExports: true, sourceDisplay: undefined }; verify.completionListContains({ name: "Test1", source: "/a" }, "function Test1(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true, { ...options, sourceDisplay: "./a" }); -verify.completionListContains("Test2", "import Test2", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ undefined, options); +verify.completionListContains("Test2", "(alias) function Test2(): void\nimport Test2", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ undefined, options); verify.not.completionListContains({ name: "Test2", source: "/a" }, undefined, undefined, undefined, undefined, undefined, options); verify.applyCodeActionFromCompletion("", { diff --git a/tests/cases/fourslash/completionsImport_ofAlias.ts b/tests/cases/fourslash/completionsImport_ofAlias.ts index a693065b93c..5808e6c9f1a 100644 --- a/tests/cases/fourslash/completionsImport_ofAlias.ts +++ b/tests/cases/fourslash/completionsImport_ofAlias.ts @@ -21,7 +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" }, "import foo", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ true, options); +verify.completionListContains({ name: "foo", source: "/a" }, "(alias) const foo: 0\nimport 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/duplicatePackageServices.ts b/tests/cases/fourslash/duplicatePackageServices.ts index c84c43cdd9e..48dfdf8aa83 100644 --- a/tests/cases/fourslash/duplicatePackageServices.ts +++ b/tests/cases/fourslash/duplicatePackageServices.ts @@ -36,9 +36,9 @@ verify.goToDefinition("useAX", "defAX"); verify.goToDefinition("useBX", "defAX"); const [r0, r1, r2, r3, r4, r5] = test.ranges(); -const aImport = { definition: "import X", ranges: [r0, r1] }; +const aImport = { definition: "(alias) class X\nimport X", ranges: [r0, r1] }; const def = { definition: "class X", ranges: [r2] }; -const bImport = { definition: "import X", ranges: [r3, r4] }; +const bImport = { definition: "(alias) class X\nimport X", ranges: [r3, r4] }; verify.referenceGroups([r0, r1], [aImport, def, bImport]); verify.referenceGroups([r2], [def, aImport, bImport]); verify.referenceGroups([r3, r4], [bImport, def, aImport]); diff --git a/tests/cases/fourslash/exportEqualTypes.ts b/tests/cases/fourslash/exportEqualTypes.ts index f130d211031..cb1e2ec90a1 100644 --- a/tests/cases/fourslash/exportEqualTypes.ts +++ b/tests/cases/fourslash/exportEqualTypes.ts @@ -15,7 +15,7 @@ ////var /*3*/r2 = t./*4*/foo; // t should have 'foo' in dropdown list and be of type 'string' verify.quickInfos({ - 1: "import test = require('./exportEqualTypes_file0')", + 1: "(alias) interface test\nimport test = require('./exportEqualTypes_file0')", 2: "var r1: Date", 3: "var r2: string" }); diff --git a/tests/cases/fourslash/externalModuleWithExportAssignment.ts b/tests/cases/fourslash/externalModuleWithExportAssignment.ts index 5b392623690..e35a89f1d7e 100644 --- a/tests/cases/fourslash/externalModuleWithExportAssignment.ts +++ b/tests/cases/fourslash/externalModuleWithExportAssignment.ts @@ -29,8 +29,22 @@ ////var v1: a1./*15*/connectExport; goTo.file("externalModuleWithExportAssignment_file1.ts"); -verify.quickInfoAt("1", 'import a1 = require("./externalModuleWithExportAssignment_file0")'); -verify.quickInfoAt("2", "var a: {\n (): a1.connectExport;\n test1: a1.connectModule;\n test2(): a1.connectModule;\n}", undefined); +verify.quickInfoAt("1", [ + "(alias) namespace a1", + "(alias) var a1: {", + " (): connectExport;", + " test1: connectModule;", + " test2(): connectModule;", + "}", + 'import a1 = require("./externalModuleWithExportAssignment_file0")' +].join("\n")); +verify.quickInfoAt("2", [ + "var a: {", + " (): a1.connectExport;", + " test1: a1.connectModule;", + " test2(): a1.connectModule;", + "}" +].join("\n"), undefined); goTo.marker('3'); verify.quickInfoIs("(property) test1: a1.connectModule\n(res: any, req: any, next: any) => void", undefined); diff --git a/tests/cases/fourslash/findAllReferencesOfConstructor.ts b/tests/cases/fourslash/findAllReferencesOfConstructor.ts index 37f0264c816..d177907b974 100644 --- a/tests/cases/fourslash/findAllReferencesOfConstructor.ts +++ b/tests/cases/fourslash/findAllReferencesOfConstructor.ts @@ -48,7 +48,7 @@ verify.referenceGroups(a1, defs("constructor C(): C (+1 overload)")); function defs(definition: string) { return [ { definition, ranges: [a0, a1, a2, a3, d0, d1, a4] }, - { definition: "import C", ranges: [b0] }, - { definition: "import C", ranges: [c0] } + { definition: "(alias) class C\nimport C", ranges: [b0] }, + { definition: "(alias) class C\nimport C", ranges: [c0] } ] } diff --git a/tests/cases/fourslash/findAllRefsClassExpression2.ts b/tests/cases/fourslash/findAllRefsClassExpression2.ts index ce2fc8bbf3d..b9d2267c516 100644 --- a/tests/cases/fourslash/findAllRefsClassExpression2.ts +++ b/tests/cases/fourslash/findAllRefsClassExpression2.ts @@ -11,6 +11,6 @@ const [r0, r1, r2] = test.ranges(); const defs = { definition: "(property) A: typeof (Anonymous class)", ranges: [r0] }; -const imports = { definition: "import A", ranges: [r1, r2] }; +const imports = { definition: "(alias) (property) A: typeof (Anonymous class)\nimport A", ranges: [r1, r2] }; verify.referenceGroups([r0], [defs, imports]); verify.referenceGroups([r1, r2], [imports, defs]); diff --git a/tests/cases/fourslash/findAllRefsExportAsNamespace.ts b/tests/cases/fourslash/findAllRefsExportAsNamespace.ts index e6b29fce47f..f6149f17d90 100644 --- a/tests/cases/fourslash/findAllRefsExportAsNamespace.ts +++ b/tests/cases/fourslash/findAllRefsExportAsNamespace.ts @@ -18,7 +18,7 @@ const ranges = test.ranges(); const [r0, r1, r2] = ranges; const globals = { definition: "function f(): void", ranges: [r0, r2] }; -const imports = { definition: "import f", ranges: [r1] }; +const imports = { definition: "(alias) function f(): void\nimport f", ranges: [r1] }; verify.referenceGroups([r0, r2], [globals, imports]); verify.referenceGroups(r1, [imports, globals]); diff --git a/tests/cases/fourslash/findAllRefsExportConstEqualToClass.ts b/tests/cases/fourslash/findAllRefsExportConstEqualToClass.ts index a5e9bd1cd7d..6be7ea0bdba 100644 --- a/tests/cases/fourslash/findAllRefsExportConstEqualToClass.ts +++ b/tests/cases/fourslash/findAllRefsExportConstEqualToClass.ts @@ -12,6 +12,6 @@ const [C0, D0, C1, D1] = test.ranges(); verify.singleReferenceGroup("class C", [C0, C1]); const d0Group = { definition: "const D: typeof C", ranges: [D0] }; -const d1Group = { definition: "import D", ranges: [D1] }; +const d1Group = { definition: "(alias) const D: typeof C\nimport D", ranges: [D1] }; verify.referenceGroups(D0, [d0Group, d1Group]); verify.referenceGroups(D1, [d1Group, d0Group]); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport.ts b/tests/cases/fourslash/findAllRefsForDefaultExport.ts index 414b2503391..1fe48cd78ae 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport.ts @@ -14,9 +14,9 @@ const ranges = test.ranges(); const [r0, r1, r2] = ranges; verify.referenceGroups(r0, [ { definition: "function f(): void", ranges: [r0] }, - { definition: "import g", ranges: [r1, r2] } + { definition: "(alias) function g(): void\nimport g", ranges: [r1, r2] } ]); -verify.referenceGroups(r1, [{ definition: "import g", ranges: [r1, r2] }]); +verify.referenceGroups(r1, [{ definition: "(alias) function g(): void\nimport g", ranges: [r1, r2] }]); verify.referenceGroups(r2, [{ definition: "(alias) g(): void\nimport g", ranges: [r1, r2] }]); verify.goToDefinition("ref", "def"); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport04.ts b/tests/cases/fourslash/findAllRefsForDefaultExport04.ts index 093910d1cb5..279f2bd1e81 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport04.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport04.ts @@ -11,13 +11,13 @@ const [r0, r1, r2, r3, r4] = test.ranges(); verify.referenceGroups([r0, r2], [ { definition: "const a: 0", ranges: [r0, r2] }, - { definition: "import a", ranges: [r3, r4] } + { definition: "(alias) const a: 0\nimport a", ranges: [r3, r4] } ]); verify.referenceGroups(r1, [ - { definition: "export default a", ranges: [r1] }, - { definition: "import a", ranges: [r3, r4] }, + { definition: "(alias) const a: 0\nexport default a", ranges: [r1] }, + { definition: "(alias) const a: 0\nimport a", ranges: [r3, r4] }, ]); verify.referenceGroups([r3, r4], [ - { definition: "import a", ranges: [r3, r4] }, - { definition: "export default a", ranges: [r1] }, + { definition: "(alias) const a: 0\nimport a", ranges: [r3, r4] }, + { definition: "(alias) const a: 0\nexport default a", ranges: [r1] }, ]); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport_reExport.ts b/tests/cases/fourslash/findAllRefsForDefaultExport_reExport.ts index 4c2427639f8..2154087d81a 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: "import default", ranges: [r2], }, - { definition: "import fooDefault", ranges: [r3] }, + { definition: "(alias) const foo: 1\nimport default", ranges: [r2], }, + { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, ]); verify.referenceGroups(r2, [ - { definition: "import default", ranges: [r2] }, - { definition: "import fooDefault", ranges: [r3] }, + { definition: "(alias) const foo: 1\nimport default", ranges: [r2] }, + { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, { definition: "const foo: 1", ranges: [r0, r1] }, ]); verify.referenceGroups(r3, [ - { definition: "import fooDefault", ranges: [r3] }, - { definition: "import default", ranges: [r2] }, + { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, + { definition: "(alias) const foo: 1\nimport 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 26a05f2e12e..41377a41aca 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: "import default", ranges: [r2], }, - { definition: "import fooDefault", ranges: [r3] }, + { definition: "(alias) const foo: 1\nimport default", ranges: [r2], }, + { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, ]); verify.referenceGroups(r2, [ - { definition: "import default", ranges: [r2] }, - { definition: "import fooDefault", ranges: [r3] }, + { definition: "(alias) const foo: 1\nimport default", ranges: [r2] }, + { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, { definition: "const foo: 1", ranges: [r0, r1] }, ]); verify.referenceGroups(r3, [ - { definition: "import fooDefault", ranges: [r3] }, - { definition: "import default", ranges: [r2] }, + { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, + { definition: "(alias) const foo: 1\nimport default", ranges: [r2] }, { definition: "const foo: 1", ranges: [r0, r1] }, ]); diff --git a/tests/cases/fourslash/findAllRefsImportStarOfExportEquals.ts b/tests/cases/fourslash/findAllRefsImportStarOfExportEquals.ts index c57f4a67fda..c1d3bd8c7f5 100644 --- a/tests/cases/fourslash/findAllRefsImportStarOfExportEquals.ts +++ b/tests/cases/fourslash/findAllRefsImportStarOfExportEquals.ts @@ -28,31 +28,31 @@ const cRanges = [c0, c1, c2]; verify.referenceGroups(a0, [ { definition: "function a(): void\nnamespace a", ranges: aRanges }, - { definition: "import b", ranges: bRanges }, - { definition: "import a", ranges: cRanges } + { definition: "(alias) function b(): void\n(alias) namespace b\nimport b", ranges: bRanges }, + { definition: "(alias) function a(): void\n(alias) namespace a\nimport a", ranges: cRanges } ]); verify.referenceGroups([a1, a2], [ { definition: "namespace a\nfunction a(): void", ranges: aRanges }, - { definition: "import b", ranges: bRanges }, - { definition: "import a", ranges: cRanges } + { definition: "(alias) function b(): void\n(alias) namespace b\nimport b", ranges: bRanges }, + { definition: "(alias) function a(): void\n(alias) namespace a\nimport a", ranges: cRanges } ]); verify.referenceGroups([b0, b0], [ - { definition: "import b", ranges: bRanges } + { definition: "(alias) function b(): void\n(alias) namespace b\nimport b", ranges: bRanges } ]); verify.referenceGroups(b1, [ { definition: "(alias) b(): void\nimport b", ranges: bRanges } ]); verify.referenceGroups([c0, c2], [ - { definition: "import a", ranges: cRanges }, + { definition: "(alias) function a(): void\n(alias) namespace a\nimport a", ranges: cRanges }, { definition: "namespace a\nfunction a(): void", ranges: aRanges }, - { definition: "import b", ranges: bRanges } + { definition: "(alias) function b(): void\n(alias) namespace b\nimport b", ranges: bRanges } ]); verify.referenceGroups(c1, [ { definition: "(alias) a(): void\nimport a", ranges: cRanges }, { definition: "namespace a\nfunction a(): void", ranges: aRanges }, - { definition: "import b", ranges: bRanges } + { definition: "(alias) function b(): void\n(alias) namespace b\nimport b", ranges: bRanges } ]); verify.renameLocations(aRanges, aRanges.concat(cRanges)); diff --git a/tests/cases/fourslash/findAllRefsOnImportAliases.ts b/tests/cases/fourslash/findAllRefsOnImportAliases.ts index 98509ad6938..cb5dc082157 100644 --- a/tests/cases/fourslash/findAllRefsOnImportAliases.ts +++ b/tests/cases/fourslash/findAllRefsOnImportAliases.ts @@ -15,8 +15,8 @@ const ranges = test.ranges(); const [r0, r1, r2, r3] = ranges; const classes = { definition: "class Class", ranges: [r0] }; -const imports = { definition: "import Class", ranges: [r1, r2] }; -const reExports = { definition: "import Class", ranges: [r3] }; +const imports = { definition: "(alias) class Class\nimport Class", ranges: [r1, r2] }; +const reExports = { definition: "(alias) class Class\nimport Class", ranges: [r3] }; verify.referenceGroups(r0, [classes, imports, reExports]); verify.referenceGroups(r1, [imports, classes, reExports]); verify.referenceGroups(r2, [ diff --git a/tests/cases/fourslash/findAllRefsOnImportAliases2.ts b/tests/cases/fourslash/findAllRefsOnImportAliases2.ts index 64f44018d07..74b099ea767 100644 --- a/tests/cases/fourslash/findAllRefsOnImportAliases2.ts +++ b/tests/cases/fourslash/findAllRefsOnImportAliases2.ts @@ -17,8 +17,8 @@ const c2Ranges = ranges.get("C2"); const [c2_0, c2_1] = c2Ranges; const c3Ranges = ranges.get("C3"); const classes = { definition: "class Class", ranges: classRanges }; -const c2s = { definition: "import C2", ranges: c2Ranges }; -const c3s = { definition: "import C3", ranges: c3Ranges }; +const c2s = { definition: "(alias) class C2\nimport C2", ranges: c2Ranges }; +const c3s = { definition: "(alias) class C3\nimport C3", ranges: c3Ranges }; verify.referenceGroups(classRanges, [classes, c2s, c3s]); diff --git a/tests/cases/fourslash/findAllRefsReExportLocal.ts b/tests/cases/fourslash/findAllRefsReExportLocal.ts index 3e5890e6317..f57cc8480f0 100644 --- a/tests/cases/fourslash/findAllRefsReExportLocal.ts +++ b/tests/cases/fourslash/findAllRefsReExportLocal.ts @@ -18,9 +18,9 @@ const axRanges = [ax0, ax1, ax2]; const bxRanges = [bx0, bx1]; const byRanges = [by0, by1]; const axGroup = { definition: "var x: any", ranges: axRanges }; -const bxGroup = { definition: "import x", ranges: bxRanges }; -const ayGroup = { definition: "import y", ranges: [ay] } -const byGroup = { definition: "import y", ranges: byRanges } +const bxGroup = { definition: "(alias) var x: any\nimport x", ranges: bxRanges }; +const ayGroup = { definition: "(alias) var y: any\nimport y", ranges: [ay] } +const byGroup = { definition: "(alias) var y: any\nimport y", ranges: byRanges } verify.referenceGroups(axRanges, [axGroup, bxGroup, ayGroup, byGroup]); verify.referenceGroups(bxRanges, [bxGroup, axGroup, ayGroup, byGroup]); diff --git a/tests/cases/fourslash/findAllRefsReExportRightNameWrongSymbol.ts b/tests/cases/fourslash/findAllRefsReExportRightNameWrongSymbol.ts index c9d42e53d4e..12305381fe8 100644 --- a/tests/cases/fourslash/findAllRefsReExportRightNameWrongSymbol.ts +++ b/tests/cases/fourslash/findAllRefsReExportRightNameWrongSymbol.ts @@ -19,13 +19,13 @@ const [a, b, cFromB, cFromA, cUse, d] = test.ranges(); const cFromARanges = [cFromA, cUse]; const aGroup = { definition: "const x: 0", ranges: [a] }; -const cFromAGroup = { definition: "import x", ranges: cFromARanges }; +const cFromAGroup = { definition: "(alias) const x: 0\nimport x", ranges: cFromARanges }; verify.referenceGroups(a, [aGroup, cFromAGroup]); const bGroup = { definition: "const x: 0", ranges: [b] }; -const cFromBGroup = { definition: "import x", ranges: [cFromB] }; -const dGroup = { definition: "import x", ranges: [d] }; +const cFromBGroup = { definition: "(alias) const x: 0\nimport x", ranges: [cFromB] }; +const dGroup = { definition: "(alias) const x: 0\nimport x", ranges: [d] }; verify.referenceGroups(b, [bGroup, cFromBGroup, dGroup]); verify.referenceGroups(cFromB, [cFromBGroup, dGroup, bGroup]); diff --git a/tests/cases/fourslash/findAllRefsReExportStar.ts b/tests/cases/fourslash/findAllRefsReExportStar.ts index 86901cfadf2..a82f91cc5b0 100644 --- a/tests/cases/fourslash/findAllRefsReExportStar.ts +++ b/tests/cases/fourslash/findAllRefsReExportStar.ts @@ -13,6 +13,6 @@ verify.noErrors(); const ranges = test.ranges(); const [r0, r1] = ranges; const a = { definition: "function foo(): void", ranges: [r0] }; -const c = { definition: "import foo", ranges: [r1] }; +const c = { definition: "(alias) function foo(): void\nimport foo", ranges: [r1] }; verify.referenceGroups(r0, [a, c]); verify.referenceGroups(r1, [c, a]); diff --git a/tests/cases/fourslash/findAllRefsReExports.ts b/tests/cases/fourslash/findAllRefsReExports.ts index e9936867604..9c0e3b26bfc 100644 --- a/tests/cases/fourslash/findAllRefsReExports.ts +++ b/tests/cases/fourslash/findAllRefsReExports.ts @@ -22,13 +22,13 @@ 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: "import bar", ranges: [bar0] }; -const c = { definition: "import default", ranges: [defaultC, defaultE] }; -const d = { definition: "import default", ranges: [defaultD] }; -const eBar = { definition: "import bar", ranges: [bar1, bar2] }; -const eBaz = { definition: "import baz", ranges: [baz0, baz1] }; -const eBang = { definition: "import bang", ranges: [bang0, bang1] }; -const eBoom = { definition: "import boom", ranges: [boom0, boom1] }; +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 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] }; +const eBoom = { definition: "(alias) function boom(): void\nimport boom", ranges: [boom0, boom1] }; verify.referenceGroups([foo0, foo1, foo2], [a, b, eBar, c, d, eBoom, eBaz, eBang]); diff --git a/tests/cases/fourslash/findAllRefsReExports2.ts b/tests/cases/fourslash/findAllRefsReExports2.ts index 5dfdc8aebbf..31aa07fa29e 100644 --- a/tests/cases/fourslash/findAllRefsReExports2.ts +++ b/tests/cases/fourslash/findAllRefsReExports2.ts @@ -10,5 +10,5 @@ verify.noErrors(); const [r0, r1, r2] = test.ranges(); verify.referenceGroups(r0, [ { definition: "function foo(): void", ranges: [r0, r1] }, - { definition: "import oof", ranges: [r2] } + { definition: "(alias) function oof(): void\nimport oof", ranges: [r2] } ]); diff --git a/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts b/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts index 5a5db1496a7..62b1c19c5ed 100644 --- a/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts +++ b/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts @@ -12,7 +12,7 @@ const [r0, r1, r2, r3] = test.ranges(); const aRanges = [r0, r1]; const bRanges = [r2, r3]; const aGroup = { definition: "const x: 0", ranges: aRanges }; -const bGroup = { definition: "import x", ranges: bRanges }; +const bGroup = { definition: "(alias) const x: 0\nimport x", ranges: bRanges }; verify.referenceGroups(aRanges, [aGroup, bGroup]); verify.referenceGroups(bRanges, [bGroup]); diff --git a/tests/cases/fourslash/findReferencesJSXTagName.ts b/tests/cases/fourslash/findReferencesJSXTagName.ts index 39031051f1b..8547ad8b330 100644 --- a/tests/cases/fourslash/findReferencesJSXTagName.ts +++ b/tests/cases/fourslash/findReferencesJSXTagName.ts @@ -12,7 +12,7 @@ ////

; const [r0, r1, r2] = test.ranges(); -const imports = { definition: "import SubmissionComp", ranges: [r0, r1] }; +const imports = { definition: "(alias) const SubmissionComp: (submission: any) => any\nimport SubmissionComp", ranges: [r0, r1] }; const def = { definition: "const SubmissionComp: (submission: any) => any", ranges: [r2] }; verify.referenceGroups([r0, r1], [imports, def]); verify.referenceGroups(r2, [def, imports]); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts index 4268e5d180d..e31bc46eae6 100644 --- a/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts @@ -8,6 +8,6 @@ const ranges = test.ranges(); const [r0, r1, r2] = ranges; const defs = { definition: "var x: number", ranges: [r0] }; -const imports = { definition: "import x", ranges: [r1, r2] }; +const imports = { definition: "(alias) var x: number\nimport x", ranges: [r1, r2] }; verify.referenceGroups(r0, [defs, imports]); verify.referenceGroups([r1, r2], [imports, defs]); diff --git a/tests/cases/fourslash/mergedDeclarationsWithExportAssignment1.ts b/tests/cases/fourslash/mergedDeclarationsWithExportAssignment1.ts index fd9a2e34b4b..f6a159f7eee 100644 --- a/tests/cases/fourslash/mergedDeclarationsWithExportAssignment1.ts +++ b/tests/cases/fourslash/mergedDeclarationsWithExportAssignment1.ts @@ -15,7 +15,11 @@ ////var /*3*/z = new /*2*/Foo(); ////var /*5*/r2 = Foo./*4*/x; -verify.quickInfoAt("1", "import Foo = require('./mergedDeclarationsWithExportAssignment1_file0')"); +verify.quickInfoAt("1", [ + "(alias) class Foo", + "(alias) namespace Foo", + "import Foo = require('./mergedDeclarationsWithExportAssignment1_file0')" +].join("\n")); goTo.marker('2'); verify.completionListContains('Foo'); diff --git a/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts b/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts index 78c22b09dac..9fcedc94103 100644 --- a/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts +++ b/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts @@ -15,33 +15,4 @@ //// new /*8*/a4.c(); ////} -var marker = 0; -function goToMarker() { - marker++; - goTo.marker(marker.toString()); -} - -function verifyImport(name: string, assigningDisplay:ts.SymbolDisplayPart[], optionalParentName?: string) { - goToMarker(); - var moduleNameDisplay = [{ text: name, kind: "aliasName" }]; - if (optionalParentName) { - moduleNameDisplay = [{ text: optionalParentName, kind: "moduleName" }, { text: ".", kind: "punctuation" }].concat(moduleNameDisplay); - } - verify.verifyQuickInfoDisplayParts("alias", optionalParentName ? "export" : "", { start: test.markerByName(marker.toString()).position, length: name.length }, - [{ text: "import", kind: "keyword" }, { text: " ", kind: "space" }].concat(moduleNameDisplay).concat( - { text: " ", kind: "space" }, { text: "=", kind: "operator" }, { text: " ", kind: "space" }).concat(assigningDisplay), - [], []); -} - -var moduleMDisplay = [{ text: "m", kind: "moduleName" }]; -var moduleMDotM1Display = moduleMDisplay.concat({ text: ".", kind: "punctuation" }, { text: "m1", kind: "moduleName" }); - -verifyImport("a1", moduleMDisplay); -verifyImport("a1", moduleMDisplay); -verifyImport("a2", moduleMDotM1Display); -verifyImport("a2", moduleMDotM1Display); - -verifyImport("a3", moduleMDisplay, "m2"); -verifyImport("a3", moduleMDisplay, "m2"); -verifyImport("a4", moduleMDotM1Display, "m2"); -verifyImport("a4", moduleMDotM1Display, "m2"); \ No newline at end of file +verify.baselineQuickInfo(); diff --git a/tests/cases/fourslash/quickInfoImportedTypes.ts b/tests/cases/fourslash/quickInfoImportedTypes.ts new file mode 100644 index 00000000000..52da97ada91 --- /dev/null +++ b/tests/cases/fourslash/quickInfoImportedTypes.ts @@ -0,0 +1,34 @@ +/// + +// @Filename: quickInfoImportedTypes.ts +//// /** This is an interface */ +//// export interface Foo { +//// a?: number; +//// } +//// /** One or two */ +//// export type Bar = 1 | 2 +//// /** This is a class */ +//// export class Baz { +//// public x: T = {} as T +//// } + +// @Filename: two.ts +//// import { Foo, Bar, Baz } from './quickInfoImportedTypes'; +//// let x: Foo/*1*/; +//// let y: Bar/*2*/; +//// let z: Baz/*3*/; + +verify.quickInfoAt("1", [ + "(alias) interface Foo", + "import Foo", +].join("\n"), "This is an interface "); + +verify.quickInfoAt("2", [ + "(alias) type Bar = 1 | 2", + "import Bar", +].join("\n"), "One or two "); + +verify.quickInfoAt("3", [ + "(alias) class Baz", + "import Baz", +].join("\n"), "This is a class "); diff --git a/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts b/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts new file mode 100644 index 00000000000..9e7efc52761 --- /dev/null +++ b/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts @@ -0,0 +1,28 @@ +/// + +// @Filename: quickInfoImportedTypesWithMergedMeanings.ts +//// export namespace Original { } +//// export type Original = () => T; +//// /** some docs */ +//// export function Original() { } + +// @Filename: transient.ts +//// export { Original/*1*/ } from './quickInfoImportedTypesWithMergedMeanings'; + +// @Filename: importer.ts +//// import { Original as Alias } from './quickInfoImportedTypesWithMergedMeanings'; +//// Alias/*2*/; + +verify.quickInfoAt("1", [ + "(alias) type Original = () => T", + "(alias) namespace Original", + "(alias) function Original(): void", + "import Original", +].join("\n"), "some docs "); + +verify.quickInfoAt("2", [ + "(alias) type Alias = () => T", + "(alias) namespace Alias", + "(alias) function Alias(): void", + "import Alias", +].join("\n"), "some docs "); diff --git a/tests/cases/fourslash/quickInfoMeaning.ts b/tests/cases/fourslash/quickInfoMeaning.ts index 2c7aa5a0ccd..f50675ba393 100644 --- a/tests/cases/fourslash/quickInfoMeaning.ts +++ b/tests/cases/fourslash/quickInfoMeaning.ts @@ -29,7 +29,7 @@ verify.quickInfoIs("const foo: number"); verify.goToDefinitionIs("foo_value_declaration"); goTo.marker("foo_type"); -verify.quickInfoIs("import foo = require(\"foo_module\")"); +verify.quickInfoIs("(alias) interface foo\nimport foo = require(\"foo_module\")"); verify.goToDefinitionIs("foo_type_declaration"); @@ -54,7 +54,7 @@ verify.navigationItemsListContains("bar", "alias", "bar", "exact"); verify.navigationItemsListContains("bar", "interface", "bar", "exact"); goTo.marker("bar_value"); -verify.quickInfoIs("import bar = require(\"bar_module\")"); +verify.quickInfoIs("(alias) const bar: number\nimport bar = require(\"bar_module\")"); verify.goToDefinitionIs("bar_value_declaration"); goTo.marker("bar_type"); diff --git a/tests/cases/fourslash/quickInfoOnInternalAliases.ts b/tests/cases/fourslash/quickInfoOnInternalAliases.ts index 8d334ef4a6c..f22b61ae86d 100644 --- a/tests/cases/fourslash/quickInfoOnInternalAliases.ts +++ b/tests/cases/fourslash/quickInfoOnInternalAliases.ts @@ -21,16 +21,16 @@ verify.quickInfos({ 1: ["class m1.m2.c", "class comment;"], - 2: ["import internalAlias = m1.m2.c", "This is on import declaration"], + 2: ["(alias) class internalAlias\nimport internalAlias = m1.m2.c", "This is on import declaration"], 3: ["class m1.m2.c", "class comment;"], 4: "var newVar: internalAlias", 5: "(alias) new internalAlias(): internalAlias\nimport internalAlias = m1.m2.c", 6: "var anotherAliasVar: typeof internalAlias", - 7: ["import internalAlias = m1.m2.c", "This is on import declaration"], - 8: "import internalFoo = m1.foo", + 7: ["(alias) class internalAlias\nimport internalAlias = m1.m2.c", "This is on import declaration"], + 8: "(alias) function internalFoo(): void\nimport internalFoo = m1.foo", 9: "function m1.foo(): void", 10: "var callVar: void", 11: "(alias) internalFoo(): void\nimport internalFoo = m1.foo", 12: "var anotherAliasFoo: () => void", - 13: "import internalFoo = m1.foo" + 13: "(alias) function internalFoo(): void\nimport internalFoo = m1.foo" }); diff --git a/tests/cases/fourslash/referencesForAmbients.ts b/tests/cases/fourslash/referencesForAmbients.ts index 2397738581e..02001d2ffdf 100644 --- a/tests/cases/fourslash/referencesForAmbients.ts +++ b/tests/cases/fourslash/referencesForAmbients.ts @@ -17,5 +17,5 @@ const [moduleFoo0, f0, moduleBar0, foo0, moduleFoo1, foo1, f1, moduleBar1, foo2] = test.ranges(); verify.singleReferenceGroup('module "foo"', [moduleFoo1, moduleFoo0]); verify.singleReferenceGroup('module "bar"', [moduleBar1, moduleBar0]); -verify.singleReferenceGroup('import foo = require("foo")', [foo0, foo1, foo2]); +verify.singleReferenceGroup('(alias) module "foo"\nimport foo = require("foo")', [foo0, foo1, foo2]); verify.singleReferenceGroup("var f: number", [f0, f1]); diff --git a/tests/cases/fourslash/referencesForGlobals5.ts b/tests/cases/fourslash/referencesForGlobals5.ts index d7dd9304746..0d205b4b9b2 100644 --- a/tests/cases/fourslash/referencesForGlobals5.ts +++ b/tests/cases/fourslash/referencesForGlobals5.ts @@ -12,4 +12,4 @@ // @Filename: referencesForGlobals_2.ts ////var m = [|globalAlias|]; -verify.singleReferenceGroup("import globalAlias = globalModule"); +verify.singleReferenceGroup("(alias) namespace globalAlias\nimport globalAlias = globalModule"); diff --git a/tests/cases/fourslash/referencesForMergedDeclarations2.ts b/tests/cases/fourslash/referencesForMergedDeclarations2.ts index 5cf9234511a..ba61d4c9061 100644 --- a/tests/cases/fourslash/referencesForMergedDeclarations2.ts +++ b/tests/cases/fourslash/referencesForMergedDeclarations2.ts @@ -11,4 +11,8 @@ ////var a: [|alias|].Bar; // namespace ////[|alias|].call(this); // value -verify.singleReferenceGroup("import alias = ATest"); +verify.singleReferenceGroup([ + "(alias) namespace alias", + "(alias) function alias(): void", + "import alias = ATest" +].join("\n")); diff --git a/tests/cases/fourslash/renameDefaultImport.ts b/tests/cases/fourslash/renameDefaultImport.ts index 086a05f6b99..3cf0c8b0880 100644 --- a/tests/cases/fourslash/renameDefaultImport.ts +++ b/tests/cases/fourslash/renameDefaultImport.ts @@ -18,7 +18,7 @@ const ranges = test.ranges(); const [C, B0, B1] = ranges; const classes = { definition: "class B", ranges: [C] }; -const imports = { definition: "import B", ranges: [B0, B1] }; +const imports = { definition: "(alias) class B\nimport B", ranges: [B0, B1] }; verify.referenceGroups(C, [classes, imports]); verify.referenceGroups(B0, [imports, classes]); verify.referenceGroups(B1, [ diff --git a/tests/cases/fourslash/renameDefaultImportDifferentName.ts b/tests/cases/fourslash/renameDefaultImportDifferentName.ts index ac44c26c443..75f80257e0b 100644 --- a/tests/cases/fourslash/renameDefaultImportDifferentName.ts +++ b/tests/cases/fourslash/renameDefaultImportDifferentName.ts @@ -18,7 +18,7 @@ const ranges = test.ranges(); const [C, B0, B1] = ranges; const bRanges = [B0, B1]; const classes = { definition: "class C", ranges: [C] }; -const imports = { definition: "import B", ranges: [B0, B1] }; +const imports = { definition: "(alias) class B\nimport B", ranges: [B0, B1] }; verify.referenceGroups(C, [classes, imports]); verify.referenceGroups(B0, [imports]); verify.referenceGroups(B1, [{ definition: "(alias) new B(): B\nimport B", ranges: bRanges }]); diff --git a/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts b/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts index 30feb0760e9..a961ebf2411 100644 --- a/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts +++ b/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts @@ -10,7 +10,7 @@ const ranges = test.ranges(); const [r0, r1, r2] = ranges; const vars = { definition: "var a: any", ranges: [r0] }; -const imports = { definition: "import a", ranges: [r1, r2] }; +const imports = { definition: "(alias) var a: any\nimport a", ranges: [r1, r2] }; verify.referenceGroups(r0, [vars, imports]); verify.referenceGroups(r1, [imports, vars]); verify.referenceGroups(r2, [imports, vars]); diff --git a/tests/cases/fourslash/renameImportOfExportEquals.ts b/tests/cases/fourslash/renameImportOfExportEquals.ts index 12cd86df647..65c65a62400 100644 --- a/tests/cases/fourslash/renameImportOfExportEquals.ts +++ b/tests/cases/fourslash/renameImportOfExportEquals.ts @@ -22,8 +22,8 @@ const bRanges = [b0, b1]; const xRanges = [x0, x1]; const nGroup = { definition: "namespace N", ranges: nRanges }; -const aGroup = { definition: "import N", ranges: aRanges }; -const bGroup = { definition: "import N", ranges: [b0, b1] }; +const aGroup = { definition: "(alias) namespace N\nimport N", ranges: aRanges }; +const bGroup = { definition: "(alias) namespace N\nimport N", ranges: [b0, b1] }; verify.referenceGroups(nRanges, [nGroup, aGroup, bGroup]); verify.referenceGroups([a0, a1], [aGroup, nGroup, bGroup]); diff --git a/tests/cases/fourslash/renameImportOfExportEquals2.ts b/tests/cases/fourslash/renameImportOfExportEquals2.ts index 8ac00b8c012..83ff1794bde 100644 --- a/tests/cases/fourslash/renameImportOfExportEquals2.ts +++ b/tests/cases/fourslash/renameImportOfExportEquals2.ts @@ -24,9 +24,9 @@ const pRanges = [P0, P1]; const qRanges = [Q0, Q1]; const ns = { definition: "namespace N", ranges: nRanges }; -const os = { definition: "import O", ranges: oRanges }; -const ps = { definition: "import P", ranges: pRanges }; -const qs = { definition: "import Q", ranges: qRanges }; +const os = { definition: "(alias) namespace O\nimport O", ranges: oRanges }; +const ps = { definition: "(alias) namespace P\nimport P", ranges: pRanges }; +const qs = { definition: "(alias) namespace Q\nimport Q", ranges: qRanges }; verify.referenceGroups(nRanges, [ns, os, ps, qs]); verify.referenceGroups(oRanges, [os, ps, qs]); diff --git a/tests/cases/fourslash/renameImportOfReExport.ts b/tests/cases/fourslash/renameImportOfReExport.ts index 3f8250b4d77..6afb953ad53 100644 --- a/tests/cases/fourslash/renameImportOfReExport.ts +++ b/tests/cases/fourslash/renameImportOfReExport.ts @@ -20,8 +20,8 @@ const ranges = test.ranges(); const [r0, r1, r2, r3] = ranges; const importRanges = [r2, r3]; const classes = { definition: "class C", ranges: [r0] }; -const bs = { definition: "import C", ranges: [r1] }; -const imports = { definition: "import C", ranges: importRanges }; +const bs = { definition: "(alias) class C\nimport 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]); verify.referenceGroups(importRanges, [imports, bs, classes]); diff --git a/tests/cases/fourslash/renameImportOfReExport2.ts b/tests/cases/fourslash/renameImportOfReExport2.ts index ac61200b2f0..bcaa0e41c8a 100644 --- a/tests/cases/fourslash/renameImportOfReExport2.ts +++ b/tests/cases/fourslash/renameImportOfReExport2.ts @@ -18,8 +18,8 @@ const cRanges = ranges.get("C"); const [d0, d1, d2] = ranges.get("D"); const classes = { definition: "class C", ranges: cRanges }; -const bImports = { definition: "import D", ranges: [d0] }; -const cImports = { definition: "import D", ranges: [d1, d2] }; +const bImports = { definition: "(alias) class D\nimport D", ranges: [d0] }; +const cImports = { definition: "(alias) class D\nimport D", ranges: [d1, d2] }; verify.referenceGroups(cRanges, [classes, bImports, cImports]); verify.referenceGroups(d0, [bImports, cImports]); diff --git a/tests/cases/fourslash/transitiveExportImports.ts b/tests/cases/fourslash/transitiveExportImports.ts index 093121c1d9e..68cca0c407b 100644 --- a/tests/cases/fourslash/transitiveExportImports.ts +++ b/tests/cases/fourslash/transitiveExportImports.ts @@ -21,7 +21,7 @@ const aRanges = [a0, a1]; const bRanges = [b0, c2]; const cRanges = [c0, c1]; -const bGroup = { definition: "import b = require('./a')", ranges: bRanges } +const bGroup = { definition: "(alias) class b\nimport b = require('./a')", ranges: bRanges } verify.referenceGroups(aRanges, [ { definition: "class A", ranges: aRanges }, diff --git a/tests/cases/fourslash/transitiveExportImports2.ts b/tests/cases/fourslash/transitiveExportImports2.ts index 397bbf44a37..73e1e828b0c 100644 --- a/tests/cases/fourslash/transitiveExportImports2.ts +++ b/tests/cases/fourslash/transitiveExportImports2.ts @@ -20,8 +20,8 @@ const bRanges = [B0, B1]; const cRanges = [B2]; const aGroup = { definition: "namespace A", ranges: aRanges }; -const bGroup = { definition: "import B = A", ranges: bRanges }; -const cGroup = { definition: "import B", ranges: cRanges }; +const bGroup = { definition: "(alias) namespace B\nimport B = A", ranges: bRanges }; +const cGroup = { definition: "(alias) namespace B\nimport B", ranges: cRanges }; verify.referenceGroups(aRanges, [aGroup, bGroup, cGroup]); verify.referenceGroups(bRanges, [bGroup, cGroup]); diff --git a/tests/cases/fourslash/transitiveExportImports3.ts b/tests/cases/fourslash/transitiveExportImports3.ts index 638fa85df83..abb7b2a2983 100644 --- a/tests/cases/fourslash/transitiveExportImports3.ts +++ b/tests/cases/fourslash/transitiveExportImports3.ts @@ -13,9 +13,9 @@ verify.noErrors(); const [f0, f1, g0, f2, g1] = test.ranges(); const af = { definition: "function f(): void", ranges: [f0, f1] }; -const g0Group = { definition: "import g", ranges: [g0] }; -const g1Group = { definition: "import g", ranges: [g1] }; -const bf = { definition: "import f", ranges: [f2] }; +const g0Group = { definition: "(alias) function g(): void\nimport 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] }; verify.referenceGroups([f0, f1], [af, g0Group, g1Group, bf]); verify.referenceGroups(g0, [g0Group, g1Group]); From cc7710c71c715eb60864b89e80da217e93a10cfa Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 4 Jan 2018 10:55:41 -0800 Subject: [PATCH 038/189] Add fourslash tests and update missed baselines --- .../isomorphicMappedTypeInference.js | 12 +--- .../reference/keyofAndIndexedAccess.js | 2 +- .../reference/thisTypeInObjectLiterals2.js | 8 +-- ...letionEntryForDeferredMappedTypeMembers.ts | 17 ++++++ .../quickInfoMappedTypeRecursiveInference.ts | 56 +++++++++++++++++++ 5 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 tests/cases/fourslash/completionEntryForDeferredMappedTypeMembers.ts create mode 100644 tests/cases/fourslash/quickInfoMappedTypeRecursiveInference.ts diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.js b/tests/baselines/reference/isomorphicMappedTypeInference.js index 9c4e8c9e9f1..d749e71c534 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.js +++ b/tests/baselines/reference/isomorphicMappedTypeInference.js @@ -310,17 +310,11 @@ declare type Spec = { */ declare function applySpec(obj: Spec): (...args: any[]) => T; declare var g1: (...args: any[]) => { - sum: number; - nested: { - mul: string; - }; + sum: {}; + nested: {}; }; declare var g2: (...args: any[]) => { - foo: { - bar: { - baz: boolean; - }; - }; + foo: {}; }; declare const foo: (object: T, partial: Partial) => T; declare let o: { diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index 530a2b8bbf3..bd9e1a44bfe 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -1105,7 +1105,7 @@ declare var hashOfEmpty1: { test: {}; }; declare var hashOfEmpty2: { - test: boolean; + test: {}; }; interface Options1 { data?: Data; diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.js b/tests/baselines/reference/thisTypeInObjectLiterals2.js index ca62ee37665..d614f0fa74c 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals2.js +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.js @@ -462,8 +462,8 @@ declare function defineProps(obj: T, descs: PropDescMap & ThisType): declare let p10: Point & Record<"foo", number>; declare let p11: Point & Record<"bar", number>; declare let p12: Point & { - foo: number; - bar: number; + foo: {}; + bar: {}; }; declare type Accessors = { [K in keyof T]: (() => T[K]) | Computed; @@ -487,6 +487,6 @@ declare let vue: { } & { f(x: string): number; } & { - test: number; - hello: string; + test: {}; + hello: {}; }; diff --git a/tests/cases/fourslash/completionEntryForDeferredMappedTypeMembers.ts b/tests/cases/fourslash/completionEntryForDeferredMappedTypeMembers.ts new file mode 100644 index 00000000000..785ac32ee39 --- /dev/null +++ b/tests/cases/fourslash/completionEntryForDeferredMappedTypeMembers.ts @@ -0,0 +1,17 @@ +/// +// @Filename: test.ts +//// interface A { a: A } +//// declare let a: A; +//// type Deep = { [K in keyof T]: Deep } +//// declare function foo(deep: Deep): T; +//// const out = foo(a); +//// out./*1*/a +//// out.a./*2*/a +//// out.a.a./*3*/a + +goTo.marker('1'); +verify.completionListCount(1); +goTo.marker('2'); +verify.completionListCount(1); +goTo.marker('3'); +verify.completionListCount(1); diff --git a/tests/cases/fourslash/quickInfoMappedTypeRecursiveInference.ts b/tests/cases/fourslash/quickInfoMappedTypeRecursiveInference.ts new file mode 100644 index 00000000000..84fd9da4ebe --- /dev/null +++ b/tests/cases/fourslash/quickInfoMappedTypeRecursiveInference.ts @@ -0,0 +1,56 @@ +/// +// @Filename: test.ts +//// interface A { a: A } +//// declare let a: A; +//// type Deep = { [K in keyof T]: Deep } +//// declare function foo(deep: Deep): T; +//// const out/*1*/ = foo/*2*/(a); +//// out.a/*3*/ +//// out.a.a/*4*/ +//// out.a.a.a.a.a.a.a/*5*/ +//// +//// interface B { [s: string]: B } +//// declare let b: B; +//// const oub/*6*/ = foo/*7*/(b); +//// oub.b/*8*/ +//// oub.b.b/*9*/ +//// oub.b.a.n.a.n.a/*10*/ + +verify.quickInfoAt('1', `const out: { + a: {}; +}`); +verify.quickInfoAt('2', `function foo<{ + a: {}; +}>(deep: Deep<{ + a: {}; +}>): { + a: {}; +}`); +verify.quickInfoAt('3', `(property) a: { + a: {}; +}`); +verify.quickInfoAt('4', `(property) a: { + a: {}; +}`); +verify.quickInfoAt('5', `(property) a: { + a: {}; +}`); +verify.quickInfoAt('6', `const oub: { + [x: string]: {}; +}`); +verify.quickInfoAt('7', `function foo<{ + [x: string]: {}; +}>(deep: Deep<{ + [x: string]: {}; +}>): { + [x: string]: {}; +}`); +verify.quickInfoAt('8', `{ + [x: string]: {}; +}`); +verify.quickInfoAt('9', `{ + [x: string]: {}; +}`); +verify.quickInfoAt('10', `{ + [x: string]: {}; +}`); From db82a5604a238abe494a1dcef10bd327dc36830c Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 4 Jan 2018 10:58:14 -0800 Subject: [PATCH 039/189] Improve find-all-references for redeclared property in a derived interface (#21002) --- src/services/findAllReferences.ts | 52 ++++++------------- ...cellationWhenfindingAllRefsOnDefinition.ts | 5 +- .../findAllRefsForObjectLiteralProperties.ts | 8 +-- .../fourslash/findAllRefsForObjectSpread.ts | 3 +- .../findAllRefsInheritedProperties1.ts | 6 +-- .../findAllRefsInheritedProperties3.ts | 8 +-- .../cases/fourslash/findAllRefsMappedType.ts | 7 +-- .../fourslash/findAllRefsOnDefinition.ts | 5 +- ...efsRedeclaredPropertyInDerivedInterface.ts | 30 +++++++++++ .../cases/fourslash/findAllRefsRootSymbols.ts | 3 +- .../cases/fourslash/findAllRefsThisKeyword.ts | 6 +-- .../findAllRefsWithLeadingUnderscoreNames1.ts | 8 +-- .../findAllRefsWithLeadingUnderscoreNames2.ts | 8 +-- .../findAllRefsWithLeadingUnderscoreNames3.ts | 8 +-- .../findAllRefsWithLeadingUnderscoreNames4.ts | 8 +-- ...dAllRefsWithShorthandPropertyAssignment.ts | 5 +- ...AllRefsWithShorthandPropertyAssignment2.ts | 5 +- ...currencesIsDefinitionOfComputedProperty.ts | 9 +--- ...rencesIsDefinitionOfNumberNamedProperty.ts | 8 +-- ...rencesIsDefinitionOfStringNamedProperty.ts | 8 +-- .../cases/fourslash/referencesBloomFilters.ts | 5 +- .../fourslash/referencesBloomFilters2.ts | 6 +-- .../fourslash/referencesForClassMembers.ts | 7 +-- ...esForClassMembersExtendingAbstractClass.ts | 7 +-- ...cesForClassMembersExtendingGenericClass.ts | 7 +-- .../fourslash/referencesForClassParameter.ts | 8 +-- .../referencesForInheritedProperties.ts | 8 +-- .../referencesForInheritedProperties2.ts | 8 +-- .../referencesForInheritedProperties4.ts | 8 +-- .../referencesForInheritedProperties6.ts | 7 +-- .../referencesForInheritedProperties7.ts | 3 +- .../referencesForObjectLiteralProperties.ts | 8 +-- .../referencesForPropertiesOfGenericType.ts | 10 +--- ...eferencesForStringLiteralPropertyNames2.ts | 9 +--- ...eferencesForStringLiteralPropertyNames3.ts | 8 +-- ...eferencesForStringLiteralPropertyNames4.ts | 3 +- .../fourslash/referencesForUnionProperties.ts | 3 +- .../shims-pp/getReferencesAtPosition.ts | 5 +- .../shims/getReferencesAtPosition.ts | 5 +- 39 files changed, 85 insertions(+), 240 deletions(-) create mode 100644 tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index fa56326b9f0..67752f2b78f 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -876,6 +876,8 @@ namespace ts.FindAllReferences.Core { case SpecialSearchKind.Class: addClassStaticThisReferences(referenceLocation, search, state); break; + default: + Debug.assertNever(state.specialSearchKind); } getImportOrExportReferences(referenceLocation, referenceSymbol, search, state); @@ -1436,7 +1438,7 @@ namespace ts.FindAllReferences.Core { // This is not needed when searching for re-exports. function populateSearchSymbolSet(symbol: Symbol, location: Node, checker: TypeChecker, implementations: boolean): Symbol[] { // The search set contains at least the current symbol - const result = [symbol]; + const result: Symbol[] = []; const containingObjectLiteralElement = getContainingObjectLiteralElement(location); if (containingObjectLiteralElement) { @@ -1453,9 +1455,9 @@ namespace ts.FindAllReferences.Core { // If the location is in a context sensitive location (i.e. in an object literal) try // to get a contextual type for it, and add the property symbol from the contextual // type to the search set - forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), contextualSymbol => { - addRange(result, checker.getRootSymbols(contextualSymbol)); - }); + for (const contextualSymbol of getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker)) { + addRootSymbols(contextualSymbol); + } /* Because in short-hand property assignment, location has two meaning : property name and as value of the property * When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of @@ -1496,9 +1498,7 @@ namespace ts.FindAllReferences.Core { // If this is a union property, add all the symbols from all its source symbols in all unioned types. // If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list for (const rootSymbol of checker.getRootSymbols(sym)) { - if (rootSymbol !== sym) { - result.push(rootSymbol); - } + result.push(rootSymbol); // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { @@ -1522,7 +1522,7 @@ namespace ts.FindAllReferences.Core { * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol. * The value of previousIterationSymbol is undefined when the function is first called. */ - function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[], previousIterationSymbolsCache: SymbolTable, checker: TypeChecker): void { + function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Push, previousIterationSymbolsCache: SymbolTable, checker: TypeChecker): void { if (!symbol) { return; } @@ -1591,9 +1591,7 @@ namespace ts.FindAllReferences.Core { // compare to our searchSymbol const containingObjectLiteralElement = getContainingObjectLiteralElement(referenceLocation); if (containingObjectLiteralElement) { - const contextualSymbol = forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), contextualSymbol => - find(checker.getRootSymbols(contextualSymbol), search.includes)); - + const contextualSymbol = firstDefined(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), findRootSymbol); if (contextualSymbol) { return contextualSymbol; } @@ -1622,7 +1620,7 @@ namespace ts.FindAllReferences.Core { function findRootSymbol(sym: Symbol): Symbol | undefined { // Unwrap symbols to get to the root (e.g. transient symbols as a result of widening) // Or a union property, use its underlying unioned symbols - return forEach(state.checker.getRootSymbols(sym), rootSymbol => { + return firstDefined(checker.getRootSymbols(sym), rootSymbol => { // if it is in the list, then we are done if (search.includes(rootSymbol)) { return rootSymbol; @@ -1633,12 +1631,12 @@ namespace ts.FindAllReferences.Core { // parent symbol if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { // Parents will only be defined if implementations is true - if (search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, state.checker))) { + if (search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, checker))) { return undefined; } const result: Symbol[] = []; - getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), state.checker); + getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), checker); return find(result, search.includes); } @@ -1660,28 +1658,12 @@ namespace ts.FindAllReferences.Core { } /** Gets all symbols for one property. Does not get symbols for every property. */ - function getPropertySymbolsFromContextualType(node: ObjectLiteralElement, checker: TypeChecker): Symbol[] | undefined { - const objectLiteral = node.parent; - const contextualType = checker.getContextualType(objectLiteral); + function getPropertySymbolsFromContextualType(node: ObjectLiteralElement, checker: TypeChecker): ReadonlyArray { + const contextualType = checker.getContextualType(node.parent); const name = getNameFromObjectLiteralElement(node); - if (name && contextualType) { - const result: Symbol[] = []; - const symbol = contextualType.getProperty(name); - if (symbol) { - result.push(symbol); - } - - if (contextualType.flags & TypeFlags.Union) { - forEach((contextualType).types, t => { - const symbol = t.getProperty(name); - if (symbol) { - result.push(symbol); - } - }); - } - return result; - } - return undefined; + const symbol = contextualType && name && contextualType.getProperty(name); + return symbol ? [symbol] : + contextualType && contextualType.flags & TypeFlags.Union ? mapDefined((contextualType).types, t => t.getProperty(name)) : emptyArray; } /** diff --git a/tests/cases/fourslash/cancellationWhenfindingAllRefsOnDefinition.ts b/tests/cases/fourslash/cancellationWhenfindingAllRefsOnDefinition.ts index 8f80c871eb3..13927f9d2dd 100644 --- a/tests/cases/fourslash/cancellationWhenfindingAllRefsOnDefinition.ts +++ b/tests/cases/fourslash/cancellationWhenfindingAllRefsOnDefinition.ts @@ -36,8 +36,5 @@ function checkRefs() { const ranges = test.ranges(); const [r0, r1] = ranges; verify.referenceGroups(r0, [{ definition: "(method) Test.start(): this", ranges }]); - verify.referenceGroups(r1, [ - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r0] }, - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r1] } - ]); + verify.referenceGroups(r1, [{ definition: "(method) Second.Test.start(): Second.Test", ranges }]); } diff --git a/tests/cases/fourslash/findAllRefsForObjectLiteralProperties.ts b/tests/cases/fourslash/findAllRefsForObjectLiteralProperties.ts index 125a11f19c4..2d9d9e267c5 100644 --- a/tests/cases/fourslash/findAllRefsForObjectLiteralProperties.ts +++ b/tests/cases/fourslash/findAllRefsForObjectLiteralProperties.ts @@ -8,10 +8,4 @@ //// ////let {[|property|]: pVar} = x; -const ranges = test.ranges(); -const [r0, r1, r2] = ranges; -verify.referenceGroups(r0, [{ definition: "(property) property: {}", ranges }]); -verify.referenceGroups([r1, r2], [ - { definition: "(property) property: {}", ranges: [r0] }, - { definition: "(property) property: {}", ranges: [r1, r2] } -]); +verify.singleReferenceGroup("(property) property: {}"); diff --git a/tests/cases/fourslash/findAllRefsForObjectSpread.ts b/tests/cases/fourslash/findAllRefsForObjectSpread.ts index c9c70edffd2..970806922ed 100644 --- a/tests/cases/fourslash/findAllRefsForObjectSpread.ts +++ b/tests/cases/fourslash/findAllRefsForObjectSpread.ts @@ -16,9 +16,8 @@ verify.referenceGroups(r1, [{ definition: "(property) A2.a: number", ranges: [r1 // but the resulting property refers to everything verify.referenceGroups(r2, [ - { definition: "(property) A1.a: string", ranges: [r0, r3] }, + { definition: "(property) A1.a: string", ranges: [r0, r2, r3] }, { definition: "(property) A2.a: number", ranges: [r1] }, - { definition: "(property) a: string | number", ranges: [r2] } ]); verify.referenceGroups(r3, [{ definition: "(property) A1.a: string", ranges: [r0, r2, r3] }]); diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties1.ts b/tests/cases/fourslash/findAllRefsInheritedProperties1.ts index 41acc117f9e..3b14e686cc6 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties1.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties1.ts @@ -10,9 +10,5 @@ //// v.[|propName|]; const [r0, r1, r2, r3] = test.ranges(); -verify.referenceGroups(r0, [{ definition: "(method) class1.doStuff(): void", ranges: [r0, r2] }]); -verify.referenceGroups(r2, [ - { definition: "(method) class1.doStuff(): void", ranges: [r0] }, - { definition: "(method) class1.doStuff(): void", ranges: [r2] } -]); +verify.singleReferenceGroup("(method) class1.doStuff(): void", [r0, r2]); verify.singleReferenceGroup("(property) class1.propName: string", [r1, r3]); diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties3.ts b/tests/cases/fourslash/findAllRefsInheritedProperties3.ts index cc82e4a4e44..a88943a7f54 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties3.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties3.ts @@ -22,7 +22,7 @@ verify.referenceGroups(r0, [{ definition: "(method) class1.doStuff(): void", ran verify.referenceGroups(r1, [{ definition: "(property) class1.propName: string", ranges: [r1, r5, r7] }]); verify.referenceGroups(r2, [{ definition: "(method) interface1.doStuff(): void", ranges: [r2, r4, r6] }]); verify.referenceGroups(r3, [{ definition: "(property) interface1.propName: string", ranges: [r3, r5, r7] }]); -verify.referenceGroups(r4, [ +verify.referenceGroups([r4, r6], [ { definition: "(method) class1.doStuff(): void", ranges: [r0] }, { definition: "(method) interface1.doStuff(): void", ranges: [r2] }, { definition: "(method) class2.doStuff(): void", ranges: [r4, r6] } @@ -32,9 +32,3 @@ verify.referenceGroups([r5, r7], [ { definition: "(property) interface1.propName: string", ranges: [r3] }, { definition: "(property) class2.propName: string", ranges: [r5, r7] } ]); -verify.referenceGroups(r6, [ - { definition: "(method) class1.doStuff(): void", ranges: [r0] }, - { definition: "(method) interface1.doStuff(): void", ranges: [r2] }, - { definition: "(method) class2.doStuff(): void", ranges: [r4] }, - { definition: "(method) class2.doStuff(): void", ranges: [r6] } -]); diff --git a/tests/cases/fourslash/findAllRefsMappedType.ts b/tests/cases/fourslash/findAllRefsMappedType.ts index 7daf0296d94..97658da08c1 100644 --- a/tests/cases/fourslash/findAllRefsMappedType.ts +++ b/tests/cases/fourslash/findAllRefsMappedType.ts @@ -7,9 +7,4 @@ ////declare const u: U; ////u.[|a|]; -const ranges = test.ranges(); -const [r0, r1, r2] = ranges; -verify.referenceGroups([r0, r1], [{ definition: "(property) T.a: number", ranges }]); -verify.referenceGroups(r2, [ - { definition: "(property) T.a: number", ranges: [r0, r1] }, - { definition: "(property) a: string", ranges: [r2] }]); +verify.singleReferenceGroup("(property) T.a: number"); diff --git a/tests/cases/fourslash/findAllRefsOnDefinition.ts b/tests/cases/fourslash/findAllRefsOnDefinition.ts index 7d136efc42a..99b402aba8c 100644 --- a/tests/cases/fourslash/findAllRefsOnDefinition.ts +++ b/tests/cases/fourslash/findAllRefsOnDefinition.ts @@ -26,7 +26,4 @@ const ranges = test.ranges(); const [r0, r1] = ranges; verify.referenceGroups(r0, [{ definition: "(method) Test.start(): this", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r0] }, - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r1] }, -]); +verify.referenceGroups(r1, [{ definition: "(method) Second.Test.start(): Second.Test", ranges }]); diff --git a/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts b/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts new file mode 100644 index 00000000000..4447c5a4641 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts @@ -0,0 +1,30 @@ +/// + +// @noLib: true + +////interface A { +//// readonly [|{| "isWriteAccess": true, "isDefinition": true |}x|]: number | string; +////} +////interface B extends A { +//// readonly [|{| "isWriteAccess": true, "isDefinition": true |}x|]: number; +////} +////const a: A = { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: 0 }; +////const b: B = { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: 0 }; + +const [r0, r1, r2, r3] = test.ranges(); +verify.referenceGroups(r0, [ + { definition: "(property) A.x: string | number", ranges: [r0, r1, r2, r3] }, +]); +verify.referenceGroups(r1, [ + { definition: "(property) A.x: string | number", ranges: [r0, r2] }, + { definition: "(property) B.x: number", ranges: [r1, r3] }, +]); +verify.referenceGroups(r2, [ + { definition: "(property) A.x: string | number", ranges: [r0, r1, r3] }, + { definition: "(property) x: number", ranges: [r2] }, +]); +verify.referenceGroups(r3, [ + { definition: "(property) A.x: string | number", ranges: [r0, r2] }, + { definition: "(property) B.x: number", ranges: [r1] }, + { definition: "(property) x: number", ranges: [r3] }, +]); diff --git a/tests/cases/fourslash/findAllRefsRootSymbols.ts b/tests/cases/fourslash/findAllRefsRootSymbols.ts index f72dcb54aef..05407b6a2e3 100644 --- a/tests/cases/fourslash/findAllRefsRootSymbols.ts +++ b/tests/cases/fourslash/findAllRefsRootSymbols.ts @@ -10,8 +10,7 @@ verify.referenceGroups(r0, [{ definition: "(property) I.x: {}", ranges: [r0, r3] verify.referenceGroups(r1, [{ definition: "(property) J.x: {}", ranges: [r1, r3] }]); verify.referenceGroups(r2, [{ definition: "(property) x: string", ranges: [r2, r3] }]); verify.referenceGroups(r3, [ - { definition: "(property) I.x: {}", ranges: [r0] }, + { definition: "(property) I.x: {}", ranges: [r0, r3] }, { definition: "(property) J.x: {}", ranges: [r1] }, { definition: "(property) x: string", ranges: [r2] }, - { definition: "(property) x: string & {}", ranges: [r3] }, ]); diff --git a/tests/cases/fourslash/findAllRefsThisKeyword.ts b/tests/cases/fourslash/findAllRefsThisKeyword.ts index 6f5374f902a..61dd687fd64 100644 --- a/tests/cases/fourslash/findAllRefsThisKeyword.ts +++ b/tests/cases/fourslash/findAllRefsThisKeyword.ts @@ -32,8 +32,4 @@ verify.referenceGroups(g0, [{ definition: "(parameter) this: any", ranges: [g0, verify.referenceGroups(g1, [{ definition: "this: any", ranges: [g0, g1] }]); verify.singleReferenceGroup("this: typeof C", [x, y]); verify.singleReferenceGroup("this: this", [constructor, method]); -verify.referenceGroups(propDef, [{ definition: "(property) this: number", ranges: [propDef, propUse] }]); -verify.referenceGroups(propUse, [ - { definition: "(property) this: number", ranges: [propDef] }, - { definition: "(property) this: number", ranges: [propUse] }, -]); +verify.singleReferenceGroup("(property) this: number", [propDef, propUse]); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames1.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames1.ts index d2baf7c96b3..4a1bf374c05 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames1.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames1.ts @@ -7,10 +7,4 @@ ////var x: Foo; ////x.[|_bar|]; -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: "(method) Foo._bar(): number", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Foo._bar(): number", ranges: [r0] }, - { definition: "(method) Foo._bar(): number", ranges: [r1] } -]); +verify.singleReferenceGroup("(method) Foo._bar(): number"); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames2.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames2.ts index 3f5cd9ddbed..ec120254fde 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames2.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames2.ts @@ -7,10 +7,4 @@ ////var x: Foo; ////x.[|__bar|]; -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: "(method) Foo.__bar(): number", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Foo.__bar(): number", ranges: [r0] }, - { definition: "(method) Foo.__bar(): number", ranges: [r1] } -]); +verify.singleReferenceGroup("(method) Foo.__bar(): number"); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames3.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames3.ts index e1870065325..e6f46b128e7 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames3.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames3.ts @@ -7,10 +7,4 @@ ////var x: Foo; ////x.[|___bar|]; -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: "(method) Foo.___bar(): number", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Foo.___bar(): number", ranges: [r0] }, - { definition: "(method) Foo.___bar(): number", ranges: [r1] } -]); +verify.singleReferenceGroup("(method) Foo.___bar(): number"); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames4.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames4.ts index 74eef0ae989..593d61f3fbe 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames4.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames4.ts @@ -7,10 +7,4 @@ ////var x: Foo; ////x.[|____bar|]; -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: "(method) Foo.____bar(): number", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Foo.____bar(): number", ranges: [r0] }, - { definition: "(method) Foo.____bar(): number", ranges: [r1] } -]); +verify.singleReferenceGroup("(method) Foo.____bar(): number"); diff --git a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts index 0c6f088d06b..897bf9f562a 100644 --- a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts +++ b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts @@ -13,7 +13,4 @@ verify.referenceGroups(r1, [ { definition: "(property) name: string", ranges: [r1, r4] } ]); verify.singleReferenceGroup("(property) name: string", [r2]); -verify.referenceGroups(r4, [ - { definition: "(property) name: string", ranges: [r1] }, - { definition: "(property) name: string", ranges: [r4] }, -]); +verify.referenceGroups(r4, [{ definition: "(property) name: string", ranges: [r1, r4] }]); diff --git a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts index d4f758696fe..0f9b95c75ed 100644 --- a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts +++ b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts @@ -16,7 +16,4 @@ verify.referenceGroups(r2, [ { definition: "var M.dx: any", ranges: [r1] }, { definition: "(property) dx: any", ranges: [r2, r3] } ]); -verify.referenceGroups(r3, [ - { definition: "(property) dx: any", ranges: [r2] }, - { definition: "(property) dx: any", ranges: [r3] } -]); +verify.referenceGroups(r3, [{ definition: "(property) dx: any", ranges: [r2, r3] }]); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts index 329a72c30fd..e4c3c93d0e1 100644 --- a/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts @@ -3,11 +3,4 @@ ////let y = o.[|foo|]; ////let z = o['[|foo|]']; -const ranges = test.ranges(); -const [r0, r1, r2] = ranges; -verify.referenceGroups(r0, [{ definition: '(property) ["foo"]: number', ranges }]); -verify.referenceGroups([r1, r2], [ - // TODO: these are the same thing, should be in the same group. - { definition: "(property) [\"foo\"]: number", ranges: [r0] }, - { definition: "(property) [\"foo\"]: number", ranges: [r1, r2] }, -]); +verify.singleReferenceGroup('(property) ["foo"]: number'); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts index b391deec9cc..33bdad09e1a 100644 --- a/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts @@ -2,10 +2,4 @@ ////let o = { [|{| "isWriteAccess": true, "isDefinition": true |}1|]: 12 }; ////let y = o[[|1|]]; -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: "(property) 1: number", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(property) 1: number", ranges: [r0] }, - { definition: "(property) 1: number", ranges: [r1] } -]); +verify.singleReferenceGroup("(property) 1: number"); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts index 4b842da6f59..cf88d476fef 100644 --- a/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts @@ -2,10 +2,4 @@ ////let o = { "[|{| "isWriteAccess": true, "isDefinition": true |}x|]": 12 }; ////let y = o.[|x|]; -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: '(property) "x": number', ranges }]); -verify.referenceGroups(r1, [ - { definition: '(property) "x": number', ranges: [r0] }, - { definition: '(property) "x": number', ranges: [r1] }, -]); +verify.singleReferenceGroup('(property) "x": number'); diff --git a/tests/cases/fourslash/referencesBloomFilters.ts b/tests/cases/fourslash/referencesBloomFilters.ts index 2745f6144ca..2f3fd02a827 100644 --- a/tests/cases/fourslash/referencesBloomFilters.ts +++ b/tests/cases/fourslash/referencesBloomFilters.ts @@ -17,10 +17,7 @@ const ranges = test.ranges(); const [r0, r1, r2, r3] = ranges; verify.referenceGroups(r0, [{ definition: "(property) searchProp: number", ranges }]); -verify.referenceGroups([r1, r2], [ - { definition: "(property) searchProp: number", ranges: [r0, r3] }, - { definition: "(property) searchProp: number", ranges: [r1, r2] } -]); +verify.referenceGroups([r1, r2], [{ definition: "(property) searchProp: number", ranges }]); verify.referenceGroups(r3, [ { definition: "(property) searchProp: number", ranges: [r0, r1, r2] }, { definition: '(property) "searchProp": number', ranges: [r3] } diff --git a/tests/cases/fourslash/referencesBloomFilters2.ts b/tests/cases/fourslash/referencesBloomFilters2.ts index 26690e437ee..3dea66b593d 100644 --- a/tests/cases/fourslash/referencesBloomFilters2.ts +++ b/tests/cases/fourslash/referencesBloomFilters2.ts @@ -16,11 +16,7 @@ const ranges = test.ranges(); const [r0, r1, r2, r3] = ranges; -verify.referenceGroups(r0, [{ definition: "(property) 42: number", ranges }]); -verify.referenceGroups([r1, r2], [ - { definition: "(property) 42: number", ranges: [r0, r3] }, - { definition: "(property) 42: number", ranges: [r1, r2] } -]); +verify.referenceGroups([r0, r1, r2], [{ definition: "(property) 42: number", ranges }]); verify.referenceGroups(r3, [ { definition: "(property) 42: number", ranges: [r0, r1, r2] }, { definition: '(property) "42": number', ranges: [r3] } diff --git a/tests/cases/fourslash/referencesForClassMembers.ts b/tests/cases/fourslash/referencesForClassMembers.ts index 0db4ebb0873..847ebcb84b6 100644 --- a/tests/cases/fourslash/referencesForClassMembers.ts +++ b/tests/cases/fourslash/referencesForClassMembers.ts @@ -25,12 +25,7 @@ verify.referenceGroups([a1, a2], [ const methods = ranges.get("method"); const [m0, m1, m2] = methods; verify.referenceGroups(m0, [{ definition: "(method) Base.method(): void", ranges: methods }]); -verify.referenceGroups(m1, [ +verify.referenceGroups([m1, m2], [ { definition: "(method) Base.method(): void", ranges: [m0] }, { definition: "(method) MyClass.method(): void", ranges: [m1, m2] } ]); -verify.referenceGroups(m2, [ - { definition: "(method) Base.method(): void", ranges: [m0] }, - { definition: "(method) MyClass.method(): void", ranges: [m1] }, - { definition: "(method) MyClass.method(): void", ranges: [m2] } -]); diff --git a/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts b/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts index b5be77a73bb..d42c0331469 100644 --- a/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts +++ b/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts @@ -25,12 +25,7 @@ verify.referenceGroups([a1, a2], [ const methods = ranges.get("method"); const [m0, m1, m2] = methods; verify.referenceGroups(m0, [{ definition: "(method) Base.method(): void", ranges: methods }]); -verify.referenceGroups(m1, [ +verify.referenceGroups([m1, m2], [ { definition: "(method) Base.method(): void", ranges: [m0] }, { definition: "(method) MyClass.method(): void", ranges: [m1, m2] } ]); -verify.referenceGroups(m2, [ - { definition: "(method) Base.method(): void", ranges: [m0] }, - { definition: "(method) MyClass.method(): void", ranges: [m1] }, - { definition: "(method) MyClass.method(): void", ranges: [m2] } -]); diff --git a/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts b/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts index 448c2627531..e995294a94d 100644 --- a/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts +++ b/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts @@ -25,12 +25,7 @@ verify.referenceGroups([a1, a2], [ const methods = ranges.get("method"); const [m0, m1, m2] = methods; verify.referenceGroups(m0, [{ definition: "(method) Base.method(a?: T, b?: U): this", ranges: methods }]); -verify.referenceGroups(m1, [ +verify.referenceGroups([m1, m2], [ { definition: "(method) Base.method(a?: T, b?: U): this", ranges: [m0] }, { definition: "(method) MyClass.method(): void", ranges: [m1, m2] } ]); -verify.referenceGroups(m2, [ - { definition: "(method) Base.method(a?: T, b?: U): this", ranges: [m0] }, - { definition: "(method) MyClass.method(): void", ranges: [m1] }, - { definition: "(method) MyClass.method(): void", ranges: [m2] } -]); diff --git a/tests/cases/fourslash/referencesForClassParameter.ts b/tests/cases/fourslash/referencesForClassParameter.ts index 24eb9e5496e..ec1e1bb2f0e 100644 --- a/tests/cases/fourslash/referencesForClassParameter.ts +++ b/tests/cases/fourslash/referencesForClassParameter.ts @@ -19,10 +19,4 @@ ////var n = new foo(undefined); ////n.[|{| "isWriteAccess": true |}p|] = null; -const ranges = test.ranges(); -const [r0, r1, r2] = ranges; -verify.referenceGroups([r0, r1], [{ definition: "(property) foo.p: any", ranges }]); -verify.referenceGroups(r2, [ - { definition: "(property) foo.p: any", ranges: [r0, r1] }, - { definition: "(property) foo.p: any", ranges: [r2] } -]); +verify.singleReferenceGroup("(property) foo.p: any"); diff --git a/tests/cases/fourslash/referencesForInheritedProperties.ts b/tests/cases/fourslash/referencesForInheritedProperties.ts index c2674fe1fe1..100fda73f89 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties.ts @@ -28,14 +28,8 @@ verify.referenceGroups(r1, [ { definition: "(method) interface1.doStuff(): void", ranges: [r0] }, { definition: "(method) interface2.doStuff(): void", ranges: [r1, r2, r3] } ]); -verify.referenceGroups(r2, [ +verify.referenceGroups([r2, r3], [ { definition: "(method) interface1.doStuff(): void", ranges: [r0] }, { definition: "(method) interface2.doStuff(): void", ranges: [r1] }, { definition: "(method) class1.doStuff(): void", ranges: [r2, r3] } ]); -verify.referenceGroups(r3, [ - { definition: "(method) interface1.doStuff(): void", ranges: [r0] }, - { definition: "(method) interface2.doStuff(): void", ranges: [r1] }, - { definition: "(method) class1.doStuff(): void", ranges: [r2] }, - { definition: "(method) class1.doStuff(): void", ranges: [r3] } -]); diff --git a/tests/cases/fourslash/referencesForInheritedProperties2.ts b/tests/cases/fourslash/referencesForInheritedProperties2.ts index 0f89a9aa744..39bc01e5eb6 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties2.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties2.ts @@ -33,14 +33,8 @@ verify.referenceGroups(r1, [ { definition: "(method) interface1.doStuff(): void", ranges: [r0] }, { definition: "(method) interface2.doStuff(): void", ranges: [r1, r2, r3] } ]); -verify.referenceGroups(r2, [ +verify.referenceGroups([r2, r3], [ { definition: "(method) interface1.doStuff(): void", ranges: [r0] }, { definition: "(method) interface2.doStuff(): void", ranges: [r1] }, { definition: "(method) class1.doStuff(): void", ranges: [r2, r3] } ]); -verify.referenceGroups(r3, [ - { definition: "(method) interface1.doStuff(): void", ranges: [r0] }, - { definition: "(method) interface2.doStuff(): void", ranges: [r1] }, - { definition: "(method) class1.doStuff(): void", ranges: [r2] }, - { definition: "(method) class1.doStuff(): void", ranges: [r3] } -]); diff --git a/tests/cases/fourslash/referencesForInheritedProperties4.ts b/tests/cases/fourslash/referencesForInheritedProperties4.ts index 8a822ec5238..adf8240ea31 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties4.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties4.ts @@ -11,11 +11,5 @@ const ranges = test.rangesByText(); const [r0, r1] = ranges.get("doStuff"); -verify.referenceGroups(r0, [ - { definition: "(method) class1.doStuff(): void", ranges: [r0, r1] }, -]); -verify.referenceGroups(r1, [ - { definition: "(method) class1.doStuff(): void", ranges: [r0] }, - { definition: "(method) class1.doStuff(): void", ranges: [r1] }, -]); +verify.singleReferenceGroup("(method) class1.doStuff(): void", ranges.get("doStuff")); verify.singleReferenceGroup("(property) class1.propName: string", ranges.get("propName")); diff --git a/tests/cases/fourslash/referencesForInheritedProperties6.ts b/tests/cases/fourslash/referencesForInheritedProperties6.ts index a39dc085c71..df1f0810018 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties6.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties6.ts @@ -16,12 +16,7 @@ const ranges = test.rangesByText(); const [m0, m1, m2] = ranges.get("doStuff"); verify.referenceGroups(m0, [{ definition: "(method) class1.doStuff(): void", ranges: [m0, m1, m2] }]); -verify.referenceGroups(m1, [ +verify.referenceGroups([m1, m2], [ { definition: "(method) class1.doStuff(): void", ranges: [m0] }, { definition: "(method) class2.doStuff(): void", ranges: [m1, m2] } ]); -verify.referenceGroups(m2, [ - { definition: "(method) class1.doStuff(): void", ranges: [m0] }, - { definition: "(method) class2.doStuff(): void", ranges: [m1] }, - { definition: "(method) class2.doStuff(): void", ranges: [m2] } -]); diff --git a/tests/cases/fourslash/referencesForInheritedProperties7.ts b/tests/cases/fourslash/referencesForInheritedProperties7.ts index 4911cbefd57..be92ced55aa 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties7.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties7.ts @@ -35,6 +35,5 @@ verify.referenceGroups([r5, r7], [ verify.referenceGroups(r6, [ { definition: "(method) class1.doStuff(): void", ranges: [r0] }, { definition: "(method) interface1.doStuff(): void", ranges: [r2] }, - { definition: "(method) class2.doStuff(): void", ranges: [r4] }, - { definition: "(method) class2.doStuff(): void", ranges: [r6] } + { definition: "(method) class2.doStuff(): void", ranges: [r4, r6] }, ]); diff --git a/tests/cases/fourslash/referencesForObjectLiteralProperties.ts b/tests/cases/fourslash/referencesForObjectLiteralProperties.ts index ea7c20829ae..804faaebe6e 100644 --- a/tests/cases/fourslash/referencesForObjectLiteralProperties.ts +++ b/tests/cases/fourslash/referencesForObjectLiteralProperties.ts @@ -8,10 +8,4 @@ ////var y = x; ////y.[|add|]; -const ranges = test.ranges(); -const [r0, r1, r2, r3] = ranges; -verify.referenceGroups(r0, [{ definition: "(property) add: number", ranges }]); -verify.referenceGroups([r1, r2, r3], [ - { definition: "(property) add: number", ranges: [r0] }, - { definition: "(property) add: number", ranges: [r1, r2, r3] } -]); +verify.singleReferenceGroup("(property) add: number"); diff --git a/tests/cases/fourslash/referencesForPropertiesOfGenericType.ts b/tests/cases/fourslash/referencesForPropertiesOfGenericType.ts index a92ac909782..34c84dba5ca 100644 --- a/tests/cases/fourslash/referencesForPropertiesOfGenericType.ts +++ b/tests/cases/fourslash/referencesForPropertiesOfGenericType.ts @@ -13,11 +13,5 @@ const ranges = test.ranges(); const [r0, r1, r2] = ranges; verify.referenceGroups(r0, [{ definition: "(method) IFoo.doSomething(v: T): T", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) IFoo.doSomething(v: string): string", ranges: [r0, r2] }, - { definition: "(method) IFoo.doSomething(v: string): string", ranges: [r1] } -]); -verify.referenceGroups(r2, [ - { definition: "(method) IFoo.doSomething(v: number): number", ranges: [r0, r1] }, - { definition: "(method) IFoo.doSomething(v: number): number", ranges: [r2] } -]); +verify.referenceGroups(r1, [{ definition: "(method) IFoo.doSomething(v: string): string", ranges }]); +verify.referenceGroups(r2, [{ definition: "(method) IFoo.doSomething(v: number): number", ranges }]); diff --git a/tests/cases/fourslash/referencesForStringLiteralPropertyNames2.ts b/tests/cases/fourslash/referencesForStringLiteralPropertyNames2.ts index 89b6c7c755e..ce5d474b9dc 100644 --- a/tests/cases/fourslash/referencesForStringLiteralPropertyNames2.ts +++ b/tests/cases/fourslash/referencesForStringLiteralPropertyNames2.ts @@ -7,11 +7,4 @@ ////var x: Foo; ////x.[|blah|]; -//verify.singleReferenceGroup('(method) Foo["blah"](): number'); -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: '(method) Foo["blah"](): number', ranges }]); -verify.referenceGroups(r1, [ - { definition: '(method) Foo["blah"](): number', ranges: [r0] }, - { definition: '(method) Foo["blah"](): number', ranges: [r1] } -]); +verify.singleReferenceGroup('(method) Foo["blah"](): number'); diff --git a/tests/cases/fourslash/referencesForStringLiteralPropertyNames3.ts b/tests/cases/fourslash/referencesForStringLiteralPropertyNames3.ts index aae15afd0c7..22fa6b30cbc 100644 --- a/tests/cases/fourslash/referencesForStringLiteralPropertyNames3.ts +++ b/tests/cases/fourslash/referencesForStringLiteralPropertyNames3.ts @@ -8,10 +8,4 @@ ////var y: Foo2; ////y[[|42|]]; -const ranges = test.ranges(); -const [r0, r1, r2] = ranges; -verify.referenceGroups([r0, r1], [{ definition: '(property) Foo2["42"]: number', ranges }]); -verify.referenceGroups(r2, [ - { definition: '(property) Foo2["42"]: number', ranges: [r0, r1] }, - { definition: '(property) Foo2["42"]: number', ranges: [r2] }, -]); +verify.singleReferenceGroup('(property) Foo2["42"]: number'); diff --git a/tests/cases/fourslash/referencesForStringLiteralPropertyNames4.ts b/tests/cases/fourslash/referencesForStringLiteralPropertyNames4.ts index c289a17c91c..a7589ba29a0 100644 --- a/tests/cases/fourslash/referencesForStringLiteralPropertyNames4.ts +++ b/tests/cases/fourslash/referencesForStringLiteralPropertyNames4.ts @@ -8,6 +8,5 @@ const ranges = test.ranges(); const [r0, r1, r2] = ranges; verify.referenceGroups(r0, [{ definition: '(property) "someProperty": number', ranges }]); verify.referenceGroups([r1, r2], [ - { definition: '(property) "someProperty": number', ranges: [r0] }, - { definition: '(property) "someProperty": number', ranges: [r1, r2] }, + { definition: '(property) "someProperty": number', ranges: [r0, r1, r2] }, ]); diff --git a/tests/cases/fourslash/referencesForUnionProperties.ts b/tests/cases/fourslash/referencesForUnionProperties.ts index 97570077346..2df9ce96844 100644 --- a/tests/cases/fourslash/referencesForUnionProperties.ts +++ b/tests/cases/fourslash/referencesForUnionProperties.ts @@ -30,8 +30,7 @@ verify.referenceGroups(hasAOrB, [ { definition: "(property) HasAOrB.a: string", ranges: [hasAOrB, x] } ]); verify.referenceGroups(x, [ - { definition: "(property) a: number", ranges: [one] }, + { definition: "(property) a: number", ranges: [one, x] }, { definition: "(property) Base.a: string", ranges: [base] }, { definition: "(property) HasAOrB.a: string", ranges: [hasAOrB] }, - { definition: "(property) a: string | number", ranges: [x] } ]); diff --git a/tests/cases/fourslash/shims-pp/getReferencesAtPosition.ts b/tests/cases/fourslash/shims-pp/getReferencesAtPosition.ts index fa9a510d5ac..0b333721914 100644 --- a/tests/cases/fourslash/shims-pp/getReferencesAtPosition.ts +++ b/tests/cases/fourslash/shims-pp/getReferencesAtPosition.ts @@ -26,7 +26,4 @@ const ranges = test.ranges(); const [r0, r1] = ranges; verify.referenceGroups(r0, [{ definition: "(method) Test.start(): this", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r0] }, - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r1] } -]); +verify.referenceGroups(r1, [{ definition: "(method) Second.Test.start(): Second.Test", ranges }]); diff --git a/tests/cases/fourslash/shims/getReferencesAtPosition.ts b/tests/cases/fourslash/shims/getReferencesAtPosition.ts index fa9a510d5ac..0b333721914 100644 --- a/tests/cases/fourslash/shims/getReferencesAtPosition.ts +++ b/tests/cases/fourslash/shims/getReferencesAtPosition.ts @@ -26,7 +26,4 @@ const ranges = test.ranges(); const [r0, r1] = ranges; verify.referenceGroups(r0, [{ definition: "(method) Test.start(): this", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r0] }, - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r1] } -]); +verify.referenceGroups(r1, [{ definition: "(method) Second.Test.start(): Second.Test", ranges }]); From aab5c262c2748c9d4b34c832e5f0af2d910fa402 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 4 Jan 2018 12:24:41 -0800 Subject: [PATCH 040/189] Remove unnecessary existence check (#21005) --- src/services/completions.ts | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index 15a99942c85..ed1933c3616 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -203,26 +203,24 @@ namespace ts.Completions { // Based on the order we add things we will always see locals first, then globals, then module exports. // So adding a completion for a local will prevent us from adding completions for external module exports sharing the same name. const uniques = createMap(); - if (symbols) { - for (const symbol of symbols) { - const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[getSymbolId(symbol)] : undefined; - const entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral, origin, recommendedCompletion); - if (!entry) { - continue; - } - - const { name } = entry; - if (uniques.has(name)) { - continue; - } - - // Latter case tests whether this is a global variable. - if (!origin && !(symbol.parent === undefined && !some(symbol.declarations, d => d.getSourceFile() === location.getSourceFile()))) { - uniques.set(name, true); - } - - entries.push(entry); + for (const symbol of symbols) { + const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[getSymbolId(symbol)] : undefined; + const entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral, origin, recommendedCompletion); + if (!entry) { + continue; } + + const { name } = entry; + if (uniques.has(name)) { + continue; + } + + // Latter case tests whether this is a global variable. + if (!origin && !(symbol.parent === undefined && !some(symbol.declarations, d => d.getSourceFile() === location.getSourceFile()))) { + uniques.set(name, true); + } + + entries.push(entry); } log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (timestamp() - start)); From 0427d0a72be99a943dbe47981821a6549642f80c Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 4 Jan 2018 12:25:00 -0800 Subject: [PATCH 041/189] Use 'mapDefined' array helper (#21006) --- src/services/findAllReferences.ts | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 67752f2b78f..68ada59125b 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -43,21 +43,10 @@ namespace ts.FindAllReferences { export function findReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray, sourceFile: SourceFile, position: number): ReferencedSymbol[] | undefined { const referencedSymbols = findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position); - - if (!referencedSymbols || !referencedSymbols.length) { - return undefined; - } - - const out: ReferencedSymbol[] = []; const checker = program.getTypeChecker(); - for (const { definition, references } of referencedSymbols) { + return !referencedSymbols || !referencedSymbols.length ? undefined : mapDefined(referencedSymbols, ({ definition, references }) => // Only include referenced symbols that have a valid definition. - if (definition) { - out.push({ definition: definitionToReferencedSymbolDefinitionInfo(definition, checker), references: references.map(toReferenceEntry) }); - } - } - - return out; + definition && { definition: definitionToReferencedSymbolDefinitionInfo(definition, checker), references: references.map(toReferenceEntry) }); } export function getImplementationsAtPosition(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray, sourceFile: SourceFile, position: number): ImplementationLocation[] { From 5e7ce21a9e7fbcd4b395e42aa921966346b9e485 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 4 Jan 2018 12:34:01 -0800 Subject: [PATCH 042/189] Print inferred mapped property types as any not {} This makes them compatible in d.ts and slightly less misleading in services. --- src/compiler/checker.ts | 8 +- .../isomorphicMappedTypeInference.js | 6 +- .../isomorphicMappedTypeInference.types | 44 +++---- .../reference/keyofAndIndexedAccess.js | 4 +- .../reference/keyofAndIndexedAccess.types | 8 +- .../mappedTypeInferenceErrors.errors.txt | 12 +- .../mappedTypeRecursiveInference.types | 124 +++++++++--------- .../reference/thisTypeInObjectLiterals2.js | 8 +- .../reference/thisTypeInObjectLiterals2.types | 30 ++--- 9 files changed, 122 insertions(+), 122 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bb30894d613..d21b15249ba 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2862,7 +2862,7 @@ namespace ts { } if (resolvedType.stringIndexInfo) { const indexInfo = resolvedType.objectFlags & ObjectFlags.Deferred ? - createIndexInfo(emptyObjectType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration) : + createIndexInfo(anyType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration) : resolvedType.stringIndexInfo; typeElements.push(indexInfoToIndexSignatureDeclarationHelper(indexInfo, IndexKind.String, context)); } @@ -2876,7 +2876,7 @@ namespace ts { } for (const propertySymbol of properties) { - const propertyType = getCheckFlags(propertySymbol) & CheckFlags.Deferred ? emptyObjectType : getTypeOfSymbol(propertySymbol); + const propertyType = getCheckFlags(propertySymbol) & CheckFlags.Deferred ? anyType : getTypeOfSymbol(propertySymbol); const saveEnclosingDeclaration = context.enclosingDeclaration; context.enclosingDeclaration = undefined; const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true); @@ -3686,7 +3686,7 @@ namespace ts { writer.writeLine(); } const stringIndexInfo = resolved.objectFlags & ObjectFlags.Deferred && resolved.stringIndexInfo ? - createIndexInfo(emptyObjectType, resolved.stringIndexInfo.isReadonly, resolved.stringIndexInfo.declaration) : + createIndexInfo(anyType, resolved.stringIndexInfo.isReadonly, resolved.stringIndexInfo.declaration) : resolved.stringIndexInfo; buildIndexSignatureDisplay(stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack); buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, IndexKind.Number, enclosingDeclaration, globalFlags, symbolStack); @@ -3699,7 +3699,7 @@ namespace ts { writer.reportPrivateInBaseOfClassExpression(symbolName(p)); } } - const t = getCheckFlags(p) & CheckFlags.Deferred ? emptyObjectType : getTypeOfSymbol(p); + const t = getCheckFlags(p) & CheckFlags.Deferred ? anyType : getTypeOfSymbol(p); if (p.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) { const signatures = getSignaturesOfType(t, SignatureKind.Call); for (const signature of signatures) { diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.js b/tests/baselines/reference/isomorphicMappedTypeInference.js index d749e71c534..aa000bc2913 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.js +++ b/tests/baselines/reference/isomorphicMappedTypeInference.js @@ -310,11 +310,11 @@ declare type Spec = { */ declare function applySpec(obj: Spec): (...args: any[]) => T; declare var g1: (...args: any[]) => { - sum: {}; - nested: {}; + sum: any; + nested: any; }; declare var g2: (...args: any[]) => { - foo: {}; + foo: any; }; declare const foo: (object: T, partial: Partial) => T; declare let o: { diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.types b/tests/baselines/reference/isomorphicMappedTypeInference.types index 1a78dff0e78..abb1bca93fc 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.types +++ b/tests/baselines/reference/isomorphicMappedTypeInference.types @@ -203,15 +203,15 @@ function f2() { }; let v = unboxify(b); ->v : { a: {}; b: {}; c: {}; } ->unboxify(b) : { a: {}; b: {}; c: {}; } +>v : { a: any; b: any; c: any; } +>unboxify(b) : { a: any; b: any; c: any; } >unboxify : (obj: Boxified) => T >b : { a: Box; b: Box; c: Box; } let x: number = v.a; >x : number >v.a : number ->v : { a: {}; b: {}; c: {}; } +>v : { a: any; b: any; c: any; } >a : number } @@ -277,11 +277,11 @@ function f4() { }; b = boxify(unboxify(b)); ->b = boxify(unboxify(b)) : Boxified<{ a: {}; b: {}; c: {}; }> +>b = boxify(unboxify(b)) : Boxified<{ a: any; b: any; c: any; }> >b : { a: Box; b: Box; c: Box; } ->boxify(unboxify(b)) : Boxified<{ a: {}; b: {}; c: {}; }> +>boxify(unboxify(b)) : Boxified<{ a: any; b: any; c: any; }> >boxify : (obj: T) => Boxified ->unboxify(b) : { a: {}; b: {}; c: {}; } +>unboxify(b) : { a: any; b: any; c: any; } >unboxify : (obj: Boxified) => T >b : { a: Box; b: Box; c: Box; } @@ -338,15 +338,15 @@ function f5(s: string) { }); let v = unboxify(b); ->v : { a: {}; b: {}; c: {}; } ->unboxify(b) : { a: {}; b: {}; c: {}; } +>v : { a: any; b: any; c: any; } +>unboxify(b) : { a: any; b: any; c: any; } >unboxify : (obj: Boxified) => T >b : { a: Box | Box | Box; b: Box | Box | Box; c: Box | Box | Box; } let x: string | number | boolean = v.a; >x : string | number | boolean >v.a : string | number | boolean ->v : { a: {}; b: {}; c: {}; } +>v : { a: any; b: any; c: any; } >a : string | number | boolean } @@ -391,15 +391,15 @@ function f6(s: string) { }); let v = unboxify(b); ->v : { [x: string]: {}; } ->unboxify(b) : { [x: string]: {}; } +>v : { [x: string]: any; } +>unboxify(b) : { [x: string]: any; } >unboxify : (obj: Boxified) => T >b : { [x: string]: Box | Box | Box; } let x: string | number | boolean = v[s]; >x : string | number | boolean >v[s] : string | number | boolean ->v : { [x: string]: {}; } +>v : { [x: string]: any; } >s : string } @@ -449,20 +449,20 @@ function f10(foo: Foo) { >Foo : Foo let x = validate(foo); // { a: number, readonly b: string } ->x : { a: {}; readonly b: {}; } ->validate(foo) : { a: {}; readonly b: {}; } +>x : { a: any; readonly b: any; } +>validate(foo) : { a: any; readonly b: any; } >validate : (obj: { [P in keyof T]?: T[P] | undefined; }) => T >foo : Foo let y = clone(foo); // { a?: number, b: string } ->y : { a?: {}; b: {}; } ->clone(foo) : { a?: {}; b: {}; } +>y : { a?: any; b: any; } +>clone(foo) : { a?: any; b: any; } >clone : (obj: { readonly [P in keyof T]: T[P]; }) => T >foo : Foo let z = validateAndClone(foo); // { a: number, b: string } ->z : { a: {}; b: {}; } ->validateAndClone(foo) : { a: {}; b: {}; } +>z : { a: any; b: any; } +>validateAndClone(foo) : { a: any; b: any; } >validateAndClone : (obj: { readonly [P in keyof T]?: T[P] | undefined; }) => T >foo : Foo } @@ -507,8 +507,8 @@ declare function applySpec(obj: Spec): (...args: any[]) => T; // Infers g1: (...args: any[]) => { sum: number, nested: { mul: string } } var g1 = applySpec({ ->g1 : (...args: any[]) => { sum: {}; nested: {}; } ->applySpec({ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }}) : (...args: any[]) => { sum: {}; nested: {}; } +>g1 : (...args: any[]) => { sum: any; nested: any; } +>applySpec({ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }}) : (...args: any[]) => { sum: any; nested: any; } >applySpec : (obj: Spec) => (...args: any[]) => T >{ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }} : { sum: (a: any) => number; nested: { mul: (b: any) => string; }; } @@ -532,8 +532,8 @@ var g1 = applySpec({ // Infers g2: (...args: any[]) => { foo: { bar: { baz: boolean } } } var g2 = applySpec({ foo: { bar: { baz: (x: any) => true } } }); ->g2 : (...args: any[]) => { foo: {}; } ->applySpec({ foo: { bar: { baz: (x: any) => true } } }) : (...args: any[]) => { foo: {}; } +>g2 : (...args: any[]) => { foo: any; } +>applySpec({ foo: { bar: { baz: (x: any) => true } } }) : (...args: any[]) => { foo: any; } >applySpec : (obj: Spec) => (...args: any[]) => T >{ foo: { bar: { baz: (x: any) => true } } } : { foo: { bar: { baz: (x: any) => boolean; }; }; } >foo : { bar: { baz: (x: any) => boolean; }; } diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index bd9e1a44bfe..8ea17554b35 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -1102,10 +1102,10 @@ declare type Handlers = { }; declare function on(handlerHash: Handlers): T; declare var hashOfEmpty1: { - test: {}; + test: any; }; declare var hashOfEmpty2: { - test: {}; + test: any; }; interface Options1 { data?: Data; diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 9e09c2a3c35..0e7da19c3e2 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -1793,16 +1793,16 @@ declare function on(handlerHash: Handlers): T >T : T var hashOfEmpty1 = on({ test: () => {} }); // {} ->hashOfEmpty1 : { test: {}; } ->on({ test: () => {} }) : { test: {}; } +>hashOfEmpty1 : { test: any; } +>on({ test: () => {} }) : { test: any; } >on : (handlerHash: Handlers) => T >{ test: () => {} } : { test: () => void; } >test : () => void >() => {} : () => void var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean } ->hashOfEmpty2 : { test: {}; } ->on({ test: (x: boolean) => {} }) : { test: {}; } +>hashOfEmpty2 : { test: any; } +>on({ test: (x: boolean) => {} }) : { test: any; } >on : (handlerHash: Handlers) => T >{ test: (x: boolean) => {} } : { test: (x: boolean) => void; } >test : (x: boolean) => void diff --git a/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt b/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt index 2293fd6bfd5..9b7efb94850 100644 --- a/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt +++ b/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: {}; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: {}; baz: {}; }>'. - Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: {}; baz: {}; }>; }'. +tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; } & ThisType<{ x: number; y: number; } & { bar: any; baz: any; }>'. + Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; }'. Types of property 'computed' are incompatible. - Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: {}; baz: {}; }>'. + Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: any; baz: any; }>'. Types of property 'baz' are incompatible. Type 'number' is not assignable to type '() => {}'. @@ -35,10 +35,10 @@ tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS ~~~~~ }); ~ -!!! error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: {}; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: {}; baz: {}; }>'. -!!! error TS2345: Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: {}; baz: {}; }>; }'. +!!! error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; } & ThisType<{ x: number; y: number; } & { bar: any; baz: any; }>'. +!!! error TS2345: Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; }'. !!! error TS2345: Types of property 'computed' are incompatible. -!!! error TS2345: Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: {}; baz: {}; }>'. +!!! error TS2345: Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: any; baz: any; }>'. !!! error TS2345: Types of property 'baz' are incompatible. !!! error TS2345: Type 'number' is not assignable to type '() => {}'. \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.types b/tests/baselines/reference/mappedTypeRecursiveInference.types index c48dda05f31..04995464f67 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.types +++ b/tests/baselines/reference/mappedTypeRecursiveInference.types @@ -26,39 +26,39 @@ declare function foo(deep: Deep): T; >T : T const out = foo(a); ->out : { a: {}; } ->foo(a) : { a: {}; } +>out : { a: any; } +>foo(a) : { a: any; } >foo : (deep: Deep) => T >a : A out.a ->out.a : { a: {}; } ->out : { a: {}; } ->a : { a: {}; } +>out.a : { a: any; } +>out : { a: any; } +>a : { a: any; } out.a.a ->out.a.a : { a: {}; } ->out.a : { a: {}; } ->out : { a: {}; } ->a : { a: {}; } ->a : { a: {}; } +>out.a.a : { a: any; } +>out.a : { a: any; } +>out : { a: any; } +>a : { a: any; } +>a : { a: any; } out.a.a.a.a.a.a.a ->out.a.a.a.a.a.a.a : { a: {}; } ->out.a.a.a.a.a.a : { a: {}; } ->out.a.a.a.a.a : { a: {}; } ->out.a.a.a.a : { a: {}; } ->out.a.a.a : { a: {}; } ->out.a.a : { a: {}; } ->out.a : { a: {}; } ->out : { a: {}; } ->a : { a: {}; } ->a : { a: {}; } ->a : { a: {}; } ->a : { a: {}; } ->a : { a: {}; } ->a : { a: {}; } ->a : { a: {}; } +>out.a.a.a.a.a.a.a : { a: any; } +>out.a.a.a.a.a.a : { a: any; } +>out.a.a.a.a.a : { a: any; } +>out.a.a.a.a : { a: any; } +>out.a.a.a : { a: any; } +>out.a.a : { a: any; } +>out.a : { a: any; } +>out : { a: any; } +>a : { a: any; } +>a : { a: any; } +>a : { a: any; } +>a : { a: any; } +>a : { a: any; } +>a : { a: any; } +>a : { a: any; } interface B { [s: string]: B } @@ -71,61 +71,61 @@ declare let b: B; >B : B const oub = foo(b); ->oub : { [x: string]: {}; } ->foo(b) : { [x: string]: {}; } +>oub : { [x: string]: any; } +>foo(b) : { [x: string]: any; } >foo : (deep: Deep) => T >b : B oub.b ->oub.b : { [x: string]: {}; } ->oub : { [x: string]: {}; } ->b : { [x: string]: {}; } +>oub.b : { [x: string]: any; } +>oub : { [x: string]: any; } +>b : { [x: string]: any; } oub.b.b ->oub.b.b : { [x: string]: {}; } ->oub.b : { [x: string]: {}; } ->oub : { [x: string]: {}; } ->b : { [x: string]: {}; } ->b : { [x: string]: {}; } +>oub.b.b : { [x: string]: any; } +>oub.b : { [x: string]: any; } +>oub : { [x: string]: any; } +>b : { [x: string]: any; } +>b : { [x: string]: any; } oub.b.a.n.a.n.a ->oub.b.a.n.a.n.a : { [x: string]: {}; } ->oub.b.a.n.a.n : { [x: string]: {}; } ->oub.b.a.n.a : { [x: string]: {}; } ->oub.b.a.n : { [x: string]: {}; } ->oub.b.a : { [x: string]: {}; } ->oub.b : { [x: string]: {}; } ->oub : { [x: string]: {}; } ->b : { [x: string]: {}; } ->a : { [x: string]: {}; } ->n : { [x: string]: {}; } ->a : { [x: string]: {}; } ->n : { [x: string]: {}; } ->a : { [x: string]: {}; } +>oub.b.a.n.a.n.a : { [x: string]: any; } +>oub.b.a.n.a.n : { [x: string]: any; } +>oub.b.a.n.a : { [x: string]: any; } +>oub.b.a.n : { [x: string]: any; } +>oub.b.a : { [x: string]: any; } +>oub.b : { [x: string]: any; } +>oub : { [x: string]: any; } +>b : { [x: string]: any; } +>a : { [x: string]: any; } +>n : { [x: string]: any; } +>a : { [x: string]: any; } +>n : { [x: string]: any; } +>a : { [x: string]: any; } let xhr: XMLHttpRequest; >xhr : XMLHttpRequest >XMLHttpRequest : XMLHttpRequest const out2 = foo(xhr); ->out2 : { onreadystatechange: {}; readonly readyState: {}; readonly response: {}; readonly responseText: {}; responseType: {}; readonly responseURL: {}; readonly responseXML: {}; readonly status: {}; readonly statusText: {}; timeout: {}; readonly upload: {}; withCredentials: {}; msCaching?: {}; abort: {}; getAllResponseHeaders: {}; getResponseHeader: {}; msCachingEnabled: {}; open: {}; overrideMimeType: {}; send: {}; setRequestHeader: {}; readonly DONE: {}; readonly HEADERS_RECEIVED: {}; readonly LOADING: {}; readonly OPENED: {}; readonly UNSENT: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; } ->foo(xhr) : { onreadystatechange: {}; readonly readyState: {}; readonly response: {}; readonly responseText: {}; responseType: {}; readonly responseURL: {}; readonly responseXML: {}; readonly status: {}; readonly statusText: {}; timeout: {}; readonly upload: {}; withCredentials: {}; msCaching?: {}; abort: {}; getAllResponseHeaders: {}; getResponseHeader: {}; msCachingEnabled: {}; open: {}; overrideMimeType: {}; send: {}; setRequestHeader: {}; readonly DONE: {}; readonly HEADERS_RECEIVED: {}; readonly LOADING: {}; readonly OPENED: {}; readonly UNSENT: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; } +>out2 : { onreadystatechange: any; readonly readyState: any; readonly response: any; readonly responseText: any; responseType: any; readonly responseURL: any; readonly responseXML: any; readonly status: any; readonly statusText: any; timeout: any; readonly upload: any; withCredentials: any; msCaching?: any; abort: any; getAllResponseHeaders: any; getResponseHeader: any; msCachingEnabled: any; open: any; overrideMimeType: any; send: any; setRequestHeader: any; readonly DONE: any; readonly HEADERS_RECEIVED: any; readonly LOADING: any; readonly OPENED: any; readonly UNSENT: any; addEventListener: any; removeEventListener: any; dispatchEvent: any; onabort: any; onerror: any; onload: any; onloadend: any; onloadstart: any; onprogress: any; ontimeout: any; } +>foo(xhr) : { onreadystatechange: any; readonly readyState: any; readonly response: any; readonly responseText: any; responseType: any; readonly responseURL: any; readonly responseXML: any; readonly status: any; readonly statusText: any; timeout: any; readonly upload: any; withCredentials: any; msCaching?: any; abort: any; getAllResponseHeaders: any; getResponseHeader: any; msCachingEnabled: any; open: any; overrideMimeType: any; send: any; setRequestHeader: any; readonly DONE: any; readonly HEADERS_RECEIVED: any; readonly LOADING: any; readonly OPENED: any; readonly UNSENT: any; addEventListener: any; removeEventListener: any; dispatchEvent: any; onabort: any; onerror: any; onload: any; onloadend: any; onloadstart: any; onprogress: any; ontimeout: any; } >foo : (deep: Deep) => T >xhr : XMLHttpRequest out2.responseXML ->out2.responseXML : { readonly activeElement: {}; alinkColor: {}; readonly all: {}; anchors: {}; applets: {}; bgColor: {}; body: {}; readonly characterSet: {}; charset: {}; readonly compatMode: {}; cookie: {}; readonly currentScript: {}; readonly defaultView: {}; designMode: {}; dir: {}; readonly doctype: {}; documentElement: {}; domain: {}; embeds: {}; fgColor: {}; forms: {}; readonly fullscreenElement: {}; readonly fullscreenEnabled: {}; readonly head: {}; readonly hidden: {}; images: {}; readonly implementation: {}; readonly inputEncoding: {}; readonly lastModified: {}; linkColor: {}; links: {}; readonly location: {}; msCapsLockWarningOff: {}; msCSSOMElementFloatMetrics: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforedeactivate: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onfullscreenchange: {}; onfullscreenerror: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmsmanipulationstatechanged: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onmssitemodejumplistitemremoved: {}; onmsthumbnailclick: {}; onpause: {}; onplay: {}; onplaying: {}; onpointerlockchange: {}; onpointerlockerror: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectionchange: {}; onselectstart: {}; onstalled: {}; onstop: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onvolumechange: {}; onwaiting: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; plugins: {}; readonly pointerLockElement: {}; readonly readyState: {}; readonly referrer: {}; readonly rootElement: {}; scripts: {}; readonly scrollingElement: {}; readonly styleSheets: {}; title: {}; readonly URL: {}; readonly URLUnencoded: {}; readonly visibilityState: {}; vlinkColor: {}; readonly webkitCurrentFullScreenElement: {}; readonly webkitFullscreenElement: {}; readonly webkitFullscreenEnabled: {}; readonly webkitIsFullScreen: {}; readonly xmlEncoding: {}; xmlStandalone: {}; xmlVersion: {}; adoptNode: {}; captureEvents: {}; caretRangeFromPoint: {}; clear: {}; close: {}; createAttribute: {}; createAttributeNS: {}; createCDATASection: {}; createComment: {}; createDocumentFragment: {}; createElement: {}; createElementNS: {}; createExpression: {}; createNodeIterator: {}; createNSResolver: {}; createProcessingInstruction: {}; createRange: {}; createTextNode: {}; createTouch: {}; createTouchList: {}; createTreeWalker: {}; elementFromPoint: {}; evaluate: {}; execCommand: {}; execCommandShowHelp: {}; exitFullscreen: {}; exitPointerLock: {}; focus: {}; getElementById: {}; getElementsByClassName: {}; getElementsByName: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; getSelection: {}; hasFocus: {}; importNode: {}; msElementsFromPoint: {}; msElementsFromRect: {}; open: {}; queryCommandEnabled: {}; queryCommandIndeterm: {}; queryCommandState: {}; queryCommandSupported: {}; queryCommandText: {}; queryCommandValue: {}; releaseEvents: {}; updateSettings: {}; webkitCancelFullScreen: {}; webkitExitFullscreen: {}; write: {}; writeln: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; querySelector: {}; querySelectorAll: {}; createEvent: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; readonly stylesheets: {}; elementsFromPoint: {}; } ->out2 : { onreadystatechange: {}; readonly readyState: {}; readonly response: {}; readonly responseText: {}; responseType: {}; readonly responseURL: {}; readonly responseXML: {}; readonly status: {}; readonly statusText: {}; timeout: {}; readonly upload: {}; withCredentials: {}; msCaching?: {}; abort: {}; getAllResponseHeaders: {}; getResponseHeader: {}; msCachingEnabled: {}; open: {}; overrideMimeType: {}; send: {}; setRequestHeader: {}; readonly DONE: {}; readonly HEADERS_RECEIVED: {}; readonly LOADING: {}; readonly OPENED: {}; readonly UNSENT: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; } ->responseXML : { readonly activeElement: {}; alinkColor: {}; readonly all: {}; anchors: {}; applets: {}; bgColor: {}; body: {}; readonly characterSet: {}; charset: {}; readonly compatMode: {}; cookie: {}; readonly currentScript: {}; readonly defaultView: {}; designMode: {}; dir: {}; readonly doctype: {}; documentElement: {}; domain: {}; embeds: {}; fgColor: {}; forms: {}; readonly fullscreenElement: {}; readonly fullscreenEnabled: {}; readonly head: {}; readonly hidden: {}; images: {}; readonly implementation: {}; readonly inputEncoding: {}; readonly lastModified: {}; linkColor: {}; links: {}; readonly location: {}; msCapsLockWarningOff: {}; msCSSOMElementFloatMetrics: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforedeactivate: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onfullscreenchange: {}; onfullscreenerror: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmsmanipulationstatechanged: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onmssitemodejumplistitemremoved: {}; onmsthumbnailclick: {}; onpause: {}; onplay: {}; onplaying: {}; onpointerlockchange: {}; onpointerlockerror: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectionchange: {}; onselectstart: {}; onstalled: {}; onstop: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onvolumechange: {}; onwaiting: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; plugins: {}; readonly pointerLockElement: {}; readonly readyState: {}; readonly referrer: {}; readonly rootElement: {}; scripts: {}; readonly scrollingElement: {}; readonly styleSheets: {}; title: {}; readonly URL: {}; readonly URLUnencoded: {}; readonly visibilityState: {}; vlinkColor: {}; readonly webkitCurrentFullScreenElement: {}; readonly webkitFullscreenElement: {}; readonly webkitFullscreenEnabled: {}; readonly webkitIsFullScreen: {}; readonly xmlEncoding: {}; xmlStandalone: {}; xmlVersion: {}; adoptNode: {}; captureEvents: {}; caretRangeFromPoint: {}; clear: {}; close: {}; createAttribute: {}; createAttributeNS: {}; createCDATASection: {}; createComment: {}; createDocumentFragment: {}; createElement: {}; createElementNS: {}; createExpression: {}; createNodeIterator: {}; createNSResolver: {}; createProcessingInstruction: {}; createRange: {}; createTextNode: {}; createTouch: {}; createTouchList: {}; createTreeWalker: {}; elementFromPoint: {}; evaluate: {}; execCommand: {}; execCommandShowHelp: {}; exitFullscreen: {}; exitPointerLock: {}; focus: {}; getElementById: {}; getElementsByClassName: {}; getElementsByName: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; getSelection: {}; hasFocus: {}; importNode: {}; msElementsFromPoint: {}; msElementsFromRect: {}; open: {}; queryCommandEnabled: {}; queryCommandIndeterm: {}; queryCommandState: {}; queryCommandSupported: {}; queryCommandText: {}; queryCommandValue: {}; releaseEvents: {}; updateSettings: {}; webkitCancelFullScreen: {}; webkitExitFullscreen: {}; write: {}; writeln: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; querySelector: {}; querySelectorAll: {}; createEvent: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; readonly stylesheets: {}; elementsFromPoint: {}; } +>out2.responseXML : { readonly activeElement: any; alinkColor: any; readonly all: any; anchors: any; applets: any; bgColor: any; body: any; readonly characterSet: any; charset: any; readonly compatMode: any; cookie: any; readonly currentScript: any; readonly defaultView: any; designMode: any; dir: any; readonly doctype: any; documentElement: any; domain: any; embeds: any; fgColor: any; forms: any; readonly fullscreenElement: any; readonly fullscreenEnabled: any; readonly head: any; readonly hidden: any; images: any; readonly implementation: any; readonly inputEncoding: any; readonly lastModified: any; linkColor: any; links: any; readonly location: any; msCapsLockWarningOff: any; msCSSOMElementFloatMetrics: any; onabort: any; onactivate: any; onbeforeactivate: any; onbeforedeactivate: any; onblur: any; oncanplay: any; oncanplaythrough: any; onchange: any; onclick: any; oncontextmenu: any; ondblclick: any; ondeactivate: any; ondrag: any; ondragend: any; ondragenter: any; ondragleave: any; ondragover: any; ondragstart: any; ondrop: any; ondurationchange: any; onemptied: any; onended: any; onerror: any; onfocus: any; onfullscreenchange: any; onfullscreenerror: any; oninput: any; oninvalid: any; onkeydown: any; onkeypress: any; onkeyup: any; onload: any; onloadeddata: any; onloadedmetadata: any; onloadstart: any; onmousedown: any; onmousemove: any; onmouseout: any; onmouseover: any; onmouseup: any; onmousewheel: any; onmscontentzoom: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsinertiastart: any; onmsmanipulationstatechanged: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; onmssitemodejumplistitemremoved: any; onmsthumbnailclick: any; onpause: any; onplay: any; onplaying: any; onpointerlockchange: any; onpointerlockerror: any; onprogress: any; onratechange: any; onreadystatechange: any; onreset: any; onscroll: any; onseeked: any; onseeking: any; onselect: any; onselectionchange: any; onselectstart: any; onstalled: any; onstop: any; onsubmit: any; onsuspend: any; ontimeupdate: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onvolumechange: any; onwaiting: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; plugins: any; readonly pointerLockElement: any; readonly readyState: any; readonly referrer: any; readonly rootElement: any; scripts: any; readonly scrollingElement: any; readonly styleSheets: any; title: any; readonly URL: any; readonly URLUnencoded: any; readonly visibilityState: any; vlinkColor: any; readonly webkitCurrentFullScreenElement: any; readonly webkitFullscreenElement: any; readonly webkitFullscreenEnabled: any; readonly webkitIsFullScreen: any; readonly xmlEncoding: any; xmlStandalone: any; xmlVersion: any; adoptNode: any; captureEvents: any; caretRangeFromPoint: any; clear: any; close: any; createAttribute: any; createAttributeNS: any; createCDATASection: any; createComment: any; createDocumentFragment: any; createElement: any; createElementNS: any; createExpression: any; createNodeIterator: any; createNSResolver: any; createProcessingInstruction: any; createRange: any; createTextNode: any; createTouch: any; createTouchList: any; createTreeWalker: any; elementFromPoint: any; evaluate: any; execCommand: any; execCommandShowHelp: any; exitFullscreen: any; exitPointerLock: any; focus: any; getElementById: any; getElementsByClassName: any; getElementsByName: any; getElementsByTagName: any; getElementsByTagNameNS: any; getSelection: any; hasFocus: any; importNode: any; msElementsFromPoint: any; msElementsFromRect: any; open: any; queryCommandEnabled: any; queryCommandIndeterm: any; queryCommandState: any; queryCommandSupported: any; queryCommandText: any; queryCommandValue: any; releaseEvents: any; updateSettings: any; webkitCancelFullScreen: any; webkitExitFullscreen: any; write: any; writeln: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; querySelector: any; querySelectorAll: any; createEvent: any; readonly children: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly childElementCount: any; readonly stylesheets: any; elementsFromPoint: any; } +>out2 : { onreadystatechange: any; readonly readyState: any; readonly response: any; readonly responseText: any; responseType: any; readonly responseURL: any; readonly responseXML: any; readonly status: any; readonly statusText: any; timeout: any; readonly upload: any; withCredentials: any; msCaching?: any; abort: any; getAllResponseHeaders: any; getResponseHeader: any; msCachingEnabled: any; open: any; overrideMimeType: any; send: any; setRequestHeader: any; readonly DONE: any; readonly HEADERS_RECEIVED: any; readonly LOADING: any; readonly OPENED: any; readonly UNSENT: any; addEventListener: any; removeEventListener: any; dispatchEvent: any; onabort: any; onerror: any; onload: any; onloadend: any; onloadstart: any; onprogress: any; ontimeout: any; } +>responseXML : { readonly activeElement: any; alinkColor: any; readonly all: any; anchors: any; applets: any; bgColor: any; body: any; readonly characterSet: any; charset: any; readonly compatMode: any; cookie: any; readonly currentScript: any; readonly defaultView: any; designMode: any; dir: any; readonly doctype: any; documentElement: any; domain: any; embeds: any; fgColor: any; forms: any; readonly fullscreenElement: any; readonly fullscreenEnabled: any; readonly head: any; readonly hidden: any; images: any; readonly implementation: any; readonly inputEncoding: any; readonly lastModified: any; linkColor: any; links: any; readonly location: any; msCapsLockWarningOff: any; msCSSOMElementFloatMetrics: any; onabort: any; onactivate: any; onbeforeactivate: any; onbeforedeactivate: any; onblur: any; oncanplay: any; oncanplaythrough: any; onchange: any; onclick: any; oncontextmenu: any; ondblclick: any; ondeactivate: any; ondrag: any; ondragend: any; ondragenter: any; ondragleave: any; ondragover: any; ondragstart: any; ondrop: any; ondurationchange: any; onemptied: any; onended: any; onerror: any; onfocus: any; onfullscreenchange: any; onfullscreenerror: any; oninput: any; oninvalid: any; onkeydown: any; onkeypress: any; onkeyup: any; onload: any; onloadeddata: any; onloadedmetadata: any; onloadstart: any; onmousedown: any; onmousemove: any; onmouseout: any; onmouseover: any; onmouseup: any; onmousewheel: any; onmscontentzoom: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsinertiastart: any; onmsmanipulationstatechanged: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; onmssitemodejumplistitemremoved: any; onmsthumbnailclick: any; onpause: any; onplay: any; onplaying: any; onpointerlockchange: any; onpointerlockerror: any; onprogress: any; onratechange: any; onreadystatechange: any; onreset: any; onscroll: any; onseeked: any; onseeking: any; onselect: any; onselectionchange: any; onselectstart: any; onstalled: any; onstop: any; onsubmit: any; onsuspend: any; ontimeupdate: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onvolumechange: any; onwaiting: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; plugins: any; readonly pointerLockElement: any; readonly readyState: any; readonly referrer: any; readonly rootElement: any; scripts: any; readonly scrollingElement: any; readonly styleSheets: any; title: any; readonly URL: any; readonly URLUnencoded: any; readonly visibilityState: any; vlinkColor: any; readonly webkitCurrentFullScreenElement: any; readonly webkitFullscreenElement: any; readonly webkitFullscreenEnabled: any; readonly webkitIsFullScreen: any; readonly xmlEncoding: any; xmlStandalone: any; xmlVersion: any; adoptNode: any; captureEvents: any; caretRangeFromPoint: any; clear: any; close: any; createAttribute: any; createAttributeNS: any; createCDATASection: any; createComment: any; createDocumentFragment: any; createElement: any; createElementNS: any; createExpression: any; createNodeIterator: any; createNSResolver: any; createProcessingInstruction: any; createRange: any; createTextNode: any; createTouch: any; createTouchList: any; createTreeWalker: any; elementFromPoint: any; evaluate: any; execCommand: any; execCommandShowHelp: any; exitFullscreen: any; exitPointerLock: any; focus: any; getElementById: any; getElementsByClassName: any; getElementsByName: any; getElementsByTagName: any; getElementsByTagNameNS: any; getSelection: any; hasFocus: any; importNode: any; msElementsFromPoint: any; msElementsFromRect: any; open: any; queryCommandEnabled: any; queryCommandIndeterm: any; queryCommandState: any; queryCommandSupported: any; queryCommandText: any; queryCommandValue: any; releaseEvents: any; updateSettings: any; webkitCancelFullScreen: any; webkitExitFullscreen: any; write: any; writeln: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; querySelector: any; querySelectorAll: any; createEvent: any; readonly children: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly childElementCount: any; readonly stylesheets: any; elementsFromPoint: any; } out2.responseXML.activeElement.className.length ->out2.responseXML.activeElement.className.length : { toString: {}; toFixed: {}; toExponential: {}; toPrecision: {}; valueOf: {}; toLocaleString: {}; } ->out2.responseXML.activeElement.className : { toString: {}; charAt: {}; charCodeAt: {}; concat: {}; indexOf: {}; lastIndexOf: {}; localeCompare: {}; match: {}; replace: {}; search: {}; slice: {}; split: {}; substring: {}; toLowerCase: {}; toLocaleLowerCase: {}; toUpperCase: {}; toLocaleUpperCase: {}; trim: {}; readonly length: {}; substr: {}; valueOf: {}; [Symbol.iterator]: {}; codePointAt: {}; includes: {}; endsWith: {}; normalize: {}; repeat: {}; startsWith: {}; anchor: {}; big: {}; blink: {}; bold: {}; fixed: {}; fontcolor: {}; fontsize: {}; italics: {}; link: {}; small: {}; strike: {}; sub: {}; sup: {}; } ->out2.responseXML.activeElement : { readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; } ->out2.responseXML : { readonly activeElement: {}; alinkColor: {}; readonly all: {}; anchors: {}; applets: {}; bgColor: {}; body: {}; readonly characterSet: {}; charset: {}; readonly compatMode: {}; cookie: {}; readonly currentScript: {}; readonly defaultView: {}; designMode: {}; dir: {}; readonly doctype: {}; documentElement: {}; domain: {}; embeds: {}; fgColor: {}; forms: {}; readonly fullscreenElement: {}; readonly fullscreenEnabled: {}; readonly head: {}; readonly hidden: {}; images: {}; readonly implementation: {}; readonly inputEncoding: {}; readonly lastModified: {}; linkColor: {}; links: {}; readonly location: {}; msCapsLockWarningOff: {}; msCSSOMElementFloatMetrics: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforedeactivate: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onfullscreenchange: {}; onfullscreenerror: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmsmanipulationstatechanged: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onmssitemodejumplistitemremoved: {}; onmsthumbnailclick: {}; onpause: {}; onplay: {}; onplaying: {}; onpointerlockchange: {}; onpointerlockerror: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectionchange: {}; onselectstart: {}; onstalled: {}; onstop: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onvolumechange: {}; onwaiting: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; plugins: {}; readonly pointerLockElement: {}; readonly readyState: {}; readonly referrer: {}; readonly rootElement: {}; scripts: {}; readonly scrollingElement: {}; readonly styleSheets: {}; title: {}; readonly URL: {}; readonly URLUnencoded: {}; readonly visibilityState: {}; vlinkColor: {}; readonly webkitCurrentFullScreenElement: {}; readonly webkitFullscreenElement: {}; readonly webkitFullscreenEnabled: {}; readonly webkitIsFullScreen: {}; readonly xmlEncoding: {}; xmlStandalone: {}; xmlVersion: {}; adoptNode: {}; captureEvents: {}; caretRangeFromPoint: {}; clear: {}; close: {}; createAttribute: {}; createAttributeNS: {}; createCDATASection: {}; createComment: {}; createDocumentFragment: {}; createElement: {}; createElementNS: {}; createExpression: {}; createNodeIterator: {}; createNSResolver: {}; createProcessingInstruction: {}; createRange: {}; createTextNode: {}; createTouch: {}; createTouchList: {}; createTreeWalker: {}; elementFromPoint: {}; evaluate: {}; execCommand: {}; execCommandShowHelp: {}; exitFullscreen: {}; exitPointerLock: {}; focus: {}; getElementById: {}; getElementsByClassName: {}; getElementsByName: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; getSelection: {}; hasFocus: {}; importNode: {}; msElementsFromPoint: {}; msElementsFromRect: {}; open: {}; queryCommandEnabled: {}; queryCommandIndeterm: {}; queryCommandState: {}; queryCommandSupported: {}; queryCommandText: {}; queryCommandValue: {}; releaseEvents: {}; updateSettings: {}; webkitCancelFullScreen: {}; webkitExitFullscreen: {}; write: {}; writeln: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; querySelector: {}; querySelectorAll: {}; createEvent: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; readonly stylesheets: {}; elementsFromPoint: {}; } ->out2 : { onreadystatechange: {}; readonly readyState: {}; readonly response: {}; readonly responseText: {}; responseType: {}; readonly responseURL: {}; readonly responseXML: {}; readonly status: {}; readonly statusText: {}; timeout: {}; readonly upload: {}; withCredentials: {}; msCaching?: {}; abort: {}; getAllResponseHeaders: {}; getResponseHeader: {}; msCachingEnabled: {}; open: {}; overrideMimeType: {}; send: {}; setRequestHeader: {}; readonly DONE: {}; readonly HEADERS_RECEIVED: {}; readonly LOADING: {}; readonly OPENED: {}; readonly UNSENT: {}; addEventListener: {}; removeEventListener: {}; dispatchEvent: {}; onabort: {}; onerror: {}; onload: {}; onloadend: {}; onloadstart: {}; onprogress: {}; ontimeout: {}; } ->responseXML : { readonly activeElement: {}; alinkColor: {}; readonly all: {}; anchors: {}; applets: {}; bgColor: {}; body: {}; readonly characterSet: {}; charset: {}; readonly compatMode: {}; cookie: {}; readonly currentScript: {}; readonly defaultView: {}; designMode: {}; dir: {}; readonly doctype: {}; documentElement: {}; domain: {}; embeds: {}; fgColor: {}; forms: {}; readonly fullscreenElement: {}; readonly fullscreenEnabled: {}; readonly head: {}; readonly hidden: {}; images: {}; readonly implementation: {}; readonly inputEncoding: {}; readonly lastModified: {}; linkColor: {}; links: {}; readonly location: {}; msCapsLockWarningOff: {}; msCSSOMElementFloatMetrics: {}; onabort: {}; onactivate: {}; onbeforeactivate: {}; onbeforedeactivate: {}; onblur: {}; oncanplay: {}; oncanplaythrough: {}; onchange: {}; onclick: {}; oncontextmenu: {}; ondblclick: {}; ondeactivate: {}; ondrag: {}; ondragend: {}; ondragenter: {}; ondragleave: {}; ondragover: {}; ondragstart: {}; ondrop: {}; ondurationchange: {}; onemptied: {}; onended: {}; onerror: {}; onfocus: {}; onfullscreenchange: {}; onfullscreenerror: {}; oninput: {}; oninvalid: {}; onkeydown: {}; onkeypress: {}; onkeyup: {}; onload: {}; onloadeddata: {}; onloadedmetadata: {}; onloadstart: {}; onmousedown: {}; onmousemove: {}; onmouseout: {}; onmouseover: {}; onmouseup: {}; onmousewheel: {}; onmscontentzoom: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsinertiastart: {}; onmsmanipulationstatechanged: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; onmssitemodejumplistitemremoved: {}; onmsthumbnailclick: {}; onpause: {}; onplay: {}; onplaying: {}; onpointerlockchange: {}; onpointerlockerror: {}; onprogress: {}; onratechange: {}; onreadystatechange: {}; onreset: {}; onscroll: {}; onseeked: {}; onseeking: {}; onselect: {}; onselectionchange: {}; onselectstart: {}; onstalled: {}; onstop: {}; onsubmit: {}; onsuspend: {}; ontimeupdate: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onvolumechange: {}; onwaiting: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; plugins: {}; readonly pointerLockElement: {}; readonly readyState: {}; readonly referrer: {}; readonly rootElement: {}; scripts: {}; readonly scrollingElement: {}; readonly styleSheets: {}; title: {}; readonly URL: {}; readonly URLUnencoded: {}; readonly visibilityState: {}; vlinkColor: {}; readonly webkitCurrentFullScreenElement: {}; readonly webkitFullscreenElement: {}; readonly webkitFullscreenEnabled: {}; readonly webkitIsFullScreen: {}; readonly xmlEncoding: {}; xmlStandalone: {}; xmlVersion: {}; adoptNode: {}; captureEvents: {}; caretRangeFromPoint: {}; clear: {}; close: {}; createAttribute: {}; createAttributeNS: {}; createCDATASection: {}; createComment: {}; createDocumentFragment: {}; createElement: {}; createElementNS: {}; createExpression: {}; createNodeIterator: {}; createNSResolver: {}; createProcessingInstruction: {}; createRange: {}; createTextNode: {}; createTouch: {}; createTouchList: {}; createTreeWalker: {}; elementFromPoint: {}; evaluate: {}; execCommand: {}; execCommandShowHelp: {}; exitFullscreen: {}; exitPointerLock: {}; focus: {}; getElementById: {}; getElementsByClassName: {}; getElementsByName: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; getSelection: {}; hasFocus: {}; importNode: {}; msElementsFromPoint: {}; msElementsFromRect: {}; open: {}; queryCommandEnabled: {}; queryCommandIndeterm: {}; queryCommandState: {}; queryCommandSupported: {}; queryCommandText: {}; queryCommandValue: {}; releaseEvents: {}; updateSettings: {}; webkitCancelFullScreen: {}; webkitExitFullscreen: {}; write: {}; writeln: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; querySelector: {}; querySelectorAll: {}; createEvent: {}; readonly children: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly childElementCount: {}; readonly stylesheets: {}; elementsFromPoint: {}; } ->activeElement : { readonly classList: {}; className: {}; readonly clientHeight: {}; readonly clientLeft: {}; readonly clientTop: {}; readonly clientWidth: {}; id: {}; innerHTML: {}; msContentZoomFactor: {}; readonly msRegionOverflow: {}; onariarequest: {}; oncommand: {}; ongotpointercapture: {}; onlostpointercapture: {}; onmsgesturechange: {}; onmsgesturedoubletap: {}; onmsgestureend: {}; onmsgesturehold: {}; onmsgesturestart: {}; onmsgesturetap: {}; onmsgotpointercapture: {}; onmsinertiastart: {}; onmslostpointercapture: {}; onmspointercancel: {}; onmspointerdown: {}; onmspointerenter: {}; onmspointerleave: {}; onmspointermove: {}; onmspointerout: {}; onmspointerover: {}; onmspointerup: {}; ontouchcancel: {}; ontouchend: {}; ontouchmove: {}; ontouchstart: {}; onwebkitfullscreenchange: {}; onwebkitfullscreenerror: {}; outerHTML: {}; readonly prefix: {}; readonly scrollHeight: {}; scrollLeft: {}; scrollTop: {}; readonly scrollWidth: {}; readonly tagName: {}; readonly assignedSlot: {}; slot: {}; readonly shadowRoot: {}; getAttribute: {}; getAttributeNode: {}; getAttributeNodeNS: {}; getAttributeNS: {}; getBoundingClientRect: {}; getClientRects: {}; getElementsByTagName: {}; getElementsByTagNameNS: {}; hasAttribute: {}; hasAttributeNS: {}; msGetRegionContent: {}; msGetUntransformedBounds: {}; msMatchesSelector: {}; msReleasePointerCapture: {}; msSetPointerCapture: {}; msZoomTo: {}; releasePointerCapture: {}; removeAttribute: {}; removeAttributeNode: {}; removeAttributeNS: {}; requestFullscreen: {}; requestPointerLock: {}; setAttribute: {}; setAttributeNode: {}; setAttributeNodeNS: {}; setAttributeNS: {}; setPointerCapture: {}; webkitMatchesSelector: {}; webkitRequestFullscreen: {}; webkitRequestFullScreen: {}; getElementsByClassName: {}; matches: {}; closest: {}; scrollIntoView: {}; scroll: {}; scrollTo: {}; scrollBy: {}; insertAdjacentElement: {}; insertAdjacentHTML: {}; insertAdjacentText: {}; attachShadow: {}; addEventListener: {}; removeEventListener: {}; readonly attributes: {}; readonly baseURI: {}; readonly childNodes: {}; readonly firstChild: {}; readonly lastChild: {}; readonly localName: {}; readonly namespaceURI: {}; readonly nextSibling: {}; readonly nodeName: {}; readonly nodeType: {}; nodeValue: {}; readonly ownerDocument: {}; readonly parentElement: {}; readonly parentNode: {}; readonly previousSibling: {}; textContent: {}; appendChild: {}; cloneNode: {}; compareDocumentPosition: {}; contains: {}; hasAttributes: {}; hasChildNodes: {}; insertBefore: {}; isDefaultNamespace: {}; isEqualNode: {}; isSameNode: {}; lookupNamespaceURI: {}; lookupPrefix: {}; normalize: {}; removeChild: {}; replaceChild: {}; readonly ATTRIBUTE_NODE: {}; readonly CDATA_SECTION_NODE: {}; readonly COMMENT_NODE: {}; readonly DOCUMENT_FRAGMENT_NODE: {}; readonly DOCUMENT_NODE: {}; readonly DOCUMENT_POSITION_CONTAINED_BY: {}; readonly DOCUMENT_POSITION_CONTAINS: {}; readonly DOCUMENT_POSITION_DISCONNECTED: {}; readonly DOCUMENT_POSITION_FOLLOWING: {}; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: {}; readonly DOCUMENT_POSITION_PRECEDING: {}; readonly DOCUMENT_TYPE_NODE: {}; readonly ELEMENT_NODE: {}; readonly ENTITY_NODE: {}; readonly ENTITY_REFERENCE_NODE: {}; readonly NOTATION_NODE: {}; readonly PROCESSING_INSTRUCTION_NODE: {}; readonly TEXT_NODE: {}; dispatchEvent: {}; onpointercancel: {}; onpointerdown: {}; onpointerenter: {}; onpointerleave: {}; onpointermove: {}; onpointerout: {}; onpointerover: {}; onpointerup: {}; onwheel: {}; readonly childElementCount: {}; readonly firstElementChild: {}; readonly lastElementChild: {}; readonly nextElementSibling: {}; readonly previousElementSibling: {}; querySelector: {}; querySelectorAll: {}; remove: {}; readonly children: {}; } ->className : { toString: {}; charAt: {}; charCodeAt: {}; concat: {}; indexOf: {}; lastIndexOf: {}; localeCompare: {}; match: {}; replace: {}; search: {}; slice: {}; split: {}; substring: {}; toLowerCase: {}; toLocaleLowerCase: {}; toUpperCase: {}; toLocaleUpperCase: {}; trim: {}; readonly length: {}; substr: {}; valueOf: {}; [Symbol.iterator]: {}; codePointAt: {}; includes: {}; endsWith: {}; normalize: {}; repeat: {}; startsWith: {}; anchor: {}; big: {}; blink: {}; bold: {}; fixed: {}; fontcolor: {}; fontsize: {}; italics: {}; link: {}; small: {}; strike: {}; sub: {}; sup: {}; } ->length : { toString: {}; toFixed: {}; toExponential: {}; toPrecision: {}; valueOf: {}; toLocaleString: {}; } +>out2.responseXML.activeElement.className.length : { toString: any; toFixed: any; toExponential: any; toPrecision: any; valueOf: any; toLocaleString: any; } +>out2.responseXML.activeElement.className : { toString: any; charAt: any; charCodeAt: any; concat: any; indexOf: any; lastIndexOf: any; localeCompare: any; match: any; replace: any; search: any; slice: any; split: any; substring: any; toLowerCase: any; toLocaleLowerCase: any; toUpperCase: any; toLocaleUpperCase: any; trim: any; readonly length: any; substr: any; valueOf: any; [Symbol.iterator]: any; codePointAt: any; includes: any; endsWith: any; normalize: any; repeat: any; startsWith: any; anchor: any; big: any; blink: any; bold: any; fixed: any; fontcolor: any; fontsize: any; italics: any; link: any; small: any; strike: any; sub: any; sup: any; } +>out2.responseXML.activeElement : { readonly classList: any; className: any; readonly clientHeight: any; readonly clientLeft: any; readonly clientTop: any; readonly clientWidth: any; id: any; innerHTML: any; msContentZoomFactor: any; readonly msRegionOverflow: any; onariarequest: any; oncommand: any; ongotpointercapture: any; onlostpointercapture: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsgotpointercapture: any; onmsinertiastart: any; onmslostpointercapture: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; outerHTML: any; readonly prefix: any; readonly scrollHeight: any; scrollLeft: any; scrollTop: any; readonly scrollWidth: any; readonly tagName: any; readonly assignedSlot: any; slot: any; readonly shadowRoot: any; getAttribute: any; getAttributeNode: any; getAttributeNodeNS: any; getAttributeNS: any; getBoundingClientRect: any; getClientRects: any; getElementsByTagName: any; getElementsByTagNameNS: any; hasAttribute: any; hasAttributeNS: any; msGetRegionContent: any; msGetUntransformedBounds: any; msMatchesSelector: any; msReleasePointerCapture: any; msSetPointerCapture: any; msZoomTo: any; releasePointerCapture: any; removeAttribute: any; removeAttributeNode: any; removeAttributeNS: any; requestFullscreen: any; requestPointerLock: any; setAttribute: any; setAttributeNode: any; setAttributeNodeNS: any; setAttributeNS: any; setPointerCapture: any; webkitMatchesSelector: any; webkitRequestFullscreen: any; webkitRequestFullScreen: any; getElementsByClassName: any; matches: any; closest: any; scrollIntoView: any; scroll: any; scrollTo: any; scrollBy: any; insertAdjacentElement: any; insertAdjacentHTML: any; insertAdjacentText: any; attachShadow: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; readonly childElementCount: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly nextElementSibling: any; readonly previousElementSibling: any; querySelector: any; querySelectorAll: any; remove: any; readonly children: any; } +>out2.responseXML : { readonly activeElement: any; alinkColor: any; readonly all: any; anchors: any; applets: any; bgColor: any; body: any; readonly characterSet: any; charset: any; readonly compatMode: any; cookie: any; readonly currentScript: any; readonly defaultView: any; designMode: any; dir: any; readonly doctype: any; documentElement: any; domain: any; embeds: any; fgColor: any; forms: any; readonly fullscreenElement: any; readonly fullscreenEnabled: any; readonly head: any; readonly hidden: any; images: any; readonly implementation: any; readonly inputEncoding: any; readonly lastModified: any; linkColor: any; links: any; readonly location: any; msCapsLockWarningOff: any; msCSSOMElementFloatMetrics: any; onabort: any; onactivate: any; onbeforeactivate: any; onbeforedeactivate: any; onblur: any; oncanplay: any; oncanplaythrough: any; onchange: any; onclick: any; oncontextmenu: any; ondblclick: any; ondeactivate: any; ondrag: any; ondragend: any; ondragenter: any; ondragleave: any; ondragover: any; ondragstart: any; ondrop: any; ondurationchange: any; onemptied: any; onended: any; onerror: any; onfocus: any; onfullscreenchange: any; onfullscreenerror: any; oninput: any; oninvalid: any; onkeydown: any; onkeypress: any; onkeyup: any; onload: any; onloadeddata: any; onloadedmetadata: any; onloadstart: any; onmousedown: any; onmousemove: any; onmouseout: any; onmouseover: any; onmouseup: any; onmousewheel: any; onmscontentzoom: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsinertiastart: any; onmsmanipulationstatechanged: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; onmssitemodejumplistitemremoved: any; onmsthumbnailclick: any; onpause: any; onplay: any; onplaying: any; onpointerlockchange: any; onpointerlockerror: any; onprogress: any; onratechange: any; onreadystatechange: any; onreset: any; onscroll: any; onseeked: any; onseeking: any; onselect: any; onselectionchange: any; onselectstart: any; onstalled: any; onstop: any; onsubmit: any; onsuspend: any; ontimeupdate: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onvolumechange: any; onwaiting: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; plugins: any; readonly pointerLockElement: any; readonly readyState: any; readonly referrer: any; readonly rootElement: any; scripts: any; readonly scrollingElement: any; readonly styleSheets: any; title: any; readonly URL: any; readonly URLUnencoded: any; readonly visibilityState: any; vlinkColor: any; readonly webkitCurrentFullScreenElement: any; readonly webkitFullscreenElement: any; readonly webkitFullscreenEnabled: any; readonly webkitIsFullScreen: any; readonly xmlEncoding: any; xmlStandalone: any; xmlVersion: any; adoptNode: any; captureEvents: any; caretRangeFromPoint: any; clear: any; close: any; createAttribute: any; createAttributeNS: any; createCDATASection: any; createComment: any; createDocumentFragment: any; createElement: any; createElementNS: any; createExpression: any; createNodeIterator: any; createNSResolver: any; createProcessingInstruction: any; createRange: any; createTextNode: any; createTouch: any; createTouchList: any; createTreeWalker: any; elementFromPoint: any; evaluate: any; execCommand: any; execCommandShowHelp: any; exitFullscreen: any; exitPointerLock: any; focus: any; getElementById: any; getElementsByClassName: any; getElementsByName: any; getElementsByTagName: any; getElementsByTagNameNS: any; getSelection: any; hasFocus: any; importNode: any; msElementsFromPoint: any; msElementsFromRect: any; open: any; queryCommandEnabled: any; queryCommandIndeterm: any; queryCommandState: any; queryCommandSupported: any; queryCommandText: any; queryCommandValue: any; releaseEvents: any; updateSettings: any; webkitCancelFullScreen: any; webkitExitFullscreen: any; write: any; writeln: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; querySelector: any; querySelectorAll: any; createEvent: any; readonly children: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly childElementCount: any; readonly stylesheets: any; elementsFromPoint: any; } +>out2 : { onreadystatechange: any; readonly readyState: any; readonly response: any; readonly responseText: any; responseType: any; readonly responseURL: any; readonly responseXML: any; readonly status: any; readonly statusText: any; timeout: any; readonly upload: any; withCredentials: any; msCaching?: any; abort: any; getAllResponseHeaders: any; getResponseHeader: any; msCachingEnabled: any; open: any; overrideMimeType: any; send: any; setRequestHeader: any; readonly DONE: any; readonly HEADERS_RECEIVED: any; readonly LOADING: any; readonly OPENED: any; readonly UNSENT: any; addEventListener: any; removeEventListener: any; dispatchEvent: any; onabort: any; onerror: any; onload: any; onloadend: any; onloadstart: any; onprogress: any; ontimeout: any; } +>responseXML : { readonly activeElement: any; alinkColor: any; readonly all: any; anchors: any; applets: any; bgColor: any; body: any; readonly characterSet: any; charset: any; readonly compatMode: any; cookie: any; readonly currentScript: any; readonly defaultView: any; designMode: any; dir: any; readonly doctype: any; documentElement: any; domain: any; embeds: any; fgColor: any; forms: any; readonly fullscreenElement: any; readonly fullscreenEnabled: any; readonly head: any; readonly hidden: any; images: any; readonly implementation: any; readonly inputEncoding: any; readonly lastModified: any; linkColor: any; links: any; readonly location: any; msCapsLockWarningOff: any; msCSSOMElementFloatMetrics: any; onabort: any; onactivate: any; onbeforeactivate: any; onbeforedeactivate: any; onblur: any; oncanplay: any; oncanplaythrough: any; onchange: any; onclick: any; oncontextmenu: any; ondblclick: any; ondeactivate: any; ondrag: any; ondragend: any; ondragenter: any; ondragleave: any; ondragover: any; ondragstart: any; ondrop: any; ondurationchange: any; onemptied: any; onended: any; onerror: any; onfocus: any; onfullscreenchange: any; onfullscreenerror: any; oninput: any; oninvalid: any; onkeydown: any; onkeypress: any; onkeyup: any; onload: any; onloadeddata: any; onloadedmetadata: any; onloadstart: any; onmousedown: any; onmousemove: any; onmouseout: any; onmouseover: any; onmouseup: any; onmousewheel: any; onmscontentzoom: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsinertiastart: any; onmsmanipulationstatechanged: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; onmssitemodejumplistitemremoved: any; onmsthumbnailclick: any; onpause: any; onplay: any; onplaying: any; onpointerlockchange: any; onpointerlockerror: any; onprogress: any; onratechange: any; onreadystatechange: any; onreset: any; onscroll: any; onseeked: any; onseeking: any; onselect: any; onselectionchange: any; onselectstart: any; onstalled: any; onstop: any; onsubmit: any; onsuspend: any; ontimeupdate: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onvolumechange: any; onwaiting: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; plugins: any; readonly pointerLockElement: any; readonly readyState: any; readonly referrer: any; readonly rootElement: any; scripts: any; readonly scrollingElement: any; readonly styleSheets: any; title: any; readonly URL: any; readonly URLUnencoded: any; readonly visibilityState: any; vlinkColor: any; readonly webkitCurrentFullScreenElement: any; readonly webkitFullscreenElement: any; readonly webkitFullscreenEnabled: any; readonly webkitIsFullScreen: any; readonly xmlEncoding: any; xmlStandalone: any; xmlVersion: any; adoptNode: any; captureEvents: any; caretRangeFromPoint: any; clear: any; close: any; createAttribute: any; createAttributeNS: any; createCDATASection: any; createComment: any; createDocumentFragment: any; createElement: any; createElementNS: any; createExpression: any; createNodeIterator: any; createNSResolver: any; createProcessingInstruction: any; createRange: any; createTextNode: any; createTouch: any; createTouchList: any; createTreeWalker: any; elementFromPoint: any; evaluate: any; execCommand: any; execCommandShowHelp: any; exitFullscreen: any; exitPointerLock: any; focus: any; getElementById: any; getElementsByClassName: any; getElementsByName: any; getElementsByTagName: any; getElementsByTagNameNS: any; getSelection: any; hasFocus: any; importNode: any; msElementsFromPoint: any; msElementsFromRect: any; open: any; queryCommandEnabled: any; queryCommandIndeterm: any; queryCommandState: any; queryCommandSupported: any; queryCommandText: any; queryCommandValue: any; releaseEvents: any; updateSettings: any; webkitCancelFullScreen: any; webkitExitFullscreen: any; write: any; writeln: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; querySelector: any; querySelectorAll: any; createEvent: any; readonly children: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly childElementCount: any; readonly stylesheets: any; elementsFromPoint: any; } +>activeElement : { readonly classList: any; className: any; readonly clientHeight: any; readonly clientLeft: any; readonly clientTop: any; readonly clientWidth: any; id: any; innerHTML: any; msContentZoomFactor: any; readonly msRegionOverflow: any; onariarequest: any; oncommand: any; ongotpointercapture: any; onlostpointercapture: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsgotpointercapture: any; onmsinertiastart: any; onmslostpointercapture: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; outerHTML: any; readonly prefix: any; readonly scrollHeight: any; scrollLeft: any; scrollTop: any; readonly scrollWidth: any; readonly tagName: any; readonly assignedSlot: any; slot: any; readonly shadowRoot: any; getAttribute: any; getAttributeNode: any; getAttributeNodeNS: any; getAttributeNS: any; getBoundingClientRect: any; getClientRects: any; getElementsByTagName: any; getElementsByTagNameNS: any; hasAttribute: any; hasAttributeNS: any; msGetRegionContent: any; msGetUntransformedBounds: any; msMatchesSelector: any; msReleasePointerCapture: any; msSetPointerCapture: any; msZoomTo: any; releasePointerCapture: any; removeAttribute: any; removeAttributeNode: any; removeAttributeNS: any; requestFullscreen: any; requestPointerLock: any; setAttribute: any; setAttributeNode: any; setAttributeNodeNS: any; setAttributeNS: any; setPointerCapture: any; webkitMatchesSelector: any; webkitRequestFullscreen: any; webkitRequestFullScreen: any; getElementsByClassName: any; matches: any; closest: any; scrollIntoView: any; scroll: any; scrollTo: any; scrollBy: any; insertAdjacentElement: any; insertAdjacentHTML: any; insertAdjacentText: any; attachShadow: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; readonly childElementCount: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly nextElementSibling: any; readonly previousElementSibling: any; querySelector: any; querySelectorAll: any; remove: any; readonly children: any; } +>className : { toString: any; charAt: any; charCodeAt: any; concat: any; indexOf: any; lastIndexOf: any; localeCompare: any; match: any; replace: any; search: any; slice: any; split: any; substring: any; toLowerCase: any; toLocaleLowerCase: any; toUpperCase: any; toLocaleUpperCase: any; trim: any; readonly length: any; substr: any; valueOf: any; [Symbol.iterator]: any; codePointAt: any; includes: any; endsWith: any; normalize: any; repeat: any; startsWith: any; anchor: any; big: any; blink: any; bold: any; fixed: any; fontcolor: any; fontsize: any; italics: any; link: any; small: any; strike: any; sub: any; sup: any; } +>length : { toString: any; toFixed: any; toExponential: any; toPrecision: any; valueOf: any; toLocaleString: any; } diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.js b/tests/baselines/reference/thisTypeInObjectLiterals2.js index d614f0fa74c..7c5b6ef110b 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals2.js +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.js @@ -462,8 +462,8 @@ declare function defineProps(obj: T, descs: PropDescMap & ThisType): declare let p10: Point & Record<"foo", number>; declare let p11: Point & Record<"bar", number>; declare let p12: Point & { - foo: {}; - bar: {}; + foo: any; + bar: any; }; declare type Accessors = { [K in keyof T]: (() => T[K]) | Computed; @@ -487,6 +487,6 @@ declare let vue: { } & { f(x: string): number; } & { - test: {}; - hello: {}; + test: any; + hello: any; }; diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.types b/tests/baselines/reference/thisTypeInObjectLiterals2.types index 4a9ab16f9ea..fe00bdbb271 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals2.types +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.types @@ -672,8 +672,8 @@ p11.bar = p11.bar + 1; >1 : 1 let p12 = defineProps(p1, { ->p12 : Point & { foo: {}; bar: {}; } ->defineProps(p1, { foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }}) : Point & { foo: {}; bar: {}; } +>p12 : Point & { foo: any; bar: any; } +>defineProps(p1, { foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }}) : Point & { foo: any; bar: any; } >defineProps : (obj: T, descs: PropDescMap & ThisType) => T & U >p1 : Point >{ foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }} : { foo: { value: number; }; bar: { get(): number; set(value: number): void; }; } @@ -716,22 +716,22 @@ let p12 = defineProps(p1, { p12.foo = p12.foo + 1; >p12.foo = p12.foo + 1 : number >p12.foo : number ->p12 : Point & { foo: {}; bar: {}; } +>p12 : Point & { foo: any; bar: any; } >foo : number >p12.foo + 1 : number >p12.foo : number ->p12 : Point & { foo: {}; bar: {}; } +>p12 : Point & { foo: any; bar: any; } >foo : number >1 : 1 p12.bar = p12.bar + 1; >p12.bar = p12.bar + 1 : number >p12.bar : number ->p12 : Point & { foo: {}; bar: {}; } +>p12 : Point & { foo: any; bar: any; } >bar : number >p12.bar + 1 : number >p12.bar : number ->p12 : Point & { foo: {}; bar: {}; } +>p12 : Point & { foo: any; bar: any; } >bar : number >1 : 1 @@ -808,8 +808,8 @@ declare const Vue: new (options: VueOptions) => D & M & P; >P : P let vue = new Vue({ ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } ->new Vue({ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }}) : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } +>new Vue({ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }}) : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >Vue : new (options: VueOptions) => D & M & P >{ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }} : { data: () => { x: number; y: number; }; methods: { f(x: string): number; }; computed: { test(): number; hello: { get(): string; set(value: string): void; }; }; } @@ -833,7 +833,7 @@ let vue = new Vue({ return this.x; >this.x : number ->this : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } +>this : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >x : number } }, @@ -846,7 +846,7 @@ let vue = new Vue({ return this.x; >this.x : number ->this : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } +>this : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >x : number }, @@ -870,27 +870,27 @@ let vue = new Vue({ }); vue; ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } vue.x; >vue.x : number ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >x : number vue.f("abc"); >vue.f("abc") : number >vue.f : (x: string) => number ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >f : (x: string) => number >"abc" : "abc" vue.test; >vue.test : number ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >test : number vue.hello; >vue.hello : string ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >hello : string From 2ea5f58d60094ebf6ddd3fe6df8ec55c5ee849e6 Mon Sep 17 00:00:00 2001 From: Wenlu Wang <805037171@163.com> Date: Fri, 5 Jan 2018 04:45:16 +0800 Subject: [PATCH 043/189] quick fix of indexed access type (#20956) --- ...correctQualifiedNameToIndexedAccessType.ts | 2 +- .../fourslash/codeFixInPropertyAccess_js.ts | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/codeFixInPropertyAccess_js.ts diff --git a/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts b/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts index 3d99b571248..de4498035be 100644 --- a/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts +++ b/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts @@ -21,7 +21,7 @@ namespace ts.codefix { }); function getQualifiedName(sourceFile: SourceFile, pos: number): QualifiedName & { left: Identifier } | undefined { - const qualifiedName = findAncestor(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false), isQualifiedName)!; + const qualifiedName = findAncestor(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ true), isQualifiedName)!; Debug.assert(!!qualifiedName, "Expected position to be owned by a qualified name."); return isIdentifier(qualifiedName.left) ? qualifiedName as QualifiedName & { left: Identifier } : undefined; } diff --git a/tests/cases/fourslash/codeFixInPropertyAccess_js.ts b/tests/cases/fourslash/codeFixInPropertyAccess_js.ts new file mode 100644 index 00000000000..2afde9b5ee1 --- /dev/null +++ b/tests/cases/fourslash/codeFixInPropertyAccess_js.ts @@ -0,0 +1,45 @@ +/// + +// @allowJs: true +// @checkJs: true + +// @Filename: /a.js +//// /** +//// * @typedef Foo +//// * @property foo +//// */ + +//// /** +//// * @param {Foo.foo} inst +//// */ +//// function blah(inst) { +//// return false; +//// } + +verify.codeFixAll({ + fixId: "correctQualifiedNameToIndexedAccessType", + newFileContent: +`/** + * @typedef Foo + * @property foo + */ +/** + * @param {Foo["foo"]} inst + */ +function blah(inst) { + return false; +}`, +}); + + +/** + * @typedef Foo + * @property foo + */ + +/** + * @param {Foo.foo} inst + */ +function blah(inst) { + return false; +} \ No newline at end of file From 0834732cd11cd9b0566812082ab87041b041067f Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 4 Jan 2018 12:53:03 -0800 Subject: [PATCH 044/189] Update fourslash baselines too --- .../quickInfoMappedTypeRecursiveInference.ts | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/cases/fourslash/quickInfoMappedTypeRecursiveInference.ts b/tests/cases/fourslash/quickInfoMappedTypeRecursiveInference.ts index 84fd9da4ebe..1b46eba1f6b 100644 --- a/tests/cases/fourslash/quickInfoMappedTypeRecursiveInference.ts +++ b/tests/cases/fourslash/quickInfoMappedTypeRecursiveInference.ts @@ -17,40 +17,40 @@ //// oub.b.a.n.a.n.a/*10*/ verify.quickInfoAt('1', `const out: { - a: {}; + a: any; }`); verify.quickInfoAt('2', `function foo<{ - a: {}; + a: any; }>(deep: Deep<{ - a: {}; + a: any; }>): { - a: {}; + a: any; }`); verify.quickInfoAt('3', `(property) a: { - a: {}; + a: any; }`); verify.quickInfoAt('4', `(property) a: { - a: {}; + a: any; }`); verify.quickInfoAt('5', `(property) a: { - a: {}; + a: any; }`); verify.quickInfoAt('6', `const oub: { - [x: string]: {}; + [x: string]: any; }`); verify.quickInfoAt('7', `function foo<{ - [x: string]: {}; + [x: string]: any; }>(deep: Deep<{ - [x: string]: {}; + [x: string]: any; }>): { - [x: string]: {}; + [x: string]: any; }`); verify.quickInfoAt('8', `{ - [x: string]: {}; + [x: string]: any; }`); verify.quickInfoAt('9', `{ - [x: string]: {}; + [x: string]: any; }`); verify.quickInfoAt('10', `{ - [x: string]: {}; + [x: string]: any; }`); From 3f577b86171f9e3c49ede945087a8f01d1be8e6f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Jan 2018 15:17:40 -0800 Subject: [PATCH 045/189] Fix quick info for require template string (#20851) * Fix quick info for require template string Fixes #20850 * Add path completions tests --- src/compiler/checker.ts | 1 + src/services/findAllReferences.ts | 2 +- tests/cases/fourslash/completionsPaths.ts | 9 +++++++++ tests/cases/fourslash/quickInfoForRequire.ts | 5 +++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 49dde4ea6e4..0fbe3358ce5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -24470,6 +24470,7 @@ namespace ts { return undefined; case SyntaxKind.StringLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: // 1). import x = require("./mo/*gotToDefinitionHere*/d") // 2). External module name in an import declaration // 3). Dynamic import call or require in javascript diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 68ada59125b..6e43ac37def 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -275,7 +275,7 @@ namespace ts.FindAllReferences.Core { } function isModuleReferenceLocation(node: ts.Node): boolean { - if (node.kind !== SyntaxKind.StringLiteral) { + if (node.kind !== SyntaxKind.StringLiteral && node.kind !== SyntaxKind.NoSubstitutionTemplateLiteral) { return false; } switch (node.parent.kind) { diff --git a/tests/cases/fourslash/completionsPaths.ts b/tests/cases/fourslash/completionsPaths.ts index 9473ae54b25..454ef78eef8 100644 --- a/tests/cases/fourslash/completionsPaths.ts +++ b/tests/cases/fourslash/completionsPaths.ts @@ -17,5 +17,14 @@ // @Filename: /src/folder/b.ts ////import {} from "x//*2*/"; +// @Filename: /src/folder/c.ts +////const foo = require("x//*3*/"); + +// @Filename: /src/folder/4.ts +////const foo = require(`x//*4*/`); + verify.completionsAt("1", ["y", "x"]); verify.completionsAt("2", ["bar", "foo"]); +verify.completionsAt("3", ["bar", "foo"]); +verify.completionsAt("4", ["bar", "foo"]); + diff --git a/tests/cases/fourslash/quickInfoForRequire.ts b/tests/cases/fourslash/quickInfoForRequire.ts index fe923945429..231dd8603b2 100644 --- a/tests/cases/fourslash/quickInfoForRequire.ts +++ b/tests/cases/fourslash/quickInfoForRequire.ts @@ -5,6 +5,11 @@ //@Filename: quickInfoForRequire_input.ts ////import a = require("./AA/B/*1*/B"); +////import b = require(`./AA/B/*2*/B`); + goTo.marker("1"); verify.quickInfoIs("module a"); + +goTo.marker("2"); +verify.quickInfoIs("module a"); From 8ed4e666e84afeee8251433795155cf902f2f8ca Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Jan 2018 15:18:41 -0800 Subject: [PATCH 046/189] Log TS Server version and process args (#20847) * Print TS Server version and args in logs Fixes #18867 Adds basic logging of the version of tsserver being run and the full command line arguments used to run it * Don't check log level for logging versions/args --- src/server/server.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/server/server.ts b/src/server/server.ts index 86349fa2be5..8e53c4d5109 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -979,6 +979,10 @@ namespace ts.server { allowLocalPluginLoads }; + logger.info(`Starting TS Server`); + logger.info(`Version: ${versionMajorMinor}`); + logger.info(`Arguments: ${process.argv.join(" ")}`); + const ioSession = new IOSession(options); process.on("uncaughtException", err => { ioSession.logError(err, "unknown"); From b36d614b5600d101491489b6c28c61ea50e533b7 Mon Sep 17 00:00:00 2001 From: benbraou Date: Fri, 5 Jan 2018 00:31:59 +0100 Subject: [PATCH 047/189] bug(esnext): add definition for promise.finally (#20511) Fixes #20411 --- Gulpfile.ts | 3 +- Jakefile.js | 3 +- src/compiler/commandLineParser.ts | 1 + src/harness/unittests/commandLineParsing.ts | 6 ++-- .../convertCompilerOptionsFromJson.ts | 8 ++--- src/lib/esnext.d.ts | 3 +- src/lib/esnext.promise.d.ts | 12 +++++++ .../types.asyncGenerators.esnext.1.symbols | 32 +++++++++---------- .../types.asyncGenerators.esnext.2.symbols | 2 +- .../baselines/reference/uniqueSymbols.symbols | 4 +-- .../uniqueSymbolsDeclarations.symbols | 4 +-- 11 files changed, 47 insertions(+), 31 deletions(-) create mode 100644 src/lib/esnext.promise.d.ts diff --git a/Gulpfile.ts b/Gulpfile.ts index 4d90d5cf24a..996fa1fc140 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -150,7 +150,8 @@ const es2018LibrarySourceMap = es2018LibrarySource.map(source => ({ target: "lib." + source, sources: ["header.d.ts", source] })); const esnextLibrarySource = [ - "esnext.asynciterable.d.ts" + "esnext.asynciterable.d.ts", + "esnext.promise.d.ts" ]; const esnextLibrarySourceMap = esnextLibrarySource.map(source => diff --git a/Jakefile.js b/Jakefile.js index e016c1bd0bd..f2a15aa4e19 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -213,7 +213,8 @@ var es2018LibrarySourceMap = es2018LibrarySource.map(function (source) { }); var esnextLibrarySource = [ - "esnext.asynciterable.d.ts" + "esnext.asynciterable.d.ts", + "esnext.promise.d.ts" ]; var esnextLibrarySourceMap = esnextLibrarySource.map(function (source) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index a0f91e3d0e9..19d4dbbd003 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -145,6 +145,7 @@ namespace ts { "es2017.intl": "lib.es2017.intl.d.ts", "es2017.typedarrays": "lib.es2017.typedarrays.d.ts", "esnext.asynciterable": "lib.esnext.asynciterable.d.ts", + "esnext.promise": "lib.esnext.promise.d.ts", }), }, showInSimplifiedHelpView: true, diff --git a/src/harness/unittests/commandLineParsing.ts b/src/harness/unittests/commandLineParsing.ts index 82c2af7f64e..8cfd4ad406c 100644 --- a/src/harness/unittests/commandLineParsing.ts +++ b/src/harness/unittests/commandLineParsing.ts @@ -60,7 +60,7 @@ namespace ts { assertParseResult(["--lib", "es5,invalidOption", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -263,7 +263,7 @@ namespace ts { assertParseResult(["--lib", "es5,", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -283,7 +283,7 @@ namespace ts { assertParseResult(["--lib", "es5, ", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index 2a8f1fe3a89..42e0903c93c 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -266,7 +266,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -297,7 +297,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -328,7 +328,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -359,7 +359,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] diff --git a/src/lib/esnext.d.ts b/src/lib/esnext.d.ts index 71fab82a866..685a10ef4d7 100644 --- a/src/lib/esnext.d.ts +++ b/src/lib/esnext.d.ts @@ -1,2 +1,3 @@ -/// +/// /// +/// diff --git a/src/lib/esnext.promise.d.ts b/src/lib/esnext.promise.d.ts new file mode 100644 index 00000000000..28f903870b6 --- /dev/null +++ b/src/lib/esnext.promise.d.ts @@ -0,0 +1,12 @@ +/** + * Represents the completion of an asynchronous operation + */ +interface Promise { + /** + * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The + * resolved value cannot be modified from the callback. + * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected). + * @returns A Promise for the completion of the callback. + */ + finally(onfinally?: (() => void) | undefined | null): Promise +} diff --git a/tests/baselines/reference/types.asyncGenerators.esnext.1.symbols b/tests/baselines/reference/types.asyncGenerators.esnext.1.symbols index b5707649fda..59b93d7ab1a 100644 --- a/tests/baselines/reference/types.asyncGenerators.esnext.1.symbols +++ b/tests/baselines/reference/types.asyncGenerators.esnext.1.symbols @@ -17,7 +17,7 @@ async function * inferReturnType4() { yield Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) } async function * inferReturnType5() { @@ -26,7 +26,7 @@ async function * inferReturnType5() { yield 1; yield Promise.resolve(2); >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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) } async function * inferReturnType6() { @@ -39,7 +39,7 @@ async function * inferReturnType7() { yield* [Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) } async function * inferReturnType8() { @@ -59,7 +59,7 @@ const assignability2: () => AsyncIterableIterator = async function * () yield Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) }; @@ -75,7 +75,7 @@ const assignability4: () => AsyncIterableIterator = async function * () yield* [Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) }; @@ -97,7 +97,7 @@ const assignability7: () => AsyncIterable = async function * () { yield Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) }; @@ -113,7 +113,7 @@ const assignability9: () => AsyncIterable = async function * () { yield* [Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) }; @@ -135,7 +135,7 @@ const assignability12: () => AsyncIterator = async function * () { yield Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) }; @@ -151,7 +151,7 @@ const assignability14: () => AsyncIterator = async function * () { yield* [Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) }; @@ -173,7 +173,7 @@ async function * explicitReturnType2(): AsyncIterableIterator { yield Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) } async function * explicitReturnType3(): AsyncIterableIterator { @@ -188,7 +188,7 @@ async function * explicitReturnType4(): AsyncIterableIterator { yield* [Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) } async function * explicitReturnType5(): AsyncIterableIterator { @@ -209,7 +209,7 @@ async function * explicitReturnType7(): AsyncIterable { yield Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) } async function * explicitReturnType8(): AsyncIterable { @@ -224,7 +224,7 @@ async function * explicitReturnType9(): AsyncIterable { yield* [Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) } async function * explicitReturnType10(): AsyncIterable { @@ -245,7 +245,7 @@ async function * explicitReturnType12(): AsyncIterator { yield Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) } async function * explicitReturnType13(): AsyncIterator { @@ -260,7 +260,7 @@ async function * explicitReturnType14(): AsyncIterator { yield* [Promise.resolve(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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) } async function * explicitReturnType15(): AsyncIterator { @@ -286,6 +286,6 @@ async function * awaitedType2() { const x = await Promise.resolve(1); >x : Symbol(x, Decl(types.asyncGenerators.esnext.1.ts, 121, 9)) >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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) } diff --git a/tests/baselines/reference/types.asyncGenerators.esnext.2.symbols b/tests/baselines/reference/types.asyncGenerators.esnext.2.symbols index bb6ec27150c..9d4bcc17b13 100644 --- a/tests/baselines/reference/types.asyncGenerators.esnext.2.symbols +++ b/tests/baselines/reference/types.asyncGenerators.esnext.2.symbols @@ -15,7 +15,7 @@ async function * inferReturnType3() { yield* Promise.resolve([1, 2]); >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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) } const assignability1: () => AsyncIterableIterator = async function * () { diff --git a/tests/baselines/reference/uniqueSymbols.symbols b/tests/baselines/reference/uniqueSymbols.symbols index e798011683a..42324fa6e4d 100644 --- a/tests/baselines/reference/uniqueSymbols.symbols +++ b/tests/baselines/reference/uniqueSymbols.symbols @@ -388,7 +388,7 @@ const constInitToLReadonlyNestedTypeWithIndexedAccess: L["nested"]["readonlyNest const promiseForConstCall = Promise.resolve(constCall); >promiseForConstCall : Symbol(promiseForConstCall, Decl(uniqueSymbols.ts, 111, 5)) >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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) >constCall : Symbol(constCall, Decl(uniqueSymbols.ts, 1, 5)) @@ -725,7 +725,7 @@ interface Context { method2(): Promise; >method2 : Symbol(Context.method2, Decl(uniqueSymbols.ts, 214, 24)) ->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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >s : Symbol(s, Decl(uniqueSymbols.ts, 115, 13)) method3(): AsyncIterableIterator; diff --git a/tests/baselines/reference/uniqueSymbolsDeclarations.symbols b/tests/baselines/reference/uniqueSymbolsDeclarations.symbols index ff433aa19d0..beff6685aa7 100644 --- a/tests/baselines/reference/uniqueSymbolsDeclarations.symbols +++ b/tests/baselines/reference/uniqueSymbolsDeclarations.symbols @@ -388,7 +388,7 @@ const constInitToLReadonlyNestedTypeWithIndexedAccess: L["nested"]["readonlyNest const promiseForConstCall = Promise.resolve(constCall); >promiseForConstCall : Symbol(promiseForConstCall, Decl(uniqueSymbolsDeclarations.ts, 111, 5)) >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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), 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, --, --)) >constCall : Symbol(constCall, Decl(uniqueSymbolsDeclarations.ts, 1, 5)) @@ -725,7 +725,7 @@ interface Context { method2(): Promise; >method2 : Symbol(Context.method2, Decl(uniqueSymbolsDeclarations.ts, 214, 24)) ->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, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >s : Symbol(s, Decl(uniqueSymbolsDeclarations.ts, 115, 13)) method3(): AsyncIterableIterator; From ff58f1f2f9b479d73f4026da1b98b3a8c7175c49 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 3 Jan 2018 16:37:43 -0800 Subject: [PATCH 048/189] Handle different default export forms the same way in import code fixes `export default C` and `export { C as default }` should be handled the same as `export default class C { }`. Fixes #19115 --- src/services/codefixes/importFixes.ts | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 20d6ac4d5ba..936bb15e947 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -770,8 +770,11 @@ namespace ts.codefix { const defaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol); if (defaultExport) { const localSymbol = getLocalSymbolForExportDefault(defaultExport); - if ((localSymbol && localSymbol.escapedName === symbolName || moduleSymbolToValidIdentifier(moduleSymbol, context.compilerOptions.target) === symbolName) - && checkSymbolHasMeaning(localSymbol || defaultExport, currentTokenMeaning)) { + if (( + localSymbol && localSymbol.escapedName === symbolName || + getEscapedNameForExportDefault(defaultExport) === symbolName || + moduleSymbolToValidIdentifier(moduleSymbol, context.compilerOptions.target) === symbolName + ) && checkSymbolHasMeaning(localSymbol || defaultExport, currentTokenMeaning)) { // check if this symbol is already used const symbolId = getUniqueSymbolId(localSymbol || defaultExport, checker); symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, { ...context, kind: ImportKind.Default })); @@ -784,6 +787,23 @@ namespace ts.codefix { const symbolId = getUniqueSymbolId(exportSymbolWithIdenticalName, checker); symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, { ...context, kind: ImportKind.Named })); } + + function getEscapedNameForExportDefault(symbol: Symbol): __String | undefined { + const declarations = symbol.declarations; + if (length(declarations) > 0) { + const declaration = declarations[0]; + if (isExportAssignment(declaration)) { + if (isIdentifier(declaration.expression)) { + return declaration.expression.escapedText; + } + } + else if (isExportSpecifier(declaration)) { + if (declaration.propertyName) { + return declaration.propertyName.escapedText; + } + } + } + } }); return symbolIdActionMap.getAllActions(); From 1e93967ec4161fe209768d5a0a581be00ffaa152 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 3 Jan 2018 17:58:49 -0800 Subject: [PATCH 049/189] Add regression tests --- src/services/codefixes/importFixes.ts | 1 + .../importNameCodeFixDefaultExport2.ts | 21 +++++++++++++++++++ .../importNameCodeFixDefaultExport3.ts | 21 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 tests/cases/fourslash/importNameCodeFixDefaultExport2.ts create mode 100644 tests/cases/fourslash/importNameCodeFixDefaultExport3.ts diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 936bb15e947..1ff23f679d8 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -798,6 +798,7 @@ namespace ts.codefix { } } else if (isExportSpecifier(declaration)) { + Debug.assert(declaration.name.escapedText === InternalSymbolName.Default); if (declaration.propertyName) { return declaration.propertyName.escapedText; } diff --git a/tests/cases/fourslash/importNameCodeFixDefaultExport2.ts b/tests/cases/fourslash/importNameCodeFixDefaultExport2.ts new file mode 100644 index 00000000000..8e09196d06c --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixDefaultExport2.ts @@ -0,0 +1,21 @@ +/// + +// @allowJs: true +// @checkJs: true + +// @Filename: /lib.js +////class Base { } +////export default Base; + +// @Filename: /test.js +////[|class Derived extends Base { }|] + +goTo.file("/test.js"); +verify.importFixAtPosition([ +`// @ts-ignore +class Derived extends Base { }`, +`// @ts-nocheck +class Derived extends Base { }`, +`import Base from "./lib"; + +class Derived extends Base { }`,]); diff --git a/tests/cases/fourslash/importNameCodeFixDefaultExport3.ts b/tests/cases/fourslash/importNameCodeFixDefaultExport3.ts new file mode 100644 index 00000000000..1d4c6bae8c2 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixDefaultExport3.ts @@ -0,0 +1,21 @@ +/// + +// @allowJs: true +// @checkJs: true + +// @Filename: /lib.js +////class Base { } +////export { Base as default }; + +// @Filename: /test.js +////[|class Derived extends Base { }|] + +goTo.file("/test.js"); +verify.importFixAtPosition([ +`// @ts-ignore +class Derived extends Base { }`, +`// @ts-nocheck +class Derived extends Base { }`, +`import Base from "./lib"; + +class Derived extends Base { }`,]); From f0d9cb3fbfe7317ff3f82c36cde5601992ed2875 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 4 Jan 2018 14:28:24 -0800 Subject: [PATCH 050/189] Add explanatory comment to FAR call-site --- src/services/findAllReferences.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index fa56326b9f0..de81cce8000 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -510,6 +510,8 @@ namespace ts.FindAllReferences.Core { /** @param allSearchSymbols set of additinal symbols for use by `includes`. */ createSearch(location: Node, symbol: Symbol, comingFrom: ImportExport | undefined, searchOptions: { text?: string, allSearchSymbols?: Symbol[] } = {}): Search { // Note: if this is an external module symbol, the name doesn't include quotes. + // Note: getLocalSymbolForExportDefault handles `export default class C {}`, but not `export default C` or `export { C as default }`. + // The other two forms seem to be handled downstream (i.e. special-casing the first form here appears to be intentional). const { text = stripQuotes(unescapeLeadingUnderscores((getLocalSymbolForExportDefault(symbol) || symbol).escapedName)), allSearchSymbols = undefined, From 50e3044ed2bb335830193f837bdf0cdc99f23cd4 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 4 Jan 2018 11:13:03 -0800 Subject: [PATCH 051/189] Correct fullDisplayName returned from rename The regular displayName had special handling for `as` clauses in imports and exports but the fullDisplayName did not. They should be consistent. (The impact of this change is very minor - it only affects the root node of the tree control in the rename preview, which is off by default.) Bonus: Eliminate `getDeclaredName` which is only called by rename. Note: Special handling of default exports was not preserved since `default` cannot be renamed. --- src/services/rename.ts | 12 ++++++++++-- src/services/utilities.ts | 13 ------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/services/rename.ts b/src/services/rename.ts index cfe79679fba..ca46a93f3c9 100644 --- a/src/services/rename.ts +++ b/src/services/rename.ts @@ -38,9 +38,17 @@ namespace ts.Rename { return undefined; } - const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node); - return kind ? getRenameInfoSuccess(displayName, typeChecker.getFullyQualifiedName(symbol), kind, SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile) : undefined; + if (!kind) { + return undefined; + } + + const specifierName = (isImportOrExportSpecifierName(node) || isStringOrNumericLiteral(node) && node.parent.kind === SyntaxKind.ComputedPropertyName) + ? stripQuotes(getTextOfIdentifierOrLiteral(node)) + : undefined; + const displayName = specifierName || typeChecker.symbolToString(symbol); + const fullDisplayName = specifierName || typeChecker.getFullyQualifiedName(symbol); + return getRenameInfoSuccess(displayName, fullDisplayName, kind, SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile); } } else if (node.kind === SyntaxKind.StringLiteral) { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 140873dc06d..b5178005521 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1278,19 +1278,6 @@ namespace ts { }); } - export function getDeclaredName(typeChecker: TypeChecker, symbol: Symbol, location: Node): string { - // If this is an export or import specifier it could have been renamed using the 'as' syntax. - // If so we want to search for whatever is under the cursor. - if (isImportOrExportSpecifierName(location) || isStringOrNumericLiteral(location) && location.parent.kind === SyntaxKind.ComputedPropertyName) { - return getTextOfIdentifierOrLiteral(location); - } - - // Try to get the local symbol if we're dealing with an 'export default' - // since that symbol has the "true" name. - const localExportDefaultSymbol = getLocalSymbolForExportDefault(symbol); - return typeChecker.symbolToString(localExportDefaultSymbol || symbol); - } - export function isImportOrExportSpecifierName(location: Node): location is Identifier { return location.parent && (location.parent.kind === SyntaxKind.ImportSpecifier || location.parent.kind === SyntaxKind.ExportSpecifier) && From 12d5063e4ce3dcb84e0a2458196c403d201658e7 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Jan 2018 16:36:31 -0800 Subject: [PATCH 052/189] Add kindModifier to mark if a completion item is for an optional field (#20839) * Add kindModifier to mark if a completion item is for an optional field For #12458 Adds a new KindModifier for completion items to mark when a property is optional. This can be used by editors to either change the item icon or add a `?` to the item text * Add method test * Baseline-accept --- src/harness/fourslash.ts | 24 ++++++++++++++----- src/services/symbolDisplay.ts | 7 +++++- src/services/types.ts | 1 + .../reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + .../completionsOptionalKindModifier.ts | 10 ++++++++ tests/cases/fourslash/fourslash.ts | 2 +- 7 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 tests/cases/fourslash/completionsOptionalKindModifier.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 99d643ec438..9ab7dd31ffd 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -872,7 +872,7 @@ namespace FourSlash { }); } - public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean, options?: FourSlashInterface.VerifyCompletionListContainsOptions) { + public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, hasAction?: boolean, options?: FourSlashInterface.VerifyCompletionListContainsOptions) { const completions = this.getCompletionListAtCaret(options); if (completions) { this.assertItemInCompletionList(completions.entries, entryId, text, documentation, kind, spanIndex, hasAction, options); @@ -893,7 +893,7 @@ namespace FourSlash { * @param expectedKind the kind of symbol (see ScriptElementKind) * @param spanIndex the index of the range that the completion item's replacement text span should match */ - public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string, spanIndex?: number, options?: FourSlashInterface.CompletionsAtOptions) { + public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, options?: FourSlashInterface.CompletionsAtOptions) { let replacementSpan: ts.TextSpan; if (spanIndex !== undefined) { replacementSpan = this.getTextSpanForRangeAtIndex(spanIndex); @@ -902,7 +902,7 @@ namespace FourSlash { const completions = this.getCompletionListAtCaret(options); if (completions) { let filterCompletions = completions.entries.filter(e => e.name === entryId.name && e.source === entryId.source); - filterCompletions = expectedKind ? filterCompletions.filter(e => e.kind === expectedKind) : filterCompletions; + filterCompletions = expectedKind ? filterCompletions.filter(e => e.kind === expectedKind || (typeof expectedKind === "object" && e.kind === expectedKind.kind)) : filterCompletions; filterCompletions = filterCompletions.filter(entry => { const details = this.getCompletionEntryDetails(entry.name); const documentation = details && ts.displayPartsToString(details.documentation); @@ -3089,7 +3089,7 @@ Actual: ${stringify(fullActual)}`); entryId: ts.Completions.CompletionEntryIdentifier, text: string | undefined, documentation: string | undefined, - kind: string | undefined, + kind: string | undefined | { kind?: string, kindModifiers?: string }, spanIndex: number | undefined, hasAction: boolean | undefined, options: FourSlashInterface.VerifyCompletionListContainsOptions | undefined, @@ -3123,9 +3123,21 @@ Actual: ${stringify(fullActual)}`); } if (kind !== undefined) { - assert.equal(item.kind, kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + entryId)); + if (typeof kind === "string") { + assert.equal(item.kind, kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + entryId)); + } + else { + if (kind.kind) { + assert.equal(item.kind, kind.kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + entryId)); + } + if (kind.kindModifiers !== undefined) { + assert.equal(item.kindModifiers, kind.kindModifiers, this.assertionMessageAtLastKnownMarker("completion item kindModifiers for " + entryId)); + } + } } + + if (spanIndex !== undefined) { const span = this.getTextSpanForRangeAtIndex(spanIndex); assert.isTrue(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + entryId)); @@ -3842,7 +3854,7 @@ namespace FourSlashInterface { // Verifies the completion list contains the specified symbol. The // completion list is brought up if necessary - public completionListContains(entryId: string | ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean, options?: VerifyCompletionListContainsOptions) { + public completionListContains(entryId: string | ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, hasAction?: boolean, options?: VerifyCompletionListContainsOptions) { if (typeof entryId === "string") { entryId = { name: entryId, source: undefined }; } diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index caf38306bec..e79dde41e69 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -91,9 +91,14 @@ namespace ts.SymbolDisplay { } export function getSymbolModifiers(symbol: Symbol): string { - return symbol && symbol.declarations && symbol.declarations.length > 0 + const nodeModifiers = symbol && symbol.declarations && symbol.declarations.length > 0 ? getNodeModifiers(symbol.declarations[0]) : ScriptElementKindModifier.none; + + const symbolModifiers = symbol && symbol.flags & SymbolFlags.Optional ? + ScriptElementKindModifier.optionalModifier + : ScriptElementKindModifier.none; + return nodeModifiers && symbolModifiers ? nodeModifiers + "," + symbolModifiers : nodeModifiers || symbolModifiers; } interface SymbolDisplayPartsDocumentationAndSymbolKind { diff --git a/src/services/types.ts b/src/services/types.ts index 471ae3b3459..813e8790933 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -954,6 +954,7 @@ namespace ts { ambientModifier = "declare", staticModifier = "static", abstractModifier = "abstract", + optionalModifier = "optional" } export const enum ClassificationTypeNames { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index d7d06fd9adc..6d3829d8133 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4505,6 +4505,7 @@ declare namespace ts { ambientModifier = "declare", staticModifier = "static", abstractModifier = "abstract", + optionalModifier = "optional", } enum ClassificationTypeNames { comment = "comment", diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 4d06e48dc25..54226c4a25f 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4505,6 +4505,7 @@ declare namespace ts { ambientModifier = "declare", staticModifier = "static", abstractModifier = "abstract", + optionalModifier = "optional", } enum ClassificationTypeNames { comment = "comment", diff --git a/tests/cases/fourslash/completionsOptionalKindModifier.ts b/tests/cases/fourslash/completionsOptionalKindModifier.ts new file mode 100644 index 00000000000..39ace2342d3 --- /dev/null +++ b/tests/cases/fourslash/completionsOptionalKindModifier.ts @@ -0,0 +1,10 @@ +/// + +////interface A { a?: number; method?(): number; }; +////function f(x: A) { +////x./*a*/; +////} + +goTo.marker("a"); +verify.completionListContains("a", /* text */ undefined, /* documentation */ undefined, { kindModifiers: "optional" }); +verify.completionListContains("method", /* text */ undefined, /* documentation */ undefined, { kindModifiers: "optional" }); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 8b581e62e6c..933e7a88f94 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -146,7 +146,7 @@ declare namespace FourSlashInterface { entryId: string | { name: string, source?: string }, text?: string, documentation?: string, - kind?: string, + kind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, hasAction?: boolean, options?: { includeExternalModuleExports?: boolean, sourceDisplay?: string, isRecommended?: true }, From 5865494453628d04ef4c192c769a71e793b3d94a Mon Sep 17 00:00:00 2001 From: Orta Date: Thu, 4 Jan 2018 19:38:52 -0500 Subject: [PATCH 053/189] Switch the pretty output to use colons to separate file:line:char so that lines are clickable in terminals (#20736) --- src/compiler/program.ts | 6 +++--- .../reference/prettyContextNotDebugAssertion.errors.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 3274e81ce81..a99128fbf6b 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -331,11 +331,11 @@ namespace ts { } output += formatColorAndReset(relativeFileName, ForegroundColorEscapeSequences.Cyan); - output += "("; + output += ":"; output += formatColorAndReset(`${ firstLine + 1 }`, ForegroundColorEscapeSequences.Yellow); - output += ","; + output += ":"; output += formatColorAndReset(`${ firstLineChar + 1 }`, ForegroundColorEscapeSequences.Yellow); - output += "): "; + output += " - "; } const categoryColor = getCategoryFormat(diagnostic.category); diff --git a/tests/baselines/reference/prettyContextNotDebugAssertion.errors.txt b/tests/baselines/reference/prettyContextNotDebugAssertion.errors.txt index f03b87ba947..3c94d3bd0b8 100644 --- a/tests/baselines/reference/prettyContextNotDebugAssertion.errors.txt +++ b/tests/baselines/reference/prettyContextNotDebugAssertion.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/index.ts(2,1): error TS1005: '}' expected. +tests/cases/compiler/index.ts:2:1 - error TS1005: '}' expected. 2    From 624f68a8e105ce297da06f08ea5cfd461bda065c Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Thu, 4 Jan 2018 16:51:19 -0800 Subject: [PATCH 054/189] Simplify marker names --- .../fourslash/formattingOptionsChangeJsx.ts | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tests/cases/fourslash/formattingOptionsChangeJsx.ts b/tests/cases/fourslash/formattingOptionsChangeJsx.ts index 067f0b882f2..363b53fe81c 100644 --- a/tests/cases/fourslash/formattingOptionsChangeJsx.ts +++ b/tests/cases/fourslash/formattingOptionsChangeJsx.ts @@ -1,37 +1,39 @@ /// //@Filename: file.tsx -/////*InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces1*/; +/////*1*/; //// //// -runTest("InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces1", ";", ";"); -runTest("InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces2", " { ...this._getButtonProps() }", " {...this._getButtonProps()}"); +runTest("1", ";", ";"); +runTest("2", " { ...this._getButtonProps() }", " {...this._getButtonProps()}"); -function runTest(propertyName: string, expectedStringWhenTrue: string, expectedStringWhenFalse: string) { +function runTest(markerName: string, expectedStringWhenTrue: string, expectedStringWhenFalse: string) { + const propertyName = "InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"; + // Go to the correct file - goTo.marker(propertyName); + goTo.marker(markerName); // Set the option to false first - format.setOption(propertyName.slice(0, -1), false); + format.setOption(propertyName, false); // Format format.document(); // Verify - goTo.marker(propertyName); + goTo.marker(markerName); verify.currentLineContentIs(expectedStringWhenFalse); // Set the option to true - format.setOption(propertyName.slice(0, -1), true); + format.setOption(propertyName, true); // Format format.document(); // Verify - goTo.marker(propertyName); + goTo.marker(markerName); verify.currentLineContentIs(expectedStringWhenTrue); } \ No newline at end of file From 85b32ed22198ed9860f2802cb35ccd9d8a05f6cf Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 4 Jan 2018 19:52:32 -0500 Subject: [PATCH 055/189] Added localization instructions to CONTRIBUTING.md (#20451) * Added localization instructions to CONTRIBUTING.md Fixes #20418 * Corrected mention of generated ts file * Mentioned coding guidelines --- CONTRIBUTING.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6dbb7e514a0..fd0f4348c62 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -183,3 +183,10 @@ jake baseline-accept ``` to establish the new baselines as the desired behavior. This will change the files in `tests\baselines\reference`, which should be included as part of your commit. It's important to carefully validate changes in the baselines. + +## Localization + +All strings the user may see are stored in [`diagnosticMessages.json`](./src/compiler/diagnosticMessages.json). +If you make changes to it, run `jake generate-diagnostics` to push them to the `Diagnostic` interface in [`diagnosticInformationMap.generated.ts`](./src/compiler/diagnosticInformationMap.generated.ts). + +See [coding guidelines on diagnostic messages](https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#diagnostic-messages). From 131cf4714cbbe03c7b359eb6c4b257df3c74803f Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 4 Jan 2018 19:54:51 -0500 Subject: [PATCH 056/189] Allowed trailing commas in type parameter/argument lists (#20599) This change is only one source file and one error file... there must be something I'm missing!? --- src/compiler/checker.ts | 4 ---- .../typeParameterListWithTrailingComma1.errors.txt | 8 -------- 2 files changed, 12 deletions(-) delete mode 100644 tests/baselines/reference/typeParameterListWithTrailingComma1.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0fbe3358ce5..5321baf2bc3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25736,10 +25736,6 @@ namespace ts { } function checkGrammarTypeParameterList(typeParameters: NodeArray, file: SourceFile): boolean { - if (checkGrammarForDisallowedTrailingComma(typeParameters)) { - return true; - } - if (typeParameters && typeParameters.length === 0) { const start = typeParameters.pos - "<".length; const end = skipTrivia(file.text, typeParameters.end) + ">".length; diff --git a/tests/baselines/reference/typeParameterListWithTrailingComma1.errors.txt b/tests/baselines/reference/typeParameterListWithTrailingComma1.errors.txt deleted file mode 100644 index ac20e826969..00000000000 --- a/tests/baselines/reference/typeParameterListWithTrailingComma1.errors.txt +++ /dev/null @@ -1,8 +0,0 @@ -tests/cases/compiler/typeParameterListWithTrailingComma1.ts(1,10): error TS1009: Trailing comma not allowed. - - -==== tests/cases/compiler/typeParameterListWithTrailingComma1.ts (1 errors) ==== - class C { - ~ -!!! error TS1009: Trailing comma not allowed. - } \ No newline at end of file From 7ef541ca1fe283d88557c1c9d403c9f76076faca Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Fri, 5 Jan 2018 01:56:29 +0100 Subject: [PATCH 057/189] findConfigFile can return undefined (#20556) --- src/compiler/program.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/compiler/program.ts b/src/compiler/program.ts index a99128fbf6b..959dee19e03 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -6,7 +6,7 @@ namespace ts { const ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/; - export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string { + export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string | undefined { return forEachAncestorDirectory(searchPath, ancestor => { const fileName = combinePaths(ancestor, configName); return fileExists(fileName) ? fileName : undefined; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 6d3829d8133..6d7a69d350f 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3770,7 +3770,7 @@ declare namespace ts { } } declare namespace ts { - function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string; + function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string | undefined; function resolveTripleslashReference(moduleName: string, containingFile: string): string; function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 54226c4a25f..4e9f13be2ce 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3717,7 +3717,7 @@ declare namespace ts { } } declare namespace ts { - function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string; + function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string | undefined; function resolveTripleslashReference(moduleName: string, containingFile: string): string; function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; From 67eabb98bc83c8be4b28068c8489d295d7e6ec36 Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Fri, 5 Jan 2018 08:57:27 +0800 Subject: [PATCH 058/189] fix #20449, insert space between decorators (#20491) --- src/services/formatting/rules.ts | 2 +- tests/cases/fourslash/formattingDecorators.ts | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index bf1c57b2188..9a12392644f 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -198,7 +198,7 @@ namespace ts.formatting { RuleAction.Delete), // decorators - rule("SpaceBeforeAt", anyToken, SyntaxKind.AtToken, [isNonJsxSameLineTokenContext], RuleAction.Space), + rule("SpaceBeforeAt", [SyntaxKind.CloseParenToken, SyntaxKind.Identifier], SyntaxKind.AtToken, [isNonJsxSameLineTokenContext], RuleAction.Space), rule("NoSpaceAfterAt", SyntaxKind.AtToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), // Insert space after @ in decorator rule("SpaceAfterDecorator", diff --git a/tests/cases/fourslash/formattingDecorators.ts b/tests/cases/fourslash/formattingDecorators.ts index 366b9cb7729..9ff6de3cf18 100644 --- a/tests/cases/fourslash/formattingDecorators.ts +++ b/tests/cases/fourslash/formattingDecorators.ts @@ -41,6 +41,8 @@ /////*29*/ property1; //// /////*30*/ @ decorator33 @ decorator34 @decorator35 property2; +/////*31*/function test(@decorator36@decorator37 param) {}; +/////*32*/function test2(@decorator38()@decorator39()param) {}; ////} format.document(); @@ -103,4 +105,8 @@ verify.currentLineContentIs(" @decorator32"); goTo.marker("29"); verify.currentLineContentIs(" property1;"); goTo.marker("30"); -verify.currentLineContentIs(" @decorator33 @decorator34 @decorator35 property2;"); \ No newline at end of file +verify.currentLineContentIs(" @decorator33 @decorator34 @decorator35 property2;"); +goTo.marker("31"); +verify.currentLineContentIs("function test(@decorator36 @decorator37 param) { };"); +goTo.marker("32"); +verify.currentLineContentIs("function test2(@decorator38() @decorator39() param) { };"); \ No newline at end of file From 4eb633e0d9ac8e022cdd745206062de573ae5b77 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 4 Jan 2018 17:46:09 -0800 Subject: [PATCH 059/189] Fix version of @types/node to 8.5.5 (#21019) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c87650afa8c..fb089b64918 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@types/minimist": "latest", "@types/mkdirp": "latest", "@types/mocha": "latest", - "@types/node": "latest", + "@types/node": "8.5.5", "@types/q": "latest", "@types/run-sequence": "latest", "@types/through2": "latest", From afae97ce6ec84f57daebc16491025f43857a4b92 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 3 Jan 2018 12:37:43 -0800 Subject: [PATCH 060/189] Refine extends-to-implements code fix 1. Retain surrounding trivia when swapping the keyword. 2. Insert commas at the full-starts, rather than starts, of existing keywords when merging with existing implements clauses. Fixes #18794 --- .../fixExtendsInterfaceBecomesImplements.ts | 15 +++++++++++++-- ...angeExtendsToImplementsAbstractModifier.ts | 2 +- ...xChangeExtendsToImplementsWithDecorator.ts | 2 +- ...eFixChangeExtendsToImplementsWithTrivia.ts | 19 +++++++++++++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 tests/cases/fourslash/codeFixChangeExtendsToImplementsWithTrivia.ts diff --git a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts index 446b0bddfab..cfa1a288ca8 100644 --- a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts +++ b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts @@ -27,11 +27,22 @@ namespace ts.codefix { } function doChanges(changes: textChanges.ChangeTracker, sourceFile: SourceFile, extendsToken: Node, heritageClauses: ReadonlyArray): void { - changes.replaceNode(sourceFile, extendsToken, createToken(SyntaxKind.ImplementsKeyword)); + changes.replaceRange(sourceFile, { pos: extendsToken.getStart(), end: extendsToken.end }, createToken(SyntaxKind.ImplementsKeyword)); // We replace existing keywords with commas. for (let i = 1; i < heritageClauses.length; i++) { const keywordToken = heritageClauses[i].getFirstToken()!; - changes.replaceNode(sourceFile, keywordToken, createToken(SyntaxKind.CommaToken)); + const keywordFullStart = keywordToken.getFullStart(); + changes.replaceRange(sourceFile, { pos: keywordFullStart, end: keywordFullStart }, createToken(SyntaxKind.CommaToken)); + + // Rough heuristic: delete trailing whitespace after keyword so that it's not excessive. + // (Trailing because leading might be indentation, which is more sensitive.) + const text = sourceFile.text; + let end = keywordToken.end; + while (end < text.length && ts.isWhiteSpaceSingleLine(text.charCodeAt(end))) { + end++; + } + + changes.deleteRange(sourceFile, { pos: keywordToken.getStart(), end }); } } } diff --git a/tests/cases/fourslash/codeFixChangeExtendsToImplementsAbstractModifier.ts b/tests/cases/fourslash/codeFixChangeExtendsToImplementsAbstractModifier.ts index 9bec3df4f41..0a7ae3e0e68 100644 --- a/tests/cases/fourslash/codeFixChangeExtendsToImplementsAbstractModifier.ts +++ b/tests/cases/fourslash/codeFixChangeExtendsToImplementsAbstractModifier.ts @@ -8,5 +8,5 @@ verify.codeFix({ description: "Change 'extends' to 'implements'", // TODO: GH#18794 - newRangeContent: "abstract class A implements I1 , I2", + newRangeContent: "abstract class A implements I1, I2", }); diff --git a/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithDecorator.ts b/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithDecorator.ts index 6940cd27830..e183677a31f 100644 --- a/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithDecorator.ts +++ b/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithDecorator.ts @@ -13,5 +13,5 @@ verify.codeFix({ description: "Change 'extends' to 'implements'", // TODO: GH#18794 - newRangeContent: "class A implements I1 , I2 { }", + newRangeContent: "class A implements I1, I2 { }", }); diff --git a/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithTrivia.ts b/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithTrivia.ts new file mode 100644 index 00000000000..ed7fa4c3b1d --- /dev/null +++ b/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithTrivia.ts @@ -0,0 +1,19 @@ +/// + +//// interface I1 { } +//// interface I2 { } +//// interface I3 { } + +//// [|class MyClass /*A !*/ //B ! +//// /*C !*/ extends /*D !*/ I1 /*E !*/ //F ! +//// /*G !*/ implements /*H !*/ I2 /*I !*/, /*J !*/ I3 /*K !*/ //L !|] +//// { +//// } + +verify.codeFix({ + description: "Change 'extends' to 'implements'", + // TODO: GH#18794 + newRangeContent: `class MyClass /*A !*/ //B ! + /*C !*/ implements /*D !*/ I1, /*E !*/ //F ! + /*G !*/ /*H !*/ I2 /*I !*/, /*J !*/ I3 /*K !*/ //L !`, +}); From a961d7aa047aeecd7e14f206c6371d0c10ed24ec Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 4 Jan 2018 18:05:58 -0800 Subject: [PATCH 061/189] Only replace `implements` with a comma if the heritage clauses are sensible --- .../fixExtendsInterfaceBecomesImplements.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts index cfa1a288ca8..d98ca556f47 100644 --- a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts +++ b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts @@ -28,21 +28,25 @@ namespace ts.codefix { function doChanges(changes: textChanges.ChangeTracker, sourceFile: SourceFile, extendsToken: Node, heritageClauses: ReadonlyArray): void { changes.replaceRange(sourceFile, { pos: extendsToken.getStart(), end: extendsToken.end }, createToken(SyntaxKind.ImplementsKeyword)); - // We replace existing keywords with commas. - for (let i = 1; i < heritageClauses.length; i++) { - const keywordToken = heritageClauses[i].getFirstToken()!; - const keywordFullStart = keywordToken.getFullStart(); - changes.replaceRange(sourceFile, { pos: keywordFullStart, end: keywordFullStart }, createToken(SyntaxKind.CommaToken)); + + // If there is already an implements clause, replace the implements keyword with a comma. + if (heritageClauses.length === 2 && + heritageClauses[0].token === SyntaxKind.ExtendsKeyword && + heritageClauses[1].token === SyntaxKind.ImplementsKeyword) { + + const implementsToken = heritageClauses[1].getFirstToken()!; + const implementsFullStart = implementsToken.getFullStart(); + changes.replaceRange(sourceFile, { pos: implementsFullStart, end: implementsFullStart }, createToken(SyntaxKind.CommaToken)); // Rough heuristic: delete trailing whitespace after keyword so that it's not excessive. // (Trailing because leading might be indentation, which is more sensitive.) const text = sourceFile.text; - let end = keywordToken.end; + let end = implementsToken.end; while (end < text.length && ts.isWhiteSpaceSingleLine(text.charCodeAt(end))) { end++; } - changes.deleteRange(sourceFile, { pos: keywordToken.getStart(), end }); + changes.deleteRange(sourceFile, { pos: implementsToken.getStart(), end }); } } } From f6dc0ad7070fbdfac52d17534ac0e69fc8ba513d Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 5 Jan 2018 09:10:58 -0800 Subject: [PATCH 062/189] Check for unused getter/setter in classes (#21013) * Check for unused getter/setter in classes * Write-only use of setter is still a reference; and don't error on setter if getter exists --- src/compiler/checker.ts | 68 +++++++++++-------- .../reference/unusedGetterInClass.errors.txt | 15 ++++ .../reference/unusedGetterInClass.js | 6 +- .../reference/unusedGetterInClass.symbols | 8 ++- .../reference/unusedGetterInClass.types | 6 +- .../reference/unusedSetterInClass.errors.txt | 7 +- .../reference/unusedSetterInClass.js | 2 +- .../reference/unusedSetterInClass.symbols | 6 +- .../reference/unusedSetterInClass.types | 2 +- .../reference/unusedSetterInClass2.errors.txt | 14 ++++ .../reference/unusedSetterInClass2.js | 25 +++++++ .../reference/unusedSetterInClass2.symbols | 18 +++++ .../reference/unusedSetterInClass2.types | 20 ++++++ tests/cases/compiler/unusedGetterInClass.ts | 4 +- tests/cases/compiler/unusedSetterInClass.ts | 2 +- tests/cases/compiler/unusedSetterInClass2.ts | 10 +++ 16 files changed, 173 insertions(+), 40 deletions(-) create mode 100644 tests/baselines/reference/unusedGetterInClass.errors.txt create mode 100644 tests/baselines/reference/unusedSetterInClass2.errors.txt create mode 100644 tests/baselines/reference/unusedSetterInClass2.js create mode 100644 tests/baselines/reference/unusedSetterInClass2.symbols create mode 100644 tests/baselines/reference/unusedSetterInClass2.types create mode 100644 tests/cases/compiler/unusedSetterInClass2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 46ba176a6bf..77b57b34b07 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16034,26 +16034,26 @@ namespace ts { } function markPropertyAsReferenced(prop: Symbol, nodeForCheckWriteOnly: Node | undefined, isThisAccess: boolean) { - if (prop && - noUnusedIdentifiers && - (prop.flags & SymbolFlags.ClassMember) && - prop.valueDeclaration && hasModifier(prop.valueDeclaration, ModifierFlags.Private) - && !(nodeForCheckWriteOnly && isWriteOnlyAccess(nodeForCheckWriteOnly))) { + if (!prop || !noUnusedIdentifiers || !(prop.flags & SymbolFlags.ClassMember) || !prop.valueDeclaration || !hasModifier(prop.valueDeclaration, ModifierFlags.Private)) { + return; + } + if (nodeForCheckWriteOnly && isWriteOnlyAccess(nodeForCheckWriteOnly) && !(prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor))) { + return; + } - if (isThisAccess) { - // Find any FunctionLikeDeclaration because those create a new 'this' binding. But this should only matter for methods (or getters/setters). - const containingMethod = findAncestor(nodeForCheckWriteOnly, isFunctionLikeDeclaration); - if (containingMethod && containingMethod.symbol === prop) { - return; - } + if (isThisAccess) { + // Find any FunctionLikeDeclaration because those create a new 'this' binding. But this should only matter for methods (or getters/setters). + const containingMethod = findAncestor(nodeForCheckWriteOnly, isFunctionLikeDeclaration); + if (containingMethod && containingMethod.symbol === prop) { + return; } + } - if (getCheckFlags(prop) & CheckFlags.Instantiated) { - getSymbolLinks(prop).target.isReferenced = true; - } - else { - prop.isReferenced = true; - } + if (getCheckFlags(prop) & CheckFlags.Instantiated) { + getSymbolLinks(prop).target.isReferenced = true; + } + else { + prop.isReferenced = true; } } @@ -21222,17 +21222,31 @@ namespace ts { if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) { if (node.members) { for (const member of node.members) { - if (member.kind === SyntaxKind.MethodDeclaration || member.kind === SyntaxKind.PropertyDeclaration) { - if (!member.symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) { - error(member.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(member.symbol)); - } - } - else if (member.kind === SyntaxKind.Constructor) { - for (const parameter of (member).parameters) { - if (!parameter.symbol.isReferenced && hasModifier(parameter, ModifierFlags.Private)) { - error(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol)); + switch (member.kind) { + case SyntaxKind.MethodDeclaration: + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + if (member.kind === SyntaxKind.SetAccessor && member.symbol.flags & SymbolFlags.GetAccessor) { + // Already would have reported an error on the getter. + break; } - } + if (!member.symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) { + error(member.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(member.symbol)); + } + break; + case SyntaxKind.Constructor: + for (const parameter of (member).parameters) { + if (!parameter.symbol.isReferenced && hasModifier(parameter, ModifierFlags.Private)) { + error(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol)); + } + } + break; + case SyntaxKind.IndexSignature: + // Can't be private + break; + default: + Debug.fail(); } } } diff --git a/tests/baselines/reference/unusedGetterInClass.errors.txt b/tests/baselines/reference/unusedGetterInClass.errors.txt new file mode 100644 index 00000000000..7ab8d33fd95 --- /dev/null +++ b/tests/baselines/reference/unusedGetterInClass.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/unusedGetterInClass.ts(4,17): error TS6133: 'fullName' is declared but its value is never read. + + +==== tests/cases/compiler/unusedGetterInClass.ts (1 errors) ==== + class Employee { + private _fullName: string; + + private get fullName(): string { + ~~~~~~~~ +!!! error TS6133: 'fullName' is declared but its value is never read. + return this._fullName; + } + // Will not also error on the setter + private set fullName(_: string) {} + } \ No newline at end of file diff --git a/tests/baselines/reference/unusedGetterInClass.js b/tests/baselines/reference/unusedGetterInClass.js index 0bdbf006608..3cdac7b63df 100644 --- a/tests/baselines/reference/unusedGetterInClass.js +++ b/tests/baselines/reference/unusedGetterInClass.js @@ -2,9 +2,11 @@ class Employee { private _fullName: string; - get fullName(): string { + private get fullName(): string { return this._fullName; } + // Will not also error on the setter + private set fullName(_: string) {} } //// [unusedGetterInClass.js] @@ -15,6 +17,8 @@ var Employee = /** @class */ (function () { get: function () { return this._fullName; }, + // Will not also error on the setter + set: function (_) { }, enumerable: true, configurable: true }); diff --git a/tests/baselines/reference/unusedGetterInClass.symbols b/tests/baselines/reference/unusedGetterInClass.symbols index 7bab42f6743..f80229b1972 100644 --- a/tests/baselines/reference/unusedGetterInClass.symbols +++ b/tests/baselines/reference/unusedGetterInClass.symbols @@ -5,12 +5,16 @@ class Employee { private _fullName: string; >_fullName : Symbol(Employee._fullName, Decl(unusedGetterInClass.ts, 0, 16)) - get fullName(): string { ->fullName : Symbol(Employee.fullName, Decl(unusedGetterInClass.ts, 1, 30)) + private get fullName(): string { +>fullName : Symbol(Employee.fullName, Decl(unusedGetterInClass.ts, 1, 30), Decl(unusedGetterInClass.ts, 5, 5)) return this._fullName; >this._fullName : Symbol(Employee._fullName, Decl(unusedGetterInClass.ts, 0, 16)) >this : Symbol(Employee, Decl(unusedGetterInClass.ts, 0, 0)) >_fullName : Symbol(Employee._fullName, Decl(unusedGetterInClass.ts, 0, 16)) } + // Will not also error on the setter + private set fullName(_: string) {} +>fullName : Symbol(Employee.fullName, Decl(unusedGetterInClass.ts, 1, 30), Decl(unusedGetterInClass.ts, 5, 5)) +>_ : Symbol(_, Decl(unusedGetterInClass.ts, 7, 25)) } diff --git a/tests/baselines/reference/unusedGetterInClass.types b/tests/baselines/reference/unusedGetterInClass.types index 648bed6ac5d..822d47e6952 100644 --- a/tests/baselines/reference/unusedGetterInClass.types +++ b/tests/baselines/reference/unusedGetterInClass.types @@ -5,7 +5,7 @@ class Employee { private _fullName: string; >_fullName : string - get fullName(): string { + private get fullName(): string { >fullName : string return this._fullName; @@ -13,4 +13,8 @@ class Employee { >this : this >_fullName : string } + // Will not also error on the setter + private set fullName(_: string) {} +>fullName : string +>_ : string } diff --git a/tests/baselines/reference/unusedSetterInClass.errors.txt b/tests/baselines/reference/unusedSetterInClass.errors.txt index d7cd764b293..d5380cdc1dd 100644 --- a/tests/baselines/reference/unusedSetterInClass.errors.txt +++ b/tests/baselines/reference/unusedSetterInClass.errors.txt @@ -1,13 +1,16 @@ tests/cases/compiler/unusedSetterInClass.ts(2,13): error TS6133: '_fullName' is declared but its value is never read. +tests/cases/compiler/unusedSetterInClass.ts(4,17): error TS6133: 'fullName' is declared but its value is never read. -==== tests/cases/compiler/unusedSetterInClass.ts (1 errors) ==== +==== tests/cases/compiler/unusedSetterInClass.ts (2 errors) ==== class Employee { private _fullName: string; ~~~~~~~~~ !!! error TS6133: '_fullName' is declared but its value is never read. - set fullName(newName: string) { + private set fullName(newName: string) { + ~~~~~~~~ +!!! error TS6133: 'fullName' is declared but its value is never read. this._fullName = newName; } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedSetterInClass.js b/tests/baselines/reference/unusedSetterInClass.js index 30911d8ef2a..9b7a65eb449 100644 --- a/tests/baselines/reference/unusedSetterInClass.js +++ b/tests/baselines/reference/unusedSetterInClass.js @@ -2,7 +2,7 @@ class Employee { private _fullName: string; - set fullName(newName: string) { + private set fullName(newName: string) { this._fullName = newName; } } diff --git a/tests/baselines/reference/unusedSetterInClass.symbols b/tests/baselines/reference/unusedSetterInClass.symbols index cf04d2da65f..da5d62bdc85 100644 --- a/tests/baselines/reference/unusedSetterInClass.symbols +++ b/tests/baselines/reference/unusedSetterInClass.symbols @@ -5,14 +5,14 @@ class Employee { private _fullName: string; >_fullName : Symbol(Employee._fullName, Decl(unusedSetterInClass.ts, 0, 16)) - set fullName(newName: string) { + private set fullName(newName: string) { >fullName : Symbol(Employee.fullName, Decl(unusedSetterInClass.ts, 1, 30)) ->newName : Symbol(newName, Decl(unusedSetterInClass.ts, 3, 17)) +>newName : Symbol(newName, Decl(unusedSetterInClass.ts, 3, 25)) this._fullName = newName; >this._fullName : Symbol(Employee._fullName, Decl(unusedSetterInClass.ts, 0, 16)) >this : Symbol(Employee, Decl(unusedSetterInClass.ts, 0, 0)) >_fullName : Symbol(Employee._fullName, Decl(unusedSetterInClass.ts, 0, 16)) ->newName : Symbol(newName, Decl(unusedSetterInClass.ts, 3, 17)) +>newName : Symbol(newName, Decl(unusedSetterInClass.ts, 3, 25)) } } diff --git a/tests/baselines/reference/unusedSetterInClass.types b/tests/baselines/reference/unusedSetterInClass.types index 1f6cf0d25a0..1a4c5c8a76c 100644 --- a/tests/baselines/reference/unusedSetterInClass.types +++ b/tests/baselines/reference/unusedSetterInClass.types @@ -5,7 +5,7 @@ class Employee { private _fullName: string; >_fullName : string - set fullName(newName: string) { + private set fullName(newName: string) { >fullName : string >newName : string diff --git a/tests/baselines/reference/unusedSetterInClass2.errors.txt b/tests/baselines/reference/unusedSetterInClass2.errors.txt new file mode 100644 index 00000000000..c3be0fc0302 --- /dev/null +++ b/tests/baselines/reference/unusedSetterInClass2.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/unusedSetterInClass2.ts(3,17): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + + +==== tests/cases/compiler/unusedSetterInClass2.ts (1 errors) ==== + // Unlike everything else, a setter without a getter is used by a write access. + class Employee { + private set p(_: number) {} + ~ +!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + + m() { + this.p = 0; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/unusedSetterInClass2.js b/tests/baselines/reference/unusedSetterInClass2.js new file mode 100644 index 00000000000..9c3111982a9 --- /dev/null +++ b/tests/baselines/reference/unusedSetterInClass2.js @@ -0,0 +1,25 @@ +//// [unusedSetterInClass2.ts] +// Unlike everything else, a setter without a getter is used by a write access. +class Employee { + private set p(_: number) {} + + m() { + this.p = 0; + } +} + +//// [unusedSetterInClass2.js] +// Unlike everything else, a setter without a getter is used by a write access. +var Employee = /** @class */ (function () { + function Employee() { + } + Object.defineProperty(Employee.prototype, "p", { + set: function (_) { }, + enumerable: true, + configurable: true + }); + Employee.prototype.m = function () { + this.p = 0; + }; + return Employee; +}()); diff --git a/tests/baselines/reference/unusedSetterInClass2.symbols b/tests/baselines/reference/unusedSetterInClass2.symbols new file mode 100644 index 00000000000..1092f85ff9e --- /dev/null +++ b/tests/baselines/reference/unusedSetterInClass2.symbols @@ -0,0 +1,18 @@ +=== tests/cases/compiler/unusedSetterInClass2.ts === +// Unlike everything else, a setter without a getter is used by a write access. +class Employee { +>Employee : Symbol(Employee, Decl(unusedSetterInClass2.ts, 0, 0)) + + private set p(_: number) {} +>p : Symbol(Employee.p, Decl(unusedSetterInClass2.ts, 1, 16)) +>_ : Symbol(_, Decl(unusedSetterInClass2.ts, 2, 18)) + + m() { +>m : Symbol(Employee.m, Decl(unusedSetterInClass2.ts, 2, 31)) + + this.p = 0; +>this.p : Symbol(Employee.p, Decl(unusedSetterInClass2.ts, 1, 16)) +>this : Symbol(Employee, Decl(unusedSetterInClass2.ts, 0, 0)) +>p : Symbol(Employee.p, Decl(unusedSetterInClass2.ts, 1, 16)) + } +} diff --git a/tests/baselines/reference/unusedSetterInClass2.types b/tests/baselines/reference/unusedSetterInClass2.types new file mode 100644 index 00000000000..0237db7ce8c --- /dev/null +++ b/tests/baselines/reference/unusedSetterInClass2.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/unusedSetterInClass2.ts === +// Unlike everything else, a setter without a getter is used by a write access. +class Employee { +>Employee : Employee + + private set p(_: number) {} +>p : number +>_ : number + + m() { +>m : () => void + + this.p = 0; +>this.p = 0 : 0 +>this.p : number +>this : this +>p : number +>0 : 0 + } +} diff --git a/tests/cases/compiler/unusedGetterInClass.ts b/tests/cases/compiler/unusedGetterInClass.ts index e5259f91cdc..cc08954eb75 100644 --- a/tests/cases/compiler/unusedGetterInClass.ts +++ b/tests/cases/compiler/unusedGetterInClass.ts @@ -5,7 +5,9 @@ class Employee { private _fullName: string; - get fullName(): string { + private get fullName(): string { return this._fullName; } + // Will not also error on the setter + private set fullName(_: string) {} } \ No newline at end of file diff --git a/tests/cases/compiler/unusedSetterInClass.ts b/tests/cases/compiler/unusedSetterInClass.ts index a8e45bab434..634f2b2b08e 100644 --- a/tests/cases/compiler/unusedSetterInClass.ts +++ b/tests/cases/compiler/unusedSetterInClass.ts @@ -5,7 +5,7 @@ class Employee { private _fullName: string; - set fullName(newName: string) { + private set fullName(newName: string) { this._fullName = newName; } } \ No newline at end of file diff --git a/tests/cases/compiler/unusedSetterInClass2.ts b/tests/cases/compiler/unusedSetterInClass2.ts new file mode 100644 index 00000000000..2e6ee32e0e6 --- /dev/null +++ b/tests/cases/compiler/unusedSetterInClass2.ts @@ -0,0 +1,10 @@ +// @noUnusedLocals:true + +// Unlike everything else, a setter without a getter is used by a write access. +class Employee { + private set p(_: number) {} + + m() { + this.p = 0; + } +} \ No newline at end of file From 25c5e570914ed6f83ed692c825506c1c4f02fff4 Mon Sep 17 00:00:00 2001 From: Marius Schulz Date: Sat, 30 Dec 2017 09:40:53 +0100 Subject: [PATCH 063/189] Return string completions for indexed access types --- src/compiler/utilities.ts | 2 +- src/services/completions.ts | 20 ++++++++++++++----- .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- ...letionForStringLiteralInIndexedAccess01.ts | 13 ++++++++++++ 5 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 tests/cases/fourslash/completionForStringLiteralInIndexedAccess01.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8a3e3132315..fce141490a3 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4403,7 +4403,7 @@ namespace ts { return node.kind === SyntaxKind.RegularExpressionLiteral; } - export function isNoSubstitutionTemplateLiteral(node: Node): node is LiteralExpression { + export function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral { return node.kind === SyntaxKind.NoSubstitutionTemplateLiteral; } diff --git a/src/services/completions.ts b/src/services/completions.ts index ed1933c3616..bc1cb4d6777 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -264,7 +264,8 @@ namespace ts.Completions { // } // let a: A; // a['/*completion position*/'] - return getStringLiteralCompletionEntriesFromElementAccess(node.parent, typeChecker, compilerOptions.target, log); + const type = typeChecker.getTypeAtLocation(node.parent.expression); + return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, type, typeChecker, compilerOptions.target, log); } else if (node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration || isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || isImportCall(node.parent) @@ -278,6 +279,16 @@ namespace ts.Completions { const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(node, compilerOptions, host, typeChecker); return pathCompletionsInfo(entries); } + else if (isIndexedAccessTypeNode(node.parent.parent)) { + // Get all apparent property names + // i.e. interface Foo { + // foo: string; + // bar: string; + // } + // let x: Foo["/*completion position*/"] + const type = typeChecker.getTypeFromTypeNode(node.parent.parent.objectType); + return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, type, typeChecker, compilerOptions.target, log); + } else { const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile); if (argumentInfo) { @@ -334,11 +345,10 @@ namespace ts.Completions { return undefined; } - function getStringLiteralCompletionEntriesFromElementAccess(node: ElementAccessExpression, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined { - const type = typeChecker.getTypeAtLocation(node.expression); + function getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(stringLiteralNode: StringLiteral | NoSubstitutionTemplateLiteral, type: Type, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined { const entries: CompletionEntry[] = []; if (type) { - getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true); + getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, stringLiteralNode, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true); if (entries.length) { return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries }; } @@ -1583,7 +1593,7 @@ namespace ts.Completions { switch (contextToken.kind) { case SyntaxKind.OpenParenToken: case SyntaxKind.CommaToken: - return isConstructorDeclaration(contextToken.parent) && contextToken.parent; + return isConstructorDeclaration(contextToken.parent) && contextToken.parent; default: if (isConstructorParameterCompletion(contextToken)) { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 6d7a69d350f..84ae424e07a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2911,7 +2911,7 @@ declare namespace ts { function isStringLiteral(node: Node): node is StringLiteral; function isJsxText(node: Node): node is JsxText; function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral; - function isNoSubstitutionTemplateLiteral(node: Node): node is LiteralExpression; + function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral; function isTemplateHead(node: Node): node is TemplateHead; function isTemplateMiddle(node: Node): node is TemplateMiddle; function isTemplateTail(node: Node): node is TemplateTail; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 4e9f13be2ce..c48392e9c15 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2964,7 +2964,7 @@ declare namespace ts { function isStringLiteral(node: Node): node is StringLiteral; function isJsxText(node: Node): node is JsxText; function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral; - function isNoSubstitutionTemplateLiteral(node: Node): node is LiteralExpression; + function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral; function isTemplateHead(node: Node): node is TemplateHead; function isTemplateMiddle(node: Node): node is TemplateMiddle; function isTemplateTail(node: Node): node is TemplateTail; diff --git a/tests/cases/fourslash/completionForStringLiteralInIndexedAccess01.ts b/tests/cases/fourslash/completionForStringLiteralInIndexedAccess01.ts new file mode 100644 index 00000000000..0a86f5396c4 --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteralInIndexedAccess01.ts @@ -0,0 +1,13 @@ +/// + +////interface Foo { +//// foo: string; +//// bar: string; +////} +//// +////let x: Foo["/*1*/"] + +goTo.marker("1"); +verify.completionListContains("foo"); +verify.completionListContains("bar"); +verify.completionListCount(2); From a0495a65fe1f84edc560aaf94dbf56051978a3d5 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Fri, 5 Jan 2018 10:53:18 -0800 Subject: [PATCH 064/189] Improve comment --- src/services/findAllReferences.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index de81cce8000..3665e097026 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -511,7 +511,8 @@ namespace ts.FindAllReferences.Core { createSearch(location: Node, symbol: Symbol, comingFrom: ImportExport | undefined, searchOptions: { text?: string, allSearchSymbols?: Symbol[] } = {}): Search { // Note: if this is an external module symbol, the name doesn't include quotes. // Note: getLocalSymbolForExportDefault handles `export default class C {}`, but not `export default C` or `export { C as default }`. - // The other two forms seem to be handled downstream (i.e. special-casing the first form here appears to be intentional). + // The other two forms seem to be handled downstream (e.g. in `skipPastExportOrImportSpecifier`), so special-casing the first form + // here appears to be intentional). const { text = stripQuotes(unescapeLeadingUnderscores((getLocalSymbolForExportDefault(symbol) || symbol).escapedName)), allSearchSymbols = undefined, From c6e4373403059d66743839a0677050edbf7deb04 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 5 Jan 2018 12:34:01 -0800 Subject: [PATCH 065/189] In checkAndAggregateReturnExpressionTypes, treat MethodDeclaration in an object literal same as a FunctionExpression (#20052) * In checkAndAggregateReturnExpressionTypes, treat MethodDeclaration in an object literal same as a FunctionExpression * Add original test case --- src/compiler/checker.ts | 24 +++++++++++++------ ...ature_objectLiteralMethodMayReturnNever.js | 7 ++++++ ..._objectLiteralMethodMayReturnNever.symbols | 11 +++++++++ ...re_objectLiteralMethodMayReturnNever.types | 14 +++++++++++ .../parserArrowFunctionExpression7.types | 6 ++--- .../throwInEnclosingStatements.types | 6 ++--- ...FunctionComponentsWithTypeArguments3.types | 4 ++-- ...ature_objectLiteralMethodMayReturnNever.ts | 2 ++ 8 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.js create mode 100644 tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.symbols create mode 100644 tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.types create mode 100644 tests/cases/compiler/contextualSignature_objectLiteralMethodMayReturnNever.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 77b57b34b07..7ef37260f8a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17985,7 +17985,6 @@ namespace ts { } function getReturnTypeFromBody(func: FunctionLikeDeclaration, checkMode?: CheckMode): Type { - const contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func); if (!func.body) { return unknownType; } @@ -18003,9 +18002,9 @@ namespace ts { } } else { - let types: Type[]; + let types = checkAndAggregateReturnExpressionTypes(func, checkMode); if (functionFlags & FunctionFlags.Generator) { // Generator or AsyncGenerator function - types = concatenate(checkAndAggregateYieldOperandTypes(func, checkMode), checkAndAggregateReturnExpressionTypes(func, checkMode)); + types = concatenate(checkAndAggregateYieldOperandTypes(func, checkMode), types); if (!types || types.length === 0) { const iterableIteratorAny = functionFlags & FunctionFlags.Async ? createAsyncIterableIteratorType(anyType) // AsyncGenerator function @@ -18018,7 +18017,6 @@ namespace ts { } } else { - types = checkAndAggregateReturnExpressionTypes(func, checkMode); if (!types) { // For an async function, the return type will not be never, but rather a Promise for never. return functionFlags & FunctionFlags.Async @@ -18037,6 +18035,7 @@ namespace ts { type = getUnionType(types, UnionReduction.Subtype); } + const contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func); if (!contextualSignature) { reportErrorsFromWidening(func, type); } @@ -18126,7 +18125,8 @@ namespace ts { return true; } - function checkAndAggregateReturnExpressionTypes(func: FunctionLikeDeclaration, checkMode: CheckMode): Type[] { + /** NOTE: Return value of `[]` means a different thing than `undefined`. `[]` means return `void`, `undefined` means return `never`. */ + function checkAndAggregateReturnExpressionTypes(func: FunctionLikeDeclaration, checkMode: CheckMode): Type[] | undefined { const functionFlags = getFunctionFlags(func); const aggregatedTypes: Type[] = []; let hasReturnWithNoExpression = functionHasImplicitReturn(func); @@ -18151,8 +18151,7 @@ namespace ts { hasReturnWithNoExpression = true; } }); - if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || - func.kind === SyntaxKind.FunctionExpression || func.kind === SyntaxKind.ArrowFunction)) { + if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || mayReturnNever(func))) { return undefined; } if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression) { @@ -18160,6 +18159,17 @@ namespace ts { } return aggregatedTypes; } + function mayReturnNever(func: FunctionLikeDeclaration): boolean { + switch (func.kind) { + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + return true; + case SyntaxKind.MethodDeclaration: + return func.parent.kind === SyntaxKind.ObjectLiteralExpression; + default: + return false; + } + } /** * TypeScript Specification 1.0 (6.3) - July 2014 diff --git a/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.js b/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.js new file mode 100644 index 00000000000..1f507791802 --- /dev/null +++ b/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.js @@ -0,0 +1,7 @@ +//// [contextualSignature_objectLiteralMethodMayReturnNever.ts] +interface I { m(): number; } +const o: I = { m() { throw new Error("not implemented"); } }; + + +//// [contextualSignature_objectLiteralMethodMayReturnNever.js] +var o = { m: function () { throw new Error("not implemented"); } }; diff --git a/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.symbols b/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.symbols new file mode 100644 index 00000000000..dd58d4d35ed --- /dev/null +++ b/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/contextualSignature_objectLiteralMethodMayReturnNever.ts === +interface I { m(): number; } +>I : Symbol(I, Decl(contextualSignature_objectLiteralMethodMayReturnNever.ts, 0, 0)) +>m : Symbol(I.m, Decl(contextualSignature_objectLiteralMethodMayReturnNever.ts, 0, 13)) + +const o: I = { m() { throw new Error("not implemented"); } }; +>o : Symbol(o, Decl(contextualSignature_objectLiteralMethodMayReturnNever.ts, 1, 5)) +>I : Symbol(I, Decl(contextualSignature_objectLiteralMethodMayReturnNever.ts, 0, 0)) +>m : Symbol(m, Decl(contextualSignature_objectLiteralMethodMayReturnNever.ts, 1, 14)) +>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + diff --git a/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.types b/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.types new file mode 100644 index 00000000000..aa1da8edcfc --- /dev/null +++ b/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/contextualSignature_objectLiteralMethodMayReturnNever.ts === +interface I { m(): number; } +>I : I +>m : () => number + +const o: I = { m() { throw new Error("not implemented"); } }; +>o : I +>I : I +>{ m() { throw new Error("not implemented"); } } : { m(): never; } +>m : () => never +>new Error("not implemented") : Error +>Error : ErrorConstructor +>"not implemented" : "not implemented" + diff --git a/tests/baselines/reference/parserArrowFunctionExpression7.types b/tests/baselines/reference/parserArrowFunctionExpression7.types index 072a1548bd2..9edac3b8474 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression7.types +++ b/tests/baselines/reference/parserArrowFunctionExpression7.types @@ -1,10 +1,10 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression7.ts === ({ ->({ async m() { for (;;) { } }}) : { m(): Promise; } ->{ async m() { for (;;) { } }} : { m(): Promise; } +>({ async m() { for (;;) { } }}) : { m(): Promise; } +>{ async m() { for (;;) { } }} : { m(): Promise; } async m() { ->m : () => Promise +>m : () => Promise for (;;) { } diff --git a/tests/baselines/reference/throwInEnclosingStatements.types b/tests/baselines/reference/throwInEnclosingStatements.types index e031d00147d..d46307b0ea2 100644 --- a/tests/baselines/reference/throwInEnclosingStatements.types +++ b/tests/baselines/reference/throwInEnclosingStatements.types @@ -92,15 +92,15 @@ class C { } var aa = { ->aa : { id: number; biz(): void; } ->{ id:12, biz() { throw this; }} : { id: number; biz(): void; } +>aa : { id: number; biz(): never; } +>{ id:12, biz() { throw this; }} : { id: number; biz(): never; } id:12, >id : number >12 : 12 biz() { ->biz : () => void +>biz : () => never throw this; >this : any diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.types b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.types index aa38d2ccf8a..32f483227d3 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.types +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.types @@ -130,8 +130,8 @@ function createLink(func: (a: number)=>void) { >o1 : JSX.Element >{}} /> : JSX.Element >Link : { (l: { func: (arg: U) => void; }): JSX.Element; (l: { func: (arg1: U, arg2: string) => void; }): JSX.Element; } ->func : (a: number, b: string) => any ->(a:number, b:string)=>{} : (a: number, b: string) => any +>func : (a: number, b: string) => void +>(a:number, b:string)=>{} : (a: number, b: string) => void >a : number >b : string } diff --git a/tests/cases/compiler/contextualSignature_objectLiteralMethodMayReturnNever.ts b/tests/cases/compiler/contextualSignature_objectLiteralMethodMayReturnNever.ts new file mode 100644 index 00000000000..2536f67f6c4 --- /dev/null +++ b/tests/cases/compiler/contextualSignature_objectLiteralMethodMayReturnNever.ts @@ -0,0 +1,2 @@ +interface I { m(): number; } +const o: I = { m() { throw new Error("not implemented"); } }; From 13c26fe8cf16dc812526298e5e78d00d51af98b6 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Fri, 5 Jan 2018 13:32:01 -0800 Subject: [PATCH 066/189] Add regression tests for rename display name --- tests/cases/fourslash/renameForAliasingExport01.ts | 9 +++++++++ tests/cases/fourslash/renameForAliasingExport02.ts | 9 +++++++++ 2 files changed, 18 insertions(+) create mode 100644 tests/cases/fourslash/renameForAliasingExport01.ts create mode 100644 tests/cases/fourslash/renameForAliasingExport02.ts diff --git a/tests/cases/fourslash/renameForAliasingExport01.ts b/tests/cases/fourslash/renameForAliasingExport01.ts new file mode 100644 index 00000000000..a46d1806933 --- /dev/null +++ b/tests/cases/fourslash/renameForAliasingExport01.ts @@ -0,0 +1,9 @@ +/// + +// @Filename: foo.ts +////let x = 1; +//// +////export { /**/[|x|] as y }; + +goTo.marker(); +verify.renameInfoSucceeded(/*displayName*/"x", /*fullDisplayName*/"x"); \ No newline at end of file diff --git a/tests/cases/fourslash/renameForAliasingExport02.ts b/tests/cases/fourslash/renameForAliasingExport02.ts new file mode 100644 index 00000000000..ece969ca504 --- /dev/null +++ b/tests/cases/fourslash/renameForAliasingExport02.ts @@ -0,0 +1,9 @@ +/// + +// @Filename: foo.ts +////let x = 1; +//// +////export { x as /**/[|y|] }; + +goTo.marker(); +verify.renameInfoSucceeded(/*displayName*/"y", /*fullDisplayName*/'"/tests/cases/fourslash/foo".y'); \ No newline at end of file From 8f5a76d48bf309d2387df517918e9ed389bb9bd4 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Fri, 5 Jan 2018 14:24:40 -0800 Subject: [PATCH 067/189] Make fixCannotFindModule return an empty array if there is no code action --- src/services/codefixes/fixCannotFindModule.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/services/codefixes/fixCannotFindModule.ts b/src/services/codefixes/fixCannotFindModule.ts index 2a3736531b2..2a123267435 100644 --- a/src/services/codefixes/fixCannotFindModule.ts +++ b/src/services/codefixes/fixCannotFindModule.ts @@ -4,9 +4,8 @@ namespace ts.codefix { const errorCodes = [Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code]; registerCodeFix({ errorCodes, - getCodeActions: context => [ - { fixId, ...tryGetCodeActionForInstallPackageTypes(context.host, context.sourceFile.fileName, getModuleName(context.sourceFile, context.span.start)) } - ], + getCodeActions: context => (codeAction => codeAction ? [ { fixId, ...codeAction } ] : [])( + tryGetCodeActionForInstallPackageTypes(context.host, context.sourceFile.fileName, getModuleName(context.sourceFile, context.span.start))), fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (_, diag, commands) => { const pkg = getTypesPackageNameToInstall(context.host, getModuleName(diag.file, diag.start)); From ded788e56074e334860d93ec7fc1b1c7f4e041ef Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Fri, 5 Jan 2018 14:54:59 -0800 Subject: [PATCH 068/189] Slightly simplify getCodeActions --- src/services/codefixes/fixCannotFindModule.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/codefixes/fixCannotFindModule.ts b/src/services/codefixes/fixCannotFindModule.ts index 2a123267435..75aad8935f6 100644 --- a/src/services/codefixes/fixCannotFindModule.ts +++ b/src/services/codefixes/fixCannotFindModule.ts @@ -4,7 +4,7 @@ namespace ts.codefix { const errorCodes = [Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code]; registerCodeFix({ errorCodes, - getCodeActions: context => (codeAction => codeAction ? [ { fixId, ...codeAction } ] : [])( + getCodeActions: context => (codeAction => codeAction && [{ fixId, ...codeAction }])( tryGetCodeActionForInstallPackageTypes(context.host, context.sourceFile.fileName, getModuleName(context.sourceFile, context.span.start))), fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (_, diag, commands) => { From f8c86552bcd8d672c9f47ce961199d1d295b7f45 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 5 Jan 2018 15:44:38 -0800 Subject: [PATCH 069/189] Better name for deferred mapped type:ReverseMapped --- src/compiler/checker.ts | 52 ++++++++++--------- src/compiler/types.ts | 8 +-- .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d21b15249ba..b3669978bab 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -339,7 +339,7 @@ namespace ts { const jsObjectLiteralIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false); const globals = createSymbolTable(); - const deferredInferenceCache = createMap(); + const reverseMappedCache = createMap(); let ambientModulesCache: Symbol[] | undefined; /** * List of every ambient module with a "*" wildcard. @@ -2861,7 +2861,7 @@ namespace ts { typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructSignature, context)); } if (resolvedType.stringIndexInfo) { - const indexInfo = resolvedType.objectFlags & ObjectFlags.Deferred ? + const indexInfo = resolvedType.objectFlags & ObjectFlags.ReverseMapped ? createIndexInfo(anyType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration) : resolvedType.stringIndexInfo; typeElements.push(indexInfoToIndexSignatureDeclarationHelper(indexInfo, IndexKind.String, context)); @@ -2876,7 +2876,7 @@ namespace ts { } for (const propertySymbol of properties) { - const propertyType = getCheckFlags(propertySymbol) & CheckFlags.Deferred ? anyType : getTypeOfSymbol(propertySymbol); + const propertyType = getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped ? anyType : getTypeOfSymbol(propertySymbol); const saveEnclosingDeclaration = context.enclosingDeclaration; context.enclosingDeclaration = undefined; const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true); @@ -3685,7 +3685,7 @@ namespace ts { writePunctuation(writer, SyntaxKind.SemicolonToken); writer.writeLine(); } - const stringIndexInfo = resolved.objectFlags & ObjectFlags.Deferred && resolved.stringIndexInfo ? + const stringIndexInfo = resolved.objectFlags & ObjectFlags.ReverseMapped && resolved.stringIndexInfo ? createIndexInfo(anyType, resolved.stringIndexInfo.isReadonly, resolved.stringIndexInfo.declaration) : resolved.stringIndexInfo; buildIndexSignatureDisplay(stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack); @@ -3699,7 +3699,7 @@ namespace ts { writer.reportPrivateInBaseOfClassExpression(symbolName(p)); } } - const t = getCheckFlags(p) & CheckFlags.Deferred ? anyType : getTypeOfSymbol(p); + const t = getCheckFlags(p) & CheckFlags.ReverseMapped ? anyType : getTypeOfSymbol(p); if (p.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) { const signatures = getSignaturesOfType(t, SignatureKind.Call); for (const signature of signatures) { @@ -4907,8 +4907,8 @@ namespace ts { if (getCheckFlags(symbol) & CheckFlags.Instantiated) { return getTypeOfInstantiatedSymbol(symbol); } - if (getCheckFlags(symbol) & CheckFlags.Deferred) { - return inferDeferredMappedType((symbol as DeferredTransientSymbol).propertyType, (symbol as DeferredTransientSymbol).mappedType); + if (getCheckFlags(symbol) & CheckFlags.ReverseMapped) { + return getTypeOfReverseMappedSymbol(symbol as ReverseMappedSymbol); } if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) { return getTypeOfVariableOrParameterOrProperty(symbol); @@ -6120,15 +6120,15 @@ namespace ts { } } - function resolveDeferredMappedTypeMembers(type: DeferredMappedType) { + function resolveReverseMappedTypeMembers(type: ReverseMappedType) { const indexInfo = getIndexInfoOfType(type.source, IndexKind.String); const readonlyMask = type.mappedType.declaration.readonlyToken ? false : true; const optionalMask = type.mappedType.declaration.questionToken ? 0 : SymbolFlags.Optional; - const stringIndexInfo = indexInfo && createIndexInfo(inferDeferredMappedType(indexInfo.type, type.mappedType), readonlyMask && indexInfo.isReadonly); + const stringIndexInfo = indexInfo && createIndexInfo(inferReverseMappedType(indexInfo.type, type.mappedType), readonlyMask && indexInfo.isReadonly); const members = createSymbolTable(); for (const prop of getPropertiesOfType(type.source)) { - const checkFlags = CheckFlags.Deferred | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); - const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as DeferredTransientSymbol; + 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.propertyType = getTypeOfSymbol(prop); inferredProp.mappedType = type.mappedType; @@ -6276,8 +6276,8 @@ namespace ts { else if ((type).objectFlags & ObjectFlags.ClassOrInterface) { resolveClassOrInterfaceMembers(type); } - else if ((type).objectFlags & ObjectFlags.Deferred) { - resolveDeferredMappedTypeMembers(type as DeferredMappedType); + else if ((type).objectFlags & ObjectFlags.ReverseMapped) { + resolveReverseMappedTypeMembers(type as ReverseMappedType); } else if ((type).objectFlags & ObjectFlags.Anonymous) { resolveAnonymousTypeMembers(type); @@ -11307,16 +11307,16 @@ namespace ts { */ function inferTypeForHomomorphicMappedType(source: Type, target: MappedType): Type { const key = source.id + "," + target.id; - if (deferredInferenceCache.has(key)) { - return deferredInferenceCache.get(key); + if (reverseMappedCache.has(key)) { + return reverseMappedCache.get(key); } - deferredInferenceCache.set(key, undefined); - const type = createDeferredMappedType(source, target); - deferredInferenceCache.set(key, type); + reverseMappedCache.set(key, undefined); + const type = createReverseMappedType(source, target); + reverseMappedCache.set(key, type); return type; } - function createDeferredMappedType(source: Type, target: MappedType) { + function createReverseMappedType(source: Type, target: MappedType) { const properties = getPropertiesOfType(source); if (properties.length === 0 && !getIndexInfoOfType(source, IndexKind.String)) { return undefined; @@ -11328,13 +11328,17 @@ namespace ts { return undefined; } } - const deferred = createObjectType(ObjectFlags.Deferred | ObjectFlags.Anonymous, /*symbol*/ undefined) as DeferredMappedType; - deferred.source = source; - deferred.mappedType = target; - return deferred; + const reversed = createObjectType(ObjectFlags.ReverseMapped | ObjectFlags.Anonymous, /*symbol*/ undefined) as ReverseMappedType; + reversed.source = source; + reversed.mappedType = target; + return reversed; } - function inferDeferredMappedType(sourceType: Type, target: MappedType): Type { + function getTypeOfReverseMappedSymbol(symbol: ReverseMappedSymbol) { + return inferReverseMappedType(symbol.propertyType, symbol.mappedType); + } + + function inferReverseMappedType(sourceType: Type, target: MappedType): Type { const typeParameter = getIndexedAccessType((getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target)); const templateType = getTemplateTypeFromMappedType(target); const inference = createInferenceInfo(typeParameter); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index bd49ce9f90c..8398726ee66 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3251,7 +3251,7 @@ namespace ts { ContainsPrivate = 1 << 8, // Synthetic property with private constituent(s) ContainsStatic = 1 << 9, // Synthetic property with static constituent(s) Late = 1 << 10, // Late-bound symbol for a computed property with a dynamic name - Deferred = 1 << 11, // Deferred inferred property of homomorphic mapped type. + ReverseMapped = 1 << 11, // property of reverse-inferred homomorphic mapped type. Synthetic = SyntheticProperty | SyntheticMethod } @@ -3262,7 +3262,7 @@ namespace ts { } /* @internal */ - export interface DeferredTransientSymbol extends TransientSymbol { + export interface ReverseMappedSymbol extends TransientSymbol { propertyType: Type; mappedType: MappedType; } @@ -3501,7 +3501,7 @@ namespace ts { EvolvingArray = 1 << 8, // Evolving array type ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties ContainsSpread = 1 << 10, // Object literal contains spread operation - Deferred = 1 << 11, // Object contains a deferred inferred property + ReverseMapped = 1 << 11, // Object contains a property from a reverse-mapped type ClassOrInterface = Class | Interface } @@ -3610,7 +3610,7 @@ namespace ts { } /* @internal */ - export interface DeferredMappedType extends ObjectType { + export interface ReverseMappedType extends ObjectType { source: Type; mappedType: MappedType; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 926e715aaf3..145bf5f6fa8 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2066,7 +2066,7 @@ declare namespace ts { EvolvingArray = 256, ObjectLiteralPatternWithComputedProperties = 512, ContainsSpread = 1024, - Deferred = 2048, + ReverseMapped = 2048, ClassOrInterface = 3, } interface ObjectType extends Type { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 2709e0c5294..ea547f4f45e 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2066,7 +2066,7 @@ declare namespace ts { EvolvingArray = 256, ObjectLiteralPatternWithComputedProperties = 512, ContainsSpread = 1024, - Deferred = 2048, + ReverseMapped = 2048, ClassOrInterface = 3, } interface ObjectType extends Type { From 47aad0b8fd2dd1989afbf82079dc1f7b097ef9d1 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Fri, 5 Jan 2018 16:12:12 -0800 Subject: [PATCH 070/189] Switch to block-bodied lambda --- src/services/codefixes/fixCannotFindModule.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/services/codefixes/fixCannotFindModule.ts b/src/services/codefixes/fixCannotFindModule.ts index 75aad8935f6..a28a46caf1b 100644 --- a/src/services/codefixes/fixCannotFindModule.ts +++ b/src/services/codefixes/fixCannotFindModule.ts @@ -4,8 +4,10 @@ namespace ts.codefix { const errorCodes = [Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code]; registerCodeFix({ errorCodes, - getCodeActions: context => (codeAction => codeAction && [{ fixId, ...codeAction }])( - tryGetCodeActionForInstallPackageTypes(context.host, context.sourceFile.fileName, getModuleName(context.sourceFile, context.span.start))), + getCodeActions: context => { + const codeAction = tryGetCodeActionForInstallPackageTypes(context.host, context.sourceFile.fileName, getModuleName(context.sourceFile, context.span.start)); + return codeAction && [{ fixId, ...codeAction }]; + }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (_, diag, commands) => { const pkg = getTypesPackageNameToInstall(context.host, getModuleName(diag.file, diag.start)); From b07797cc97b81652027b7e2606886090ab085c3f Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Fri, 5 Jan 2018 16:23:08 -0800 Subject: [PATCH 071/189] Convert test from JS to TS --- .../fourslash/importNameCodeFixDefaultExport2.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/tests/cases/fourslash/importNameCodeFixDefaultExport2.ts b/tests/cases/fourslash/importNameCodeFixDefaultExport2.ts index 8e09196d06c..f6c12044dd9 100644 --- a/tests/cases/fourslash/importNameCodeFixDefaultExport2.ts +++ b/tests/cases/fourslash/importNameCodeFixDefaultExport2.ts @@ -1,21 +1,14 @@ /// -// @allowJs: true -// @checkJs: true - -// @Filename: /lib.js +// @Filename: /lib.ts ////class Base { } ////export default Base; -// @Filename: /test.js +// @Filename: /test.ts ////[|class Derived extends Base { }|] -goTo.file("/test.js"); +goTo.file("/test.ts"); verify.importFixAtPosition([ -`// @ts-ignore -class Derived extends Base { }`, -`// @ts-nocheck -class Derived extends Base { }`, `import Base from "./lib"; class Derived extends Base { }`,]); From 18f9d693fe65080d2a0f24f2c03992f8f213dba9 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Fri, 5 Jan 2018 16:29:53 -0800 Subject: [PATCH 072/189] Stop limiting getEscapedNameForExportDefault to the first declaration --- src/services/codefixes/importFixes.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 1ff23f679d8..171a0925843 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -789,9 +789,7 @@ namespace ts.codefix { } function getEscapedNameForExportDefault(symbol: Symbol): __String | undefined { - const declarations = symbol.declarations; - if (length(declarations) > 0) { - const declaration = declarations[0]; + return firstDefined(symbol.declarations, declaration => { if (isExportAssignment(declaration)) { if (isIdentifier(declaration.expression)) { return declaration.expression.escapedText; @@ -803,7 +801,7 @@ namespace ts.codefix { return declaration.propertyName.escapedText; } } - } + }); } }); From e35585b938c5ed1f5a8f725f934b7fa4fe9e0639 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 5 Jan 2018 17:33:29 -0800 Subject: [PATCH 073/189] Fix conflict between formatting rules (#21038) --- src/services/formatting/rules.ts | 2 +- .../formatInsertSpaceAfterCloseBraceBeforeCloseBracket.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/formatInsertSpaceAfterCloseBraceBeforeCloseBracket.ts diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 40cb764f292..debf1702b49 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -80,7 +80,7 @@ namespace ts.formatting { rule("SpaceAfterSubtractWhenFollowedByUnaryMinus", SyntaxKind.MinusToken, SyntaxKind.MinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), rule("SpaceAfterSubtractWhenFollowedByPredecrement", SyntaxKind.MinusToken, SyntaxKind.MinusMinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), - rule("NoSpaceAfterCloseBrace", SyntaxKind.CloseBraceToken, [SyntaxKind.CloseBracketToken, SyntaxKind.CommaToken, SyntaxKind.SemicolonToken], [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceAfterCloseBrace", SyntaxKind.CloseBraceToken, [SyntaxKind.CommaToken, SyntaxKind.SemicolonToken], [isNonJsxSameLineTokenContext], RuleAction.Delete), // For functions and control block place } on a new line [multi-line rule] rule("NewLineBeforeCloseBraceInBlockContext", anyTokenIncludingMultilineComments, SyntaxKind.CloseBraceToken, [isMultilineBlockContext], RuleAction.NewLine), diff --git a/tests/cases/fourslash/formatInsertSpaceAfterCloseBraceBeforeCloseBracket.ts b/tests/cases/fourslash/formatInsertSpaceAfterCloseBraceBeforeCloseBracket.ts new file mode 100644 index 00000000000..c7df70734b0 --- /dev/null +++ b/tests/cases/fourslash/formatInsertSpaceAfterCloseBraceBeforeCloseBracket.ts @@ -0,0 +1,7 @@ +/// + +////[{}] + +format.setOption("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets", true); +format.document(); +verify.currentFileContentIs("[ {} ]"); From bc2983def97ccaa10c98b17d3942b9d5806dcfda Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Sat, 6 Jan 2018 02:36:33 +0100 Subject: [PATCH 074/189] API: fix types to undefined union (#20909) --- src/compiler/types.ts | 6 +++--- tests/baselines/reference/api/tsserverlibrary.d.ts | 6 +++--- tests/baselines/reference/api/typescript.d.ts | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8398726ee66..4f5ef1900f5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2540,7 +2540,7 @@ namespace ts { export interface ParseConfigHost { useCaseSensitiveFileNames: boolean; - readDirectory(rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray, includes: ReadonlyArray, depth: number): string[]; + readDirectory(rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray | undefined, includes: ReadonlyArray, depth?: number): string[]; /** * Gets a value indicating whether the specified path exists and is a file. @@ -4380,11 +4380,11 @@ namespace ts { * If resolveModuleNames is implemented then implementation for members from ModuleResolutionHost can be just * 'throw new Error("NotImplemented")' */ - resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[]; + resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): (ResolvedModule | undefined)[]; /** * This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files */ - resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; + resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): (ResolvedTypeReferenceDirective | undefined)[]; getEnvironmentVariable?(name: string): string; /* @internal */ onReleaseOldSourceFile?(oldSourceFile: SourceFile, oldOptions: CompilerOptions): void; /* @internal */ hasInvalidatedResolution?: HasInvalidatedResolution; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index aeefab5761e..aa9e1d9a62f 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1615,7 +1615,7 @@ declare namespace ts { } interface ParseConfigHost { useCaseSensitiveFileNames: boolean; - readDirectory(rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray, includes: ReadonlyArray, depth: number): string[]; + readDirectory(rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray | undefined, includes: ReadonlyArray, depth?: number): string[]; /** * Gets a value indicating whether the specified path exists and is a file. * @param path The path to test. @@ -2468,11 +2468,11 @@ declare namespace ts { getCanonicalFileName(fileName: string): string; useCaseSensitiveFileNames(): boolean; getNewLine(): string; - resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[]; + resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): (ResolvedModule | undefined)[]; /** * This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files */ - resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; + resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): (ResolvedTypeReferenceDirective | undefined)[]; getEnvironmentVariable?(name: string): string; } interface SourceMapRange extends TextRange { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 5d4b0d8b7b8..3ee55ce823d 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1615,7 +1615,7 @@ declare namespace ts { } interface ParseConfigHost { useCaseSensitiveFileNames: boolean; - readDirectory(rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray, includes: ReadonlyArray, depth: number): string[]; + readDirectory(rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray | undefined, includes: ReadonlyArray, depth?: number): string[]; /** * Gets a value indicating whether the specified path exists and is a file. * @param path The path to test. @@ -2468,11 +2468,11 @@ declare namespace ts { getCanonicalFileName(fileName: string): string; useCaseSensitiveFileNames(): boolean; getNewLine(): string; - resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[]; + resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): (ResolvedModule | undefined)[]; /** * This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files */ - resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; + resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): (ResolvedTypeReferenceDirective | undefined)[]; getEnvironmentVariable?(name: string): string; } interface SourceMapRange extends TextRange { From 0875916afbc786874f27f82761f1015dbf112898 Mon Sep 17 00:00:00 2001 From: csigs Date: Sat, 6 Jan 2018 11:10:13 +0000 Subject: [PATCH 075/189] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 3 +++ 2 files 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 8131e17425e..922edbca2de 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2067,6 +2067,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index daf741d6980..34cf0f01ff6 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2066,6 +2066,9 @@ + + + From c7c88140be68d281dbdfc9ea28e396d5b53b2350 Mon Sep 17 00:00:00 2001 From: csigs Date: Sun, 7 Jan 2018 05:10:17 +0000 Subject: [PATCH 076/189] 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/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 44e5ea6192f..30850814f26 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2082,6 +2082,9 @@ + + + From 902d3b70554a2332816659eeb29c7a7964d4226e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Sat, 6 Jan 2018 23:11:40 -0800 Subject: [PATCH 077/189] Add release-2.7 to covered branches --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 06e912c55f5..b4a5227c34a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,7 @@ branches: - master - release-2.5 - release-2.6 + - release-2.7 install: - npm uninstall typescript --no-save From fd96b81130b92a34002ffad52cd80d48bb796cb8 Mon Sep 17 00:00:00 2001 From: csigs Date: Sun, 7 Jan 2018 23:10:50 +0000 Subject: [PATCH 078/189] 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/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 8c388d5fd73..c2febd1ee9b 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2082,6 +2082,9 @@ + + + From f63dd5356b50a85f6886edfad11d2a2eade85073 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 8 Jan 2018 08:04:46 -0800 Subject: [PATCH 079/189] Update CONTRIBUTING.md --- CONTRIBUTING.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fd0f4348c62..1d11db2f87b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,14 @@ Issues that ask questions answered in the FAQ will be closed without elaboration ## 2. Search for Duplicates -[Search the existing issues](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=is%3Aissue) before logging a new one. +[Search the existing issues](https://github.com/Microsoft/TypeScript/search?type=Issues) before logging a new one. + +Some search tips: + * *Don't* restrict your search to only open issues. An issue with a title similar to yours may have been closed as a duplicate of one with a less-findable title. + * Check for synonyms. For example, if your bug involves an interface, it likely also occurs with type aliases or classes. + * Search for the title of the issue you're about to log. This sounds obvious but 80% of the time this is sufficient to find a duplicate when one exists. + * Read more than the first page of results. Many bugs here use the same words so relevancy sorting is not particularly strong. + * If you have a crash, search for the first few topmost function names shown in the call stack. ## 3. Do you have a question? From 6f2ba154464a310a8262a0b6f6967318ba83b7d2 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 08:52:13 -0800 Subject: [PATCH 080/189] Start linting for double spaces (#20820) * Start linting for double spaces * Code review * Fix cases that were excluded by countDoubleSpaces * Remove extraneous closing parenthesis --- package-lock.json | 1774 ++++++++++++----- scripts/tslint/rules/noDoubleSpaceRule.ts | 54 + src/compiler/binder.ts | 4 +- src/compiler/checker.ts | 14 +- src/compiler/commandLineParser.ts | 2 +- src/compiler/core.ts | 6 +- src/compiler/declarationEmitter.ts | 3 +- src/compiler/factory.ts | 8 +- src/compiler/parser.ts | 31 +- src/compiler/scanner.ts | 10 +- src/compiler/transformers/generators.ts | 4 +- src/compiler/transformers/ts.ts | 2 +- src/compiler/types.ts | 42 +- src/compiler/utilities.ts | 4 +- src/harness/harness.ts | 4 +- src/harness/projectsRunner.ts | 2 +- src/harness/unittests/builder.ts | 2 +- src/harness/unittests/moduleResolution.ts | 16 +- src/harness/virtualFileSystem.ts | 2 +- .../cancellationToken/cancellationToken.ts | 2 +- src/server/protocol.ts | 2 +- src/server/scriptVersionCache.ts | 2 +- src/services/breakpoints.ts | 4 +- src/services/classifier.ts | 2 +- src/services/codefixes/fixSpelling.ts | 2 +- src/services/codefixes/helpers.ts | 2 +- src/services/completions.ts | 5 +- src/services/formatting/rules.ts | 6 +- src/services/importTracker.ts | 2 +- src/services/navigateTo.ts | 2 +- src/services/preProcess.ts | 2 +- src/services/services.ts | 2 +- src/services/signatureHelp.ts | 15 +- src/services/symbolDisplay.ts | 2 +- tslint.json | 1 + 35 files changed, 1473 insertions(+), 564 deletions(-) create mode 100644 scripts/tslint/rules/noDoubleSpaceRule.ts diff --git a/package-lock.json b/package-lock.json index 2f651895c08..4a071afa0f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "dev": true, "requires": { "@types/insert-module-globals": "7.0.0", - "@types/node": "8.0.54" + "@types/node": "8.5.2" } }, "@types/chai": { @@ -63,7 +63,7 @@ "integrity": "sha512-18mSs54BvzV8+TTQxt0ancig6tsuPZySnhp3cQkWFFDmDMavU4pmWwR+bHHqRBWODYqpzIzVkqKLuk/fP6yypQ==", "dev": true, "requires": { - "@types/glob": "5.0.33" + "@types/glob": "5.0.34" } }, "@types/events": { @@ -73,13 +73,14 @@ "dev": true }, "@types/glob": { - "version": "5.0.33", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.33.tgz", - "integrity": "sha512-BcD4yyWz+qmCggaYMSFF0Xn7GkO6tgwm3Fh9Gxk/kQmEU3Z7flQTnVlMyKBUNvXXNTCCyjqK4XT4/2hLd1gQ2A==", + "version": "5.0.34", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.34.tgz", + "integrity": "sha512-sUvpieq+HsWTLdkeOI8Mi8u22Ag3AoGuM3sv+XMP1bKtbaIAHpEA2f52K2mz6vK5PVhTa3bFyRZLZMqTxOo2Cw==", "dev": true, "requires": { - "@types/minimatch": "3.0.1", - "@types/node": "8.0.54" + "@types/events": "1.1.0", + "@types/minimatch": "3.0.2", + "@types/node": "8.5.2" } }, "@types/gulp": { @@ -88,7 +89,7 @@ "integrity": "sha512-h9clNJu8X6+zW74ZLa5zhh5HP0LxnvlelVXdXby6pM/DDEj/gKqmmFXKwjzvupZKlMpof02jr6c3JokPbHXQgg==", "dev": true, "requires": { - "@types/node": "8.0.54", + "@types/node": "8.5.2", "@types/orchestrator": "0.3.2", "@types/vinyl": "2.0.1" } @@ -99,7 +100,7 @@ "integrity": "sha512-CUCFADlITzzBfBa2bdGzhKtvBr4eFh+evb+4igVbvPoO5RyPfHifmyQlZl6lM7q19+OKncRlFXDU7B4X9Ayo2g==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.2" } }, "@types/gulp-help": { @@ -109,7 +110,7 @@ "dev": true, "requires": { "@types/gulp": "3.8.35", - "@types/node": "8.0.54", + "@types/node": "8.5.2", "@types/orchestrator": "0.3.2" } }, @@ -119,7 +120,7 @@ "integrity": "sha512-e7J/Zv5Wd7CC0WpuA2syWVitgwrkG0u221e41w7r07XUR6hMH6kHPkq9tUrusHkbeW8QbuLbis5fODOwQCyggQ==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.2" } }, "@types/gulp-sourcemaps": { @@ -128,7 +129,7 @@ "integrity": "sha512-+7BAmptW2bxyJnJcCEuie7vLoop3FwWgCdBMzyv7MYXED/HeNMeQuX7uPCkp4vfU1TTu4CYFH0IckNPvo0VePA==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.2" } }, "@types/insert-module-globals": { @@ -137,7 +138,7 @@ "integrity": "sha512-zudCJPwluh1VUDB6Gl/OQdRp+fYy3+47huJB/JMQubMS2p+sH18MCVK4WUz3FqaWLB12yh5ELxVR/+tqwlm/qA==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.2" } }, "@types/merge2": { @@ -146,13 +147,13 @@ "integrity": "sha512-GjaXY4OultxbaOOk7lCLO7xvEcFpdjExC605YmfI6X29vhHKpJfMWKCDZd3x+BITrZaXKg97DgV/SdGVSwdzxA==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.2" } }, "@types/minimatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.1.tgz", - "integrity": "sha512-rUO/jz10KRSyA9SHoCWQ8WX9BICyj5jZYu1/ucKEJKb4KzLZCKMURdYbadP157Q6Zl1x0vHsrU+Z/O0XlhYQDw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.2.tgz", + "integrity": "sha512-tctoxbfuMCxeI2CAsnwoZQfaBA+T7gPzDzDuiiFnyCSSyGYEB92cmRTh6E3tdR1hWsprbJ9IdbvX3PzLmJU/GA==", "dev": true }, "@types/minimist": { @@ -167,7 +168,7 @@ "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.2" } }, "@types/mocha": { @@ -177,13 +178,10 @@ "dev": true }, "@types/node": { - "version": "8.0.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.54.tgz", - "integrity": "sha512-qetMdTv3Ytz9u9ESLdcYs45LPI0mczYZIbC184n7kY0jczOqPNQsabBfVCh+na3B2shAfvC459JqHV771A8Rxg==", - "dev": true, - "requires": { - "@types/events": "1.1.0" - } + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.2.tgz", + "integrity": "sha512-KA4GKOpgXnrqEH2eCVhiv2CsxgXGQJgV1X0vsGlh+WCnxbeAE1GT44ZsTU1IN5dEeV/gDupKa7gWo08V5IxWVQ==", + "dev": true }, "@types/orchestrator": { "version": "0.3.2", @@ -191,7 +189,7 @@ "integrity": "sha512-cKB4yTX0wGaRCSkdHDX2fkGQbMAA8UOshC2U7DQky1CE5o+5q2iQQ8VkbPbE/88uaTtsusvBPMcCX7dgmjxBhQ==", "dev": true, "requires": { - "@types/node": "8.0.54", + "@types/node": "8.5.2", "@types/q": "1.0.6" } }, @@ -208,16 +206,28 @@ "dev": true, "requires": { "@types/gulp": "3.8.35", - "@types/node": "8.0.54" + "@types/node": "8.5.2" } }, + "@types/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=", + "dev": true + }, + "@types/strip-json-comments": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", + "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", + "dev": true + }, "@types/through2": { "version": "2.0.33", "resolved": "https://registry.npmjs.org/@types/through2/-/through2-2.0.33.tgz", "integrity": "sha1-H/LoihAN+1sUDnu5h5HxGUQA0TE=", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.2" } }, "@types/vinyl": { @@ -226,7 +236,7 @@ "integrity": "sha512-Joudabfn2ZofU2usW04y8OLmN75u7ZQkW0MCT3AnoBf5oUBp5iQ3Pgfz9+y1RdWkzhCPZo9/wBJ7FMWW2JrY0g==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.2" } }, "@types/xml2js": { @@ -235,13 +245,13 @@ "integrity": "sha512-8aKUBSj3oGcnuiBmDLm3BIk09RYg01mz9HlQ2u4aS17oJ25DxjQrEUVGFSBVNOfM45pQW4OjcBPplq6r/exJdA==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.2" } }, "JSONStream": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", - "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", + "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", "dev": true, "requires": { "jsonparse": "1.3.1", @@ -269,6 +279,17 @@ "kind-of": "3.2.2", "longest": "1.0.1", "repeat-string": "1.6.1" + }, + "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" + } + } } }, "amdefine": { @@ -277,6 +298,15 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -292,6 +322,12 @@ "color-convert": "1.9.1" } }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "dev": true + }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", @@ -308,13 +344,10 @@ } }, "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "1.1.0" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true }, "arr-flatten": { "version": "1.1.0", @@ -322,6 +355,12 @@ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, "array-differ": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", @@ -380,9 +419,9 @@ "dev": true }, "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, "arrify": { @@ -417,6 +456,12 @@ "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", "dev": true }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, "astw": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz", @@ -433,9 +478,9 @@ "dev": true }, "atob": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz", - "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz", + "integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10=", "dev": true }, "babel-code-frame": { @@ -482,6 +527,21 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "1.0.1", + "class-utils": "0.3.5", + "component-emitter": "1.2.1", + "define-property": "1.0.0", + "isobject": "3.0.1", + "mixin-deep": "1.3.0", + "pascalcase": "0.1.1" + } + }, "base64-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", @@ -511,14 +571,22 @@ } }, "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.0.tgz", + "integrity": "sha512-P4O8UQRdGiMLWSizsApmXVQDBS6KCt7dSexgLKBmH5Hr1CZq7vsnscFh8oR1sP1ab1Zj0uCHCEzZeV6SfUf3rA==", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" + "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-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.1" } }, "brorand": { @@ -533,7 +601,7 @@ "integrity": "sha1-+GzWzvT1MAyOY+B6TVEvZfv/RTE=", "dev": true, "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "combine-source-map": "0.7.2", "defined": "1.0.0", "through2": "2.0.3", @@ -561,7 +629,7 @@ "integrity": "sha512-gKfOsNQv/toWz+60nSPfYzuwSEdzvV2WdxrVPUbPD/qui44rAkB3t3muNtmmGYHqrG56FGwX9SUEQmzNLAeS7g==", "dev": true, "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "assert": "1.4.1", "browser-pack": "6.0.2", "browser-resolve": "1.11.2", @@ -714,6 +782,23 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "1.0.0", + "component-emitter": "1.2.1", + "get-value": "2.0.6", + "has-value": "1.0.0", + "isobject": "3.0.1", + "set-value": "2.0.0", + "to-object-path": "0.3.0", + "union-value": "1.0.0", + "unset-value": "1.0.0" + } + }, "cached-path-relative": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", @@ -745,6 +830,15 @@ "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": { @@ -788,6 +882,47 @@ "safe-buffer": "5.1.1" } }, + "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=", + "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": { + "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-descriptor": { + "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": "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": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", @@ -838,6 +973,16 @@ "through2": "2.0.3" } }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "1.0.0", + "object-visit": "1.0.1" + } + }, "color-convert": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", @@ -853,6 +998,12 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true + }, "combine-source-map": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", @@ -879,6 +1030,12 @@ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -948,6 +1105,12 @@ "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", "dev": true }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -1021,6 +1184,12 @@ "urix": "0.1.0" }, "dependencies": { + "atob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz", + "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=", + "dev": true + }, "source-map": { "version": "0.1.43", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", @@ -1029,6 +1198,24 @@ "requires": { "amdefine": "1.0.1" } + }, + "source-map-resolve": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz", + "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", + "dev": true, + "requires": { + "atob": "1.1.3", + "resolve-url": "0.2.1", + "source-map-url": "0.3.0", + "urix": "0.1.0" + } + }, + "source-map-url": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz", + "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=", + "dev": true } } }, @@ -1063,23 +1250,34 @@ "dev": true }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" } }, "debug-fabulous": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.2.1.tgz", - "integrity": "sha512-u0TV6HcfLsZ03xLBhdhSViQMldaiQ2o+8/nSILaXkuNSWvxkx66vYJUAam0Eu7gAilJRX/69J4kKdqajQPaPyw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.0.0.tgz", + "integrity": "sha512-dsd50qQ1atDeurcxL7XOjPp4nZCGZzWIONDujDXzl1atSyC3hMbZD+v6440etw+Vt0Pr8ce4TQzHfX3KZM05Mw==", "dev": true, "requires": { "debug": "3.1.0", "memoizee": "0.4.11", "object-assign": "4.1.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "decamelize": { @@ -1088,6 +1286,12 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", @@ -1112,6 +1316,15 @@ "clone": "1.0.3" } }, + "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.1" + } + }, "defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", @@ -1144,7 +1357,7 @@ "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", "dev": true, "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "shasum": "1.0.2", "subarg": "1.0.0", "through2": "2.0.3" @@ -1161,13 +1374,10 @@ } }, "detect-file": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", - "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", - "dev": true, - "requires": { - "fs-exists-sync": "0.1.0" - } + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true }, "detect-newline": { "version": "2.1.0", @@ -1176,9 +1386,9 @@ "dev": true }, "detective": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.0.tgz", - "integrity": "sha512-4mBqSEdMfBpRAo/DQZnTcAXenpiSIJmVKbCMSotS+SFWWcrP/CKM6iBRPdTiEO+wZhlfEsoZlGqpG6ycl5vTqw==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", + "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", "dev": true, "requires": { "acorn": "5.2.1", @@ -1417,12 +1627,46 @@ } }, "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "debug": "2.6.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" + }, + "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-descriptor": { + "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": "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": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } } }, "expand-range": { @@ -1432,15 +1676,57 @@ "dev": true, "requires": { "fill-range": "2.2.3" + }, + "dependencies": { + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "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" + } + } } }, "expand-tilde": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", - "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", "dev": true, "requires": { - "os-homedir": "1.0.2" + "homedir-polyfill": "1.0.1" } }, "extend": { @@ -1459,49 +1745,30 @@ } }, "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.2.tgz", + "integrity": "sha512-I0+eZBH+jFGL8F5BnIz2ON2nKCjTS3AS3H/5PeSmCp7UVC70Ym8IhdRiQly2juKYQ//f7z1aj1BRpQniFJoU1w==", "dev": true, "requires": { - "is-extglob": "1.0.0" + "array-unique": "0.3.2", + "define-property": "1.0.0", + "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" } }, "fancy-log": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", - "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz", + "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=", "dev": true, "requires": { - "chalk": "1.1.3", + "ansi-gray": "0.1.1", + "color-support": "1.1.3", "time-stamp": "1.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } } }, "fast-levenshtein": { @@ -1535,16 +1802,15 @@ "dev": true }, "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" } }, "find-index": { @@ -1564,15 +1830,15 @@ } }, "findup-sync": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", - "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", "dev": true, "requires": { - "detect-file": "0.1.0", - "is-glob": "2.0.1", - "micromatch": "2.3.11", - "resolve-dir": "0.1.1" + "detect-file": "1.0.0", + "is-glob": "3.1.0", + "micromatch": "3.1.4", + "resolve-dir": "1.0.1" } }, "fined": { @@ -1585,18 +1851,7 @@ "is-plain-object": "2.0.4", "object.defaults": "1.1.0", "object.pick": "1.3.0", - "parse-filepath": "1.0.1" - }, - "dependencies": { - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "1.0.1" - } - } + "parse-filepath": "1.0.2" } }, "first-chunk-stream": { @@ -1606,9 +1861,9 @@ "dev": true }, "flagged-respawn": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", - "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz", + "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=", "dev": true }, "for-in": { @@ -1618,19 +1873,22 @@ "dev": true }, "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "dev": true, "requires": { "for-in": "1.0.2" } }, - "fs-exists-sync": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", - "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", - "dev": true + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "0.2.2" + } }, "fs.realpath": { "version": "1.0.0", @@ -1665,6 +1923,12 @@ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", "dev": true }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", @@ -1687,15 +1951,42 @@ "requires": { "glob-parent": "2.0.0", "is-glob": "2.0.1" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + } } }, "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "2.0.1" + "is-glob": "3.1.0", + "path-dirname": "1.0.2" } }, "glob-stream": { @@ -1788,24 +2079,26 @@ } }, "global-modules": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", - "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "dev": true, "requires": { - "global-prefix": "0.1.5", - "is-windows": "0.2.0" + "global-prefix": "1.0.2", + "is-windows": "1.0.1", + "resolve-dir": "1.0.1" } }, "global-prefix": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", - "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", "dev": true, "requires": { + "expand-tilde": "2.0.2", "homedir-polyfill": "1.0.1", "ini": "1.3.5", - "is-windows": "0.2.0", + "is-windows": "1.0.1", "which": "1.3.0" } }, @@ -1891,7 +2184,7 @@ "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", "dev": true, "requires": { - "natives": "1.1.0" + "natives": "1.1.1" } }, "growl": { @@ -1911,7 +2204,7 @@ "deprecated": "0.0.1", "gulp-util": "3.0.8", "interpret": "1.1.0", - "liftoff": "2.3.0", + "liftoff": "2.5.0", "minimist": "1.2.0", "orchestrator": "0.3.8", "pretty-hrtime": "1.0.3", @@ -2278,7 +2571,7 @@ "acorn": "4.0.13", "convert-source-map": "1.5.1", "css": "2.2.1", - "debug-fabulous": "0.2.1", + "debug-fabulous": "1.0.0", "detect-newline": "2.1.0", "graceful-fs": "4.1.11", "source-map": "0.5.7", @@ -2318,6 +2611,50 @@ "vinyl-fs": "2.4.4" }, "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", @@ -2331,16 +2668,6 @@ "path-is-absolute": "1.0.1" } }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - } - }, "glob-stream": { "version": "5.3.5", "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", @@ -2401,18 +2728,18 @@ } }, "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "1.0.0" } }, "isarray": { @@ -2430,6 +2757,36 @@ "jsonify": "0.0.0" } }, + "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" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, "ordered-read-streams": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", @@ -2514,7 +2871,7 @@ "beeper": "1.1.1", "chalk": "1.1.3", "dateformat": "2.2.0", - "fancy-log": "1.3.0", + "fancy-log": "1.3.2", "gulplog": "1.0.0", "has-gulplog": "0.1.0", "lodash._reescape": "3.0.0", @@ -2630,9 +2987,9 @@ "dev": true }, "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, "has-gulplog": { @@ -2644,6 +3001,38 @@ "sparkles": "1.0.0" } }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "1.0.0", + "isobject": "3.0.1" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, "hash-base": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", @@ -2765,7 +3154,7 @@ "integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=", "dev": true, "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "combine-source-map": "0.7.2", "concat-stream": "1.5.2", "is-buffer": "1.1.6", @@ -2782,13 +3171,33 @@ "dev": true }, "is-absolute": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", - "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, "requires": { - "is-relative": "0.2.1", - "is-windows": "0.2.0" + "is-relative": "1.0.0", + "is-windows": "1.0.1" + } + }, + "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-arrayish": { @@ -2812,6 +3221,45 @@ "builtin-modules": "1.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": "1.0.1", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.1.tgz", + "integrity": "sha512-G3fFVFTqfaqu7r4YuSBHKBAuOaLz8Sy7ekklUpFEliaLMP1Y2ZjoN9jS62YWCAPQrQpMUQSitRlrzibbuCZjdA==", + "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": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", @@ -2834,9 +3282,9 @@ "dev": true }, "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-finite": { @@ -2849,21 +3297,41 @@ } }, "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "2.1.1" } }, "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "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-odd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-1.0.0.tgz", + "integrity": "sha1-O4qTLrAos3dcObsJ6RdnrM22kIg=", + "dev": true, + "requires": { + "is-number": "3.0.0" } }, "is-path-cwd": { @@ -2897,14 +3365,6 @@ "dev": true, "requires": { "isobject": "3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "is-posix-bracket": { @@ -2926,12 +3386,12 @@ "dev": true }, "is-relative": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", - "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "requires": { - "is-unc-path": "0.1.2" + "is-unc-path": "1.0.0" } }, "is-stream": { @@ -2941,9 +3401,9 @@ "dev": true }, "is-unc-path": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", - "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, "requires": { "unc-path-regex": "0.1.2" @@ -2962,9 +3422,9 @@ "dev": true }, "is-windows": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", - "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.1.tgz", + "integrity": "sha1-MQ23D3QtJZoWo2kgK1GvhCMzENk=", "dev": true }, "isarray": { @@ -2980,13 +3440,10 @@ "dev": true }, "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "istanbul": { "version": "0.4.5", @@ -3023,6 +3480,12 @@ "path-is-absolute": "1.0.1" } }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", @@ -3130,13 +3593,10 @@ "dev": true }, "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" - } + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true }, "labeled-stream-splicer": { "version": "2.0.0", @@ -3158,11 +3618,13 @@ } }, "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", + "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", "dev": true, - "optional": true + "requires": { + "set-getter": "0.1.0" + } }, "lazystream": { "version": "1.0.0", @@ -3193,18 +3655,17 @@ } }, "liftoff": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", - "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", + "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", "dev": true, "requires": { "extend": "3.0.1", - "findup-sync": "0.4.3", + "findup-sync": "2.0.0", "fined": "1.1.0", - "flagged-respawn": "0.3.2", - "lodash.isplainobject": "4.0.6", - "lodash.isstring": "4.0.1", - "lodash.mapvalues": "4.6.0", + "flagged-respawn": "1.0.0", + "is-plain-object": "2.0.4", + "object.map": "1.0.1", "rechoir": "0.6.2", "resolve": "1.1.7" } @@ -3429,18 +3890,6 @@ "lodash._objecttypes": "2.4.1" } }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", - "dev": true - }, "lodash.keys": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", @@ -3452,12 +3901,6 @@ "lodash.isarray": "3.0.4" } }, - "lodash.mapvalues": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", - "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", - "dev": true - }, "lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", @@ -3556,6 +3999,26 @@ "integrity": "sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y=", "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=", + "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" + } + } + } + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -3568,6 +4031,15 @@ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "1.0.1" + } + }, "md5.js": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", @@ -3640,24 +4112,24 @@ "dev": true }, "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.4.tgz", + "integrity": "sha512-kFRtviKYoAJT+t7HggMl0tBFGNAKLw/S7N+CO9qfEQyisob1Oy4pao+geRbkyeEd+V9aOkvZ4mhuyPvI/q9Sfg==", "dev": true, "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "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.2", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.6", + "object.pick": "1.3.0", + "regex-not": "1.0.0", + "snapdragon": "0.8.1", + "to-regex": "3.0.1" } }, "miller-rabin": { @@ -3697,6 +4169,27 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, + "mixin-deep": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.0.tgz", + "integrity": "sha512-dgaCvoh6i1nosAUBKb0l0pfJ78K8+S9fluyIR2YvAeUD/QuMahnFnF3xYty5eYXMjhGSsB0DsW6A0uAZyetoAg==", + "dev": true, + "requires": { + "for-in": "1.0.2", + "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" + } + } + } + }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", @@ -3732,11 +4225,14 @@ "supports-color": "4.4.0" }, "dependencies": { - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } }, "supports-color": { "version": "4.4.0", @@ -3761,12 +4257,12 @@ "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", "dev": true, "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "browser-resolve": "1.11.2", "cached-path-relative": "1.0.1", "concat-stream": "1.5.2", "defined": "1.0.0", - "detective": "4.7.0", + "detective": "4.7.1", "duplexer2": "0.1.4", "inherits": "2.0.3", "parents": "1.0.1", @@ -3828,10 +4324,37 @@ } } }, + "nanomatch": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.6.tgz", + "integrity": "sha512-WJ6XTCbvWXUFPbi/bDwKcYkCeOGUHzaJj72KbuPqGn78Ba/F5Vu26Zlo6SuMQbCIst1RGKL1zfWBCOGAlbRLAg==", + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "define-property": "1.0.0", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "is-odd": "1.0.0", + "kind-of": "5.1.0", + "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 + } + } + }, "natives": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz", - "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.1.tgz", + "integrity": "sha512-8eRaxn8u/4wN8tGkhlc2cgwwvOLMLUMUn4IYTexMgWd+LyUDfeXVkk2ygQR0hvIHbJQXgHujia3ieUUDwNGkEA==", "dev": true }, "next-tick": { @@ -3882,12 +4405,71 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "0.1.1", + "define-property": "0.2.5", + "kind-of": "3.2.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-descriptor": { + "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": "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 + } + } + }, + "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" + } + } + } + }, "object-keys": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", "dev": true }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "3.0.1" + } + }, "object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", @@ -3898,23 +4480,16 @@ "array-slice": "1.1.0", "for-own": "1.0.0", "isobject": "3.0.1" - }, - "dependencies": { - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "1.0.0", + "make-iterator": "1.0.0" } }, "object.omit": { @@ -3925,6 +4500,17 @@ "requires": { "for-own": "0.1.5", "is-extendable": "0.1.1" + }, + "dependencies": { + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + } } }, "object.pick": { @@ -3934,14 +4520,6 @@ "dev": true, "requires": { "isobject": "3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "once": { @@ -4055,12 +4633,12 @@ } }, "parse-filepath": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", - "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", "dev": true, "requires": { - "is-absolute": "0.2.6", + "is-absolute": "1.0.0", "map-cache": "0.2.2", "path-root": "0.1.1" } @@ -4075,6 +4653,23 @@ "is-dotfile": "1.0.3", "is-extglob": "1.0.0", "is-glob": "2.0.1" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + } } }, "parse-json": { @@ -4092,6 +4687,12 @@ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, "path-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", @@ -4217,6 +4818,12 @@ "pinkie": "2.0.4" } }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -4294,26 +4901,6 @@ "kind-of": "4.0.0" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "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": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -4417,6 +5004,15 @@ "is-equal-shallow": "0.1.3" } }, + "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=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1" + } + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -4457,13 +5053,13 @@ "dev": true }, "resolve-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", - "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", "dev": true, "requires": { - "expand-tilde": "1.2.2", - "global-modules": "0.2.3" + "expand-tilde": "2.0.2", + "global-modules": "1.0.0" } }, "resolve-url": { @@ -4582,6 +5178,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": "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" + } + }, "sha.js": { "version": "2.4.9", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", @@ -4626,6 +5243,81 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "snapdragon": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz", + "integrity": "sha1-4StUh/re0+PeoKyR6UAL91tAE3A=", + "dev": true, + "requires": { + "base": "0.11.2", + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "map-cache": "0.2.2", + "source-map": "0.5.7", + "source-map-resolve": "0.5.1", + "use": "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-descriptor": { + "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": "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": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "1.0.0", + "isobject": "3.0.1", + "snapdragon-util": "3.0.1" + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "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" + } + } + } + }, "sorcery": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.10.0.tgz", @@ -4645,14 +5337,15 @@ "dev": true }, "source-map-resolve": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz", - "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", + "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", "dev": true, "requires": { - "atob": "1.1.3", + "atob": "2.0.3", + "decode-uri-component": "0.2.0", "resolve-url": "0.2.1", - "source-map-url": "0.3.0", + "source-map-url": "0.4.0", "urix": "0.1.0" } }, @@ -4674,9 +5367,9 @@ } }, "source-map-url": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz", - "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, "sourcemap-codec": { @@ -4715,12 +5408,80 @@ "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", "dev": true }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "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": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "0.2.5", + "object-copy": "0.1.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-descriptor": { + "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": "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": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "stream-browserify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", @@ -4897,14 +5658,6 @@ "dev": true, "requires": { "has-flag": "2.0.0" - }, - "dependencies": { - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - } } }, "syntax-error": { @@ -4991,6 +5744,75 @@ "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", "dev": true }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "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" + } + } + } + }, + "to-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.1.tgz", + "integrity": "sha1-FTWL7kosg712N3uh3ASdDxiDeq4=", + "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-descriptor": { + "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": "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": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "3.0.0", + "repeat-string": "1.6.1" + } + }, "travis-fold": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/travis-fold/-/travis-fold-0.1.2.tgz", @@ -5004,9 +5826,9 @@ "dev": true }, "ts-node": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-3.3.0.tgz", - "integrity": "sha1-wTxqMCTjC+EYDdUwOPwgkonUv2k=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-4.0.2.tgz", + "integrity": "sha512-mg7l6ON8asjnfzkTi1LFWKaOGHl5Jf1+5ij0MQ502YfC6+4FBgh/idJgw9aN9kei1Rf4/pmFpNuFE1YbcQdOTA==", "dev": true, "requires": { "arrify": "1.0.1", @@ -5015,56 +5837,12 @@ "make-error": "1.3.0", "minimist": "1.2.0", "mkdirp": "0.5.1", - "source-map-support": "0.4.18", - "tsconfig": "6.0.0", + "source-map-support": "0.5.0", + "tsconfig": "7.0.0", "v8flags": "3.0.1", "yn": "2.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "0.5.7" - } - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } - }, "v8flags": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.0.1.tgz", @@ -5077,11 +5855,13 @@ } }, "tsconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz", - "integrity": "sha1-aw6DdgA9evGGT434+J3QBZ/80DI=", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", + "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", "dev": true, "requires": { + "@types/strip-bom": "3.0.0", + "@types/strip-json-comments": "0.0.30", "strip-bom": "3.0.0", "strip-json-comments": "2.0.1" }, @@ -5095,9 +5875,9 @@ } }, "tslib": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.0.tgz", - "integrity": "sha512-ymKWWZJST0/CkgduC2qkzjMOWr4bouhuURNXCn/inEX0L57BnRG6FhX76o7FOnsjHazCjfU2LKeSrlS2sIKQJg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.1.tgz", + "integrity": "sha1-aUavLR1lGnsYY7Ux1uWvpBqkTqw=", "dev": true }, "tslint": { @@ -5115,36 +5895,10 @@ "minimatch": "3.0.4", "resolve": "1.5.0", "semver": "5.4.1", - "tslib": "1.8.0", - "tsutils": "2.13.0" + "tslib": "1.8.1", + "tsutils": "2.13.1" }, "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, "resolve": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", @@ -5159,25 +5913,16 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", "dev": true - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } } } }, "tsutils": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.13.0.tgz", - "integrity": "sha512-FuWzNJbMsp3gcZMbI3b5DomhW4Ia41vMxjN63nKWI0t7f+I3UmHfRl0TrXJTwI2LUduDG+eR1Mksp3pvtlyCFQ==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.13.1.tgz", + "integrity": "sha512-XMOEvc2TiYesVSOJMI7OYPnBMSgcvERuGW5Li/J+2A0TuH607BPQnOLQ82oSPZCssB8c9+QGi6qhTBa/f1xQRA==", "dev": true, "requires": { - "tslib": "1.8.0" + "tslib": "1.8.1" } }, "tty-browserify": { @@ -5208,9 +5953,9 @@ "dev": true }, "typescript": { - "version": "2.7.0-dev.20171209", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.0-dev.20171209.tgz", - "integrity": "sha512-4ETBmIehQBmJOVwb/awg+EHMjpq3esymYD+tKRvxHv3cW+1s9+t8kdozn3/Fk50vAH13YtOHxuOcvU7OXrdG5Q==", + "version": "2.7.0-dev.20171221", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.0-dev.20171221.tgz", + "integrity": "sha512-PM09fTK1T0WSZHNDXqrB/P6lTaQkzAnXlx23Q5J/21oQ8kgU7B7TtUFTX7zzdSZnH78j49aUx5bVuQCRJkBowg==", "dev": true }, "uglify-js": { @@ -5244,12 +5989,78 @@ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "3.1.0", + "get-value": "2.0.6", + "is-extendable": "0.1.1", + "set-value": "0.4.3" + }, + "dependencies": { + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" + } + } + } + }, "unique-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", "dev": true }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "0.3.1", + "isobject": "3.0.1" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "0.1.4", + "isobject": "2.1.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -5274,6 +6085,45 @@ } } }, + "use": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/use/-/use-2.0.2.tgz", + "integrity": "sha1-riig1y+TvyJCKhii43mZMRLeyOg=", + "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-descriptor": { + "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": "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": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "user-home": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", diff --git a/scripts/tslint/rules/noDoubleSpaceRule.ts b/scripts/tslint/rules/noDoubleSpaceRule.ts new file mode 100644 index 00000000000..34ab470ebce --- /dev/null +++ b/scripts/tslint/rules/noDoubleSpaceRule.ts @@ -0,0 +1,54 @@ +import * as Lint from "tslint/lib"; +import * as ts from "typescript"; + +export class Rule extends Lint.Rules.AbstractRule { + public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { + return this.applyWithFunction(sourceFile, walk); + } +} + +function walk(ctx: Lint.WalkContext): void { + const { sourceFile } = ctx; + const lines = sourceFile.text.split("\n"); + const strings = getLiterals(sourceFile); + lines.forEach((line, idx) => { + // Skip indentation. + const firstNonSpace = /\S/.exec(line); + if (firstNonSpace === null) { + return; + } + // Allow common uses of double spaces + // * To align `=` or `!=` signs + // * To align comments at the end of lines + // * To indent inside a comment + // * To use two spaces after a period + // * To include aligned `->` in a comment + const rgx = /[^/*. ] [^-!/= ]/g; + rgx.lastIndex = firstNonSpace.index; + const doubleSpace = rgx.exec(line); + // Also allow to align comments after `@param` + if (doubleSpace !== null && !line.includes("@param")) { + const pos = lines.slice(0, idx).reduce((len, line) => len + 1 + line.length, 0) + doubleSpace.index; + if (!strings.some(s => s.getStart() <= pos && s.end > pos)) { + ctx.addFailureAt(pos + 1, 2, "Use only one space."); + } + } + }); +} + +function getLiterals(sourceFile: ts.SourceFile): ReadonlyArray { + const out: ts.Node[] = []; + sourceFile.forEachChild(function cb(node) { + switch (node.kind) { + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.TemplateHead: + case ts.SyntaxKind.TemplateMiddle: + case ts.SyntaxKind.TemplateTail: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.RegularExpressionLiteral: + out.push(node); + } + node.forEachChild(cb); + }); + return out; +} diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 4eab97f28bb..809e840472b 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1633,7 +1633,7 @@ namespace ts { // to the one we would get for: { <...>(...): T } // // We do that by making an anonymous type literal symbol, and then setting the function - // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable + // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable // from an actual type literal symbol you would have gotten had you used the long form. const symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node)); addDeclarationToSymbol(symbol, node, SymbolFlags.Signature); @@ -2431,7 +2431,7 @@ namespace ts { if (!isPrototypeProperty && (!targetSymbol || !(targetSymbol.flags & SymbolFlags.Namespace)) && isLegalPosition) { Debug.assert(isIdentifier(propertyAccess.expression)); const identifier = propertyAccess.expression as Identifier; - const flags = SymbolFlags.Module | SymbolFlags.JSContainer; + const flags = SymbolFlags.Module | SymbolFlags.JSContainer; const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.JSContainer; if (targetSymbol) { addDeclarationToSymbol(symbol, identifier, flags); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 53ad6511820..fdf27448169 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1218,7 +1218,7 @@ namespace ts { !checkAndReportErrorForExtendingInterface(errorLocation) && !checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) && !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) && - !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning)) { + !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning)) { let suggestion: string | undefined; if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) { suggestion = getSuggestionForNonexistentSymbol(originalLocation, name, meaning); @@ -9656,7 +9656,7 @@ namespace ts { } if (target.flags & TypeFlags.Union) { const discriminantType = findMatchingDiscriminantType(source, target as UnionType); - if (discriminantType) { + if (discriminantType) { // check excess properties against discriminant type only, not the entire union return hasExcessProperties(source, discriminantType, reportErrors); } @@ -11826,7 +11826,7 @@ namespace ts { const container = (node as BindingElement).parent.parent; const key = container.kind === SyntaxKind.BindingElement ? getFlowCacheKey(container) : (container.initializer && getFlowCacheKey(container.initializer)); const text = getBindingElementNameText(node as BindingElement); - const result = key && text && (key + "." + text); + const result = key && text && (key + "." + text); return result; } return undefined; @@ -12749,7 +12749,7 @@ namespace ts { firstAntecedentType = flowType; } const type = getTypeFromFlowType(flowType); - // If we see a value appear in the cache it is a sign that control flow analysis + // If we see a value appear in the cache it is a sign that control flow analysis // was restarted and completed by checkExpressionCached. We can simply pick up // the resulting type and bail out. const cached = cache.get(key); @@ -21931,7 +21931,7 @@ namespace ts { checkGrammarForInOrForOfStatement(node); const rightType = checkNonNullExpression(node.expression); - // TypeScript 1.0 spec (April 2014): 5.4 + // TypeScript 1.0 spec (April 2014): 5.4 // In a 'for-in' statement of the form // for (let VarDecl in Expr) Statement // VarDecl must be a variable declaration without a type annotation that declares a variable of type Any, @@ -24864,7 +24864,7 @@ namespace ts { // AND // - binding is not declared in loop, should be renamed to avoid name reuse across siblings // let a, b - // { let x = 1; a = () => x; } + // { let x = 1; a = () => x; } // { let x = 100; b = () => x; } // console.log(a()); // should print '1' // console.log(b()); // should print '100' @@ -25325,7 +25325,7 @@ namespace ts { // walk the parent chain for symbols to make sure that top level parent symbol is in the global scope // external modules cannot define or contribute to type declaration files - let current = symbol; + let current = symbol; while (true) { const parent = getParentOfSymbol(current); if (parent) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 19d4dbbd003..33ecf570c03 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1864,7 +1864,7 @@ namespace ts { return normalizeNonListOptionValue(option, basePath, value); } - function normalizeNonListOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue { + function normalizeNonListOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue { if (option.isFilePath) { value = normalizePath(combinePaths(basePath, value)); if (value === "") { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index eb0696a1869..d54c2a24f80 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2080,7 +2080,7 @@ namespace ts { function getNormalizedPathComponentsOfUrl(url: string) { // Get root length of http://www.website.com/folder1/folder2/ - // In this example the root is: http://www.website.com/ + // In this example the root is: http://www.website.com/ // normalized path components should be ["http://www.website.com/", "folder1", "folder2"] const urlLength = url.length; @@ -2113,7 +2113,7 @@ namespace ts { } else { // Can't find the host assume the rest of the string as component - // but make sure we append "/" to it as root is not joined using "/" + // but make sure we append "/" to it as root is not joined using "/" // eg. if url passed in was http://website.com we want to use root as [http://website.com/] // so that other path manipulations will be correct and it can be merged with relative paths correctly return [url + directorySeparator]; @@ -2134,7 +2134,7 @@ namespace ts { const directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory); if (directoryComponents.length > 1 && lastOrUndefined(directoryComponents) === "") { // If the directory path given was of type test/cases/ then we really need components of directory to be only till its name - // that is ["test", "cases", ""] needs to be actually ["test", "cases"] + // that is ["test", "cases", ""] needs to be actually ["test", "cases"] directoryComponents.pop(); } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index b4ff7c7f641..278a9cf4a5f 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -1199,7 +1199,7 @@ namespace ts { write(">"); } } - else { + else { emitHeritageClause([baseTypeNode], /*isImplementsList*/ false); } } @@ -1866,6 +1866,7 @@ namespace ts { // it allows emitSeparatedList to write separator appropriately) // Example: // original: function foo([, x, ,]) {} + // tslint:disable-next-line no-double-space // emit : function foo([ , x, , ]) {} write(" "); } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index dfc22e31833..65c17911488 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -3831,13 +3831,13 @@ namespace ts { if (isLeftSideOfBinary) { // No need to parenthesize the left operand when the binary operator is // left associative: - // (a*b)/x -> a*b/x - // (a**b)/x -> a**b/x + // (a*b)/x -> a*b/x + // (a**b)/x -> a**b/x // // Parentheses are needed for the left operand when the binary operator is // right associative: - // (a/b)**x -> (a/b)**x - // (a**b)**x -> (a**b)**x + // (a/b)**x -> (a/b)**x + // (a**b)**x -> (a**b)**x return binaryOperatorAssociativity === Associativity.Right; } else { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ce4115b08d4..ab8e52e3dfa 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -585,7 +585,7 @@ namespace ts { // 'disallow-in' set to 'false'. Otherwise, if we had 'allowsIn' set to 'true', then almost // all nodes would need extra state on them to store this info. // - // Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6 + // Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6 // grammar specification. // // An important thing about these context concepts. By default they are effectively inherited @@ -701,7 +701,7 @@ namespace ts { function getLanguageVariant(scriptKind: ScriptKind) { // .tsx and .jsx files are treated as jsx language variant. - return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard; + return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard; } function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) { @@ -1453,7 +1453,7 @@ namespace ts { function isValidHeritageClauseObjectLiteral() { Debug.assert(token() === SyntaxKind.OpenBraceToken); if (nextToken() === SyntaxKind.CloseBraceToken) { - // if we see "extends {}" then only treat the {} as what we're extending (and not + // if we see "extends {}" then only treat the {} as what we're extending (and not // the class body) if we have: // // extends {} { @@ -1549,7 +1549,7 @@ namespace ts { function isVariableDeclaratorListTerminator(): boolean { // If we can consume a semicolon (either explicitly, or with ASI), then consider us done - // with parsing the list of variable declarators. + // with parsing the list of variable declarators. if (canParseSemicolon()) { return true; } @@ -2269,7 +2269,7 @@ namespace ts { // // // - // We do *not* want to consume the > as we're consuming the expression for "". + // We do *not* want to consume the `>` as we're consuming the expression for "". node.expression = parseUnaryExpressionOrHigher(); } } @@ -3089,7 +3089,7 @@ namespace ts { // And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression". // // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is - // not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done + // not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done // with AssignmentExpression if we see one. const arrowExpression = tryParseParenthesizedArrowFunctionExpression() || tryParseAsyncSimpleArrowFunctionExpression(); if (arrowExpression) { @@ -3119,7 +3119,7 @@ namespace ts { // we're in '2' or '3'. Consume the assignment and return. // // Note: we call reScanGreaterToken so that we get an appropriately merged token - // for cases like > > = becoming >>= + // for cases like `> > =` becoming `>>=` if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) { return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher()); } @@ -3275,7 +3275,7 @@ namespace ts { if (first === SyntaxKind.OpenParenToken) { if (second === SyntaxKind.CloseParenToken) { - // Simple cases: "() =>", "(): ", and "() {". + // Simple cases: "() =>", "(): ", and "() {". // This is an arrow function with no parameters. // The last one is not actually an arrow function, // but this is probably what the user intended. @@ -3895,7 +3895,8 @@ namespace ts { // 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 + // 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(); } @@ -3945,7 +3946,7 @@ namespace ts { // treated as the invocation of "new Foo". We disambiguate that in code (to match // the original grammar) by making sure that if we see an ObjectCreationExpression // we always consume arguments if they are there. So we treat "new Foo()" as an - // object creation only, and not at all as an invocation) Another way to think + // object creation only, and not at all as an invocation. Another way to think // about this is that for every "new" that we see, we will consume an argument list if // it is there as part of the *associated* object creation node. Any additional // argument lists we see, will become invocation expressions. @@ -4361,7 +4362,7 @@ namespace ts { const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType); if (!parseExpected(SyntaxKind.GreaterThanToken)) { - // If it doesn't have the closing > then it's definitely not an type argument list. + // If it doesn't have the closing `>` then it's definitely not an type argument list. return undefined; } @@ -5394,8 +5395,8 @@ namespace ts { // off. The grammar would look something like this: // // MemberVariableDeclaration[Yield]: - // AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initializer_opt[In]; - // AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initializer_opt[In, ?Yield]; + // AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initializer_opt[In]; + // AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initializer_opt[In, ?Yield]; // // The checker may still error in the static case to explicitly disallow the yield expression. node.initializer = hasModifier(node, ModifierFlags.Static) @@ -7077,7 +7078,7 @@ namespace ts { // If the 'pos' is before the start of the change, then we don't need to touch it. // If it isn't, then the 'pos' must be inside the change. How we update it will - // depend if delta is positive or negative. If delta is positive then we have + // depend if delta is positive or negative. If delta is positive then we have // something like: // // -------------------AAA----------------- @@ -7102,7 +7103,7 @@ namespace ts { // If the 'end' is after the change range, then we always adjust it by the delta // amount. However, if the end is in the change range, then how we adjust it - // will depend on if delta is positive or negative. If delta is positive then we + // will depend on if delta is positive or negative. If delta is positive then we // have something like: // // -------------------AAA----------------- diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 1cd64931153..e4f7821897d 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -193,7 +193,7 @@ namespace ts { /* As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers IdentifierStart :: - Can contain Unicode 3.0.0 categories: + Can contain Unicode 3.0.0 categories: Uppercase letter (Lu), Lowercase letter (Ll), Titlecase letter (Lt), @@ -201,7 +201,7 @@ namespace ts { Other letter (Lo), or Letter number (Nl). IdentifierPart :: = - Can contain IdentifierStart + Unicode 3.0.0 categories: + Can contain IdentifierStart + Unicode 3.0.0 categories: Non-spacing mark (Mn), Combining spacing mark (Mc), Decimal number (Nd), or @@ -216,7 +216,7 @@ namespace ts { /* As per ECMAScript Language Specification 5th Edition, Section 7.6: ISyntaxToken Names and Identifiers IdentifierStart :: - Can contain Unicode 6.2 categories: + Can contain Unicode 6.2 categories: Uppercase letter (Lu), Lowercase letter (Ll), Titlecase letter (Lt), @@ -224,7 +224,7 @@ namespace ts { Other letter (Lo), or Letter number (Nl). IdentifierPart :: - Can contain IdentifierStart + Unicode 6.2 categories: + Can contain IdentifierStart + Unicode 6.2 categories: Non-spacing mark (Mn), Combining spacing mark (Mc), Decimal number (Nd), @@ -1594,7 +1594,7 @@ namespace ts { return token = SyntaxKind.NumericLiteral; case CharacterCodes.colon: pos++; - return token = SyntaxKind.ColonToken; + return token = SyntaxKind.ColonToken; case CharacterCodes.semicolon: pos++; return token = SyntaxKind.SemicolonToken; diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index bd2a4ef554d..8df05e4f3ab 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -3190,8 +3190,8 @@ namespace ts { // `throw` methods that step through the generator when invoked. // // parameters: - // thisArg The value to use as the `this` binding for the transformed generator body. - // body A function that acts as the transformed generator body. + // @param thisArg The value to use as the `this` binding for the transformed generator body. + // @param body A function that acts as the transformed generator body. // // variables: // _ Persistent state for the generator that is shared between the helper and the diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 3c1bba280f0..cdb0d0667ad 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -81,7 +81,7 @@ namespace ts { let classAliases: Identifier[]; /** - * Keeps track of whether we are within any containing namespaces when performing + * Keeps track of whether we are within any containing namespaces when performing * just-in-time substitution while printing an expression identifier. */ let applicableSubstitutions: TypeScriptSubstitutionFlags; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4f5ef1900f5..89406a0f42b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -438,24 +438,24 @@ namespace ts { } export const enum NodeFlags { - None = 0, - Let = 1 << 0, // Variable declaration - Const = 1 << 1, // Variable declaration - NestedNamespace = 1 << 2, // Namespace declaration - Synthesized = 1 << 3, // Node was synthesized during transformation - Namespace = 1 << 4, // Namespace declaration - ExportContext = 1 << 5, // Export context (initialized by binding) - ContainsThis = 1 << 6, // Interface contains references to "this" - HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding) - HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding) + None = 0, + Let = 1 << 0, // Variable declaration + Const = 1 << 1, // Variable declaration + NestedNamespace = 1 << 2, // Namespace declaration + Synthesized = 1 << 3, // Node was synthesized during transformation + Namespace = 1 << 4, // Namespace declaration + ExportContext = 1 << 5, // Export context (initialized by binding) + ContainsThis = 1 << 6, // Interface contains references to "this" + HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding) + HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding) GlobalAugmentation = 1 << 9, // Set if module declaration is an augmentation for the global scope - HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding) - DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed - YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator - DecoratorContext = 1 << 13, // If node was parsed as part of a decorator - AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function - ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node - JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript + HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding) + DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed + YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator + DecoratorContext = 1 << 13, // If node was parsed as part of a decorator + AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function + ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node + JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript 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 @@ -1394,7 +1394,7 @@ namespace ts { export type BinaryOperatorToken = Token; - export interface BinaryExpression extends Expression, Declaration { + export interface BinaryExpression extends Expression, Declaration { kind: SyntaxKind.BinaryExpression; left: Expression; operatorToken: BinaryOperatorToken; @@ -2977,9 +2977,9 @@ namespace ts { None = 0x00000000, // Write symbols's type argument if it is instantiated symbol - // eg. class C { p: T } <-- Show p as C.p here + // eg. class C { p: T } <-- Show p as C.p here // var a: C; - // var p = a.p; <--- Here p is property of C so show it as C.p instead of just C.p + // var p = a.p; <--- Here p is property of C so show it as C.p instead of just C.p WriteTypeParametersOrArguments = 0x00000001, // Use only external alias information to get the symbol name in the given context @@ -3628,7 +3628,7 @@ namespace ts { /* @internal */ // Object literals are initially marked fresh. Freshness disappears following an assignment, - // before a type assertion, or when an object literal's type is widened. The regular + // before a type assertion, or when an object literal's type is widened. The regular // version of a fresh type is identical except for the TypeFlags.FreshObjectLiteral flag. export interface FreshObjectLiteralType extends ResolvedType { regularType: ResolvedType; // Regular version of fresh type diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index fce141490a3..cafdce60315 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3917,8 +3917,8 @@ namespace ts { // // { // oldStart3: Min(oldStart1, oldStart2), - // oldEnd3 : Max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)), - // newEnd3 : Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2)) + // oldEnd3: Max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)), + // newEnd3: Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2)) // } const oldStart1 = oldStartN; diff --git a/src/harness/harness.ts b/src/harness/harness.ts index b38bd523fae..612224cb312 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -63,7 +63,7 @@ declare var window: {}; declare var XMLHttpRequest: { new(): XMLHttpRequest; }; -interface XMLHttpRequest { +interface XMLHttpRequest { readonly readyState: number; readonly responseText: string; readonly status: number; @@ -874,7 +874,7 @@ namespace Harness { // Cache of lib files from "built/local" let libFileNameSourceFileMap: ts.Map | undefined; - // Cache of lib files from "tests/lib/" + // Cache of lib files from "tests/lib/" const testLibFileNameSourceFileMap = ts.createMap(); const es6TestLibFileNameSourceFileMap = ts.createMap(); diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index c617cc7a0a3..f8d4d171f01 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -186,7 +186,7 @@ class ProjectRunner extends RunnerBase { getCanonicalFileName: Harness.Compiler.getCanonicalFileName, useCaseSensitiveFileNames: () => Harness.IO.useCaseSensitiveFileNames(), getNewLine: () => Harness.IO.newLine(), - fileExists: fileName => fileName === Harness.Compiler.defaultLibFileName || getSourceFileText(fileName) !== undefined, + fileExists: fileName => fileName === Harness.Compiler.defaultLibFileName || getSourceFileText(fileName) !== undefined, readFile: fileName => Harness.IO.readFile(fileName), getDirectories: path => Harness.IO.getDirectories(path) }; diff --git a/src/harness/unittests/builder.ts b/src/harness/unittests/builder.ts index bfdeb1a4067..a5d880fa551 100644 --- a/src/harness/unittests/builder.ts +++ b/src/harness/unittests/builder.ts @@ -43,7 +43,7 @@ namespace ts { }); }); - function makeAssertChanges(getProgram: () => Program): (fileNames: ReadonlyArray) => void { + function makeAssertChanges(getProgram: () => Program): (fileNames: ReadonlyArray) => void { const builder = createBuilder({ getCanonicalFileName: identity, computeHash: identity diff --git a/src/harness/unittests/moduleResolution.ts b/src/harness/unittests/moduleResolution.ts index d9a39aeba65..0dd016b2f22 100644 --- a/src/harness/unittests/moduleResolution.ts +++ b/src/harness/unittests/moduleResolution.ts @@ -441,7 +441,7 @@ export = C; "/a/b/c.ts": `/// `, "/a/b/d.ts": "var x" }); - test(files, { module: ts.ModuleKind.AMD }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "/a/b/d.ts"], []); + test(files, { module: ts.ModuleKind.AMD }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "/a/b/d.ts"], []); }); it("should fail when two files used in program differ only in casing (tripleslash references)", () => { @@ -449,7 +449,7 @@ export = C; "/a/b/c.ts": `/// `, "/a/b/d.ts": "var x" }); - test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], [1149]); + test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], [1149]); }); it("should fail when two files used in program differ only in casing (imports)", () => { @@ -457,7 +457,7 @@ export = C; "/a/b/c.ts": `import {x} from "D"`, "/a/b/d.ts": "export var x" }); - test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], [1149]); + test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], [1149]); }); it("should fail when two files used in program differ only in casing (imports, relative module names)", () => { @@ -465,7 +465,7 @@ export = C; "moduleA.ts": `import {x} from "./ModuleB"`, "moduleB.ts": "export var x" }); - test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts"], [1149]); + test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts"], [1149]); }); it("should fail when two files exist on disk that differs only in casing", () => { @@ -474,7 +474,7 @@ export = C; "/a/b/D.ts": "export var x", "/a/b/d.ts": "export var y" }); - test(files, { module: ts.ModuleKind.AMD }, "/a/b", /*useCaseSensitiveFileNames*/ true, ["c.ts", "d.ts"], [1149]); + test(files, { module: ts.ModuleKind.AMD }, "/a/b", /*useCaseSensitiveFileNames*/ true, ["c.ts", "d.ts"], [1149]); }); it("should fail when module name in 'require' calls has inconsistent casing", () => { @@ -483,7 +483,7 @@ export = C; "moduleB.ts": `import a = require("./moduleC")`, "moduleC.ts": "export var x" }); - test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts", "moduleC.ts"], [1149, 1149]); + test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts", "moduleC.ts"], [1149, 1149]); }); it("should fail when module names in 'require' calls has inconsistent casing and current directory has uppercase chars", () => { @@ -496,7 +496,7 @@ import a = require("./moduleA"); import b = require("./moduleB"); ` }); - test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], [1149]); + test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], [1149]); }); it("should not fail when module names in 'require' calls has consistent casing and current directory has uppercase chars", () => { const files = createMapFromTemplate({ @@ -508,7 +508,7 @@ import a = require("./moduleA"); import b = require("./moduleB"); ` }); - test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], []); + test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], []); }); }); diff --git a/src/harness/virtualFileSystem.ts b/src/harness/virtualFileSystem.ts index 8accd6f621e..54572814d8e 100644 --- a/src/harness/virtualFileSystem.ts +++ b/src/harness/virtualFileSystem.ts @@ -162,7 +162,7 @@ namespace Utils { /** * Reads the directory at the given path and retrieves a list of file names and a list * of directory names within it. Suitable for use with ts.matchFiles() - * @param path The path to the directory to be read + * @param path The path to the directory to be read */ getAccessibleFileSystemEntries(path: string) { const entry = this.traversePath(path); diff --git a/src/server/cancellationToken/cancellationToken.ts b/src/server/cancellationToken/cancellationToken.ts index 6f2f4a8897c..b7243ccd871 100644 --- a/src/server/cancellationToken/cancellationToken.ts +++ b/src/server/cancellationToken/cancellationToken.ts @@ -46,7 +46,7 @@ function createCancellationToken(args: string[]): ServerCancellationToken { let perRequestPipeName: string; let currentRequestId: number; return { - isCancellationRequested: () => perRequestPipeName !== undefined && pipeExists(perRequestPipeName), + isCancellationRequested: () => perRequestPipeName !== undefined && pipeExists(perRequestPipeName), setRequest(requestId: number) { currentRequestId = requestId; perRequestPipeName = namePrefix + requestId; diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 4bd7a0a0967..d406aa9c65b 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -566,7 +566,7 @@ namespace ts.server.protocol { // TODO: GH#20538 /* @internal */ - export interface GetCombinedCodeFixResponse extends Response { + export interface GetCombinedCodeFixResponse extends Response { body: CombinedCodeActions; } diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts index fe71040b4f6..9650130634e 100644 --- a/src/server/scriptVersionCache.ts +++ b/src/server/scriptVersionCache.ts @@ -257,7 +257,7 @@ namespace ts.server { export class ScriptVersionCache { private changes: TextChange[] = []; private readonly versions: LineIndexSnapshot[] = new Array(ScriptVersionCache.maxVersions); - private minVersion = 0; // no versions earlier than min version will maintain change history + private minVersion = 0; // no versions earlier than min version will maintain change history private currentVersion = 0; diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 57dbc5711e7..43934a6bfbf 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -262,8 +262,8 @@ namespace ts.BreakpointResolver { } // Set breakpoint on identifier element of destructuring pattern - // a or ...c or d: x from - // [a, b, ...c] or { a, b } or { d: x } from destructuring pattern + // `a` or `...c` or `d: x` from + // `[a, b, ...c]` or `{ a, b }` or `{ d: x }` from destructuring pattern if ((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.SpreadElement || node.kind === SyntaxKind.PropertyAssignment || diff --git a/src/services/classifier.ts b/src/services/classifier.ts index 32b3dac2cca..3e4c6058a36 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -837,7 +837,7 @@ namespace ts { return ClassificationType.keyword; } - // Special case < and > If they appear in a generic context they are punctuation, + // Special case `<` and `>`: If they appear in a generic context they are punctuation, // not operators. if (tokenKind === SyntaxKind.LessThanToken || tokenKind === SyntaxKind.GreaterThanToken) { // If the node owning the token has a type argument list or type parameter list, then diff --git a/src/services/codefixes/fixSpelling.ts b/src/services/codefixes/fixSpelling.ts index 64cdc3181fb..729f14e9ef9 100644 --- a/src/services/codefixes/fixSpelling.ts +++ b/src/services/codefixes/fixSpelling.ts @@ -9,7 +9,7 @@ namespace ts.codefix { errorCodes, getCodeActions(context) { const { sourceFile } = context; - const info = getInfo(sourceFile, context.span.start, context.program.getTypeChecker()); + const info = getInfo(sourceFile, context.span.start, context.program.getTypeChecker()); if (!info) return undefined; const { node, suggestion } = info; const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, node, suggestion)); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index bd2710244e6..47e23e717d9 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -121,7 +121,7 @@ namespace ts.codefix { createStubbedMethodBody()); } - function createDummyParameters(argCount: number, names: string[] | undefined, minArgumentCount: number | undefined, inJs: boolean): ParameterDeclaration[] { + function createDummyParameters(argCount: number, names: string[] | undefined, minArgumentCount: number | undefined, inJs: boolean): ParameterDeclaration[] { const parameters: ParameterDeclaration[] = []; for (let i = 0; i < argCount; i++) { const newParameter = createParameter( diff --git a/src/services/completions.ts b/src/services/completions.ts index bc1cb4d6777..18f09efcfe6 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -57,7 +57,8 @@ namespace ts.Completions { // In the TypeScript JSX element, if such element is not defined. When users query for completion at closing tag, // instead of simply giving unknown value, the completion will return the tag-name of an associated opening-element. // For example: - // var x =
completion list at "1" will contain "div" with type any + // var x =
+ // The completion list at "1" will contain "div" with type any const tagName = (location.parent.parent).openingElement.tagName; return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false, entries: [{ @@ -76,7 +77,7 @@ namespace ts.Completions { // If the current position is a jsDoc tag, only tags should be provided for completion ? JsDoc.getJSDocTagCompletions() : JsDoc.getJSDocParameterNameCompletions(request.tag); - return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries }; + return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries }; } const entries: CompletionEntry[] = []; diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index debf1702b49..470f3237eb9 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -69,10 +69,10 @@ namespace ts.formatting { rule("NoSpaceBeforeUnaryPostdecrementOperator", unaryPostdecrementExpressions, SyntaxKind.MinusMinusToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), // More unary operator special-casing. - // DevDiv 181814: Be careful when removing leading whitespace + // DevDiv 181814: Be careful when removing leading whitespace // around unary operators. Examples: - // 1 - -2 --X--> 1--2 - // a + ++b --X--> a+++b + // 1 - -2 --X--> 1--2 + // a + ++b --X--> a+++b rule("SpaceAfterPostincrementWhenFollowedByAdd", SyntaxKind.PlusPlusToken, SyntaxKind.PlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), rule("SpaceAfterAddWhenFollowedByUnaryPlus", SyntaxKind.PlusToken, SyntaxKind.PlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), rule("SpaceAfterAddWhenFollowedByPreincrement", SyntaxKind.PlusToken, SyntaxKind.PlusPlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index 0432c342c8f..d2ce802f177 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -616,7 +616,7 @@ namespace ts.FindAllReferences { /** If at an export specifier, go to the symbol it refers to. */ function skipExportSpecifierSymbol(symbol: Symbol, checker: TypeChecker): Symbol { - // For `export { foo } from './bar", there's nothing to skip, because it does not create a new alias. But `export { foo } does. + // For `export { foo } from './bar", there's nothing to skip, because it does not create a new alias. But `export { foo } does. if (symbol.declarations) { for (const declaration of symbol.declarations) { if (isExportSpecifier(declaration) && !(declaration as ExportSpecifier).propertyName && !(declaration as ExportSpecifier).parent.parent.moduleSpecifier) { diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 762726adb77..8449805ee71 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -46,7 +46,7 @@ namespace ts.NavigateTo { continue; } - // It was a match! If the pattern has dots in it, then also see if the + // It was a match! If the pattern has dots in it, then also see if the // declaration container matches as well. let containerMatches = matches; if (patternMatcher.patternContainsDots) { diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index 8f6a468be64..a99683d45ef 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -295,7 +295,7 @@ namespace ts { // import "mod"; // import d from "mod" // import {a as A } from "mod"; - // import * as NS from "mod" + // import * as NS from "mod" // import d, {a, b as B} from "mod" // import i = require("mod"); // import("mod"); diff --git a/src/services/services.ts b/src/services/services.ts index 1660ca10e43..eacce501469 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2053,7 +2053,7 @@ namespace ts { } function getTodoCommentsRegExp(): RegExp { - // NOTE: ?: means 'non-capture group'. It allows us to have groups without having to + // NOTE: `?:` means 'non-capture group'. It allows us to have groups without having to // filter them out later in the final result array. // TODO comments can appear in one of the following forms: diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 36c83f5f4af..f5338db954b 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -197,7 +197,7 @@ namespace ts.SignatureHelp { function getArgumentIndex(argumentsList: Node, node: Node) { // The list we got back can include commas. In the presence of errors it may // also just have nodes without commas. For example "Foo(a b c)" will have 3 - // args without commas. We want to find what index we're at. So we count + // args without commas. We want to find what index we're at. So we count // forward until we hit ourselves, only incrementing the index if it isn't a // comma. // @@ -224,12 +224,12 @@ namespace ts.SignatureHelp { // The argument count for a list is normally the number of non-comma children it has. // For example, if you have "Foo(a,b)" then there will be three children of the arg // list 'a' '' 'b'. So, in this case the arg count will be 2. However, there - // is a small subtlety. If you have "Foo(a,)", then the child list will just have + // is a small subtlety. If you have "Foo(a,)", then the child list will just have // 'a' ''. So, in the case where the last child is a comma, we increase the // arg count by one to compensate. // - // Note: this subtlety only applies to the last comma. If you had "Foo(a,," then - // we'll have: 'a' '' '' + // Note: this subtlety only applies to the last comma. If you had "Foo(a,," then + // we'll have: 'a' '' '' // That will give us 2 non-commas. We then add one for the last comma, giving us an // arg count of 3. const listChildren = argumentsList.getChildren(); @@ -253,9 +253,11 @@ namespace ts.SignatureHelp { // not enough to put us in the substitution expression; we should consider ourselves part of // the *next* span's expression by offsetting the index (argIndex = (spanIndex + 1) + 1). // + // tslint:disable no-double-space // Example: f `# abcd $#{# 1 + 1# }# efghi ${ #"#hello"# } # ` // ^ ^ ^ ^ ^ ^ ^ ^ ^ // Case: 1 1 3 2 1 3 2 2 1 + // tslint:enable no-double-space Debug.assert(position >= node.getStart(), "Assumed 'position' could not occur before node."); if (isTemplateLiteralKind(node.kind)) { if (isInsideTemplateLiteral(node, position)) { @@ -307,9 +309,8 @@ namespace ts.SignatureHelp { // Otherwise, we will not show signature help past the expression. // For example, // - // ` ${ 1 + 1 foo(10) - // | | - // + // ` ${ 1 + 1 foo(10) + // | | // This is because a Missing node has no width. However, what we actually want is to include trivia // leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail. if (template.kind === SyntaxKind.TemplateExpression) { diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index e79dde41e69..7f66d84ba68 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -333,7 +333,7 @@ namespace ts.SymbolDisplay { else if (declaration.kind === SyntaxKind.TypeAliasDeclaration) { // Type alias type parameter // For example - // type list = T[]; // Both T will go through same code path + // type list = T[]; // Both T will go through same code path addInPrefix(); displayParts.push(keywordPart(SyntaxKind.TypeKeyword)); displayParts.push(spacePart()); diff --git a/tslint.json b/tslint.json index 737a0ab8318..b801df720f2 100644 --- a/tslint.json +++ b/tslint.json @@ -31,6 +31,7 @@ "check-else" ], "no-bom": true, + "no-double-space": true, "no-in-operator": true, "no-increment-decrement": true, "no-inferrable-types": true, From c51dfa5596a6ce4ad2de7d5cf9b8be65515f4349 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 8 Jan 2018 10:35:13 -0800 Subject: [PATCH 081/189] Port generated lib files (#21071) --- src/lib/dom.generated.d.ts | 21 +++++++++++++++------ src/lib/webworker.generated.d.ts | 5 +++-- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 001c63b44a1..2a1f6dd6433 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -3596,8 +3596,8 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec slot: string; readonly shadowRoot: ShadowRoot | null; getAttribute(name: string): string | null; - getAttributeNode(name: string): Attr; - getAttributeNodeNS(namespaceURI: string, localName: string): Attr; + getAttributeNode(name: string): Attr | null; + getAttributeNodeNS(namespaceURI: string, localName: string): Attr | null; getAttributeNS(namespaceURI: string, localName: string): string; getBoundingClientRect(): ClientRect; getClientRects(): ClientRectList; @@ -3757,9 +3757,10 @@ declare var External: { }; interface File extends Blob { - readonly lastModifiedDate: any; + readonly lastModifiedDate: Date; readonly name: string; readonly webkitRelativePath: string; + readonly lastModified: number; } declare var File: { @@ -5200,6 +5201,10 @@ interface HTMLIFrameElement extends HTMLElement, GetSVGDocument { * Sets or retrieves the width of the object. */ width: string; + /** + * Sets or retrives the content of the page that is to contain. + */ + srcdoc: string; addEventListener(type: K, listener: (this: HTMLIFrameElement, ev: HTMLIFrameElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: HTMLIFrameElement, ev: HTMLIFrameElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; @@ -5495,8 +5500,9 @@ interface HTMLInputElement extends HTMLElement { * Sets the start and end positions of a selection in a text field. * @param start The offset into the text field for the start of the selection. * @param end The offset into the text field for the end of the selection. + * @param direction The direction in which the selection is performed. */ - setSelectionRange(start?: number, end?: number, direction?: string): void; + setSelectionRange(start: number, end: number, direction?: "forward" | "backward" | "none"): void; /** * Decrements a range input control's value by the value given by the Step attribute. If the optional parameter is used, it will decrement the input control's step value multiplied by the parameter's value. * @param n Value to decrement the value by. @@ -6057,6 +6063,7 @@ interface HTMLObjectElement extends HTMLElement, GetSVGDocument { * Returns whether an element will successfully validate based on forms validation rules and constraints. */ readonly willValidate: boolean; + typemustmatch: boolean; /** * Returns whether a form will validate when it is submitted, without having to submit it. */ @@ -6958,8 +6965,9 @@ interface HTMLTextAreaElement extends HTMLElement { * Sets the start and end positions of a selection in a text field. * @param start The offset into the text field for the start of the selection. * @param end The offset into the text field for the end of the selection. + * @param direction The direction in which the selection is performed. */ - setSelectionRange(start: number, end: number): void; + setSelectionRange(start: number, end: number, direction?: "forward" | "backward" | "none"): void; addEventListener(type: K, listener: (this: HTMLTextAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: HTMLTextAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; @@ -12213,7 +12221,7 @@ interface URL { declare var URL: { prototype: URL; - new(url: string, base?: string): URL; + new(url: string, base?: string | URL): URL; createObjectURL(object: any, options?: ObjectURLOptions): string; revokeObjectURL(url: string): void; }; @@ -15029,6 +15037,7 @@ interface SVGElementTagNameMap { "view": SVGViewElement; } +/** @deprecated Directly use HTMLElementTagNameMap or SVGElementTagNameMap as appropriate, instead. */ interface ElementTagNameMap extends HTMLElementTagNameMap, SVGElementTagNameMap { } declare var Audio: { new(src?: string): HTMLAudioElement; }; diff --git a/src/lib/webworker.generated.d.ts b/src/lib/webworker.generated.d.ts index 6eb17c33c5e..4a582d3c9c6 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -414,9 +414,10 @@ declare var EventTarget: { }; interface File extends Blob { - readonly lastModifiedDate: any; + readonly lastModifiedDate: Date; readonly name: string; readonly webkitRelativePath: string; + readonly lastModified: number; } declare var File: { @@ -1061,7 +1062,7 @@ interface URL { declare var URL: { prototype: URL; - new(url: string, base?: string): URL; + new(url: string, base?: string | URL): URL; createObjectURL(object: any, options?: ObjectURLOptions): string; revokeObjectURL(url: string): void; }; From 76eafe0e75734a62d6978539f4af0bab97fa932f Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 10:37:48 -0800 Subject: [PATCH 082/189] Fix invalid cast (#20426) --- src/compiler/checker.ts | 6 +++--- src/compiler/types.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fdf27448169..21c8c97feee 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13462,7 +13462,7 @@ namespace ts { } } - function findFirstSuperCall(n: Node): Node { + function findFirstSuperCall(n: Node): SuperCall | undefined { if (isSuperCall(n)) { return n; } @@ -13478,12 +13478,12 @@ namespace ts { * * @param constructor constructor-function to look for super statement */ - function getSuperCallInConstructor(constructor: ConstructorDeclaration): ExpressionStatement { + function getSuperCallInConstructor(constructor: ConstructorDeclaration): SuperCall | undefined { const links = getNodeLinks(constructor); // Only trying to find super-call if we haven't yet tried to find one. Once we try, we will record the result if (links.hasSuperCall === undefined) { - links.superCall = findFirstSuperCall(constructor.body); + links.superCall = findFirstSuperCall(constructor.body); links.hasSuperCall = links.superCall ? true : false; } return links.superCall; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 89406a0f42b..bb79fc951b3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3372,7 +3372,7 @@ namespace ts { resolvedJsxElementAttributesType?: Type; // resolved element attributes type of a JSX openinglike element resolvedJsxElementAllAttributesType?: Type; // resolved all element attributes type of a JSX openinglike element hasSuperCall?: boolean; // recorded result when we try to find super-call. We only try to find one if this flag is undefined, indicating that we haven't made an attempt. - superCall?: ExpressionStatement; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing + superCall?: SuperCall; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing switchTypes?: Type[]; // Cached array of switch case expression types } From 7e150a914e2b368c00839531a1c0204ea0ab2a7e Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 10:38:11 -0800 Subject: [PATCH 083/189] Remove mutually-recursive functions (#20425) --- src/compiler/checker.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 21c8c97feee..5e83da5a69d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19918,24 +19918,6 @@ namespace ts { return; } - function containsSuperCallAsComputedPropertyName(n: Declaration): boolean { - const name = getNameOfDeclaration(n); - return name && containsSuperCall(name); - } - - function containsSuperCall(n: Node): boolean { - if (isSuperCall(n)) { - return true; - } - else if (isFunctionLike(n)) { - return false; - } - else if (isClassLike(n)) { - return forEach((n).members, containsSuperCallAsComputedPropertyName); - } - return forEachChild(n, containsSuperCall); - } - function isInstancePropertyWithInitializer(n: Node): boolean { return n.kind === SyntaxKind.PropertyDeclaration && !hasModifier(n, ModifierFlags.Static) && From f83283c0688596f778a1ce7a49554febfcc79a99 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 10:38:55 -0800 Subject: [PATCH 084/189] Improve parse error for double comma somewhere inside a call expression (#20399) --- src/compiler/parser.ts | 8 ++++++-- .../importCallExpressionGrammarError.errors.txt | 13 +++---------- .../reference/importCallExpressionGrammarError.js | 2 -- .../importCallExpressionGrammarError.symbols | 5 +---- .../importCallExpressionGrammarError.types | 5 ----- .../baselines/reference/missingArgument1.errors.txt | 2 +- tests/baselines/reference/missingArgument1.js | 2 +- tests/baselines/reference/missingArgument1.types | 1 - .../parseErrorDoubleCommaInCall.errors.txt | 10 ++++++++++ .../reference/parseErrorDoubleCommaInCall.js | 10 ++++++++++ .../reference/parseErrorDoubleCommaInCall.symbols | 9 +++++++++ .../reference/parseErrorDoubleCommaInCall.types | 12 ++++++++++++ .../parserErrorRecovery_ArgumentList6.errors.txt | 5 ++++- .../parserErrorRecovery_ArgumentList6.types | 1 - .../parserErrorRecovery_ArgumentList7.errors.txt | 5 ++++- .../reference/parserErrorRecovery_ArgumentList7.js | 2 +- .../parserErrorRecovery_ArgumentList7.types | 1 - tests/cases/compiler/parseErrorDoubleCommaInCall.ts | 3 +++ .../importCallExpressionGrammarError.ts | 1 - .../signatureHelpOnOverloadsDifferentArity3.ts | 4 ++-- 20 files changed, 67 insertions(+), 34 deletions(-) create mode 100644 tests/baselines/reference/parseErrorDoubleCommaInCall.errors.txt create mode 100644 tests/baselines/reference/parseErrorDoubleCommaInCall.js create mode 100644 tests/baselines/reference/parseErrorDoubleCommaInCall.symbols create mode 100644 tests/baselines/reference/parseErrorDoubleCommaInCall.types create mode 100644 tests/cases/compiler/parseErrorDoubleCommaInCall.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ab8e52e3dfa..a072579ed63 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1429,9 +1429,13 @@ namespace ts { return token() === SyntaxKind.CommaToken || token() === SyntaxKind.DotDotDotToken || isIdentifierOrPattern(); case ParsingContext.TypeParameters: return isIdentifier(); - case ParsingContext.ArgumentExpressions: case ParsingContext.ArrayLiteralMembers: - return token() === SyntaxKind.CommaToken || token() === SyntaxKind.DotDotDotToken || isStartOfExpression(); + if (token() === SyntaxKind.CommaToken) { + return true; + } + // falls through + case ParsingContext.ArgumentExpressions: + return token() === SyntaxKind.DotDotDotToken || isStartOfExpression(); case ParsingContext.Parameters: return isStartOfParameter(); case ParsingContext.TypeArguments: diff --git a/tests/baselines/reference/importCallExpressionGrammarError.errors.txt b/tests/baselines/reference/importCallExpressionGrammarError.errors.txt index 6d64808e111..b39228f100d 100644 --- a/tests/baselines/reference/importCallExpressionGrammarError.errors.txt +++ b/tests/baselines/reference/importCallExpressionGrammarError.errors.txt @@ -1,13 +1,11 @@ tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(5,8): error TS1325: Specifier of dynamic import cannot be spread element. tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(7,17): error TS1325: Specifier of dynamic import cannot be spread element. tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(8,12): error TS1324: Dynamic import must have one specifier as an argument. -tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(9,19): error TS1135: Argument expression expected. -tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(9,19): error TS7036: Dynamic import's specifier must be of type 'string', but here has type 'undefined'. -tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(10,12): error TS1324: Dynamic import must have one specifier as an argument. -tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(10,19): error TS2307: Cannot find module 'pathToModule'. +tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(9,12): error TS1324: Dynamic import must have one specifier as an argument. +tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(9,19): error TS2307: Cannot find module 'pathToModule'. -==== tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts (7 errors) ==== +==== tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts (5 errors) ==== declare function getSpecifier(): string; declare var whatToLoad: boolean; @@ -22,11 +20,6 @@ tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(10,19) const p2 = import(); ~~~~~~~~ !!! error TS1324: Dynamic import must have one specifier as an argument. - const p3 = import(,); - -!!! error TS1135: Argument expression expected. - -!!! error TS7036: Dynamic import's specifier must be of type 'string', but here has type 'undefined'. const p4 = import("pathToModule", "secondModule"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS1324: Dynamic import must have one specifier as an argument. diff --git a/tests/baselines/reference/importCallExpressionGrammarError.js b/tests/baselines/reference/importCallExpressionGrammarError.js index 435eab35d4e..61b47759581 100644 --- a/tests/baselines/reference/importCallExpressionGrammarError.js +++ b/tests/baselines/reference/importCallExpressionGrammarError.js @@ -7,7 +7,6 @@ import(...["PathModule"]); var p1 = import(...a); const p2 = import(); -const p3 = import(,); const p4 = import("pathToModule", "secondModule"); //// [importCallExpressionGrammarError.js] @@ -15,5 +14,4 @@ var a = ["./0"]; Promise.resolve().then(() => require(...["PathModule"])); var p1 = Promise.resolve().then(() => require(...a)); const p2 = Promise.resolve().then(() => require()); -const p3 = Promise.resolve().then(() => require()); const p4 = Promise.resolve().then(() => require("pathToModule")); diff --git a/tests/baselines/reference/importCallExpressionGrammarError.symbols b/tests/baselines/reference/importCallExpressionGrammarError.symbols index 7fce3af41b5..b4a0efd052e 100644 --- a/tests/baselines/reference/importCallExpressionGrammarError.symbols +++ b/tests/baselines/reference/importCallExpressionGrammarError.symbols @@ -17,9 +17,6 @@ var p1 = import(...a); const p2 = import(); >p2 : Symbol(p2, Decl(importCallExpressionGrammarError.ts, 7, 5)) -const p3 = import(,); ->p3 : Symbol(p3, Decl(importCallExpressionGrammarError.ts, 8, 5)) - const p4 = import("pathToModule", "secondModule"); ->p4 : Symbol(p4, Decl(importCallExpressionGrammarError.ts, 9, 5)) +>p4 : Symbol(p4, Decl(importCallExpressionGrammarError.ts, 8, 5)) diff --git a/tests/baselines/reference/importCallExpressionGrammarError.types b/tests/baselines/reference/importCallExpressionGrammarError.types index c9f95fbcb6b..2e2a8221a07 100644 --- a/tests/baselines/reference/importCallExpressionGrammarError.types +++ b/tests/baselines/reference/importCallExpressionGrammarError.types @@ -26,11 +26,6 @@ const p2 = import(); >p2 : Promise >import() : Promise -const p3 = import(,); ->p3 : Promise ->import(,) : Promise -> : undefined - const p4 = import("pathToModule", "secondModule"); >p4 : Promise >import("pathToModule", "secondModule") : Promise diff --git a/tests/baselines/reference/missingArgument1.errors.txt b/tests/baselines/reference/missingArgument1.errors.txt index ba2bb0892f2..7530da802c8 100644 --- a/tests/baselines/reference/missingArgument1.errors.txt +++ b/tests/baselines/reference/missingArgument1.errors.txt @@ -10,7 +10,7 @@ tests/cases/compiler/missingArgument1.ts(1,8): error TS2304: Cannot find name 'b !!! error TS2304: Cannot find name 'foo'. ~ !!! error TS2304: Cannot find name 'a'. - + ~ !!! error TS1135: Argument expression expected. ~ !!! error TS2304: Cannot find name 'b'. \ No newline at end of file diff --git a/tests/baselines/reference/missingArgument1.js b/tests/baselines/reference/missingArgument1.js index eed0d9b11d6..94f78377e40 100644 --- a/tests/baselines/reference/missingArgument1.js +++ b/tests/baselines/reference/missingArgument1.js @@ -2,4 +2,4 @@ foo(a,,b); //// [missingArgument1.js] -foo(a, , b); +foo(a, b); diff --git a/tests/baselines/reference/missingArgument1.types b/tests/baselines/reference/missingArgument1.types index 4b362a76145..b4468f4b3f6 100644 --- a/tests/baselines/reference/missingArgument1.types +++ b/tests/baselines/reference/missingArgument1.types @@ -3,6 +3,5 @@ foo(a,,b); >foo(a,,b) : any >foo : any >a : any -> : undefined >b : any diff --git a/tests/baselines/reference/parseErrorDoubleCommaInCall.errors.txt b/tests/baselines/reference/parseErrorDoubleCommaInCall.errors.txt new file mode 100644 index 00000000000..f209456d81f --- /dev/null +++ b/tests/baselines/reference/parseErrorDoubleCommaInCall.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/parseErrorDoubleCommaInCall.ts(2,10): error TS1136: Property assignment expected. + + +==== tests/cases/compiler/parseErrorDoubleCommaInCall.ts (1 errors) ==== + Boolean({ + x: 0,, + ~ +!!! error TS1136: Property assignment expected. + }); + \ No newline at end of file diff --git a/tests/baselines/reference/parseErrorDoubleCommaInCall.js b/tests/baselines/reference/parseErrorDoubleCommaInCall.js new file mode 100644 index 00000000000..f1a50cccfde --- /dev/null +++ b/tests/baselines/reference/parseErrorDoubleCommaInCall.js @@ -0,0 +1,10 @@ +//// [parseErrorDoubleCommaInCall.ts] +Boolean({ + x: 0,, +}); + + +//// [parseErrorDoubleCommaInCall.js] +Boolean({ + x: 0 +}); diff --git a/tests/baselines/reference/parseErrorDoubleCommaInCall.symbols b/tests/baselines/reference/parseErrorDoubleCommaInCall.symbols new file mode 100644 index 00000000000..fed8484d591 --- /dev/null +++ b/tests/baselines/reference/parseErrorDoubleCommaInCall.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/parseErrorDoubleCommaInCall.ts === +Boolean({ +>Boolean : Symbol(Boolean, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + x: 0,, +>x : Symbol(x, Decl(parseErrorDoubleCommaInCall.ts, 0, 9)) + +}); + diff --git a/tests/baselines/reference/parseErrorDoubleCommaInCall.types b/tests/baselines/reference/parseErrorDoubleCommaInCall.types new file mode 100644 index 00000000000..23197748490 --- /dev/null +++ b/tests/baselines/reference/parseErrorDoubleCommaInCall.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/parseErrorDoubleCommaInCall.ts === +Boolean({ +>Boolean({ x: 0,,}) : boolean +>Boolean : BooleanConstructor +>{ x: 0,,} : { x: number; } + + x: 0,, +>x : number +>0 : 0 + +}); + diff --git a/tests/baselines/reference/parserErrorRecovery_ArgumentList6.errors.txt b/tests/baselines/reference/parserErrorRecovery_ArgumentList6.errors.txt index 7562fee7936..215c8da0f4f 100644 --- a/tests/baselines/reference/parserErrorRecovery_ArgumentList6.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ArgumentList6.errors.txt @@ -1,10 +1,13 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList6.ts(1,1): error TS2304: Cannot find name 'Foo'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList6.ts(1,5): error TS1135: Argument expression expected. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList6.ts(1,6): error TS1005: ')' expected. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList6.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList6.ts (3 errors) ==== Foo(, ~~~ !!! error TS2304: Cannot find name 'Foo'. + ~ +!!! error TS1135: Argument expression expected. !!! error TS1005: ')' expected. \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ArgumentList6.types b/tests/baselines/reference/parserErrorRecovery_ArgumentList6.types index 202483685d7..8dee378e0a9 100644 --- a/tests/baselines/reference/parserErrorRecovery_ArgumentList6.types +++ b/tests/baselines/reference/parserErrorRecovery_ArgumentList6.types @@ -2,5 +2,4 @@ Foo(, >Foo(, : any >Foo : any -> : undefined diff --git a/tests/baselines/reference/parserErrorRecovery_ArgumentList7.errors.txt b/tests/baselines/reference/parserErrorRecovery_ArgumentList7.errors.txt index 3f4afaf930b..abe77ca9f1c 100644 --- a/tests/baselines/reference/parserErrorRecovery_ArgumentList7.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ArgumentList7.errors.txt @@ -1,13 +1,16 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList7.ts(1,1): error TS2304: Cannot find name 'Foo'. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList7.ts(1,5): error TS2304: Cannot find name 'a'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList7.ts(1,7): error TS1135: Argument expression expected. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList7.ts(1,8): error TS1005: ')' expected. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList7.ts (3 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList7.ts (4 errors) ==== Foo(a,, ~~~ !!! error TS2304: Cannot find name 'Foo'. ~ !!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS1135: Argument expression expected. !!! error TS1005: ')' expected. \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ArgumentList7.js b/tests/baselines/reference/parserErrorRecovery_ArgumentList7.js index 94eba9445e9..dfe0f58332f 100644 --- a/tests/baselines/reference/parserErrorRecovery_ArgumentList7.js +++ b/tests/baselines/reference/parserErrorRecovery_ArgumentList7.js @@ -2,4 +2,4 @@ Foo(a,, //// [parserErrorRecovery_ArgumentList7.js] -Foo(a, ); +Foo(a); diff --git a/tests/baselines/reference/parserErrorRecovery_ArgumentList7.types b/tests/baselines/reference/parserErrorRecovery_ArgumentList7.types index 9de43329a13..ca95e4563e1 100644 --- a/tests/baselines/reference/parserErrorRecovery_ArgumentList7.types +++ b/tests/baselines/reference/parserErrorRecovery_ArgumentList7.types @@ -3,5 +3,4 @@ Foo(a,, >Foo(a,, : any >Foo : any >a : any -> : undefined diff --git a/tests/cases/compiler/parseErrorDoubleCommaInCall.ts b/tests/cases/compiler/parseErrorDoubleCommaInCall.ts new file mode 100644 index 00000000000..2171e9262a9 --- /dev/null +++ b/tests/cases/compiler/parseErrorDoubleCommaInCall.ts @@ -0,0 +1,3 @@ +Boolean({ + x: 0,, +}); diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts b/tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts index 38dc47f3207..609a70a2013 100644 --- a/tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts +++ b/tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts @@ -10,5 +10,4 @@ import(...["PathModule"]); var p1 = import(...a); const p2 = import(); -const p3 = import(,); const p4 = import("pathToModule", "secondModule"); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpOnOverloadsDifferentArity3.ts b/tests/cases/fourslash/signatureHelpOnOverloadsDifferentArity3.ts index b98cfe6bbfe..d445997338b 100644 --- a/tests/cases/fourslash/signatureHelpOnOverloadsDifferentArity3.ts +++ b/tests/cases/fourslash/signatureHelpOnOverloadsDifferentArity3.ts @@ -13,14 +13,14 @@ verify.currentSignatureHelpIs("f(): any"); verify.currentSignatureParameterCountIs(0); verify.signatureHelpArgumentCountIs(0); -edit.insert(", "); +edit.insert("x, "); verify.signatureHelpCountIs(4); verify.currentSignatureHelpIs("f(s: string, b: boolean): any"); verify.currentSignatureParameterCountIs(2); verify.currentParameterHelpArgumentNameIs("b"); verify.currentParameterSpanIs("b: boolean"); -edit.insert(", "); +edit.insert("x, "); verify.signatureHelpCountIs(4); verify.currentSignatureHelpIs("f(s: string, b: boolean): any"); verify.currentSignatureParameterCountIs(2); \ No newline at end of file From fc18f08e63bda86ad449ec204452f9e75db806ef Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 10:39:52 -0800 Subject: [PATCH 085/189] Remove 'indexOf' helper, use 'arr.indexOf()' (#20194) --- src/compiler/binder.ts | 4 ++-- src/compiler/checker.ts | 30 ++++++++++++------------ src/compiler/core.ts | 11 --------- src/compiler/sourcemap.ts | 2 +- src/compiler/utilities.ts | 2 +- src/services/breakpoints.ts | 5 ++-- src/services/formatting/smartIndenter.ts | 11 +++++---- src/services/jsDoc.ts | 2 +- 8 files changed, 29 insertions(+), 38 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 809e840472b..4fdfacdbf50 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -303,7 +303,7 @@ namespace ts { // without names can only come from JSDocFunctionTypes. Debug.assert(node.parent.kind === SyntaxKind.JSDocFunctionType); const functionType = node.parent; - const index = indexOf(functionType.parameters, node); + const index = functionType.parameters.indexOf(node as ParameterDeclaration); return "arg" + index as __String; case SyntaxKind.JSDocTypedefTag: const name = getNameOfJSDocTypedef(node as JSDocTypedefTag); @@ -2538,7 +2538,7 @@ namespace ts { } if (isBindingPattern(node.name)) { - bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, "__" + indexOf(node.parent.parameters, node) as __String); + bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, "__" + node.parent.parameters.indexOf(node) as __String); } else { declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5e83da5a69d..613150cba42 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -845,7 +845,7 @@ namespace ts { return true; } const sourceFiles = host.getSourceFiles(); - return indexOf(sourceFiles, declarationFile) <= indexOf(sourceFiles, useFile); + return sourceFiles.indexOf(declarationFile) <= sourceFiles.indexOf(useFile); } if (declaration.pos <= usage.pos) { @@ -4336,7 +4336,7 @@ namespace ts { } else { // Use specific property type when parent is a tuple or numeric index type when parent is an array - const propName = "" + indexOf(pattern.elements, declaration); + const propName = "" + pattern.elements.indexOf(declaration); type = isTupleLikeType(parentType) ? getTypeOfPropertyOfType(parentType, propName as __String) : elementType; @@ -6758,7 +6758,7 @@ namespace ts { if (node.initializer) { const signatureDeclaration = node.parent; const signature = getSignatureFromDeclaration(signatureDeclaration); - const parameterIndex = ts.indexOf(signatureDeclaration.parameters, node); + const parameterIndex = signatureDeclaration.parameters.indexOf(node); Debug.assert(parameterIndex >= 0); return parameterIndex >= signature.minArgumentCount; } @@ -6766,7 +6766,7 @@ namespace ts { if (iife) { return !node.type && !node.dotDotDotToken && - indexOf((node.parent as SignatureDeclaration).parameters, node) >= iife.arguments.length; + node.parent.parameters.indexOf(node) >= iife.arguments.length; } return false; @@ -8707,7 +8707,7 @@ namespace ts { * This is used during inference when instantiating type parameter defaults. */ function createBackreferenceMapper(typeParameters: TypeParameter[], index: number): TypeMapper { - return t => indexOf(typeParameters, t) >= index ? emptyObjectType : t; + return t => typeParameters.indexOf(t) >= index ? emptyObjectType : t; } function isInferenceContext(mapper: TypeMapper): mapper is InferenceContext { @@ -10550,7 +10550,7 @@ namespace ts { let result = "" + type.target.id; for (const t of type.typeArguments) { if (isUnconstrainedTypeParameter(t)) { - let index = indexOf(typeParameters, t); + let index = typeParameters.indexOf(t); if (index < 0) { index = typeParameters.length; typeParameters.push(t); @@ -12120,7 +12120,7 @@ namespace ts { } function getAssignedTypeOfArrayLiteralElement(node: ArrayLiteralExpression, element: Expression): Type { - return getTypeOfDestructuredArrayElement(getAssignedType(node), indexOf(node.elements, element)); + return getTypeOfDestructuredArrayElement(getAssignedType(node), node.elements.indexOf(element)); } function getAssignedTypeOfSpreadExpression(node: SpreadElement): Type { @@ -12164,7 +12164,7 @@ namespace ts { const type = pattern.kind === SyntaxKind.ObjectBindingPattern ? getTypeOfDestructuredProperty(parentType, node.propertyName || node.name) : !node.dotDotDotToken ? - getTypeOfDestructuredArrayElement(parentType, indexOf(pattern.elements, node)) : + getTypeOfDestructuredArrayElement(parentType, pattern.elements.indexOf(node)) : getTypeOfDestructuredSpreadExpression(parentType); return getTypeWithDefault(type, node.initializer); } @@ -13918,7 +13918,7 @@ namespace ts { if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) { const iife = getImmediatelyInvokedFunctionExpression(func); if (iife && iife.arguments) { - const indexOfParameter = indexOf(func.parameters, parameter); + const indexOfParameter = func.parameters.indexOf(parameter); if (parameter.dotDotDotToken) { const restTypes: Type[] = []; for (let i = indexOfParameter; i < iife.arguments.length; i++) { @@ -13939,7 +13939,7 @@ namespace ts { if (contextualSignature) { const funcHasRestParameters = hasRestParameter(func); const len = func.parameters.length - (funcHasRestParameters ? 1 : 0); - let indexOfParameter = indexOf(func.parameters, parameter); + let indexOfParameter = func.parameters.indexOf(parameter); if (getThisParameter(func) !== undefined && !contextualSignature.thisParameter) { Debug.assert(indexOfParameter !== 0); // Otherwise we should not have called `getContextuallyTypedParameterType`. indexOfParameter -= 1; @@ -14070,7 +14070,7 @@ namespace ts { // In a typed function call, an argument or substitution expression is contextually typed by the type of the corresponding parameter. function getContextualTypeForArgument(callTarget: CallLikeExpression, arg: Expression): Type { const args = getEffectiveCallArguments(callTarget); - const argIndex = indexOf(args, arg); + const argIndex = args.indexOf(arg); if (argIndex >= 0) { // If we're already in the process of resolving the given signature, don't resolve again as // that could cause infinite recursion. Instead, return anySignature. @@ -17236,7 +17236,7 @@ namespace ts { } excludeCount--; if (excludeCount > 0) { - excludeArgument[indexOf(excludeArgument, /*value*/ true)] = false; + excludeArgument[excludeArgument.indexOf(/*value*/ true)] = false; } else { excludeArgument = undefined; @@ -19497,7 +19497,7 @@ namespace ts { error(node, Diagnostics.A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature); } if (node.name && isIdentifier(node.name) && (node.name.escapedText === "this" || node.name.escapedText === "new")) { - if (indexOf(func.parameters, node) !== 0) { + if (func.parameters.indexOf(node) !== 0) { error(node, Diagnostics.A_0_parameter_must_be_the_first_parameter, node.name.escapedText as string); } if (func.kind === SyntaxKind.Constructor || func.kind === SyntaxKind.ConstructSignature || func.kind === SyntaxKind.ConstructorType) { @@ -20604,7 +20604,7 @@ namespace ts { const promisedType = getPromisedTypeOfPromise(type); if (promisedType) { - if (type.id === promisedType.id || indexOf(awaitedTypeStack, promisedType.id) >= 0) { + if (type.id === promisedType.id || awaitedTypeStack.indexOf(promisedType.id) >= 0) { // Verify that we don't have a bad actor in the form of a promise whose // promised type is the same as the promise type, or a mutually recursive // promise. If so, we return undefined as we cannot guess the shape. If this @@ -24651,7 +24651,7 @@ namespace ts { const typeOfArrayLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr.parent); const elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || unknownType, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType; return checkArrayLiteralDestructuringElementAssignment(expr.parent, typeOfArrayLiteral, - indexOf((expr.parent).elements, expr), elementType || unknownType); + (expr.parent).elements.indexOf(expr), elementType || unknownType); } // Gets the property symbol corresponding to the property in destructuring assignment diff --git a/src/compiler/core.ts b/src/compiler/core.ts index d54c2a24f80..d9218ecc01b 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -335,17 +335,6 @@ namespace ts { return false; } - export function indexOf(array: ReadonlyArray, value: T): number { - if (array) { - for (let i = 0; i < array.length; i++) { - if (array[i] === value) { - return i; - } - } - } - return -1; - } - export function indexOfAnyCharCode(text: string, charCodes: ReadonlyArray, start?: number): number { for (let i = start || 0; i < text.length; i++) { if (contains(charCodes, text.charCodeAt(i))) { diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index b5cd1d9e322..828c5744bbd 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -420,7 +420,7 @@ namespace ts { host.getCanonicalFileName, /*isAbsolutePathAnUrl*/ true); - sourceMapSourceIndex = indexOf(sourceMapData.sourceMapSources, source); + sourceMapSourceIndex = sourceMapData.sourceMapSources.indexOf(source); if (sourceMapSourceIndex === -1) { sourceMapSourceIndex = sourceMapData.sourceMapSources.length; sourceMapData.sourceMapSources.push(source); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index cafdce60315..56f85b49e1d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -803,7 +803,7 @@ namespace ts { return node === (parent).type; case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: - return (parent).typeArguments && indexOf((parent).typeArguments, node) >= 0; + return contains((parent).typeArguments, node); case SyntaxKind.TaggedTemplateExpression: // TODO (drosen): TaggedTemplateExpressions may eventually support type arguments. return false; diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 43934a6bfbf..26df417f879 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -427,8 +427,9 @@ namespace ts.BreakpointResolver { } else { const functionDeclaration = parameter.parent; - const indexOfParameter = indexOf(functionDeclaration.parameters, parameter); - if (indexOfParameter) { + const indexOfParameter = functionDeclaration.parameters.indexOf(parameter); + Debug.assert(indexOfParameter !== -1); + if (indexOfParameter !== 0) { // Not a first parameter, go to previous parameter return spanInParameterDeclaration(functionDeclaration.parameters[indexOfParameter - 1]); } diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 443a63a2042..1e6323be9fa 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -367,12 +367,13 @@ namespace ts.formatting { function getActualIndentationForListItem(node: Node, sourceFile: SourceFile, options: EditorSettings): number { const containingList = getContainingList(node, sourceFile); - return containingList ? getActualIndentationFromList(containingList) : Value.Unknown; - - function getActualIndentationFromList(list: ReadonlyArray): number { - const index = indexOf(list, node); - return index !== -1 ? deriveActualIndentationFromList(list, index, sourceFile, options) : Value.Unknown; + if (containingList) { + const index = containingList.indexOf(node); + if (index !== -1) { + return deriveActualIndentationFromList(containingList, index, sourceFile, options); + } } + return Value.Unknown; } function getLineIndentationWhenExpressionIsInMultiLine(node: Node, sourceFile: SourceFile, options: EditorSettings): number { diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 33d84763d44..46f2458bba9 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -112,7 +112,7 @@ namespace ts.JsDoc { function forEachUnique(array: T[], callback: (element: T, index: number) => U): U { if (array) { for (let i = 0; i < array.length; i++) { - if (indexOf(array, array[i]) === i) { + if (array.indexOf(array[i]) === i) { const result = callback(array[i], i); if (result) { return result; From 1b2dc828d00b9d6d407e2ee5df06d3fb410fbb6e Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 11:25:06 -0800 Subject: [PATCH 086/189] Fix lint failure (#21073) --- src/harness/fourslash.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 9ab7dd31ffd..12b98eebcca 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -3777,7 +3777,7 @@ namespace FourSlashInterface { public eachMarker(markers: ReadonlyArray, action: (marker: FourSlash.Marker, index: number) => void): void; public eachMarker(action: (marker: FourSlash.Marker, index: number) => void): void; - public eachMarker(a: ReadonlyArray | ((marker: FourSlash.Marker, index: number) => void), b?: (marker: FourSlash.Marker, index: number) => void): void { + public eachMarker(a: ReadonlyArray | ((marker: FourSlash.Marker, index: number) => void), b?: (marker: FourSlash.Marker, index: number) => void): void { const markers = typeof a === "function" ? this.state.getMarkers() : a.map(m => this.state.getMarkerByName(m)); this.state.goToEachMarker(markers, typeof a === "function" ? a : b); } From fef7ad4986aa069ea0b20f7a841e90e6039831f6 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 11:30:36 -0800 Subject: [PATCH 087/189] Remove unncessary existence check (#21029) --- src/compiler/checker.ts | 50 ++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 613150cba42..d2fe31c11a0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21239,34 +21239,32 @@ namespace ts { function checkUnusedClassMembers(node: ClassDeclaration | ClassExpression): void { if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) { - if (node.members) { - for (const member of node.members) { - switch (member.kind) { - case SyntaxKind.MethodDeclaration: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - if (member.kind === SyntaxKind.SetAccessor && member.symbol.flags & SymbolFlags.GetAccessor) { - // Already would have reported an error on the getter. - break; - } - if (!member.symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) { - error(member.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(member.symbol)); - } + for (const member of node.members) { + switch (member.kind) { + case SyntaxKind.MethodDeclaration: + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + if (member.kind === SyntaxKind.SetAccessor && member.symbol.flags & SymbolFlags.GetAccessor) { + // Already would have reported an error on the getter. break; - case SyntaxKind.Constructor: - for (const parameter of (member).parameters) { - if (!parameter.symbol.isReferenced && hasModifier(parameter, ModifierFlags.Private)) { - error(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol)); - } + } + if (!member.symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) { + error(member.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(member.symbol)); + } + break; + case SyntaxKind.Constructor: + for (const parameter of (member).parameters) { + if (!parameter.symbol.isReferenced && hasModifier(parameter, ModifierFlags.Private)) { + error(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol)); } - break; - case SyntaxKind.IndexSignature: - // Can't be private - break; - default: - Debug.fail(); - } + } + break; + case SyntaxKind.IndexSignature: + // Can't be private + break; + default: + Debug.fail(); } } } From f34de1a1cab8d3fd784b814e7903f76038e0c82f Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 11:33:14 -0800 Subject: [PATCH 088/189] Support find-all-references starting from a `reference path` or `reference types` comment (#21007) --- src/services/documentHighlights.ts | 12 ++---- src/services/findAllReferences.ts | 25 ++++++------ src/services/goToDefinition.ts | 38 ++++++++++--------- tests/cases/fourslash/findAllRefsForModule.ts | 8 ++-- .../fourslash/findAllRefsForModuleGlobal.ts | 4 +- 5 files changed, 41 insertions(+), 46 deletions(-) diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index d9a9a03c38b..5c1e7116af4 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -2,19 +2,15 @@ namespace ts.DocumentHighlights { export function getDocumentHighlights(program: Program, cancellationToken: CancellationToken, sourceFile: SourceFile, position: number, sourceFilesToSearch: SourceFile[]): DocumentHighlights[] | undefined { const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true); - // Note that getTouchingWord indicates failure by returning the sourceFile node. - if (node === sourceFile) return undefined; - Debug.assert(node.parent !== undefined); - - if (isJsxOpeningElement(node.parent) && node.parent.tagName === node || isJsxClosingElement(node.parent)) { + if (node.parent && (isJsxOpeningElement(node.parent) && node.parent.tagName === node || isJsxClosingElement(node.parent))) { // For a JSX element, just highlight the matching tag, not all references. const { openingElement, closingElement } = node.parent.parent; const highlightSpans = [openingElement, closingElement].map(({ tagName }) => getHighlightSpanForNode(tagName, sourceFile)); return [{ fileName: sourceFile.fileName, highlightSpans }]; } - return getSemanticDocumentHighlights(node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile); + return getSemanticDocumentHighlights(position, node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile); } function getHighlightSpanForNode(node: Node, sourceFile: SourceFile): HighlightSpan { @@ -25,8 +21,8 @@ namespace ts.DocumentHighlights { }; } - function getSemanticDocumentHighlights(node: Node, program: Program, cancellationToken: CancellationToken, sourceFilesToSearch: SourceFile[]): DocumentHighlights[] { - const referenceEntries = FindAllReferences.getReferenceEntriesForNode(node, program, sourceFilesToSearch, cancellationToken); + function getSemanticDocumentHighlights(position: number, node: Node, program: Program, cancellationToken: CancellationToken, sourceFilesToSearch: SourceFile[]): DocumentHighlights[] { + const referenceEntries = FindAllReferences.getReferenceEntriesForNode(position, node, program, sourceFilesToSearch, cancellationToken); return referenceEntries && convertReferencedSymbols(referenceEntries); } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 6e43ac37def..fa8c750e45d 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -52,12 +52,12 @@ namespace ts.FindAllReferences { export function getImplementationsAtPosition(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray, sourceFile: SourceFile, position: number): ImplementationLocation[] { // A node in a JSDoc comment can't have an implementation anyway. const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ false); - const referenceEntries = getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node); + const referenceEntries = getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node, position); const checker = program.getTypeChecker(); return map(referenceEntries, entry => toImplementationLocation(entry, checker)); } - function getImplementationReferenceEntries(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray, node: Node): Entry[] | undefined { + function getImplementationReferenceEntries(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray, node: Node, position: number): Entry[] | undefined { if (node.kind === SyntaxKind.SourceFile) { return undefined; } @@ -78,7 +78,7 @@ namespace ts.FindAllReferences { } else { // Perform "Find all References" and retrieve only those that are implementations - return getReferenceEntriesForNode(node, program, sourceFiles, cancellationToken, { implementations: true }); + return getReferenceEntriesForNode(position, node, program, sourceFiles, cancellationToken, { implementations: true }); } } @@ -87,13 +87,13 @@ namespace ts.FindAllReferences { return map(x, toReferenceEntry); } - export function getReferenceEntriesForNode(node: Node, program: Program, sourceFiles: ReadonlyArray, cancellationToken: CancellationToken, options: Options = {}): Entry[] | undefined { - return flattenEntries(Core.getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options)); + export function getReferenceEntriesForNode(position: number, node: Node, program: Program, sourceFiles: ReadonlyArray, cancellationToken: CancellationToken, options: Options = {}): Entry[] | undefined { + return flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options)); } function findAllReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray, sourceFile: SourceFile, position: number, options?: Options): SymbolAndEntries[] | undefined { const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); - return Core.getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options); + return Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options); } function flattenEntries(referenceSymbols: SymbolAndEntries[]): Entry[] { @@ -242,9 +242,10 @@ namespace ts.FindAllReferences { /* @internal */ namespace ts.FindAllReferences.Core { /** Core find-all-references algorithm. Handles special cases before delegating to `getReferencedSymbolsForSymbol`. */ - export function getReferencedSymbolsForNode(node: Node, program: Program, sourceFiles: ReadonlyArray, cancellationToken: CancellationToken, options: Options = {}): SymbolAndEntries[] | undefined { - if (node.kind === ts.SyntaxKind.SourceFile) { - return undefined; + export function getReferencedSymbolsForNode(position: number, node: Node, program: Program, sourceFiles: ReadonlyArray, cancellationToken: CancellationToken, options: Options = {}): SymbolAndEntries[] | undefined { + if (isSourceFile(node)) { + const reference = GoToDefinition.getReferenceAtPosition(node, position, program); + return reference && getReferencedSymbolsForModule(program, program.getTypeChecker().getMergedSymbol(reference.file.symbol), sourceFiles); } if (!options.implementations) { @@ -260,11 +261,7 @@ namespace ts.FindAllReferences.Core { // Could not find a symbol e.g. unknown identifier if (!symbol) { // String literal might be a property (and thus have a symbol), so do this here rather than in getReferencedSymbolsSpecial. - if (!options.implementations && node.kind === SyntaxKind.StringLiteral) { - return getReferencesForStringLiteral(node, sourceFiles, cancellationToken); - } - // Can't have references to something that we have no symbol for. - return undefined; + return !options.implementations && isStringLiteral(node) ? getReferencesForStringLiteral(node, sourceFiles, cancellationToken) : undefined; } if (symbol.flags & SymbolFlags.Module && isModuleReferenceLocation(node)) { diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 35f4d079e29..5f17eccf9c5 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -1,22 +1,9 @@ /* @internal */ namespace ts.GoToDefinition { export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile, position: number): DefinitionInfo[] { - /// Triple slash reference comments - const comment = findReferenceInPosition(sourceFile.referencedFiles, position); - if (comment) { - const referenceFile = tryResolveScriptReference(program, sourceFile, comment); - if (referenceFile) { - return [getDefinitionInfoForFileReference(comment.fileName, referenceFile.fileName)]; - } - // Might still be on jsdoc, so keep looking. - } - - // Type reference directives - const typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position); - if (typeReferenceDirective) { - const referenceFile = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName); - return referenceFile && referenceFile.resolvedFileName && - [getDefinitionInfoForFileReference(typeReferenceDirective.fileName, referenceFile.resolvedFileName)]; + const reference = getReferenceAtPosition(sourceFile, position, program); + if (reference) { + return [getDefinitionInfoForFileReference(reference.fileName, reference.file.fileName)]; } const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); @@ -115,6 +102,23 @@ namespace ts.GoToDefinition { return getDefinitionFromSymbol(typeChecker, symbol, node); } + export function getReferenceAtPosition(sourceFile: SourceFile, position: number, program: Program): { fileName: string, file: SourceFile } | undefined { + const referencePath = findReferenceInPosition(sourceFile.referencedFiles, position); + if (referencePath) { + const file = tryResolveScriptReference(program, sourceFile, referencePath); + return file && { fileName: referencePath.fileName, file }; + } + + const typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position); + if (typeReferenceDirective) { + const reference = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName); + const file = reference && program.getSourceFile(reference.resolvedFileName); + return file && { fileName: typeReferenceDirective.fileName, file }; + } + + return undefined; + } + /// Goto type export function getTypeDefinitionAtPosition(typeChecker: TypeChecker, sourceFile: SourceFile, position: number): DefinitionInfo[] { const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); @@ -301,7 +305,7 @@ namespace ts.GoToDefinition { return createDefinitionInfo(decl, symbolKind, symbolName, containerName); } - function findReferenceInPosition(refs: ReadonlyArray, pos: number): FileReference { + export function findReferenceInPosition(refs: ReadonlyArray, pos: number): FileReference { for (const ref of refs) { if (ref.pos <= pos && pos <= ref.end) { return ref; diff --git a/tests/cases/fourslash/findAllRefsForModule.ts b/tests/cases/fourslash/findAllRefsForModule.ts index ae6b216463f..bff3aa17785 100644 --- a/tests/cases/fourslash/findAllRefsForModule.ts +++ b/tests/cases/fourslash/findAllRefsForModule.ts @@ -12,12 +12,12 @@ ////const a = require("[|../a|]"); // @Filename: /d.ts -//// /// +//// /// verify.noErrors(); const ranges = test.ranges(); const [r0, r1, r2] = ranges; -verify.referenceGroups([r0, r1], [{ definition: 'module "/a"', ranges: [r0, r2, r1] }]); -// TODO:GH#15736 -verify.referenceGroups(r2, undefined); +verify.referenceGroups(ranges, [{ definition: 'module "/a"', ranges: [r0, r2, r1] }]); +// Testing that it works with documentHighlights too +verify.rangesAreDocumentHighlights(); diff --git a/tests/cases/fourslash/findAllRefsForModuleGlobal.ts b/tests/cases/fourslash/findAllRefsForModuleGlobal.ts index 4c1b39cdb0f..ce3c36c7966 100644 --- a/tests/cases/fourslash/findAllRefsForModuleGlobal.ts +++ b/tests/cases/fourslash/findAllRefsForModuleGlobal.ts @@ -12,6 +12,4 @@ verify.noErrors(); const ranges = test.ranges(); const [r0, r1, r2] = ranges; -verify.referenceGroups([r1, r2], [{ definition: 'module "/node_modules/foo/index"', ranges: [r0, r1, r2] }]); -// TODO:GH#15736 -verify.referenceGroups(r0, undefined); +verify.singleReferenceGroup('module "/node_modules/foo/index"'); From 50fa0f61f5ab0a59de6fb6aff4dd9bcc0882e134 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 11:33:57 -0800 Subject: [PATCH 089/189] Fix bug: Resolve module symbol before checking whether module export is a re-export (#20989) * Fix bug: Resolve module symbol before checking whether module export is a re-export * Remove unnecessary @nolib --- src/compiler/checker.ts | 1 + src/compiler/types.ts | 2 ++ src/services/completions.ts | 5 ++-- ...tionsImport_named_exportEqualsNamespace.ts | 26 +++++++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/completionsImport_named_exportEqualsNamespace.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d2fe31c11a0..3281bf93a31 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -273,6 +273,7 @@ namespace ts { }, getJsxNamespace: () => unescapeLeadingUnderscores(getJsxNamespace()), getAccessibleSymbolChain, + resolveExternalModuleSymbol, }; const tupleTypes: GenericType[] = []; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index bb79fc951b3..6e69b46e73d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2874,6 +2874,8 @@ namespace ts { * This should be called in a loop climbing parents of the symbol, so we'll get `N`. */ /* @internal */ getAccessibleSymbolChain(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, useOnlyExternalAliasing: boolean): Symbol[] | undefined; + + /* @internal */ resolveExternalModuleSymbol(symbol: Symbol): Symbol; } /* @internal */ diff --git a/src/services/completions.ts b/src/services/completions.ts index 18f09efcfe6..46d1378af9c 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1155,9 +1155,10 @@ namespace ts.Completions { codefix.forEachExternalModuleToImportFrom(typeChecker, sourceFile, allSourceFiles, moduleSymbol => { for (let symbol of typeChecker.getExportsOfModule(moduleSymbol)) { // Don't add a completion for a re-export, only for the original. - // If `symbol.parent !== moduleSymbol`, this comes from an `export * from "foo"` re-export. Those don't create new symbols. + // If `symbol.parent !== ...`, this comes from an `export * from "foo"` re-export. Those don't create new symbols. // If `some(...)`, this comes from an `export { foo } from "foo"` re-export, which creates a new symbol (thus isn't caught by the first check). - if (symbol.parent !== moduleSymbol || some(symbol.declarations, d => isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier)) { + if (symbol.parent !== typeChecker.resolveExternalModuleSymbol(moduleSymbol) + || some(symbol.declarations, d => isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier)) { continue; } diff --git a/tests/cases/fourslash/completionsImport_named_exportEqualsNamespace.ts b/tests/cases/fourslash/completionsImport_named_exportEqualsNamespace.ts new file mode 100644 index 00000000000..b88ce9cae0d --- /dev/null +++ b/tests/cases/fourslash/completionsImport_named_exportEqualsNamespace.ts @@ -0,0 +1,26 @@ +/// + +// @Filename: /a.d.ts +////declare namespace N { +//// export const foo = 0; +////} +////export = N; + +// @Filename: /b.ts +////f/**/; + +goTo.marker(""); +verify.completionListContains({ name: "foo", source: "/a" }, "const N.foo: 0", "", "const", /*spanIndex*/ undefined, /*hasAction*/ true, { + includeExternalModuleExports: true, + sourceDisplay: "./a", +}); + +verify.applyCodeActionFromCompletion("", { + name: "foo", + source: "/a", + description: `Import 'foo' from module "./a"`, + // TODO: GH#18445 + newFileContent: `import { foo } from "./a";\r +\r +f;`, +}); From fd5ed5ac79df4f17597bab7c75badca41d2fb22b Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 11:39:52 -0800 Subject: [PATCH 090/189] Have Set and Map constructors take ReadonlyArrays (#20606) --- src/lib/es2015.collection.d.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/es2015.collection.d.ts b/src/lib/es2015.collection.d.ts index 9b35fcbeffb..f6087eb4405 100644 --- a/src/lib/es2015.collection.d.ts +++ b/src/lib/es2015.collection.d.ts @@ -10,7 +10,7 @@ interface Map { interface MapConstructor { new (): Map; - new (entries?: [K, V][]): Map; + new (entries?: ReadonlyArray<[K, V]>): Map; readonly prototype: Map; } declare var Map: MapConstructor; @@ -31,7 +31,7 @@ interface WeakMap { interface WeakMapConstructor { new (): WeakMap; - new (entries?: [K, V][]): WeakMap; + new (entries?: ReadonlyArray<[K, V]>): WeakMap; readonly prototype: WeakMap; } declare var WeakMap: WeakMapConstructor; @@ -47,7 +47,7 @@ interface Set { interface SetConstructor { new (): Set; - new (values?: T[]): Set; + new (values?: ReadonlyArray): Set; readonly prototype: Set; } declare var Set: SetConstructor; @@ -66,7 +66,7 @@ interface WeakSet { interface WeakSetConstructor { new (): WeakSet; - new (values?: T[]): WeakSet; + new (values?: ReadonlyArray): WeakSet; readonly prototype: WeakSet; } declare var WeakSet: WeakSetConstructor; From 20c846d671b03e8664b26ed0bd24a855115b3276 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 11:48:25 -0800 Subject: [PATCH 091/189] Add helper functions to simplify getCompletionEntryDisplayNameForSymbol (#20552) --- src/compiler/checker.ts | 2 +- src/compiler/utilities.ts | 4 ++++ src/services/completions.ts | 35 ++++++++--------------------------- src/services/utilities.ts | 6 +++++- 4 files changed, 18 insertions(+), 29 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3281bf93a31..6e822e1caf4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8128,7 +8128,7 @@ namespace ts { } function getLiteralTypeFromPropertyName(prop: Symbol) { - return getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier || startsWith(prop.escapedName as string, "__@") ? + return getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier || isKnownSymbol(prop) ? neverType : getLiteralType(symbolName(prop)); } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 56f85b49e1d..291e81c8990 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2119,6 +2119,10 @@ namespace ts { return "__@" + symbolName as __String; } + export function isKnownSymbol(symbol: Symbol): boolean { + return startsWith(symbol.escapedName as string, "__@"); + } + /** * Includes the word "Symbol" with unicode escapes */ diff --git a/src/services/completions.ts b/src/services/completions.ts index 46d1378af9c..f1255efdd5e 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1988,36 +1988,17 @@ namespace ts.Completions { /** * Get the name to be display in completion from a given symbol. - * - * @return undefined if the name is of external module */ function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean, allowStringLiteral: boolean, origin: SymbolOriginInfo | undefined): string | undefined { const name = getSymbolName(symbol, origin, target); - if (!name) return undefined; - - // First check of the displayName is not external module; if it is an external module, it is not valid entry - if (symbol.flags & SymbolFlags.Namespace) { - const firstCharCode = name.charCodeAt(0); - if (isSingleOrDoubleQuote(firstCharCode)) { - // If the symbol is external module, don't show it in the completion list - // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there) - return undefined; - } - } - - // If the symbol is for a member of an object type and is the internal name of an ES - // symbol, it is not a valid entry. Internal names for ES symbols start with "__@" - if (symbol.flags & SymbolFlags.ClassMember) { - const escapedName = symbol.escapedName as string; - if (escapedName.length >= 3 && - escapedName.charCodeAt(0) === CharacterCodes._ && - escapedName.charCodeAt(1) === CharacterCodes._ && - escapedName.charCodeAt(2) === CharacterCodes.at) { - return undefined; - } - } - - return getCompletionEntryDisplayName(name, target, performCharacterChecks, allowStringLiteral); + return name === undefined + // If the symbol is external module, don't show it in the completion list + // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there) + || symbol.flags & SymbolFlags.Module && startsWithQuote(name) + // If the symbol is the internal name of an ES symbol, it is not a valid entry. Internal names for ES symbols start with "__@" + || isKnownSymbol(symbol) + ? undefined + : getCompletionEntryDisplayName(name, target, performCharacterChecks, allowStringLiteral); } /** diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 96a1cdd55fc..41e3aba24ed 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1300,12 +1300,16 @@ namespace ts { */ export function stripQuotes(name: string) { const length = name.length; - if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && isSingleOrDoubleQuote(name.charCodeAt(0))) { + if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && startsWithQuote(name)) { return name.substring(1, length - 1); } return name; } + export function startsWithQuote(name: string): boolean { + return isSingleOrDoubleQuote(name.charCodeAt(0)); + } + export function scriptKindIs(fileName: string, host: LanguageServiceHost, ...scriptKinds: ScriptKind[]): boolean { const scriptKind = getScriptKind(fileName, host); return forEach(scriptKinds, k => k === scriptKind); From b5fda4970d5fe59f7976e6fda48e4b09dea576f9 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 8 Jan 2018 12:27:11 -0800 Subject: [PATCH 092/189] Use emptyObjectType for omitted members instead of unknownType (#20940) * Use emptyObjectType for omitted members instead of unknownType * Use similar logic as is used for empty arrays for missing elements --- src/compiler/checker.ts | 2 +- ...rationEmitDestructuringArrayPattern2.types | 2 +- .../declarationsAndAssignments.types | 6 +++--- ...ArrayBindingPatternAndAssignment1ES5.types | 16 ++++++++-------- ...dingPatternAndAssignment1ES5iterable.types | 16 ++++++++-------- ...ArrayBindingPatternAndAssignment1ES6.types | 16 ++++++++-------- ...rayBindingPatternAndAssignment2.errors.txt | 8 +++++++- ...ingArrayBindingPatternAndAssignment2.types | 2 +- ...destructuringVariableDeclaration1ES5.types | 6 +++--- ...uringVariableDeclaration1ES5iterable.types | 6 +++--- ...destructuringVariableDeclaration1ES6.types | 6 +++--- .../reference/downlevelLetConst12.types | 4 ++-- .../reference/downlevelLetConst16.types | 4 ++-- ...zedDestructuringAssignmentTypes.errors.txt | 9 +++++++++ ...initializedDestructuringAssignmentTypes.js | 8 ++++++++ ...alizedDestructuringAssignmentTypes.symbols | 9 +++++++++ ...tializedDestructuringAssignmentTypes.types | 19 +++++++++++++++++++ ...initializedDestructuringAssignmentTypes.ts | 3 +++ 18 files changed, 98 insertions(+), 44 deletions(-) create mode 100644 tests/baselines/reference/initializedDestructuringAssignmentTypes.errors.txt create mode 100644 tests/baselines/reference/initializedDestructuringAssignmentTypes.js create mode 100644 tests/baselines/reference/initializedDestructuringAssignmentTypes.symbols create mode 100644 tests/baselines/reference/initializedDestructuringAssignmentTypes.types create mode 100644 tests/cases/compiler/initializedDestructuringAssignmentTypes.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6e822e1caf4..ff6371e679c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14523,7 +14523,7 @@ namespace ts { if (patternElement.kind !== SyntaxKind.OmittedExpression) { error(patternElement, Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value); } - elementTypes.push(unknownType); + elementTypes.push(strictNullChecks ? implicitNeverType : undefinedWideningType); } } } diff --git a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types index 45f76b94b51..807bb154935 100644 --- a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types +++ b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types @@ -23,7 +23,7 @@ var [a11, b11, c11] = []; >a11 : any >b11 : any >c11 : any ->[] : [any, any, any] +>[] : [undefined, undefined, undefined] var [a2, [b2, { x12, y12: c2 }]=["abc", { x12: 10, y12: false }]] = [1, ["hello", { x12: 5, y12: true }]]; >a2 : number diff --git a/tests/baselines/reference/declarationsAndAssignments.types b/tests/baselines/reference/declarationsAndAssignments.types index b49868c4750..6bd5b8da7cb 100644 --- a/tests/baselines/reference/declarationsAndAssignments.types +++ b/tests/baselines/reference/declarationsAndAssignments.types @@ -24,7 +24,7 @@ function f0() { >x : number >y : string >z : any ->[1, "hello"] : [number, string, any] +>[1, "hello"] : [number, string, undefined] >1 : 1 >"hello" : "hello" @@ -258,13 +258,13 @@ function f8() { >a : any >b : any >c : any ->[] : [any, any, any] +>[] : [undefined, undefined, undefined] var [d, e, f] = [1]; // Error, [1] is a tuple >d : number >e : any >f : any ->[1] : [number, any, any] +>[1] : [number, undefined, undefined] >1 : 1 } diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types index e42d08bbebc..bddce3cc391 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types @@ -93,18 +93,18 @@ var [c0, c1] = [...temp]; var [c2] = []; >c2 : any ->[] : [any] +>[] : [undefined] var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] >c3 : any >c4 : any ->[[[]], [[[[]]]]] : [[[any]], [[[[any]]]]] ->[[]] : [[any]] ->[] : [any] ->[[[[]]]] : [[[[any]]]] ->[[[]]] : [[[any]]] ->[[]] : [[any]] ->[] : [any] +>[[[]], [[[[]]]]] : [[[undefined]], [[[[undefined]]]]] +>[[]] : [[undefined]] +>[] : [undefined] +>[[[[]]]] : [[[[undefined]]]] +>[[[]]] : [[[undefined]]] +>[[]] : [[undefined]] +>[] : [undefined] var [[c5], c6]: [[string|number], boolean] = [[1], true]; >c5 : string | number diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types index 68b6565b004..e17e37f4980 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types @@ -93,18 +93,18 @@ var [c0, c1] = [...temp]; var [c2] = []; >c2 : any ->[] : [any] +>[] : [undefined] var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] >c3 : any >c4 : any ->[[[]], [[[[]]]]] : [[[any]], [[[[any]]]]] ->[[]] : [[any]] ->[] : [any] ->[[[[]]]] : [[[[any]]]] ->[[[]]] : [[[any]]] ->[[]] : [[any]] ->[] : [any] +>[[[]], [[[[]]]]] : [[[undefined]], [[[[undefined]]]]] +>[[]] : [[undefined]] +>[] : [undefined] +>[[[[]]]] : [[[[undefined]]]] +>[[[]]] : [[[undefined]]] +>[[]] : [[undefined]] +>[] : [undefined] var [[c5], c6]: [[string|number], boolean] = [[1], true]; >c5 : string | number diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types index 8bde2455171..0c6b87eb46a 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types @@ -93,18 +93,18 @@ var [c0, c1] = [...temp]; var [c2] = []; >c2 : any ->[] : [any] +>[] : [undefined] var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] >c3 : any >c4 : any ->[[[]], [[[[]]]]] : [[[any]], [[[[any]]]]] ->[[]] : [[any]] ->[] : [any] ->[[[[]]]] : [[[[any]]]] ->[[[]]] : [[[any]]] ->[[]] : [[any]] ->[] : [any] +>[[[]], [[[[]]]]] : [[[undefined]], [[[[undefined]]]]] +>[[]] : [[undefined]] +>[] : [undefined] +>[[[[]]]] : [[[[undefined]]]] +>[[[]]] : [[[undefined]]] +>[[]] : [[undefined]] +>[] : [undefined] var [[c5], c6]: [[string|number], boolean] = [[1], true]; >c5 : string | number diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt index 610167a1bc0..848093e1161 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt @@ -1,4 +1,6 @@ +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,6): error TS2461: Type 'undefined' is not an array type. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,6): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,12): error TS2461: Type 'undefined' is not an array type. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,12): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(4,5): error TS2461: Type 'undefined' is not an array type. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(9,5): error TS2322: Type '[number, number, string]' is not assignable to type '[number, boolean, string]'. @@ -10,13 +12,17 @@ tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAss tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(34,5): error TS2461: Type 'F' is not an array type. -==== tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts (7 errors) ==== +==== tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts (9 errors) ==== // V is an array assignment pattern, S is the type Any or an array-like type (section 3.3.2), and, for each assignment element E in V, // S is the type Any, or var [[a0], [[a1]]] = [] // Error ~~~~ +!!! error TS2461: Type 'undefined' is not an array type. + ~~~~ !!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. ~~~~~~ +!!! error TS2461: Type 'undefined' is not an array type. + ~~~~~~ !!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. var [[a2], [[a3]]] = undefined // Error ~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types index dc76e8a4a8a..9c29ea1a423 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types @@ -4,7 +4,7 @@ var [[a0], [[a1]]] = [] // Error >a0 : any >a1 : any ->[] : [any, any] +>[] : [undefined, undefined] var [[a2], [[a3]]] = undefined // Error >a2 : any diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES5.types b/tests/baselines/reference/destructuringVariableDeclaration1ES5.types index 1502288895b..125fd8a2c21 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES5.types +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES5.types @@ -151,9 +151,9 @@ var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; >f4 : number >f5 : number > : undefined ->{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, any]; } ->f : [number, number, { f3: number; f5: number; }, any] ->[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, any] +>{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, undefined]; } +>f : [number, number, { f3: number; f5: number; }, undefined] +>[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, undefined] >1 : 1 >2 : 2 >{ f3: 4, f5: 0 } : { f3: number; f5: number; } diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types b/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types index 1a4b35b373b..d97bb20d24a 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types @@ -151,9 +151,9 @@ var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; >f4 : number >f5 : number > : undefined ->{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, any]; } ->f : [number, number, { f3: number; f5: number; }, any] ->[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, any] +>{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, undefined]; } +>f : [number, number, { f3: number; f5: number; }, undefined] +>[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, undefined] >1 : 1 >2 : 2 >{ f3: 4, f5: 0 } : { f3: number; f5: number; } diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES6.types b/tests/baselines/reference/destructuringVariableDeclaration1ES6.types index c71e74c0594..ec42861b2fc 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES6.types +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES6.types @@ -151,9 +151,9 @@ var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; >f4 : number >f5 : number > : undefined ->{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, any]; } ->f : [number, number, { f3: number; f5: number; }, any] ->[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, any] +>{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, undefined]; } +>f : [number, number, { f3: number; f5: number; }, undefined] +>[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, undefined] >1 : 1 >2 : 2 >{ f3: 4, f5: 0 } : { f3: number; f5: number; } diff --git a/tests/baselines/reference/downlevelLetConst12.types b/tests/baselines/reference/downlevelLetConst12.types index 918d6c94e57..725e446e010 100644 --- a/tests/baselines/reference/downlevelLetConst12.types +++ b/tests/baselines/reference/downlevelLetConst12.types @@ -12,7 +12,7 @@ const bar = 1; let [baz] = []; >baz : any ->[] : [any] +>[] : [undefined] let {a: baz2} = { a: 1 }; >a : any @@ -23,7 +23,7 @@ let {a: baz2} = { a: 1 }; const [baz3] = [] >baz3 : any ->[] : [any] +>[] : [undefined] const {a: baz4} = { a: 1 }; >a : any diff --git a/tests/baselines/reference/downlevelLetConst16.types b/tests/baselines/reference/downlevelLetConst16.types index cc9d0f1a2ca..5655b1f8f15 100644 --- a/tests/baselines/reference/downlevelLetConst16.types +++ b/tests/baselines/reference/downlevelLetConst16.types @@ -516,7 +516,7 @@ function foo3() { } for (let [y] = []; ;) { >y : any ->[] : [any] +>[] : [undefined] use(y); >use(y) : any @@ -555,7 +555,7 @@ function foo4() { } for (const [y] = []; ;) { >y : any ->[] : [any] +>[] : [undefined] use(y); >use(y) : any diff --git a/tests/baselines/reference/initializedDestructuringAssignmentTypes.errors.txt b/tests/baselines/reference/initializedDestructuringAssignmentTypes.errors.txt new file mode 100644 index 00000000000..9a8cb12b45b --- /dev/null +++ b/tests/baselines/reference/initializedDestructuringAssignmentTypes.errors.txt @@ -0,0 +1,9 @@ +tests/cases/compiler/initializedDestructuringAssignmentTypes.ts(3,3): error TS2339: Property 'toFixed' does not exist on type 'string'. + + +==== tests/cases/compiler/initializedDestructuringAssignmentTypes.ts (1 errors) ==== + const [, a = ''] = ''.match('') || []; + + a.toFixed() + ~~~~~~~ +!!! error TS2339: Property 'toFixed' does not exist on type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/initializedDestructuringAssignmentTypes.js b/tests/baselines/reference/initializedDestructuringAssignmentTypes.js new file mode 100644 index 00000000000..ee38f30ef5f --- /dev/null +++ b/tests/baselines/reference/initializedDestructuringAssignmentTypes.js @@ -0,0 +1,8 @@ +//// [initializedDestructuringAssignmentTypes.ts] +const [, a = ''] = ''.match('') || []; + +a.toFixed() + +//// [initializedDestructuringAssignmentTypes.js] +var _a = ''.match('') || [], _b = _a[1], a = _b === void 0 ? '' : _b; +a.toFixed(); diff --git a/tests/baselines/reference/initializedDestructuringAssignmentTypes.symbols b/tests/baselines/reference/initializedDestructuringAssignmentTypes.symbols new file mode 100644 index 00000000000..7d9cf531f0d --- /dev/null +++ b/tests/baselines/reference/initializedDestructuringAssignmentTypes.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/initializedDestructuringAssignmentTypes.ts === +const [, a = ''] = ''.match('') || []; +>a : Symbol(a, Decl(initializedDestructuringAssignmentTypes.ts, 0, 8)) +>''.match : Symbol(String.match, Decl(lib.d.ts, --, --)) +>match : Symbol(String.match, Decl(lib.d.ts, --, --)) + +a.toFixed() +>a : Symbol(a, Decl(initializedDestructuringAssignmentTypes.ts, 0, 8)) + diff --git a/tests/baselines/reference/initializedDestructuringAssignmentTypes.types b/tests/baselines/reference/initializedDestructuringAssignmentTypes.types new file mode 100644 index 00000000000..55ddfa4f56b --- /dev/null +++ b/tests/baselines/reference/initializedDestructuringAssignmentTypes.types @@ -0,0 +1,19 @@ +=== tests/cases/compiler/initializedDestructuringAssignmentTypes.ts === +const [, a = ''] = ''.match('') || []; +> : undefined +>a : string +>'' : "" +>''.match('') || [] : RegExpMatchArray | [undefined, ""] +>''.match('') : RegExpMatchArray +>''.match : (regexp: string | RegExp) => RegExpMatchArray +>'' : "" +>match : (regexp: string | RegExp) => RegExpMatchArray +>'' : "" +>[] : [undefined, ""] + +a.toFixed() +>a.toFixed() : any +>a.toFixed : any +>a : string +>toFixed : any + diff --git a/tests/cases/compiler/initializedDestructuringAssignmentTypes.ts b/tests/cases/compiler/initializedDestructuringAssignmentTypes.ts new file mode 100644 index 00000000000..bc3ec4ca407 --- /dev/null +++ b/tests/cases/compiler/initializedDestructuringAssignmentTypes.ts @@ -0,0 +1,3 @@ +const [, a = ''] = ''.match('') || []; + +a.toFixed() \ No newline at end of file From 84e3681b7948fdfe0c21e31ff06c4147c381a9df Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 8 Jan 2018 12:28:04 -0800 Subject: [PATCH 093/189] Support timeouts in the parallel runner (#20631) * Support timeouts in the parallel runner * Apply PR feedback: unify code paths, use string as sentinel --- Gulpfile.ts | 21 +++++++++---- Jakefile.js | 13 ++++---- src/harness/parallel/host.ts | 37 +++++++++++++++++++++- src/harness/parallel/shared.ts | 3 +- src/harness/parallel/worker.ts | 56 +++++++++++++++++++++++++--------- src/harness/runner.ts | 5 +++ 6 files changed, 106 insertions(+), 29 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index 996fa1fc140..510c0d87631 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -680,14 +680,14 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: workerCount = cmdLineOptions.workers; } - if (tests || runners || light || taskConfigsFolder) { - writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit); - } - if (tests && tests.toLocaleLowerCase() === "rwc") { testTimeout = 400000; } + if (tests || runners || light || testTimeout || taskConfigsFolder) { + writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, testTimeout); + } + const colors = cmdLineOptions.colors; const reporter = cmdLineOptions.reporter || defaultReporter; @@ -872,8 +872,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) { - const testConfigContents = JSON.stringify({ test: tests ? [tests] : undefined, runner: runners ? runners.split(",") : undefined, light, workerCount, stackTraceLimit, taskConfigsFolder, noColor: !cmdLineOptions.colors }); +function writeTestConfigFile(tests: string, runners: string, light: boolean, taskConfigsFolder?: string, workerCount?: number, stackTraceLimit?: string, timeout?: number) { + const testConfigContents = JSON.stringify({ + test: tests ? [tests] : undefined, + runner: runners ? runners.split(",") : undefined, + light, + workerCount, + stackTraceLimit, + taskConfigsFolder, + noColor: !cmdLineOptions.colors, + timeout, + }); console.log("Running tests with config: " + testConfigContents); fs.writeFileSync("test.config", testConfigContents); } diff --git a/Jakefile.js b/Jakefile.js index f2a15aa4e19..09155261434 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -858,7 +858,7 @@ function cleanTestDirs() { } // used to pass data from jake command line directly to run.js -function writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, colors) { +function writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, colors, testTimeout) { var testConfigContents = JSON.stringify({ runners: runners ? runners.split(",") : undefined, test: tests ? [tests] : undefined, @@ -866,7 +866,8 @@ function writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCou workerCount: workerCount, taskConfigsFolder: taskConfigsFolder, stackTraceLimit: stackTraceLimit, - noColor: !colors + noColor: !colors, + timeout: testTimeout }); fs.writeFileSync('test.config', testConfigContents); } @@ -908,14 +909,14 @@ function runConsoleTests(defaultReporter, runInParallel) { workerCount = process.env.workerCount || process.env.p || os.cpus().length; } - if (tests || runners || light || taskConfigsFolder) { - writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, colors); - } - if (tests && tests.toLocaleLowerCase() === "rwc") { testTimeout = 800000; } + if (tests || runners || light || testTimeout || taskConfigsFolder) { + writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, colors, testTimeout); + } + var colorsFlag = process.env.color || process.env.colors; var colors = colorsFlag !== "false" && colorsFlag !== "0"; var reporter = process.env.reporter || process.env.r || defaultReporter; diff --git a/src/harness/parallel/host.ts b/src/harness/parallel/host.ts index eca719628c7..56b8df5ecfe 100644 --- a/src/harness/parallel/host.ts +++ b/src/harness/parallel/host.ts @@ -9,6 +9,8 @@ namespace Harness.Parallel.Host { on(event: "error", listener: (err: Error) => void): this; on(event: "exit", listener: (code: number, signal: string) => void): this; on(event: "message", listener: (message: ParallelClientMessage) => void): this; + kill(signal?: string): void; + currentTasks?: {file: string}[]; // Custom monkeypatch onto child process handle } interface ProgressBarsOptions { @@ -134,6 +136,11 @@ namespace Harness.Parallel.Host { const newPerfData: {[testHash: string]: number} = {}; const workers: ChildProcessPartial[] = []; + const defaultTimeout = globalTimeout !== undefined + ? globalTimeout + : mocha && mocha.suite && mocha.suite._timeout + ? mocha.suite._timeout + : 20000; // 20 seconds let closedWorkers = 0; for (let i = 0; i < workerCount; i++) { // TODO: Just send the config over the IPC channel or in the command line arguments @@ -141,6 +148,14 @@ namespace Harness.Parallel.Host { const configPath = ts.combinePaths(taskConfigsFolder, `task-config${i}.json`); Harness.IO.writeFile(configPath, JSON.stringify(config)); const child = fork(__filename, [`--config="${configPath}"`]); + let currentTimeout = defaultTimeout; + const killChild = () => { + child.kill(); + console.error(`Worker exceeded timeout ${child.currentTasks && child.currentTasks.length ? `while running test '${child.currentTasks[0].file}'.` : `during test setup.`}`); + return process.exit(2); + }; + let timer = setTimeout(killChild, currentTimeout); + const timeoutStack: number[] = []; child.on("error", err => { console.error("Unexpected error in child process:"); console.error(err); @@ -160,8 +175,23 @@ namespace Harness.Parallel.Host { Stack: ${data.payload.stack}`); return process.exit(2); } + case "timeout": { + if (data.payload.duration === "reset") { + currentTimeout = timeoutStack.pop() || defaultTimeout; + } + else { + timeoutStack.push(currentTimeout); + currentTimeout = data.payload.duration; + } + break; + } case "progress": case "result": { + clearTimeout(timer); + timer = setTimeout(killChild, currentTimeout); + if (child.currentTasks) { + child.currentTasks.shift(); + } totalPassing += data.payload.passing; if (data.payload.errors.length) { errorResults = errorResults.concat(data.payload.errors); @@ -195,6 +225,7 @@ namespace Harness.Parallel.Host { while (tasks.length && taskList.reduce((p, c) => p + c.size, 0) < chunkSize) { taskList.push(tasks.pop()); } + child.currentTasks = taskList; if (taskList.length === 1) { child.send({ type: "test", payload: taskList[0] }); } @@ -252,18 +283,22 @@ namespace Harness.Parallel.Host { for (const worker of workers) { const payload = batches.pop(); if (payload) { + worker.currentTasks = payload; worker.send({ type: "batch", payload }); } else { // Out of batches, send off just one test const payload = tasks.pop(); ts.Debug.assert(!!payload); // The reserve kept above should ensure there is always an initial task available, even in suboptimal scenarios + worker.currentTasks = [payload]; worker.send({ type: "test", payload }); } } } else { for (let i = 0; i < workerCount; i++) { - workers[i].send({ type: "test", payload: tasks.pop() }); + const task = tasks.pop(); + workers[i].currentTasks = [task]; + workers[i].send({ type: "test", payload: task }); } } diff --git a/src/harness/parallel/shared.ts b/src/harness/parallel/shared.ts index 2eb7777f828..26b03ac6234 100644 --- a/src/harness/parallel/shared.ts +++ b/src/harness/parallel/shared.ts @@ -10,5 +10,6 @@ namespace Harness.Parallel { export type ErrorInfo = ParallelErrorMessage["payload"] & { name: string[] }; export type ParallelResultMessage = { type: "result", payload: { passing: number, errors: ErrorInfo[], duration: number, runner: TestRunnerKind | "unittest", file: string } } | never; export type ParallelBatchProgressMessage = { type: "progress", payload: ParallelResultMessage["payload"] } | never; - export type ParallelClientMessage = ParallelErrorMessage | ParallelResultMessage | ParallelBatchProgressMessage; + export type ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: number | "reset" } } | never; + export type ParallelClientMessage = ParallelErrorMessage | ParallelResultMessage | ParallelBatchProgressMessage | ParallelTimeoutChangeMessage; } \ No newline at end of file diff --git a/src/harness/parallel/worker.ts b/src/harness/parallel/worker.ts index 013992a8e35..1cfc20cbf9b 100644 --- a/src/harness/parallel/worker.ts +++ b/src/harness/parallel/worker.ts @@ -36,11 +36,28 @@ namespace Harness.Parallel.Worker { }) as Mocha.ITestDefinition; } + function setTimeoutAndExecute(timeout: number | undefined, f: () => void) { + if (timeout !== undefined) { + const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: timeout } }; + process.send(timeoutMsg); + } + f(); + if (timeout !== undefined) { + // Reset timeout + const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: "reset" } }; + process.send(timeoutMsg); + } + } + function executeSuiteCallback(name: string, callback: MochaCallback) { + let timeout: number; const fakeContext: Mocha.ISuiteCallbackContext = { retries() { return this; }, slow() { return this; }, - timeout() { return this; }, + timeout(n) { + timeout = n; + return this; + }, }; namestack.push(name); let beforeFunc: Callable; @@ -71,7 +88,10 @@ namespace Harness.Parallel.Worker { finally { beforeFunc = undefined; } - testList.forEach(({ name, callback, kind }) => executeCallback(name, callback, kind)); + + setTimeoutAndExecute(timeout, () => { + testList.forEach(({ name, callback, kind }) => executeCallback(name, callback, kind)); + }); try { if (afterFunc) { @@ -103,9 +123,13 @@ namespace Harness.Parallel.Worker { } function executeTestCallback(name: string, callback: MochaCallback) { + let timeout: number; const fakeContext: Mocha.ITestCallbackContext = { skip() { return this; }, - timeout() { return this; }, + timeout(n) { + timeout = n; + return this; + }, retries() { return this; }, slow() { return this; }, }; @@ -121,18 +145,20 @@ namespace Harness.Parallel.Worker { } } if (callback.length === 0) { - try { - // TODO: If we ever start using async test completions, polyfill promise return handling - callback.call(fakeContext); - } - catch (error) { - errors.push({ error: error.message, stack: error.stack, name: [...namestack] }); - return; - } - finally { - namestack.pop(); - } - passing++; + setTimeoutAndExecute(timeout, () => { + try { + // TODO: If we ever start using async test completions, polyfill promise return handling + callback.call(fakeContext); + } + catch (error) { + errors.push({ error: error.message, stack: error.stack, name: [...namestack] }); + return; + } + finally { + namestack.pop(); + } + passing++; + }); } else { // Uses `done` callback diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 2bd098b742d..76d65090f02 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -100,6 +100,7 @@ interface TestConfig { runners?: string[]; runUnitTests?: boolean; noColors?: boolean; + timeout?: number; } interface TaskSet { @@ -108,12 +109,16 @@ interface TaskSet { } let configOption: string; +let globalTimeout: number; function handleTestConfig() { if (testConfigContent !== "") { const testConfig = JSON.parse(testConfigContent); if (testConfig.light) { Harness.lightMode = true; } + if (testConfig.timeout) { + globalTimeout = testConfig.timeout; + } runUnitTests = testConfig.runUnitTests; if (testConfig.workerCount) { workerCount = +testConfig.workerCount; From 97c3e9c3ef2d8ea3b2046fb47e01fcbf15e7bcbd Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 12:28:50 -0800 Subject: [PATCH 094/189] Support all path mappings that end in "*" in completions (#21072) * Support all path mappings that end in "*" in completions * Check for uppercase TsConfig.JSON --- src/harness/fourslash.ts | 8 +- src/services/completions.ts | 2 +- src/services/pathCompletions.ts | 125 +++++++++--------- .../fourslash/completionsPaths_pathMapping.ts | 19 +++ 4 files changed, 88 insertions(+), 66 deletions(-) create mode 100644 tests/cases/fourslash/completionsPaths_pathMapping.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 12b98eebcca..c44fa006c03 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -265,7 +265,7 @@ namespace FourSlash { ts.forEach(testData.files, file => { // Create map between fileName and its content for easily looking up when resolveReference flag is specified this.inputFiles.set(file.fileName, file.content); - if (ts.getBaseFileName(file.fileName).toLowerCase() === "tsconfig.json") { + if (isTsconfig(file)) { const configJson = ts.parseConfigFileTextToJson(file.fileName, file.content); if (configJson.config === undefined) { throw new Error(`Failed to parse test tsconfig.json: ${configJson.error.messageText}`); @@ -3384,7 +3384,7 @@ ${code} } // @Filename is the only directive that can be used in a test that contains tsconfig.json file. - if (containTSConfigJson(files)) { + if (files.some(isTsconfig)) { let directive = getNonFileNameOptionInFileList(files); if (!directive) { directive = getNonFileNameOptionInObject(globalOptions); @@ -3403,8 +3403,8 @@ ${code} }; } - function containTSConfigJson(files: FourSlashFile[]): boolean { - return ts.forEach(files, f => f.fileOptions.Filename === "tsconfig.json"); + function isTsconfig(file: FourSlashFile): boolean { + return ts.getBaseFileName(file.fileName).toLowerCase() === "tsconfig.json"; } function getNonFileNameOptionInFileList(files: FourSlashFile[]): string { diff --git a/src/services/completions.ts b/src/services/completions.ts index f1255efdd5e..b92dffb93cc 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -277,7 +277,7 @@ namespace ts.Completions { // import x = require("/*completion position*/"); // var y = require("/*completion position*/"); // export * from "/*completion position*/"; - const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(node, compilerOptions, host, typeChecker); + const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker); return pathCompletionsInfo(entries); } else if (isIndexedAccessTypeNode(node.parent.parent)) { diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index cb285d46417..e9c8b48a7c4 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -1,12 +1,12 @@ /* @internal */ namespace ts.Completions.PathCompletions { - export function getStringLiteralCompletionsFromModuleNames(node: LiteralExpression, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionEntry[] { + export function getStringLiteralCompletionsFromModuleNames(sourceFile: SourceFile, node: LiteralExpression, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionEntry[] { const literalValue = normalizeSlashes(node.text); const scriptPath = node.getSourceFile().path; const scriptDirectory = getDirectoryPath(scriptPath); - const span = getDirectoryFragmentTextSpan((node).text, node.getStart() + 1); + const span = getDirectoryFragmentTextSpan((node).text, node.getStart(sourceFile) + 1); if (isPathRelativeToScript(literalValue) || isRootedDiskPath(literalValue)) { const extensions = getSupportedExtensions(compilerOptions); if (compilerOptions.rootDirs) { @@ -147,25 +147,15 @@ namespace ts.Completions.PathCompletions { getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/ false, span, host, /*exclude*/ undefined, result); for (const path in paths) { - if (!paths.hasOwnProperty(path)) continue; const patterns = paths[path]; - if (!patterns) continue; - - if (path === "*") { - for (const pattern of patterns) { - for (const match of getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions, host)) { - // Path mappings may provide a duplicate way to get to something we've already added, so don't add again. - if (result.some(entry => entry.name === match)) continue; - result.push(createCompletionEntryForModule(match, ScriptElementKind.externalModuleName, span)); + if (paths.hasOwnProperty(path) && patterns) { + for (const pathCompletion of getCompletionsForPathMapping(path, patterns, fragment, baseUrl, fileExtensions, host)) { + // Path mappings may provide a duplicate way to get to something we've already added, so don't add again. + if (!result.some(entry => entry.name === pathCompletion)) { + result.push(createCompletionEntryForModule(pathCompletion, ScriptElementKind.externalModuleName, span)); } } } - else if (startsWith(path, fragment)) { - if (patterns.length === 1) { - if (result.some(entry => entry.name === path)) continue; - result.push(createCompletionEntryForModule(path, ScriptElementKind.externalModuleName, span)); - } - } } } @@ -187,52 +177,65 @@ namespace ts.Completions.PathCompletions { return result; } - function getModulesForPathsPattern(fragment: string, baseUrl: string, pattern: string, fileExtensions: ReadonlyArray, host: LanguageServiceHost): string[] { - if (host.readDirectory) { - const parsed = hasZeroOrOneAsteriskCharacter(pattern) ? tryParsePattern(pattern) : undefined; - if (parsed) { - // The prefix has two effective parts: the directory path and the base component after the filepath that is not a - // full directory component. For example: directory/path/of/prefix/base* - const normalizedPrefix = normalizeAndPreserveTrailingSlash(parsed.prefix); - const normalizedPrefixDirectory = getDirectoryPath(normalizedPrefix); - const normalizedPrefixBase = getBaseFileName(normalizedPrefix); - - const fragmentHasPath = stringContains(fragment, directorySeparator); - - // Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call - const expandedPrefixDirectory = fragmentHasPath ? combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + getDirectoryPath(fragment)) : normalizedPrefixDirectory; - - const normalizedSuffix = normalizePath(parsed.suffix); - const baseDirectory = combinePaths(baseUrl, expandedPrefixDirectory); - const completePrefix = fragmentHasPath ? baseDirectory : ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase; - - // If we have a suffix, then we need to read the directory all the way down. We could create a glob - // that encodes the suffix, but we would have to escape the character "?" which readDirectory - // doesn't support. For now, this is safer but slower - const includeGlob = normalizedSuffix ? "**/*" : "./*"; - - const matches = tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]); - if (matches) { - const result: string[] = []; - - // Trim away prefix and suffix - for (const match of matches) { - const normalizedMatch = normalizePath(match); - if (!endsWith(normalizedMatch, normalizedSuffix) || !startsWith(normalizedMatch, completePrefix)) { - continue; - } - - const start = completePrefix.length; - const length = normalizedMatch.length - start - normalizedSuffix.length; - - result.push(removeFileExtension(normalizedMatch.substr(start, length))); - } - return result; - } - } + function getCompletionsForPathMapping( + path: string, patterns: ReadonlyArray, fragment: string, baseUrl: string, fileExtensions: ReadonlyArray, host: LanguageServiceHost, + ): string[] { + if (!endsWith(path, "*")) { + // For a path mapping "foo": ["/x/y/z.ts"], add "foo" itself as a completion. + return !stringContains(path, "*") && startsWith(path, fragment) ? [path] : emptyArray; } - return undefined; + const pathPrefix = path.slice(0, path.length - 1); + if (!startsWith(fragment, pathPrefix)) { + return emptyArray; + } + + const remainingFragment = fragment.slice(pathPrefix.length); + return flatMap(patterns, pattern => getModulesForPathsPattern(remainingFragment, baseUrl, pattern, fileExtensions, host)); + } + + function getModulesForPathsPattern(fragment: string, baseUrl: string, pattern: string, fileExtensions: ReadonlyArray, host: LanguageServiceHost): string[] | undefined { + if (!host.readDirectory) { + return undefined; + } + + const parsed = hasZeroOrOneAsteriskCharacter(pattern) ? tryParsePattern(pattern) : undefined; + if (!parsed) { + return undefined; + } + + // The prefix has two effective parts: the directory path and the base component after the filepath that is not a + // full directory component. For example: directory/path/of/prefix/base* + const normalizedPrefix = normalizeAndPreserveTrailingSlash(parsed.prefix); + const normalizedPrefixDirectory = getDirectoryPath(normalizedPrefix); + const normalizedPrefixBase = getBaseFileName(normalizedPrefix); + + const fragmentHasPath = stringContains(fragment, directorySeparator); + + // Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call + const expandedPrefixDirectory = fragmentHasPath ? combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + getDirectoryPath(fragment)) : normalizedPrefixDirectory; + + const normalizedSuffix = normalizePath(parsed.suffix); + const baseDirectory = combinePaths(baseUrl, expandedPrefixDirectory); + const completePrefix = fragmentHasPath ? baseDirectory : ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase; + + // If we have a suffix, then we need to read the directory all the way down. We could create a glob + // that encodes the suffix, but we would have to escape the character "?" which readDirectory + // doesn't support. For now, this is safer but slower + const includeGlob = normalizedSuffix ? "**/*" : "./*"; + + const matches = tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]); + // Trim away prefix and suffix + return mapDefined(matches, match => { + const normalizedMatch = normalizePath(match); + if (!endsWith(normalizedMatch, normalizedSuffix) || !startsWith(normalizedMatch, completePrefix)) { + return; + } + + const start = completePrefix.length; + const length = normalizedMatch.length - start - normalizedSuffix.length; + return removeFileExtension(normalizedMatch.substr(start, length)); + }); } function enumeratePotentialNonRelativeModules(fragment: string, scriptPath: string, options: CompilerOptions, typeChecker: TypeChecker, host: LanguageServiceHost): string[] { diff --git a/tests/cases/fourslash/completionsPaths_pathMapping.ts b/tests/cases/fourslash/completionsPaths_pathMapping.ts new file mode 100644 index 00000000000..61ea3d5d936 --- /dev/null +++ b/tests/cases/fourslash/completionsPaths_pathMapping.ts @@ -0,0 +1,19 @@ +/// + +// @Filename: /src/b.ts +////export const x = 0; + +// @Filename: /src/a.ts +////import {} from "foo//**/"; + +// @Filename: /tsconfig.json +////{ +//// "compilerOptions": { +//// "baseUrl": ".", +//// "paths": { +//// "foo/*": ["src/*"] +//// } +//// } +////} + +verify.completionsAt("", ["a", "b"]); From 6d361f89e3c3c5f4faafa0ecf19f6439de783167 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 12:29:21 -0800 Subject: [PATCH 095/189] Move isObjectLiteralElement to public utilities (#20605) --- src/compiler/utilities.ts | 15 +++++++++++++++ src/services/services.ts | 14 -------------- .../baselines/reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 291e81c8990..a6e8af7e706 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5847,4 +5847,19 @@ namespace ts { export function hasOnlyExpressionInitializer(node: Node): node is HasExpressionInitializer { return hasInitializer(node) && !isForStatement(node) && !isForInStatement(node) && !isForOfStatement(node) && !isJsxAttribute(node); } + + export function isObjectLiteralElement(node: Node): node is ObjectLiteralElement { + switch (node.kind) { + case SyntaxKind.JsxAttribute: + case SyntaxKind.JsxSpreadAttribute: + case SyntaxKind.PropertyAssignment: + case SyntaxKind.ShorthandPropertyAssignment: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return true; + default: + return false; + } + } } diff --git a/src/services/services.ts b/src/services/services.ts index eacce501469..94862980ca7 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2251,20 +2251,6 @@ namespace ts { isLiteralComputedPropertyDeclarationName(node); } - function isObjectLiteralElement(node: Node): node is ObjectLiteralElement { - switch (node.kind) { - case SyntaxKind.JsxAttribute: - case SyntaxKind.JsxSpreadAttribute: - case SyntaxKind.PropertyAssignment: - case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return true; - } - return false; - } - /** * Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 } */ diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 633c499e985..eafef37a5ec 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3104,6 +3104,7 @@ declare namespace ts { function isJSDocCommentContainingNode(node: Node): boolean; function isSetAccessor(node: Node): node is SetAccessorDeclaration; function isGetAccessor(node: Node): node is GetAccessorDeclaration; + function isObjectLiteralElement(node: Node): node is ObjectLiteralElement; } declare namespace ts { type ErrorCallback = (message: DiagnosticMessage, length: number) => void; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index ddc3ebee14b..6748b39e58e 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3157,6 +3157,7 @@ declare namespace ts { function isJSDocCommentContainingNode(node: Node): boolean; function isSetAccessor(node: Node): node is SetAccessorDeclaration; function isGetAccessor(node: Node): node is GetAccessorDeclaration; + function isObjectLiteralElement(node: Node): node is ObjectLiteralElement; } declare namespace ts { function createNode(kind: SyntaxKind, pos?: number, end?: number): Node; From 86eab34758ebe41a7b923f909bef4b22a451cee0 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 12:29:43 -0800 Subject: [PATCH 096/189] type-operator-spacing: Just check for presence of space, not double-space (#20817) --- package-lock.json | 1322 +++++++---------- .../tslint/rules/typeOperatorSpacingRule.ts | 30 +- src/services/shims.ts | 2 - 3 files changed, 510 insertions(+), 844 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4a071afa0f5..736551168ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,13 +4,30 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@browserify/acorn5-object-spread": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@browserify/acorn5-object-spread/-/acorn5-object-spread-5.0.1.tgz", + "integrity": "sha512-sFCUPzgeEjdq3rinwy4TFXtak2YZdhqpj6MdNusxkdTFr9TXAUEYK4YQSamR8Joqt/yii1drgl5hk8q/AtJDKA==", + "dev": true, + "requires": { + "acorn": "5.3.0" + }, + "dependencies": { + "acorn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "dev": true + } + } + }, "@gulp-sourcemaps/identity-map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz", "integrity": "sha1-z6I7xYQPkQTOMqZedNt+epdLvuE=", "dev": true, "requires": { - "acorn": "5.2.1", + "acorn": "5.3.0", "css": "2.2.1", "normalize-path": "2.1.1", "source-map": "0.5.7", @@ -18,9 +35,9 @@ }, "dependencies": { "acorn": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", - "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", "dev": true } } @@ -42,13 +59,13 @@ "dev": true, "requires": { "@types/insert-module-globals": "7.0.0", - "@types/node": "8.5.2" + "@types/node": "8.5.5" } }, "@types/chai": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.10.tgz", - "integrity": "sha512-Ejh1AXTY8lm+x91X/yar3G2z4x9RyKwdTVdyyu7Xj3dNB35fMNCnEWqTO9FgS3zjzlRNqk1MruYhgb8yhRN9rA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.0.tgz", + "integrity": "sha512-OuYBlXWHYthxIudMXMeQr92f6D97YoT9CUYCRb0BEP4OavC95jNcczjjr4Ob3H5E1IqlWqwj+leUZPSeth27Qw==", "dev": true }, "@types/convert-source-map": { @@ -79,19 +96,19 @@ "dev": true, "requires": { "@types/events": "1.1.0", - "@types/minimatch": "3.0.2", - "@types/node": "8.5.2" + "@types/minimatch": "3.0.3", + "@types/node": "8.5.5" } }, "@types/gulp": { - "version": "3.8.35", - "resolved": "https://registry.npmjs.org/@types/gulp/-/gulp-3.8.35.tgz", - "integrity": "sha512-h9clNJu8X6+zW74ZLa5zhh5HP0LxnvlelVXdXby6pM/DDEj/gKqmmFXKwjzvupZKlMpof02jr6c3JokPbHXQgg==", + "version": "3.8.36", + "resolved": "https://registry.npmjs.org/@types/gulp/-/gulp-3.8.36.tgz", + "integrity": "sha512-u6/zWPzYRNPAtvyFJ3/RSXjmBaBM1dVs5kW22/jU6J786ZGLfSndhLoNOpFI6FGQvqTA+QzFHjSMhpkAN+wxcQ==", "dev": true, "requires": { - "@types/node": "8.5.2", + "@types/node": "8.5.5", "@types/orchestrator": "0.3.2", - "@types/vinyl": "2.0.1" + "@types/vinyl": "2.0.2" } }, "@types/gulp-concat": { @@ -100,7 +117,7 @@ "integrity": "sha512-CUCFADlITzzBfBa2bdGzhKtvBr4eFh+evb+4igVbvPoO5RyPfHifmyQlZl6lM7q19+OKncRlFXDU7B4X9Ayo2g==", "dev": true, "requires": { - "@types/node": "8.5.2" + "@types/node": "8.5.5" } }, "@types/gulp-help": { @@ -109,8 +126,8 @@ "integrity": "sha512-MkW7psZznxxJg2MBk2P2qHE+T8jEZVFz3FG/qGjUYazkyJt7hBJWx5Nuewmay5RVNtUvSWPrdZLr/WTXY3T/6A==", "dev": true, "requires": { - "@types/gulp": "3.8.35", - "@types/node": "8.5.2", + "@types/gulp": "3.8.36", + "@types/node": "8.5.5", "@types/orchestrator": "0.3.2" } }, @@ -120,7 +137,7 @@ "integrity": "sha512-e7J/Zv5Wd7CC0WpuA2syWVitgwrkG0u221e41w7r07XUR6hMH6kHPkq9tUrusHkbeW8QbuLbis5fODOwQCyggQ==", "dev": true, "requires": { - "@types/node": "8.5.2" + "@types/node": "8.5.5" } }, "@types/gulp-sourcemaps": { @@ -129,7 +146,7 @@ "integrity": "sha512-+7BAmptW2bxyJnJcCEuie7vLoop3FwWgCdBMzyv7MYXED/HeNMeQuX7uPCkp4vfU1TTu4CYFH0IckNPvo0VePA==", "dev": true, "requires": { - "@types/node": "8.5.2" + "@types/node": "8.5.5" } }, "@types/insert-module-globals": { @@ -138,7 +155,7 @@ "integrity": "sha512-zudCJPwluh1VUDB6Gl/OQdRp+fYy3+47huJB/JMQubMS2p+sH18MCVK4WUz3FqaWLB12yh5ELxVR/+tqwlm/qA==", "dev": true, "requires": { - "@types/node": "8.5.2" + "@types/node": "8.5.5" } }, "@types/merge2": { @@ -147,13 +164,13 @@ "integrity": "sha512-GjaXY4OultxbaOOk7lCLO7xvEcFpdjExC605YmfI6X29vhHKpJfMWKCDZd3x+BITrZaXKg97DgV/SdGVSwdzxA==", "dev": true, "requires": { - "@types/node": "8.5.2" + "@types/node": "8.5.5" } }, "@types/minimatch": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.2.tgz", - "integrity": "sha512-tctoxbfuMCxeI2CAsnwoZQfaBA+T7gPzDzDuiiFnyCSSyGYEB92cmRTh6E3tdR1hWsprbJ9IdbvX3PzLmJU/GA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, "@types/minimist": { @@ -168,19 +185,19 @@ "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", "dev": true, "requires": { - "@types/node": "8.5.2" + "@types/node": "8.5.5" } }, "@types/mocha": { - "version": "2.2.44", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", - "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", + "version": "2.2.46", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.46.tgz", + "integrity": "sha512-fwTTP5QLf4xHMkv7ovcKvmlLWX3GrxCa5DRQDOilVyYGCp+arZTAQJCy7/4GKezzYJjfWMpB/Cy4e8nrc9XioA==", "dev": true }, "@types/node": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.2.tgz", - "integrity": "sha512-KA4GKOpgXnrqEH2eCVhiv2CsxgXGQJgV1X0vsGlh+WCnxbeAE1GT44ZsTU1IN5dEeV/gDupKa7gWo08V5IxWVQ==", + "version": "8.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.5.tgz", + "integrity": "sha512-JRnfoh0Ll4ElmIXKxbUfcOodkGvcNHljct6mO1X9hE/mlrMzAx0hYCLAD7sgT53YAY1HdlpzUcV0CkmDqUqTuA==", "dev": true }, "@types/orchestrator": { @@ -189,7 +206,7 @@ "integrity": "sha512-cKB4yTX0wGaRCSkdHDX2fkGQbMAA8UOshC2U7DQky1CE5o+5q2iQQ8VkbPbE/88uaTtsusvBPMcCX7dgmjxBhQ==", "dev": true, "requires": { - "@types/node": "8.5.2", + "@types/node": "8.5.5", "@types/q": "1.0.6" } }, @@ -205,8 +222,8 @@ "integrity": "sha512-XwGr1b4yCGUILKeBkzmeWcxmGHQ0vFFFpA6D6y1yLO6gKmYorF+PHqdU5KG+nWt38OvtrkDptmrSmlHX/XtpLw==", "dev": true, "requires": { - "@types/gulp": "3.8.35", - "@types/node": "8.5.2" + "@types/gulp": "3.8.36", + "@types/node": "8.5.5" } }, "@types/strip-bom": { @@ -227,16 +244,16 @@ "integrity": "sha1-H/LoihAN+1sUDnu5h5HxGUQA0TE=", "dev": true, "requires": { - "@types/node": "8.5.2" + "@types/node": "8.5.5" } }, "@types/vinyl": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.1.tgz", - "integrity": "sha512-Joudabfn2ZofU2usW04y8OLmN75u7ZQkW0MCT3AnoBf5oUBp5iQ3Pgfz9+y1RdWkzhCPZo9/wBJ7FMWW2JrY0g==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.2.tgz", + "integrity": "sha512-2iYpNuOl98SrLPBZfEN9Mh2JCJ2EI9HU35SfgBEb51DcmaHkhp8cKMblYeBqMQiwXMgAD3W60DbQ4i/UdLiXhw==", "dev": true, "requires": { - "@types/node": "8.5.2" + "@types/node": "8.5.5" } }, "@types/xml2js": { @@ -245,7 +262,7 @@ "integrity": "sha512-8aKUBSj3oGcnuiBmDLm3BIk09RYg01mz9HlQ2u4aS17oJ25DxjQrEUVGFSBVNOfM45pQW4OjcBPplq6r/exJdA==", "dev": true, "requires": { - "@types/node": "8.5.2" + "@types/node": "8.5.5" } }, "JSONStream": { @@ -298,6 +315,15 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "ansi-cyan": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", + "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, "ansi-gray": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", @@ -307,6 +333,15 @@ "ansi-wrap": "0.1.0" } }, + "ansi-red": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", + "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -379,12 +414,6 @@ "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", "dev": true }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, "array-map": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", @@ -451,9 +480,9 @@ } }, "assertion-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", - "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, "assign-symbols": { @@ -624,9 +653,9 @@ "dev": true }, "browserify": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-14.5.0.tgz", - "integrity": "sha512-gKfOsNQv/toWz+60nSPfYzuwSEdzvV2WdxrVPUbPD/qui44rAkB3t3muNtmmGYHqrG56FGwX9SUEQmzNLAeS7g==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-15.0.0.tgz", + "integrity": "sha512-dERxjzl4yacUzaB4XVVXDFFHARzDr6tLRhjqpE/NJUv0SkS3QVmZKiYTiKEQZhQ2HygCL02FUzSS5r3sY/SlTg==", "dev": true, "requires": { "JSONStream": "1.3.2", @@ -652,7 +681,7 @@ "inherits": "2.0.3", "insert-module-globals": "7.0.1", "labeled-stream-splicer": "2.0.0", - "module-deps": "4.1.1", + "module-deps": "5.0.1", "os-browserify": "0.3.0", "parents": "1.0.1", "path-browserify": "0.0.0", @@ -806,20 +835,11 @@ "dev": true }, "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", "dev": true, - "requires": { - "camelcase": "2.1.1", - "map-obj": "1.0.1" - } + "optional": true }, "center-align": { "version": "0.1.3", @@ -847,7 +867,7 @@ "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", "dev": true, "requires": { - "assertion-error": "1.0.2", + "assertion-error": "1.1.0", "check-error": "1.0.2", "deep-eql": "3.0.1", "get-func-name": "2.0.0", @@ -904,6 +924,46 @@ "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", @@ -1219,15 +1279,6 @@ } } }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "1.0.2" - } - }, "d": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", @@ -1284,7 +1335,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "dev": true, + "optional": true }, "decode-uri-component": { "version": "0.2.0", @@ -1322,7 +1374,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.1" + "is-descriptor": "1.0.2" } }, "defined": { @@ -1386,19 +1438,20 @@ "dev": true }, "detective": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", - "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.0.2.tgz", + "integrity": "sha512-NUsLoezj4wb9o7vpxS9F3L5vcO87ceyRBcl48op06YFNwkyIEY997JpSCA5lDlDuDc6JxOtaL5qfK3muoWxpMA==", "dev": true, "requires": { - "acorn": "5.2.1", + "@browserify/acorn5-object-spread": "5.0.1", + "acorn": "5.3.0", "defined": "1.0.0" }, "dependencies": { "acorn": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", - "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", "dev": true } } @@ -1493,15 +1546,6 @@ } } }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "dev": true, - "requires": { - "is-arrayish": "0.2.1" - } - }, "es5-ext": { "version": "0.10.37", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", @@ -1650,6 +1694,46 @@ "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", @@ -1745,9 +1829,9 @@ } }, "extglob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.2.tgz", - "integrity": "sha512-I0+eZBH+jFGL8F5BnIz2ON2nKCjTS3AS3H/5PeSmCp7UVC70Ym8IhdRiQly2juKYQ//f7z1aj1BRpQniFJoU1w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.3.tgz", + "integrity": "sha512-AyptZexgu7qppEPq59DtN/XJGZDrLcVxSHai+4hdgMMS9EpF4GBvygcWWApno8lL9qSjVpYt7Raao28qzJX1ww==", "dev": true, "requires": { "array-unique": "0.3.2", @@ -1819,16 +1903,6 @@ "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", "dev": true }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" - } - }, "findup-sync": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", @@ -1837,7 +1911,7 @@ "requires": { "detect-file": "1.0.0", "is-glob": "3.1.0", - "micromatch": "3.1.4", + "micromatch": "3.1.5", "resolve-dir": "1.0.1" } }, @@ -1917,12 +1991,6 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -2242,221 +2310,15 @@ } }, "gulp-clone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulp-clone/-/gulp-clone-1.0.0.tgz", - "integrity": "sha1-mubGVr2cTzae6AXu9WV4a8gQBbA=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/gulp-clone/-/gulp-clone-1.1.1.tgz", + "integrity": "sha512-+9z6YKyup0pxL1nD9Hw5WjC29d280dsGkegagzt4xKAOvroyzZlA8Bs9MYs2WSSFIDqmcftMUVN/oentgBv69A==", "dev": true, "requires": { - "gulp-util": "2.2.20", - "through2": "0.4.2" - }, - "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", - "dev": true - }, - "ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", - "dev": true - }, - "chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", - "dev": true, - "requires": { - "ansi-styles": "1.1.0", - "escape-string-regexp": "1.0.5", - "has-ansi": "0.1.0", - "strip-ansi": "0.3.0", - "supports-color": "0.2.0" - } - }, - "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", - "dev": true, - "requires": { - "get-stdin": "4.0.1", - "meow": "3.7.0" - } - }, - "gulp-util": { - "version": "2.2.20", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz", - "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=", - "dev": true, - "requires": { - "chalk": "0.5.1", - "dateformat": "1.0.12", - "lodash._reinterpolate": "2.4.1", - "lodash.template": "2.4.1", - "minimist": "0.2.0", - "multipipe": "0.1.2", - "through2": "0.5.1", - "vinyl": "0.2.3" - }, - "dependencies": { - "through2": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", - "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "3.0.0" - } - } - } - }, - "has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "lodash._reinterpolate": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz", - "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=", - "dev": true - }, - "lodash.escape": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz", - "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=", - "dev": true, - "requires": { - "lodash._escapehtmlchar": "2.4.1", - "lodash._reunescapedhtml": "2.4.1", - "lodash.keys": "2.4.1" - } - }, - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - }, - "lodash.template": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz", - "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=", - "dev": true, - "requires": { - "lodash._escapestringchar": "2.4.1", - "lodash._reinterpolate": "2.4.1", - "lodash.defaults": "2.4.1", - "lodash.escape": "2.4.1", - "lodash.keys": "2.4.1", - "lodash.templatesettings": "2.4.1", - "lodash.values": "2.4.1" - } - }, - "lodash.templatesettings": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz", - "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=", - "dev": true, - "requires": { - "lodash._reinterpolate": "2.4.1", - "lodash.escape": "2.4.1" - } - }, - "minimist": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", - "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - } - }, - "supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", - "dev": true - }, - "through2": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", - "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "2.1.2" - }, - "dependencies": { - "xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "dev": true, - "requires": { - "object-keys": "0.4.0" - } - } - } - }, - "vinyl": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz", - "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=", - "dev": true, - "requires": { - "clone-stats": "0.0.1" - } - }, - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } + "chai": "4.1.2", + "mocha": "4.1.0", + "plugin-error": "0.1.2", + "through2": "2.0.3" } }, "gulp-concat": { @@ -2550,25 +2412,25 @@ } }, "gulp-newer": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/gulp-newer/-/gulp-newer-1.3.0.tgz", - "integrity": "sha1-1Q7Ky7gi7aSStXMkpshaB/2aVcE=", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gulp-newer/-/gulp-newer-1.4.0.tgz", + "integrity": "sha512-h79fGO55S/P9eAADbLAP9aTtVYpLSR1ONj08VPaSdVVNVYhTS8p1CO1TW7kEMu+hC+sytmCqcUr5LesvZEtDoQ==", "dev": true, "requires": { "glob": "7.1.2", - "gulp-util": "3.0.8", - "kew": "0.7.0" + "kew": "0.7.0", + "plugin-error": "0.1.2" } }, "gulp-sourcemaps": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.1.tgz", - "integrity": "sha512-1qHCI3hdmsMdq/SUotxwUh/L8YzlI6J9zQ5ifNOtx4Y6KV5y5sGuORv1KZzWhuKtz/mXNh5xLESUtwC4EndCjA==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.3.tgz", + "integrity": "sha1-EbAz91n5CeCl8Vt730esKcxU76Q=", "dev": true, "requires": { "@gulp-sourcemaps/identity-map": "1.0.1", "@gulp-sourcemaps/map-sources": "1.0.0", - "acorn": "4.0.13", + "acorn": "5.3.0", "convert-source-map": "1.5.1", "css": "2.2.1", "debug-fabulous": "1.0.0", @@ -2576,26 +2438,20 @@ "graceful-fs": "4.1.11", "source-map": "0.5.7", "strip-bom-string": "1.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" + "through2": "2.0.3" }, "dependencies": { + "acorn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "dev": true + }, "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } } } }, @@ -3078,12 +2934,6 @@ "parse-passwd": "1.0.0" } }, - "hosted-git-info": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", - "dev": true - }, "htmlescape": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", @@ -3102,15 +2952,6 @@ "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", "dev": true }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "2.0.1" - } - }, "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", @@ -3181,83 +3022,38 @@ } }, "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=", + "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": "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" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "1.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=", + "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": "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" } }, "is-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.1.tgz", - "integrity": "sha512-G3fFVFTqfaqu7r4YuSBHKBAuOaLz8Sy7ekklUpFEliaLMP1Y2ZjoN9jS62YWCAPQrQpMUQSitRlrzibbuCZjdA==", + "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": "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-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "is-dotfile": { @@ -3287,15 +3083,6 @@ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, "is-glob": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", @@ -3670,42 +3457,6 @@ "resolve": "1.1.7" } }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - } - } - }, "lodash": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", @@ -3730,51 +3481,18 @@ "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", "dev": true }, - "lodash._escapehtmlchar": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz", - "integrity": "sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=", - "dev": true, - "requires": { - "lodash._htmlescapes": "2.4.1" - } - }, - "lodash._escapestringchar": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz", - "integrity": "sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=", - "dev": true - }, "lodash._getnative": { "version": "3.9.1", "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", "dev": true }, - "lodash._htmlescapes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", - "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", - "dev": true - }, "lodash._isiterateecall": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", "dev": true }, - "lodash._isnative": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", - "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=", - "dev": true - }, - "lodash._objecttypes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", - "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", - "dev": true - }, "lodash._reescape": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", @@ -3793,67 +3511,12 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, - "lodash._reunescapedhtml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz", - "integrity": "sha1-dHxPxAED6zu4oJduVx96JlnpO6c=", - "dev": true, - "requires": { - "lodash._htmlescapes": "2.4.1", - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - } - } - }, "lodash._root": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", "dev": true }, - "lodash._shimkeys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz", - "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1" - } - }, - "lodash.defaults": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz", - "integrity": "sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1", - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - } - } - }, "lodash.escape": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", @@ -3881,15 +3544,6 @@ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", "dev": true }, - "lodash.isobject": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", - "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1" - } - }, "lodash.keys": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", @@ -3940,44 +3594,12 @@ "lodash.escape": "3.2.0" } }, - "lodash.values": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz", - "integrity": "sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=", - "dev": true, - "requires": { - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - } - } - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", "dev": true }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "0.4.1", - "signal-exit": "3.0.2" - } - }, "lru-cache": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", @@ -3994,9 +3616,9 @@ } }, "make-error": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.0.tgz", - "integrity": "sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.2.tgz", + "integrity": "sha512-l9ra35l5VWLF24y75Tg8XgfGLX0ueRhph118WKM6H5denx4bB5QF59+4UAm9oJ2qsPQZas/CQUDdtDdfvYHBdQ==", "dev": true }, "make-iterator": { @@ -4025,12 +3647,6 @@ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", @@ -4078,24 +3694,6 @@ "timers-ext": "0.1.2" } }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "2.1.0", - "decamelize": "1.2.0", - "loud-rejection": "1.6.0", - "map-obj": "1.0.1", - "minimist": "1.2.0", - "normalize-package-data": "2.4.0", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "redent": "1.0.0", - "trim-newlines": "1.0.0" - } - }, "merge-stream": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", @@ -4112,9 +3710,9 @@ "dev": true }, "micromatch": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.4.tgz", - "integrity": "sha512-kFRtviKYoAJT+t7HggMl0tBFGNAKLw/S7N+CO9qfEQyisob1Oy4pao+geRbkyeEd+V9aOkvZ4mhuyPvI/q9Sfg==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.5.tgz", + "integrity": "sha512-ykttrLPQrz1PUJcXjwsTUjGoPJ64StIGNE2lGVD1c9CuguJ+L7/navsE8IcDNndOoCMvYV0qc/exfVbMHkUhvA==", "dev": true, "requires": { "arr-diff": "4.0.0", @@ -4122,10 +3720,10 @@ "braces": "2.3.0", "define-property": "1.0.0", "extend-shallow": "2.0.1", - "extglob": "2.0.2", + "extglob": "2.0.3", "fragment-cache": "0.2.1", "kind-of": "6.0.2", - "nanomatch": "1.2.6", + "nanomatch": "1.2.7", "object.pick": "1.3.0", "regex-not": "1.0.0", "snapdragon": "0.8.1", @@ -4208,9 +3806,9 @@ } }, "mocha": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.0.1.tgz", - "integrity": "sha512-evDmhkoA+cBNiQQQdSKZa2b9+W2mpLoj50367lhy+Klnx9OV8XlCIhigUnn1gaTFLQCa0kdNhEGDr0hCXOQFDw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", + "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", "dev": true, "requires": { "browser-stdout": "1.3.0", @@ -4252,17 +3850,17 @@ "dev": true }, "module-deps": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", - "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-5.0.1.tgz", + "integrity": "sha512-sigq/hm/L+Z5IGi1DDl0x2ptkw7S86aFh213QhPLD8v9Opv90IHzKIuWJrRa5bJ77DVKHco2CfIEuThcT/vDJA==", "dev": true, "requires": { "JSONStream": "1.3.2", "browser-resolve": "1.11.2", "cached-path-relative": "1.0.1", - "concat-stream": "1.5.2", + "concat-stream": "1.6.0", "defined": "1.0.0", - "detective": "4.7.1", + "detective": "5.0.2", "duplexer2": "0.1.4", "inherits": "2.0.3", "parents": "1.0.1", @@ -4272,6 +3870,19 @@ "subarg": "1.0.0", "through2": "2.0.3", "xtend": "4.0.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + } } }, "ms": { @@ -4325,9 +3936,9 @@ } }, "nanomatch": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.6.tgz", - "integrity": "sha512-WJ6XTCbvWXUFPbi/bDwKcYkCeOGUHzaJj72KbuPqGn78Ba/F5Vu26Zlo6SuMQbCIst1RGKL1zfWBCOGAlbRLAg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.7.tgz", + "integrity": "sha512-/5ldsnyurvEw7wNpxLFgjVvBLMta43niEYOy0CJ4ntcYSbx6bugRUTQeFb4BR/WanEL1o3aQgHuVLHQaB6tOqg==", "dev": true, "requires": { "arr-diff": "4.0.0", @@ -4372,18 +3983,6 @@ "abbrev": "1.0.9" } }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, - "requires": { - "hosted-git-info": "2.5.0", - "is-builtin-module": "1.0.0", - "semver": "4.3.6", - "validate-npm-package-license": "3.0.1" - } - }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", @@ -4393,12 +3992,6 @@ "remove-trailing-separator": "1.1.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4425,6 +4018,24 @@ "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", @@ -4455,12 +4066,6 @@ } } }, - "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", - "dev": true - }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -4672,15 +4277,6 @@ } } }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "1.3.1" - } - }, "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", @@ -4705,15 +4301,6 @@ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", "dev": true }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1" - } - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -4753,31 +4340,6 @@ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - }, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, "pathval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", @@ -4818,6 +4380,58 @@ "pinkie": "2.0.4" } }, + "plugin-error": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", + "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", + "dev": true, + "requires": { + "ansi-cyan": "0.1.1", + "ansi-red": "0.1.1", + "arr-diff": "1.1.0", + "arr-union": "2.1.0", + "extend-shallow": "1.1.4" + }, + "dependencies": { + "arr-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", + "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0", + "array-slice": "0.2.3" + } + }, + "arr-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", + "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", + "dev": true + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, + "extend-shallow": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", + "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", + "dev": true, + "requires": { + "kind-of": "1.1.0" + } + }, + "kind-of": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", + "dev": true + } + } + }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -4940,27 +4554,6 @@ "readable-stream": "2.3.3" } }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" - } - }, "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", @@ -4985,16 +4578,6 @@ "resolve": "1.1.7" } }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "2.1.0", - "strip-indent": "1.0.1" - } - }, "regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", @@ -5031,15 +4614,6 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "1.0.2" - } - }, "replace-ext": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", @@ -5098,13 +4672,14 @@ } }, "run-sequence": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-2.2.0.tgz", - "integrity": "sha512-xW5DmUwdvoyYQUMPKN8UW7TZSFs7AxtT59xo1m5y91jHbvwGlGgOmdV1Yw5P68fkjf3aHUZ4G1o1mZCtNe0qtw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-2.2.1.tgz", + "integrity": "sha512-qkzZnQWMZjcKbh3CNly2srtrkaO/2H/SI5f2eliMCapdRD3UhMrwjfOAZJAnZ2H8Ju4aBzFZkBGXUqFs9V0yxw==", "dev": true, "requires": { "chalk": "1.1.3", - "gulp-util": "3.0.8" + "fancy-log": "1.3.2", + "plugin-error": "0.1.2" }, "dependencies": { "ansi-styles": { @@ -5237,12 +4812,6 @@ "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", "dev": true }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, "snapdragon": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz", @@ -5268,6 +4837,46 @@ "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", @@ -5387,27 +4996,6 @@ "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", "dev": true }, - "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", - "dev": true, - "requires": { - "spdx-license-ids": "1.2.2" - } - }, - "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", - "dev": true - }, - "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", - "dev": true - }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -5463,6 +5051,46 @@ "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", @@ -5627,15 +5255,6 @@ "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", "dev": true }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "4.0.1" - } - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -5784,6 +5403,46 @@ "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", @@ -5819,22 +5478,16 @@ "integrity": "sha1-/sAF+dyqJZo/lFnOWmkGq6TFRdo=", "dev": true }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, "ts-node": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-4.0.2.tgz", - "integrity": "sha512-mg7l6ON8asjnfzkTi1LFWKaOGHl5Jf1+5ij0MQ502YfC6+4FBgh/idJgw9aN9kei1Rf4/pmFpNuFE1YbcQdOTA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-4.1.0.tgz", + "integrity": "sha512-xcZH12oVg9PShKhy3UHyDmuDLV3y7iKwX25aMVPt1SIXSuAfWkFiGPEkg+th8R4YKW/QCxDoW7lJdb15lx6QWg==", "dev": true, "requires": { "arrify": "1.0.1", "chalk": "2.3.0", "diff": "3.3.1", - "make-error": "1.3.0", + "make-error": "1.3.2", "minimist": "1.2.0", "mkdirp": "0.5.1", "source-map-support": "0.5.0", @@ -5896,7 +5549,7 @@ "resolve": "1.5.0", "semver": "5.4.1", "tslib": "1.8.1", - "tsutils": "2.13.1" + "tsutils": "2.16.0" }, "dependencies": { "resolve": { @@ -5917,9 +5570,9 @@ } }, "tsutils": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.13.1.tgz", - "integrity": "sha512-XMOEvc2TiYesVSOJMI7OYPnBMSgcvERuGW5Li/J+2A0TuH607BPQnOLQ82oSPZCssB8c9+QGi6qhTBa/f1xQRA==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.16.0.tgz", + "integrity": "sha512-9Ier/60O7OZRNPiw+or5QAtAY4kQA+WDiO/r6xOYATEyefH9bdfvTRLCxrYnFhQlZfET2vYXKfpr3Vw2BiArZw==", "dev": true, "requires": { "tslib": "1.8.1" @@ -5953,9 +5606,9 @@ "dev": true }, "typescript": { - "version": "2.7.0-dev.20171221", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.0-dev.20171221.tgz", - "integrity": "sha512-PM09fTK1T0WSZHNDXqrB/P6lTaQkzAnXlx23Q5J/21oQ8kgU7B7TtUFTX7zzdSZnH78j49aUx5bVuQCRJkBowg==", + "version": "2.7.0-dev.20180108", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.0-dev.20180108.tgz", + "integrity": "sha512-ZlggGsch8Y2d0LqAlCYGRzm/gdm2bqSpb4rdthY+YvpPsQqFixT0tU8sgjeRibMXW9hbS2Hz6kibS8L2oUKWfQ==", "dev": true }, "uglify-js": { @@ -6105,6 +5758,46 @@ "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", @@ -6174,16 +5867,6 @@ "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", "dev": true }, - "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", - "dev": true, - "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" - } - }, "vinyl": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", @@ -6362,15 +6045,6 @@ "cliui": "2.1.0", "decamelize": "1.2.0", "window-size": "0.1.0" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true, - "optional": true - } } }, "yn": { diff --git a/scripts/tslint/rules/typeOperatorSpacingRule.ts b/scripts/tslint/rules/typeOperatorSpacingRule.ts index d7da2e6b5e8..82dccfe0eac 100644 --- a/scripts/tslint/rules/typeOperatorSpacingRule.ts +++ b/scripts/tslint/rules/typeOperatorSpacingRule.ts @@ -2,7 +2,7 @@ import * as Lint from "tslint/lib"; import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { - public static FAILURE_STRING = "The '|' and '&' operators must be surrounded by single spaces"; + public static FAILURE_STRING = "The '|' and '&' operators must be surrounded by spaces"; public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { return this.applyWithFunction(sourceFile, walk); @@ -11,26 +11,20 @@ export class Rule extends Lint.Rules.AbstractRule { function walk(ctx: Lint.WalkContext): void { const { sourceFile } = ctx; - ts.forEachChild(sourceFile, recur); - function recur(node: ts.Node): void { - if (node.kind === ts.SyntaxKind.UnionType || node.kind === ts.SyntaxKind.IntersectionType) { - check((node as ts.UnionOrIntersectionTypeNode).types); + sourceFile.forEachChild(function cb(node: ts.Node): void { + if (ts.isUnionTypeNode(node) || ts.isIntersectionTypeNode(node)) { + check(node); } - ts.forEachChild(node, recur); - } + node.forEachChild(cb); + }); - function check(types: ReadonlyArray): void { - let expectedStart = types[0].end + 2; // space, | or & - for (let i = 1; i < types.length; i++) { - const currentType = types[i]; - if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) { - const previousTypeEndPos = sourceFile.getLineAndCharacterOfPosition(types[i - 1].end); - const currentTypeStartPos = sourceFile.getLineAndCharacterOfPosition(currentType.pos); - if (previousTypeEndPos.line === currentTypeStartPos.line) { - ctx.addFailureAtNode(currentType, Rule.FAILURE_STRING); - } + function check(node: ts.UnionTypeNode | ts.IntersectionTypeNode): void { + const list = node.getChildren().find(child => child.kind === ts.SyntaxKind.SyntaxList)!; + for (const child of list.getChildren()) { + if ((child.kind === ts.SyntaxKind.BarToken || child.kind === ts.SyntaxKind.AmpersandToken) + && (/\S/.test(sourceFile.text[child.getStart(sourceFile) - 1]) || /\S/.test(sourceFile.text[child.end]))) { + ctx.addFailureAtNode(child, Rule.FAILURE_STRING); } - expectedStart = currentType.end + 2; } } } diff --git a/src/services/shims.ts b/src/services/shims.ts index 34a8bbb10d9..fda698785b3 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -141,7 +141,6 @@ namespace ts { getEncodedSemanticClassifications(fileName: string, start: number, length: number): string; getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined): string; - // tslint:disable-next-line type-operator-spacing (false positive) getCompletionEntryDetails(fileName: string, position: number, entryName: string, options: string/*Services.FormatCodeOptions*/ | undefined, source: string | undefined): string; getQuickInfoAtPosition(fileName: string, position: number): string; @@ -907,7 +906,6 @@ namespace ts { } /** Get a string based representation of a completion list entry details */ - // tslint:disable-next-line type-operator-spacing (false positive) public getCompletionEntryDetails(fileName: string, position: number, entryName: string, options: string/*Services.FormatCodeOptions*/ | undefined, source: string | undefined) { return this.forwardJSONCall( `getCompletionEntryDetails('${fileName}', ${position}, '${entryName}')`, From 06c9a28b367e124323c7dcff9a2205ffc0a81499 Mon Sep 17 00:00:00 2001 From: Wenlu Wang <805037171@163.com> Date: Tue, 9 Jan 2018 05:06:58 +0800 Subject: [PATCH 097/189] fix narrowType check with template literals (#21024) --- src/compiler/binder.ts | 4 +- src/compiler/checker.ts | 6 +-- .../controlFlowWithTemplateLiterals.js | 19 ++++++++++ .../controlFlowWithTemplateLiterals.symbols | 28 ++++++++++++++ .../controlFlowWithTemplateLiterals.types | 37 +++++++++++++++++++ .../controlFlowWithTemplateLiterals.ts | 10 +++++ 6 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/controlFlowWithTemplateLiterals.js create mode 100644 tests/baselines/reference/controlFlowWithTemplateLiterals.symbols create mode 100644 tests/baselines/reference/controlFlowWithTemplateLiterals.types create mode 100644 tests/cases/conformance/controlFlow/controlFlowWithTemplateLiterals.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 4fdfacdbf50..701b1bfb249 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -746,11 +746,11 @@ namespace ts { } function isNarrowingTypeofOperands(expr1: Expression, expr2: Expression) { - return expr1.kind === SyntaxKind.TypeOfExpression && isNarrowableOperand((expr1).expression) && expr2.kind === SyntaxKind.StringLiteral; + return expr1.kind === SyntaxKind.TypeOfExpression && isNarrowableOperand((expr1).expression) && (expr2.kind === SyntaxKind.StringLiteral || expr2.kind === SyntaxKind.NoSubstitutionTemplateLiteral); } function isNarrowableInOperands(left: Expression, right: Expression) { - return left.kind === SyntaxKind.StringLiteral && isNarrowingExpression(right); + return (left.kind === SyntaxKind.StringLiteral || left.kind === SyntaxKind.NoSubstitutionTemplateLiteral) && isNarrowingExpression(right); } function isNarrowingBinaryExpression(expr: BinaryExpression) { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ff6371e679c..b04d39bb2b1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12838,10 +12838,10 @@ namespace ts { const operator = expr.operatorToken.kind; const left = getReferenceCandidate(expr.left); const right = getReferenceCandidate(expr.right); - if (left.kind === SyntaxKind.TypeOfExpression && right.kind === SyntaxKind.StringLiteral) { + if (left.kind === SyntaxKind.TypeOfExpression && (right.kind === SyntaxKind.StringLiteral || right.kind === SyntaxKind.NoSubstitutionTemplateLiteral)) { return narrowTypeByTypeof(type, left, operator, right, assumeTrue); } - if (right.kind === SyntaxKind.TypeOfExpression && left.kind === SyntaxKind.StringLiteral) { + if (right.kind === SyntaxKind.TypeOfExpression && (left.kind === SyntaxKind.StringLiteral || left.kind === SyntaxKind.NoSubstitutionTemplateLiteral)) { return narrowTypeByTypeof(type, right, operator, left, assumeTrue); } if (isMatchingReference(reference, left)) { @@ -12864,7 +12864,7 @@ namespace ts { return narrowTypeByInstanceof(type, expr, assumeTrue); case SyntaxKind.InKeyword: const target = getReferenceCandidate(expr.right); - if (expr.left.kind === SyntaxKind.StringLiteral && isMatchingReference(reference, target)) { + if ((expr.left.kind === SyntaxKind.StringLiteral || expr.left.kind === SyntaxKind.NoSubstitutionTemplateLiteral) && isMatchingReference(reference, target)) { return narrowByInKeyword(type, expr.left, assumeTrue); } break; diff --git a/tests/baselines/reference/controlFlowWithTemplateLiterals.js b/tests/baselines/reference/controlFlowWithTemplateLiterals.js new file mode 100644 index 00000000000..b640848f5ec --- /dev/null +++ b/tests/baselines/reference/controlFlowWithTemplateLiterals.js @@ -0,0 +1,19 @@ +//// [controlFlowWithTemplateLiterals.ts] +declare const envVar: string | undefined; +if (typeof envVar === `string`) { + envVar.slice(0) +} + +declare const obj: {test: string} | {} +if (`test` in obj) { + obj.test.slice(0) +} + + +//// [controlFlowWithTemplateLiterals.js] +if (typeof envVar === "string") { + envVar.slice(0); +} +if ("test" in obj) { + obj.test.slice(0); +} diff --git a/tests/baselines/reference/controlFlowWithTemplateLiterals.symbols b/tests/baselines/reference/controlFlowWithTemplateLiterals.symbols new file mode 100644 index 00000000000..978a0e507e0 --- /dev/null +++ b/tests/baselines/reference/controlFlowWithTemplateLiterals.symbols @@ -0,0 +1,28 @@ +=== tests/cases/conformance/controlFlow/controlFlowWithTemplateLiterals.ts === +declare const envVar: string | undefined; +>envVar : Symbol(envVar, Decl(controlFlowWithTemplateLiterals.ts, 0, 13)) + +if (typeof envVar === `string`) { +>envVar : Symbol(envVar, Decl(controlFlowWithTemplateLiterals.ts, 0, 13)) + + envVar.slice(0) +>envVar.slice : Symbol(String.slice, Decl(lib.d.ts, --, --)) +>envVar : Symbol(envVar, Decl(controlFlowWithTemplateLiterals.ts, 0, 13)) +>slice : Symbol(String.slice, Decl(lib.d.ts, --, --)) +} + +declare const obj: {test: string} | {} +>obj : Symbol(obj, Decl(controlFlowWithTemplateLiterals.ts, 5, 13)) +>test : Symbol(test, Decl(controlFlowWithTemplateLiterals.ts, 5, 20)) + +if (`test` in obj) { +>obj : Symbol(obj, Decl(controlFlowWithTemplateLiterals.ts, 5, 13)) + + obj.test.slice(0) +>obj.test.slice : Symbol(String.slice, Decl(lib.d.ts, --, --)) +>obj.test : Symbol(test, Decl(controlFlowWithTemplateLiterals.ts, 5, 20)) +>obj : Symbol(obj, Decl(controlFlowWithTemplateLiterals.ts, 5, 13)) +>test : Symbol(test, Decl(controlFlowWithTemplateLiterals.ts, 5, 20)) +>slice : Symbol(String.slice, Decl(lib.d.ts, --, --)) +} + diff --git a/tests/baselines/reference/controlFlowWithTemplateLiterals.types b/tests/baselines/reference/controlFlowWithTemplateLiterals.types new file mode 100644 index 00000000000..7775d26fe38 --- /dev/null +++ b/tests/baselines/reference/controlFlowWithTemplateLiterals.types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/controlFlow/controlFlowWithTemplateLiterals.ts === +declare const envVar: string | undefined; +>envVar : string | undefined + +if (typeof envVar === `string`) { +>typeof envVar === `string` : boolean +>typeof envVar : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>envVar : string | undefined +>`string` : "string" + + envVar.slice(0) +>envVar.slice(0) : string +>envVar.slice : (start?: number | undefined, end?: number | undefined) => string +>envVar : string +>slice : (start?: number | undefined, end?: number | undefined) => string +>0 : 0 +} + +declare const obj: {test: string} | {} +>obj : {} | { test: string; } +>test : string + +if (`test` in obj) { +>`test` in obj : boolean +>`test` : "test" +>obj : {} | { test: string; } + + obj.test.slice(0) +>obj.test.slice(0) : string +>obj.test.slice : (start?: number | undefined, end?: number | undefined) => string +>obj.test : string +>obj : { test: string; } +>test : string +>slice : (start?: number | undefined, end?: number | undefined) => string +>0 : 0 +} + diff --git a/tests/cases/conformance/controlFlow/controlFlowWithTemplateLiterals.ts b/tests/cases/conformance/controlFlow/controlFlowWithTemplateLiterals.ts new file mode 100644 index 00000000000..18777844558 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowWithTemplateLiterals.ts @@ -0,0 +1,10 @@ +// @strictNullChecks: true +declare const envVar: string | undefined; +if (typeof envVar === `string`) { + envVar.slice(0) +} + +declare const obj: {test: string} | {} +if (`test` in obj) { + obj.test.slice(0) +} From a82d1f8580c8fb2a98ac3b215a2ed79be36a93ff Mon Sep 17 00:00:00 2001 From: Wenlu Wang <805037171@163.com> Date: Tue, 9 Jan 2018 05:13:23 +0800 Subject: [PATCH 098/189] ignore Initial check if left of DestructuringAsignment (#20906) --- src/compiler/checker.ts | 3 ++- ...structuringAssignmentWithStrictNullChecks.js | 17 +++++++++++++++++ ...turingAssignmentWithStrictNullChecks.symbols | 7 +++++++ ...ucturingAssignmentWithStrictNullChecks.types | 11 +++++++++++ ...structuringAssignmentWithStrictNullChecks.ts | 3 +++ 5 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.js create mode 100644 tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.symbols create mode 100644 tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.types create mode 100644 tests/cases/compiler/destructuringAssignmentWithStrictNullChecks.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b04d39bb2b1..b1f2df5ca6a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13333,6 +13333,7 @@ namespace ts { const declarationContainer = getControlFlowContainer(declaration); let flowContainer = getControlFlowContainer(node); const isOuterVariable = flowContainer !== declarationContainer; + const isSpreadDestructuringAsignmentTarget = node.parent && node.parent.parent && isSpreadAssignment(node.parent) && isDestructuringAssignmentTarget(node.parent.parent); // When the control flow originates in a function expression or arrow function and we are referencing // a const variable or parameter from an outer function, we extend the origin of the control flow // analysis to include the immediately enclosing function. @@ -13344,7 +13345,7 @@ namespace ts { // We only look for uninitialized variables in strict null checking mode, and only when we can analyze // the entire control flow graph from the variable's declaration (i.e. when the flow container and // declaration container are the same). - const assumeInitialized = isParameter || isAlias || isOuterVariable || + const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAsignmentTarget || type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) || node.parent.kind === SyntaxKind.NonNullExpression || diff --git a/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.js b/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.js new file mode 100644 index 00000000000..52bac6e2391 --- /dev/null +++ b/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.js @@ -0,0 +1,17 @@ +//// [destructuringAssignmentWithStrictNullChecks.ts] +let bar: {}; +({ ...bar } = {}); + + +//// [destructuringAssignmentWithStrictNullChecks.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 bar; +(bar = __rest({}, [])); diff --git a/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.symbols b/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.symbols new file mode 100644 index 00000000000..b241c29c9ae --- /dev/null +++ b/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.symbols @@ -0,0 +1,7 @@ +=== tests/cases/compiler/destructuringAssignmentWithStrictNullChecks.ts === +let bar: {}; +>bar : Symbol(bar, Decl(destructuringAssignmentWithStrictNullChecks.ts, 0, 3)) + +({ ...bar } = {}); +>bar : Symbol(bar, Decl(destructuringAssignmentWithStrictNullChecks.ts, 0, 3)) + diff --git a/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.types b/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.types new file mode 100644 index 00000000000..375ddf82a59 --- /dev/null +++ b/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/destructuringAssignmentWithStrictNullChecks.ts === +let bar: {}; +>bar : {} + +({ ...bar } = {}); +>({ ...bar } = {}) : {} +>{ ...bar } = {} : {} +>{ ...bar } : {} +>bar : {} +>{} : {} + diff --git a/tests/cases/compiler/destructuringAssignmentWithStrictNullChecks.ts b/tests/cases/compiler/destructuringAssignmentWithStrictNullChecks.ts new file mode 100644 index 00000000000..b3565a38e10 --- /dev/null +++ b/tests/cases/compiler/destructuringAssignmentWithStrictNullChecks.ts @@ -0,0 +1,3 @@ +// @strictNullChecks: true +let bar: {}; +({ ...bar } = {}); From 0ecdc876f38c1660cf8b686708149a81fc56e96d Mon Sep 17 00:00:00 2001 From: Wenlu Wang <805037171@163.com> Date: Tue, 9 Jan 2018 05:16:17 +0800 Subject: [PATCH 099/189] imporve conditional operator if missing colon token (#20498) f2 --- src/compiler/parser.ts | 4 +++- .../baselines/reference/jsxAndTypeAssertion.errors.txt | 10 ++-------- .../completionWithConditionalOperatorMissingColon.ts | 6 ++++++ 3 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 tests/cases/fourslash/completionWithConditionalOperatorMissingColon.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index a072579ed63..ce2ad27329e 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3504,7 +3504,9 @@ namespace ts { node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher); node.colonToken = parseExpectedToken(SyntaxKind.ColonToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); - node.whenFalse = parseAssignmentExpressionOrHigher(); + node.whenFalse = nodeIsPresent(node.colonToken) + ? parseAssignmentExpressionOrHigher() + : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); return finishNode(node); } diff --git a/tests/baselines/reference/jsxAndTypeAssertion.errors.txt b/tests/baselines/reference/jsxAndTypeAssertion.errors.txt index d5df3915bf6..5aa92086c37 100644 --- a/tests/baselines/reference/jsxAndTypeAssertion.errors.txt +++ b/tests/baselines/reference/jsxAndTypeAssertion.errors.txt @@ -10,13 +10,11 @@ tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(14,45): error TS1005: '}' ex tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(18,2): error TS17008: JSX element 'foo' has no corresponding closing tag. tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(18,8): error TS17008: JSX element 'foo' has no corresponding closing tag. tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(18,13): error TS17008: JSX element 'foo' has no corresponding closing tag. -tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(18,83): error TS1109: Expression expected. tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(21,1): error TS1005: ':' expected. tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(21,1): error TS1005: ' +////1 ? fun/*1*/ +////function func () {} + +goTo.marker("1"); +verify.completionListContains("func"); From 7154df10dfc4386c3c4a7c1adc0ae71aec48fde2 Mon Sep 17 00:00:00 2001 From: Wenlu Wang <805037171@163.com> Date: Tue, 9 Jan 2018 05:25:02 +0800 Subject: [PATCH 100/189] add support for insertSpaceBeforeTypeAnnotation (#20466) --- src/harness/fourslash.ts | 1 + src/server/protocol.ts | 1 + src/services/formatting/rules.ts | 18 +++++++++++++++++- src/services/types.ts | 2 ++ .../reference/api/tsserverlibrary.d.ts | 3 +++ tests/baselines/reference/api/typescript.d.ts | 2 ++ .../cases/fourslash/formattingOptionsChange.ts | 2 ++ tests/cases/fourslash/fourslash.ts | 1 + 8 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index c44fa006c03..df103e9dafc 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -381,6 +381,7 @@ namespace FourSlash { insertSpaceAfterTypeAssertion: false, placeOpenBraceOnNewLineForFunctions: false, placeOpenBraceOnNewLineForControlBlocks: false, + insertSpaceBeforeTypeAnnotation: false }; // Open the first file by default diff --git a/src/server/protocol.ts b/src/server/protocol.ts index d406aa9c65b..ef59cc16406 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2556,6 +2556,7 @@ namespace ts.server.protocol { insertSpaceBeforeFunctionParenthesis?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } export interface CompilerOptions { diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 470f3237eb9..04f599039da 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -47,7 +47,7 @@ namespace ts.formatting { rule("IgnoreBeforeComment", anyToken, comments, anyContext, RuleAction.Ignore), rule("IgnoreAfterLineComment", SyntaxKind.SingleLineCommentTrivia, anyToken, anyContext, RuleAction.Ignore), - rule("NoSpaceBeforeColon", anyToken, SyntaxKind.ColonToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Delete), + rule("NotSpaceBeforeColon", anyToken, SyntaxKind.ColonToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext, isNotTypeAnnotationContext], RuleAction.Delete), rule("SpaceAfterColon", SyntaxKind.ColonToken, anyToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Space), rule("NoSpaceBeforeQuestionMark", anyToken, SyntaxKind.QuestionToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Delete), // insert space after '?' only when it is used in conditional operator @@ -300,6 +300,9 @@ namespace ts.formatting { rule("SpaceAfterTypeAssertion", SyntaxKind.GreaterThanToken, anyToken, [isOptionEnabled("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], RuleAction.Space), rule("NoSpaceAfterTypeAssertion", SyntaxKind.GreaterThanToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], RuleAction.Delete), + + rule("SpaceBeforeTypeAnnotation", anyToken, SyntaxKind.ColonToken, [isOptionEnabled("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], RuleAction.Space), + rule("NoSpaceBeforeTypeAnnotation", anyToken, SyntaxKind.ColonToken, [isOptionDisabledOrUndefined("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], RuleAction.Delete), ]; // These rules are lower in priority than user-configurable. Rules earlier in this list have priority over rules later in the list. @@ -441,6 +444,19 @@ namespace ts.formatting { return !isBinaryOpContext(context); } + function isNotTypeAnnotationContext(context: FormattingContext): boolean { + return !isTypeAnnotationContext(context); + } + + function isTypeAnnotationContext(context: FormattingContext): boolean { + const contextKind = context.contextNode.kind; + return contextKind === SyntaxKind.PropertyDeclaration || + contextKind === SyntaxKind.PropertySignature || + contextKind === SyntaxKind.Parameter || + contextKind === SyntaxKind.VariableDeclaration || + isFunctionLikeKind(contextKind); + } + function isConditionalOperatorContext(context: FormattingContext): boolean { return context.contextNode.kind === SyntaxKind.ConditionalExpression; } diff --git a/src/services/types.ts b/src/services/types.ts index 813e8790933..8e670486649 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -597,6 +597,7 @@ namespace ts { InsertSpaceBeforeFunctionParenthesis?: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } export interface FormatCodeSettings extends EditorSettings { @@ -615,6 +616,7 @@ namespace ts { insertSpaceBeforeFunctionParenthesis?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } export interface DefinitionInfo { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index eafef37a5ec..495e6083f4b 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4209,6 +4209,7 @@ declare namespace ts { InsertSpaceBeforeFunctionParenthesis?: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } interface FormatCodeSettings extends EditorSettings { insertSpaceAfterCommaDelimiter?: boolean; @@ -4226,6 +4227,7 @@ declare namespace ts { insertSpaceBeforeFunctionParenthesis?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } interface DefinitionInfo { fileName: string; @@ -6845,6 +6847,7 @@ declare namespace ts.server.protocol { insertSpaceBeforeFunctionParenthesis?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } interface CompilerOptions { allowJs?: boolean; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 6748b39e58e..5563d95aa0c 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4209,6 +4209,7 @@ declare namespace ts { InsertSpaceBeforeFunctionParenthesis?: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } interface FormatCodeSettings extends EditorSettings { insertSpaceAfterCommaDelimiter?: boolean; @@ -4226,6 +4227,7 @@ declare namespace ts { insertSpaceBeforeFunctionParenthesis?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } interface DefinitionInfo { fileName: string; diff --git a/tests/cases/fourslash/formattingOptionsChange.ts b/tests/cases/fourslash/formattingOptionsChange.ts index 0e731412ede..390ed426aa9 100644 --- a/tests/cases/fourslash/formattingOptionsChange.ts +++ b/tests/cases/fourslash/formattingOptionsChange.ts @@ -9,6 +9,7 @@ /////*insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets*/[1 ]; [ ]; []; [,]; /////*insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces*/`${1}`;`${ 1 }` /////*insertSpaceAfterTypeAssertion*/const bar = Thing.getFoo(); +/////*insertSpaceBeforeTypeAnnotation*/const bar : number = 1; /////*placeOpenBraceOnNewLineForFunctions*/class foo { ////} /////*placeOpenBraceOnNewLineForControlBlocks*/if (true) { @@ -26,6 +27,7 @@ runTest("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis", " ( 1 ) runTest("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets", "[ 1 ];[];[];[ , ];", "[1];[];[];[,];"); runTest("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces", "`${ 1 }`; `${ 1 }`", "`${1}`; `${1}`"); runTest("insertSpaceAfterTypeAssertion", "const bar = Thing.getFoo();", "const bar = Thing.getFoo();"); +runTest("insertSpaceBeforeTypeAnnotation", "const bar : number = 1;", "const bar: number = 1;"); runTest("placeOpenBraceOnNewLineForFunctions", "class foo", "class foo {"); runTest("placeOpenBraceOnNewLineForControlBlocks", "if (true)", "if (true) {"); runTest("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces", "{ var t = 1 }; var { a, b } = { a: 'sw', b: 'r' }; function f({ a, b }) { }", "{var t = 1}; var {a, b} = {a: 'sw', b: 'r'}; function f({a, b}) {}"); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 933e7a88f94..ec2a5d1a2ea 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -97,6 +97,7 @@ declare namespace FourSlashInterface { InsertSpaceAfterTypeAssertion: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; + insertSpaceBeforeTypeAnnotation: boolean; [s: string]: boolean | number | string | undefined; } interface Range { From b18ee654183cd14baa2a9ac7af4bfa0bed7b9cb2 Mon Sep 17 00:00:00 2001 From: falsandtru Date: Tue, 9 Jan 2018 06:35:28 +0900 Subject: [PATCH 101/189] Add Related section (#20151) --- issue_template.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/issue_template.md b/issue_template.md index dbc021c28ad..22acf3e9cc5 100644 --- a/issue_template.md +++ b/issue_template.md @@ -15,3 +15,5 @@ **Expected behavior:** **Actual behavior:** + +**Related:** From 16a882eb8babc24a658f3022afe01f3081310385 Mon Sep 17 00:00:00 2001 From: Jing Ma Date: Tue, 9 Jan 2018 05:44:49 +0800 Subject: [PATCH 102/189] Optimized annotation according to Spec (#19906) --- src/lib/es2015.core.d.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/es2015.core.d.ts b/src/lib/es2015.core.d.ts index ccff68968f1..eef20591a84 100644 --- a/src/lib/es2015.core.d.ts +++ b/src/lib/es2015.core.d.ts @@ -118,8 +118,9 @@ interface Math { log1p(x: number): number; /** - * Returns the result of (e^x - 1) of x (e raised to the power of x, where e is the base of - * the natural logarithms). + * Returns the result of (e^x - 1), which is an implementation-dependent approximation to + * subtracting 1 from the exponential function of x (e raised to the power of x, where e + * is the base of the natural logarithms). * @param x A numeric expression. */ expm1(x: number): number; From b2f2610b852464b1813c280e295cb7ee63dc2f86 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 8 Jan 2018 13:55:50 -0800 Subject: [PATCH 103/189] Use getInternalName not getLocalName (#20168) --- src/compiler/transformers/es2015.ts | 2 +- .../reference/classExtensionNameOutput.js | 38 +++++++++++++++++++ .../classExtensionNameOutput.symbols | 16 ++++++++ .../reference/classExtensionNameOutput.types | 20 ++++++++++ .../compiler/classExtensionNameOutput.ts | 8 ++++ 5 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/classExtensionNameOutput.js create mode 100644 tests/baselines/reference/classExtensionNameOutput.symbols create mode 100644 tests/baselines/reference/classExtensionNameOutput.types create mode 100644 tests/cases/compiler/classExtensionNameOutput.ts diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 65771410ea2..da0fcc73a98 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -859,7 +859,7 @@ namespace ts { statements.push( setTextRange( createStatement( - createExtendsHelper(context, getLocalName(node)) + createExtendsHelper(context, getInternalName(node)) ), /*location*/ extendsClauseElement ) diff --git a/tests/baselines/reference/classExtensionNameOutput.js b/tests/baselines/reference/classExtensionNameOutput.js new file mode 100644 index 00000000000..8f979863426 --- /dev/null +++ b/tests/baselines/reference/classExtensionNameOutput.js @@ -0,0 +1,38 @@ +//// [classExtensionNameOutput.ts] +class A {} +if (true) { + class B extends A {} + + const foo = function () { + new B(); + } +} + +//// [classExtensionNameOutput.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 A = /** @class */ (function () { + function A() { + } + return A; +}()); +if (true) { + var B_1 = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + return B; + }(A)); + var foo = function () { + new B_1(); + }; +} diff --git a/tests/baselines/reference/classExtensionNameOutput.symbols b/tests/baselines/reference/classExtensionNameOutput.symbols new file mode 100644 index 00000000000..7c26d980295 --- /dev/null +++ b/tests/baselines/reference/classExtensionNameOutput.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/classExtensionNameOutput.ts === +class A {} +>A : Symbol(A, Decl(classExtensionNameOutput.ts, 0, 0)) + +if (true) { + class B extends A {} +>B : Symbol(B, Decl(classExtensionNameOutput.ts, 1, 11)) +>A : Symbol(A, Decl(classExtensionNameOutput.ts, 0, 0)) + + const foo = function () { +>foo : Symbol(foo, Decl(classExtensionNameOutput.ts, 4, 7)) + + new B(); +>B : Symbol(B, Decl(classExtensionNameOutput.ts, 1, 11)) + } +} diff --git a/tests/baselines/reference/classExtensionNameOutput.types b/tests/baselines/reference/classExtensionNameOutput.types new file mode 100644 index 00000000000..0bbbb9e2119 --- /dev/null +++ b/tests/baselines/reference/classExtensionNameOutput.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/classExtensionNameOutput.ts === +class A {} +>A : A + +if (true) { +>true : true + + class B extends A {} +>B : B +>A : A + + const foo = function () { +>foo : () => void +>function () { new B(); } : () => void + + new B(); +>new B() : B +>B : typeof B + } +} diff --git a/tests/cases/compiler/classExtensionNameOutput.ts b/tests/cases/compiler/classExtensionNameOutput.ts new file mode 100644 index 00000000000..3992780b0fb --- /dev/null +++ b/tests/cases/compiler/classExtensionNameOutput.ts @@ -0,0 +1,8 @@ +class A {} +if (true) { + class B extends A {} + + const foo = function () { + new B(); + } +} \ No newline at end of file From b1a0261575ae473c1237a01d694b52f8b59b6111 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 8 Jan 2018 13:58:34 -0800 Subject: [PATCH 104/189] If declaration emit input is a module, output should be a module (#20626) --- src/compiler/declarationEmitter.ts | 9 ++++-- .../bindingPatternOmittedExpressionNesting.js | 1 + .../reference/commentsExternalModules.js | 1 + .../reference/commonSourceDirectory.js | 1 + .../baselines/reference/commonjsSafeImport.js | 1 + .../reference/emptyDeclarationEmitIsModule.js | 30 +++++++++++++++++++ .../emptyDeclarationEmitIsModule.symbols | 15 ++++++++++ .../emptyDeclarationEmitIsModule.types | 15 ++++++++++ .../reference/es6ImportDefaultBinding.js | 1 + .../reference/es6ImportDefaultBindingAmd.js | 1 + ...rtDefaultBindingFollowedWithNamedImport.js | 1 + ...tDefaultBindingFollowedWithNamedImport1.js | 1 + ...ultBindingFollowedWithNamedImport1InEs5.js | 1 + ...aultBindingFollowedWithNamedImportInEs5.js | 1 + ...aultBindingFollowedWithNamespaceBinding.js | 1 + ...ultBindingFollowedWithNamespaceBinding1.js | 1 + ...ndingFollowedWithNamespaceBinding1InEs5.js | 1 + ...indingFollowedWithNamespaceBindingInEs5.js | 1 + .../reference/es6ImportDefaultBindingInEs5.js | 1 + .../reference/es6ImportNameSpaceImport.js | 1 + .../reference/es6ImportNameSpaceImportAmd.js | 1 + .../es6ImportNameSpaceImportInEs5.js | 1 + .../reference/es6ImportNamedImport.js | 1 + .../reference/es6ImportNamedImportAmd.js | 1 + .../reference/es6ImportNamedImportInEs5.js | 1 + .../exportClassExtendingIntersection.js | 1 + .../reference/exportStarFromEmptyModule.js | 1 + .../reference/moduleAugmentationGlobal4.js | 2 -- .../moduleAugmentationInAmbientModule1.js | 1 + .../baselines/reference/multiImportExport.js | 1 + .../reference/shorthand-property-es5-es6.js | 1 + .../reference/shorthand-property-es6-amd.js | 1 + .../reference/shorthand-property-es6-es6.js | 1 + ...pressionWithUndefinedCallResolutionData.js | 1 + .../reference/unusedImportDeclaration.js | 1 + tests/baselines/reference/withImportDecl.js | 1 + .../compiler/emptyDeclarationEmitIsModule.ts | 9 ++++++ 37 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/emptyDeclarationEmitIsModule.js create mode 100644 tests/baselines/reference/emptyDeclarationEmitIsModule.symbols create mode 100644 tests/baselines/reference/emptyDeclarationEmitIsModule.types create mode 100644 tests/cases/compiler/emptyDeclarationEmitIsModule.ts diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 278a9cf4a5f..b85c79e775c 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -148,8 +148,8 @@ namespace ts { moduleElementDeclarationEmitInfo = []; } - if (!isBundledEmit && isExternalModule(sourceFile) && sourceFile.moduleAugmentations.length && !resultHasExternalModuleIndicator) { - // if file was external module with augmentations - this fact should be preserved in .d.ts as well. + if (!isBundledEmit && isExternalModule(sourceFile) && !resultHasExternalModuleIndicator) { + // if file was external module this fact should be preserved in .d.ts as well. // in case if we didn't write any external module specifiers in .d.ts we need to emit something // that will force compiler to think that this file is an external module - 'export {}' is a reasonable choice here. write("export {};"); @@ -651,6 +651,9 @@ namespace ts { } function emitExportAssignment(node: ExportAssignment) { + if (isSourceFile(node.parent)) { + resultHasExternalModuleIndicator = true; // Top-level exports are external module indicators + } if (node.expression.kind === SyntaxKind.Identifier) { write(node.isExportEquals ? "export = " : "export default "); writeTextOfNode(currentText, node.expression); @@ -745,6 +748,7 @@ namespace ts { const modifiers = getModifierFlags(node); // If the node is exported if (modifiers & ModifierFlags.Export) { + resultHasExternalModuleIndicator = true; // Top-level exports are external module indicators write("export "); } @@ -901,6 +905,7 @@ namespace ts { } function emitExportDeclaration(node: ExportDeclaration) { + resultHasExternalModuleIndicator = true; // Top-level exports are external module indicators emitJsDocComments(node); write("export "); if (node.exportClause) { diff --git a/tests/baselines/reference/bindingPatternOmittedExpressionNesting.js b/tests/baselines/reference/bindingPatternOmittedExpressionNesting.js index e2dff308879..0a8542ee637 100644 --- a/tests/baselines/reference/bindingPatternOmittedExpressionNesting.js +++ b/tests/baselines/reference/bindingPatternOmittedExpressionNesting.js @@ -9,3 +9,4 @@ var _b, _c, _d, _e; //// [bindingPatternOmittedExpressionNesting.d.ts] +export {}; diff --git a/tests/baselines/reference/commentsExternalModules.js b/tests/baselines/reference/commentsExternalModules.js index 82c6fa53b82..6271c677e65 100644 --- a/tests/baselines/reference/commentsExternalModules.js +++ b/tests/baselines/reference/commentsExternalModules.js @@ -169,3 +169,4 @@ export declare module m4 { function fooExport(): number; } //// [commentsExternalModules_1.d.ts] +export {}; diff --git a/tests/baselines/reference/commonSourceDirectory.js b/tests/baselines/reference/commonSourceDirectory.js index 5569ae6d52b..ca705a5b34e 100644 --- a/tests/baselines/reference/commonSourceDirectory.js +++ b/tests/baselines/reference/commonSourceDirectory.js @@ -28,3 +28,4 @@ foo_1.x + bar_1.y; //// [/app/bin/index.d.ts] /// +export {}; diff --git a/tests/baselines/reference/commonjsSafeImport.js b/tests/baselines/reference/commonjsSafeImport.js index 5eb560f8bb9..3bf05800aa9 100644 --- a/tests/baselines/reference/commonjsSafeImport.js +++ b/tests/baselines/reference/commonjsSafeImport.js @@ -24,3 +24,4 @@ _10_lib_1.Foo(); //// [10_lib.d.ts] export declare function Foo(): void; //// [main.d.ts] +export {}; diff --git a/tests/baselines/reference/emptyDeclarationEmitIsModule.js b/tests/baselines/reference/emptyDeclarationEmitIsModule.js new file mode 100644 index 00000000000..fb0cea6365e --- /dev/null +++ b/tests/baselines/reference/emptyDeclarationEmitIsModule.js @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/emptyDeclarationEmitIsModule.ts] //// + +//// [module.ts] +import * as i from "./index"; +class Foo {} +//// [index.ts] +import {} from "./module"; +export interface Bar { + x: string +} + +//// [index.js] +"use strict"; +exports.__esModule = true; +//// [module.js] +"use strict"; +exports.__esModule = true; +var Foo = /** @class */ (function () { + function Foo() { + } + return Foo; +}()); + + +//// [index.d.ts] +export interface Bar { + x: string; +} +//// [module.d.ts] +export {}; diff --git a/tests/baselines/reference/emptyDeclarationEmitIsModule.symbols b/tests/baselines/reference/emptyDeclarationEmitIsModule.symbols new file mode 100644 index 00000000000..60b0fd65204 --- /dev/null +++ b/tests/baselines/reference/emptyDeclarationEmitIsModule.symbols @@ -0,0 +1,15 @@ +=== tests/cases/compiler/module.ts === +import * as i from "./index"; +>i : Symbol(i, Decl(module.ts, 0, 6)) + +class Foo {} +>Foo : Symbol(Foo, Decl(module.ts, 0, 29)) + +=== tests/cases/compiler/index.ts === +import {} from "./module"; +export interface Bar { +>Bar : Symbol(Bar, Decl(index.ts, 0, 26)) + + x: string +>x : Symbol(Bar.x, Decl(index.ts, 1, 22)) +} diff --git a/tests/baselines/reference/emptyDeclarationEmitIsModule.types b/tests/baselines/reference/emptyDeclarationEmitIsModule.types new file mode 100644 index 00000000000..1a49aa948da --- /dev/null +++ b/tests/baselines/reference/emptyDeclarationEmitIsModule.types @@ -0,0 +1,15 @@ +=== tests/cases/compiler/module.ts === +import * as i from "./index"; +>i : typeof i + +class Foo {} +>Foo : Foo + +=== tests/cases/compiler/index.ts === +import {} from "./module"; +export interface Bar { +>Bar : Bar + + x: string +>x : string +} diff --git a/tests/baselines/reference/es6ImportDefaultBinding.js b/tests/baselines/reference/es6ImportDefaultBinding.js index 5629c9b8cdc..bdc9b4b8463 100644 --- a/tests/baselines/reference/es6ImportDefaultBinding.js +++ b/tests/baselines/reference/es6ImportDefaultBinding.js @@ -22,3 +22,4 @@ var x = defaultBinding; declare var a: number; export default a; //// [es6ImportDefaultBinding_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingAmd.js b/tests/baselines/reference/es6ImportDefaultBindingAmd.js index d8a13efa2d6..1f6b3c97c8f 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingAmd.js +++ b/tests/baselines/reference/es6ImportDefaultBindingAmd.js @@ -29,3 +29,4 @@ define(["require", "exports", "es6ImportDefaultBindingAmd_0"], function (require declare var a: number; export default a; //// [es6ImportDefaultBindingAmd_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport.js index a5b7700c36c..ff8d6538b04 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport.js @@ -51,3 +51,4 @@ export declare var m: number; declare const _default: {}; export default _default; //// [es6ImportDefaultBindingFollowedWithNamedImport_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1.js index 54a4d434606..31194c308ba 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1.js @@ -41,3 +41,4 @@ var x1 = defaultBinding6; declare var a: number; export default a; //// [es6ImportDefaultBindingFollowedWithNamedImport1_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1InEs5.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1InEs5.js index 46e52a43135..ef9ab7215bc 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1InEs5.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1InEs5.js @@ -45,3 +45,4 @@ var x = es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0_6.default; declare var a: number; export default a; //// [es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportInEs5.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportInEs5.js index 90875ff5878..3c55a05f25e 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportInEs5.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportInEs5.js @@ -47,3 +47,4 @@ export declare var a: number; export declare var x: number; export declare var m: number; //// [es6ImportDefaultBindingFollowedWithNamedImportInEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding.js index 4fbac48bd36..2c86e062635 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding.js @@ -17,3 +17,4 @@ var x = nameSpaceBinding.a; //// [es6ImportDefaultBindingFollowedWithNamespaceBinding_0.d.ts] export declare var a: number; //// [es6ImportDefaultBindingFollowedWithNamespaceBinding_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1.js index eb90b4882b0..039b4a3dce8 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1.js @@ -20,3 +20,4 @@ var x = defaultBinding; declare var a: number; export default a; //// [es6ImportDefaultBindingFollowedWithNamespaceBinding_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1InEs5.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1InEs5.js index a6217abb784..9183663850b 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1InEs5.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1InEs5.js @@ -24,3 +24,4 @@ var x = es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0_1.default; declare var a: number; export default a; //// [es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5.js index 5586054319a..9d87535274b 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5.js @@ -21,3 +21,4 @@ var x = nameSpaceBinding.a; //// [es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0.d.ts] export declare var a: number; //// [es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingInEs5.js b/tests/baselines/reference/es6ImportDefaultBindingInEs5.js index 165f58b9246..a6175197d8e 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingInEs5.js +++ b/tests/baselines/reference/es6ImportDefaultBindingInEs5.js @@ -20,3 +20,4 @@ Object.defineProperty(exports, "__esModule", { value: true }); declare var a: number; export = a; //// [es6ImportDefaultBindingInEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportNameSpaceImport.js b/tests/baselines/reference/es6ImportNameSpaceImport.js index c9013259e8e..7ab8a62bf6f 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImport.js +++ b/tests/baselines/reference/es6ImportNameSpaceImport.js @@ -23,3 +23,4 @@ var x = nameSpaceBinding.a; //// [es6ImportNameSpaceImport_0.d.ts] export declare var a: number; //// [es6ImportNameSpaceImport_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportNameSpaceImportAmd.js b/tests/baselines/reference/es6ImportNameSpaceImportAmd.js index 44a0635f7a2..17a0509f093 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImportAmd.js +++ b/tests/baselines/reference/es6ImportNameSpaceImportAmd.js @@ -26,3 +26,4 @@ define(["require", "exports", "es6ImportNameSpaceImportAmd_0"], function (requir //// [es6ImportNameSpaceImportAmd_0.d.ts] export declare var a: number; //// [es6ImportNameSpaceImportAmd_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportNameSpaceImportInEs5.js b/tests/baselines/reference/es6ImportNameSpaceImportInEs5.js index 1eced8142cb..4382d8f16b2 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImportInEs5.js +++ b/tests/baselines/reference/es6ImportNameSpaceImportInEs5.js @@ -23,3 +23,4 @@ var x = nameSpaceBinding.a; //// [es6ImportNameSpaceImportInEs5_0.d.ts] export declare var a: number; //// [es6ImportNameSpaceImportInEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportNamedImport.js b/tests/baselines/reference/es6ImportNamedImport.js index 92e56660cc7..0ce1c57403e 100644 --- a/tests/baselines/reference/es6ImportNamedImport.js +++ b/tests/baselines/reference/es6ImportNamedImport.js @@ -87,3 +87,4 @@ export declare var z1: number; export declare var z2: number; export declare var aaaa: number; //// [es6ImportNamedImport_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportNamedImportAmd.js b/tests/baselines/reference/es6ImportNamedImportAmd.js index 8f1a7cb013b..6b7a4bd5743 100644 --- a/tests/baselines/reference/es6ImportNamedImportAmd.js +++ b/tests/baselines/reference/es6ImportNamedImportAmd.js @@ -82,3 +82,4 @@ export declare var z1: number; export declare var z2: number; export declare var aaaa: number; //// [es6ImportNamedImportAmd_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportNamedImportInEs5.js b/tests/baselines/reference/es6ImportNamedImportInEs5.js index 8cedfa664a8..9226170d84b 100644 --- a/tests/baselines/reference/es6ImportNamedImportInEs5.js +++ b/tests/baselines/reference/es6ImportNamedImportInEs5.js @@ -87,3 +87,4 @@ export declare var z1: number; export declare var z2: number; export declare var aaaa: number; //// [es6ImportNamedImportInEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/exportClassExtendingIntersection.js b/tests/baselines/reference/exportClassExtendingIntersection.js index a6e1f52804c..9b99e90d511 100644 --- a/tests/baselines/reference/exportClassExtendingIntersection.js +++ b/tests/baselines/reference/exportClassExtendingIntersection.js @@ -119,3 +119,4 @@ export declare class MyExtendedClass extends MyExtendedClass_base { extendedClassProperty: number; } //// [Main.d.ts] +export {}; diff --git a/tests/baselines/reference/exportStarFromEmptyModule.js b/tests/baselines/reference/exportStarFromEmptyModule.js index 2730778930d..be7de642a6a 100644 --- a/tests/baselines/reference/exportStarFromEmptyModule.js +++ b/tests/baselines/reference/exportStarFromEmptyModule.js @@ -68,3 +68,4 @@ export declare class A { static q: any; } //// [exportStarFromEmptyModule_module4.d.ts] +export {}; diff --git a/tests/baselines/reference/moduleAugmentationGlobal4.js b/tests/baselines/reference/moduleAugmentationGlobal4.js index a47e4c6673a..dd1c589e43b 100644 --- a/tests/baselines/reference/moduleAugmentationGlobal4.js +++ b/tests/baselines/reference/moduleAugmentationGlobal4.js @@ -36,7 +36,6 @@ declare global { } } export { }; -export {}; //// [f2.d.ts] declare global { interface Something { @@ -44,7 +43,6 @@ declare global { } } export { }; -export {}; //// [f3.d.ts] import "./f1"; import "./f2"; diff --git a/tests/baselines/reference/moduleAugmentationInAmbientModule1.js b/tests/baselines/reference/moduleAugmentationInAmbientModule1.js index 7bd3c93496c..fe6aabc0a5e 100644 --- a/tests/baselines/reference/moduleAugmentationInAmbientModule1.js +++ b/tests/baselines/reference/moduleAugmentationInAmbientModule1.js @@ -36,3 +36,4 @@ x.foo().x; //// [main.d.ts] /// +export {}; diff --git a/tests/baselines/reference/multiImportExport.js b/tests/baselines/reference/multiImportExport.js index 01dc798bf1d..69276cbac9b 100644 --- a/tests/baselines/reference/multiImportExport.js +++ b/tests/baselines/reference/multiImportExport.js @@ -67,3 +67,4 @@ export = Math; //// [Drawing.d.ts] export import Math = require('./Math/Math'); //// [consumer.d.ts] +export {}; diff --git a/tests/baselines/reference/shorthand-property-es5-es6.js b/tests/baselines/reference/shorthand-property-es5-es6.js index 671ce39795c..814d9cd2efd 100644 --- a/tests/baselines/reference/shorthand-property-es5-es6.js +++ b/tests/baselines/reference/shorthand-property-es5-es6.js @@ -11,3 +11,4 @@ var bar = { foo: foo, baz: baz }; //// [test.d.ts] +export {}; diff --git a/tests/baselines/reference/shorthand-property-es6-amd.js b/tests/baselines/reference/shorthand-property-es6-amd.js index 9469357eea2..35d92784173 100644 --- a/tests/baselines/reference/shorthand-property-es6-amd.js +++ b/tests/baselines/reference/shorthand-property-es6-amd.js @@ -14,3 +14,4 @@ define(["require", "exports", "./foo"], function (require, exports, foo_1) { //// [test.d.ts] +export {}; diff --git a/tests/baselines/reference/shorthand-property-es6-es6.js b/tests/baselines/reference/shorthand-property-es6-es6.js index 42c80db10a0..4800de59b7e 100644 --- a/tests/baselines/reference/shorthand-property-es6-es6.js +++ b/tests/baselines/reference/shorthand-property-es6-es6.js @@ -11,3 +11,4 @@ const bar = { foo, baz }; //// [test.d.ts] +export {}; diff --git a/tests/baselines/reference/typeCheckObjectCreationExpressionWithUndefinedCallResolutionData.js b/tests/baselines/reference/typeCheckObjectCreationExpressionWithUndefinedCallResolutionData.js index df12050eaf6..558650a2a31 100644 --- a/tests/baselines/reference/typeCheckObjectCreationExpressionWithUndefinedCallResolutionData.js +++ b/tests/baselines/reference/typeCheckObjectCreationExpressionWithUndefinedCallResolutionData.js @@ -29,3 +29,4 @@ f.foo(); //// [file1.d.ts] export declare function foo(): any; //// [file2.d.ts] +export {}; diff --git a/tests/baselines/reference/unusedImportDeclaration.js b/tests/baselines/reference/unusedImportDeclaration.js index df84d925cd1..2bfcb7c2e5f 100644 --- a/tests/baselines/reference/unusedImportDeclaration.js +++ b/tests/baselines/reference/unusedImportDeclaration.js @@ -38,3 +38,4 @@ declare class TesterB { } export = TesterB; //// [unusedImportDeclaration_testerA.d.ts] +export {}; diff --git a/tests/baselines/reference/withImportDecl.js b/tests/baselines/reference/withImportDecl.js index 5c9d693c006..2bf5879ec9b 100644 --- a/tests/baselines/reference/withImportDecl.js +++ b/tests/baselines/reference/withImportDecl.js @@ -91,3 +91,4 @@ export declare class A { } //// [withImportDecl_1.d.ts] /// +export {}; diff --git a/tests/cases/compiler/emptyDeclarationEmitIsModule.ts b/tests/cases/compiler/emptyDeclarationEmitIsModule.ts new file mode 100644 index 00000000000..a96b6d75763 --- /dev/null +++ b/tests/cases/compiler/emptyDeclarationEmitIsModule.ts @@ -0,0 +1,9 @@ +// @declaration: true +// @filename: module.ts +import * as i from "./index"; +class Foo {} +// @filename: index.ts +import {} from "./module"; +export interface Bar { + x: string +} \ No newline at end of file From 464df8f699f35fd96e9f47e625c633de3d7be4c2 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 14:34:09 -0800 Subject: [PATCH 105/189] Fix build failure with newest `@types/mocha` (#21075) --- src/harness/parallel/worker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/harness/parallel/worker.ts b/src/harness/parallel/worker.ts index 1cfc20cbf9b..00fbcd23ebb 100644 --- a/src/harness/parallel/worker.ts +++ b/src/harness/parallel/worker.ts @@ -55,7 +55,7 @@ namespace Harness.Parallel.Worker { retries() { return this; }, slow() { return this; }, timeout(n) { - timeout = n; + timeout = n as number; return this; }, }; @@ -127,7 +127,7 @@ namespace Harness.Parallel.Worker { const fakeContext: Mocha.ITestCallbackContext = { skip() { return this; }, timeout(n) { - timeout = n; + timeout = n as number; return this; }, retries() { return this; }, From a23bbe65e60b4bf3a199fd78dc4bfa1f86829384 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 14:54:18 -0800 Subject: [PATCH 106/189] Use substring instead of substr (#20578) * Use substring instead of substr * Remove unused scanning of SyntaxKind.DotDotDotToken in jsdoc * Remove other unnecessary jsdoc syntax kinds * Move all pos++ together --- src/compiler/parser.ts | 38 +++++++++---------- src/compiler/scanner.ts | 34 +++-------------- src/compiler/types.ts | 17 +++++++++ .../reference/api/tsserverlibrary.d.ts | 3 +- tests/baselines/reference/api/typescript.d.ts | 3 +- 5 files changed, 44 insertions(+), 51 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ce2ad27329e..6503e6bf421 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6276,17 +6276,17 @@ namespace ts { indent += text.length; } - nextJSDocToken(); - while (token() === SyntaxKind.WhitespaceTrivia) { - nextJSDocToken(); + let t = nextJSDocToken(); + while (t === SyntaxKind.WhitespaceTrivia) { + t = nextJSDocToken(); } - if (token() === SyntaxKind.NewLineTrivia) { + if (t === SyntaxKind.NewLineTrivia) { state = JSDocState.BeginningOfLine; indent = 0; - nextJSDocToken(); + t = nextJSDocToken(); } - while (token() !== SyntaxKind.EndOfFileToken) { - switch (token()) { + loop: while (true) { + switch (t) { case SyntaxKind.AtToken: if (state === JSDocState.BeginningOfLine || state === JSDocState.SawAsterisk) { removeTrailingNewlines(comments); @@ -6340,7 +6340,7 @@ namespace ts { indent += whitespace.length; break; case SyntaxKind.EndOfFileToken: - break; + break loop; default: // anything other than whitespace or asterisk at the beginning of the line starts the comment text state = JSDocState.SavingComments; @@ -6348,10 +6348,11 @@ namespace ts { break; } if (advanceToken) { - nextJSDocToken(); + t = nextJSDocToken(); } else { advanceToken = true; + t = currentToken as JsDocSyntaxKind; } } removeLeadingNewlines(comments); @@ -6462,8 +6463,9 @@ namespace ts { comments.push(text); indent += text.length; } - while (token() !== SyntaxKind.AtToken && token() !== SyntaxKind.EndOfFileToken) { - switch (token()) { + let tok = token() as JsDocSyntaxKind; + loop: while (true) { + switch (tok) { case SyntaxKind.NewLineTrivia: if (state >= JSDocState.SawAsterisk) { state = JSDocState.BeginningOfLine; @@ -6472,8 +6474,9 @@ namespace ts { indent = 0; break; case SyntaxKind.AtToken: + case SyntaxKind.EndOfFileToken: // Done - break; + break loop; case SyntaxKind.WhitespaceTrivia: if (state === JSDocState.SavingComments) { pushComment(scanner.getTokenText()); @@ -6501,11 +6504,7 @@ namespace ts { pushComment(scanner.getTokenText()); break; } - if (token() === SyntaxKind.AtToken) { - // Done - break; - } - nextJSDocToken(); + tok = nextJSDocToken(); } removeLeadingNewlines(comments); @@ -6783,8 +6782,7 @@ namespace ts { let canParseTag = true; let seenAsterisk = false; while (true) { - nextJSDocToken(); - switch (token()) { + switch (nextJSDocToken()) { case SyntaxKind.AtToken: if (canParseTag) { const child = tryParseChildTag(target); @@ -6880,7 +6878,7 @@ namespace ts { return result; } - function nextJSDocToken(): SyntaxKind { + function nextJSDocToken(): JsDocSyntaxKind { return currentToken = scanner.scanJSDocToken(); } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index e4f7821897d..c8bb2ec0a25 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -35,7 +35,7 @@ namespace ts { scanJsxAttributeValue(): SyntaxKind; reScanJsxToken(): SyntaxKind; scanJsxToken(): SyntaxKind; - scanJSDocToken(): SyntaxKind; + scanJSDocToken(): JsDocSyntaxKind; scan(): SyntaxKind; getText(): string; // Sets the text for the scanner to scan. An optional subrange starting point and length @@ -1905,7 +1905,7 @@ namespace ts { break; } } - tokenValue += text.substr(firstCharPosition, pos - firstCharPosition); + tokenValue += text.substring(firstCharPosition, pos); } return token; } @@ -1924,7 +1924,7 @@ namespace ts { } } - function scanJSDocToken(): SyntaxKind { + function scanJSDocToken(): JsDocSyntaxKind { if (pos >= end) { return token = SyntaxKind.EndOfFileToken; } @@ -1933,6 +1933,7 @@ namespace ts { tokenPos = pos; const ch = text.charCodeAt(pos); + pos++; switch (ch) { case CharacterCodes.tab: case CharacterCodes.verticalTab: @@ -1943,56 +1944,31 @@ namespace ts { } return token = SyntaxKind.WhitespaceTrivia; case CharacterCodes.at: - pos++; return token = SyntaxKind.AtToken; case CharacterCodes.lineFeed: case CharacterCodes.carriageReturn: - pos++; return token = SyntaxKind.NewLineTrivia; case CharacterCodes.asterisk: - pos++; return token = SyntaxKind.AsteriskToken; case CharacterCodes.openBrace: - pos++; return token = SyntaxKind.OpenBraceToken; case CharacterCodes.closeBrace: - pos++; return token = SyntaxKind.CloseBraceToken; case CharacterCodes.openBracket: - pos++; return token = SyntaxKind.OpenBracketToken; case CharacterCodes.closeBracket: - pos++; return token = SyntaxKind.CloseBracketToken; case CharacterCodes.lessThan: - pos++; return token = SyntaxKind.LessThanToken; - case CharacterCodes.greaterThan: - pos++; - return token = SyntaxKind.GreaterThanToken; case CharacterCodes.equals: - pos++; return token = SyntaxKind.EqualsToken; case CharacterCodes.comma: - pos++; return token = SyntaxKind.CommaToken; case CharacterCodes.dot: - pos++; - if (text.substr(tokenPos, pos + 2) === "...") { - pos += 2; - return token = SyntaxKind.DotDotDotToken; - } return token = SyntaxKind.DotToken; - case CharacterCodes.exclamation: - pos++; - return token = SyntaxKind.ExclamationToken; - case CharacterCodes.question: - pos++; - return token = SyntaxKind.QuestionToken; } if (isIdentifierStart(ch, ScriptTarget.Latest)) { - pos++; while (isIdentifierPart(text.charCodeAt(pos), ScriptTarget.Latest) && pos < end) { pos++; } @@ -2000,7 +1976,7 @@ namespace ts { return token = SyntaxKind.Identifier; } else { - return pos += 1, token = SyntaxKind.Unknown; + return token = SyntaxKind.Unknown; } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6e69b46e73d..21fe9537424 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -58,6 +58,23 @@ namespace ts { end: number; } + export type JsDocSyntaxKind = + | SyntaxKind.EndOfFileToken + | SyntaxKind.WhitespaceTrivia + | SyntaxKind.AtToken + | SyntaxKind.NewLineTrivia + | SyntaxKind.AsteriskToken + | SyntaxKind.OpenBraceToken + | SyntaxKind.CloseBraceToken + | SyntaxKind.LessThanToken + | SyntaxKind.OpenBracketToken + | SyntaxKind.CloseBracketToken + | SyntaxKind.EqualsToken + | SyntaxKind.CommaToken + | SyntaxKind.DotToken + | SyntaxKind.Identifier + | SyntaxKind.Unknown; + // token > SyntaxKind.Identifer => token is a keyword // Also, If you add a new SyntaxKind be sure to keep the `Markers` section at the bottom in sync export const enum SyntaxKind { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 495e6083f4b..ab39eca1111 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -59,6 +59,7 @@ declare namespace ts { pos: number; end: number; } + type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.Unknown; enum SyntaxKind { Unknown = 0, EndOfFileToken = 1, @@ -3127,7 +3128,7 @@ declare namespace ts { scanJsxAttributeValue(): SyntaxKind; reScanJsxToken(): SyntaxKind; scanJsxToken(): SyntaxKind; - scanJSDocToken(): SyntaxKind; + scanJSDocToken(): JsDocSyntaxKind; scan(): SyntaxKind; getText(): string; setText(text: string, start?: number, length?: number): void; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 5563d95aa0c..df6f3362c74 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -59,6 +59,7 @@ declare namespace ts { pos: number; end: number; } + type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.Unknown; enum SyntaxKind { Unknown = 0, EndOfFileToken = 1, @@ -2788,7 +2789,7 @@ declare namespace ts { scanJsxAttributeValue(): SyntaxKind; reScanJsxToken(): SyntaxKind; scanJsxToken(): SyntaxKind; - scanJSDocToken(): SyntaxKind; + scanJSDocToken(): JsDocSyntaxKind; scan(): SyntaxKind; getText(): string; setText(text: string, start?: number, length?: number): void; From 00d4acaad2230270e715badb043e9a59e4288f91 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 8 Jan 2018 14:57:31 -0800 Subject: [PATCH 107/189] Port generated lib files (#21076) --- src/lib/dom.generated.d.ts | 114 +++++++++++++++++++++++++------ src/lib/webworker.generated.d.ts | 49 +++++++++++-- 2 files changed, 139 insertions(+), 24 deletions(-) diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 2a1f6dd6433..951d34377a6 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -761,7 +761,7 @@ interface ProgressEventInit extends EventInit { } interface PushSubscriptionOptionsInit { - applicationServerKey?: any; + applicationServerKey?: BufferSource | null; userVisibleOnly?: boolean; } @@ -770,7 +770,8 @@ interface RegistrationOptions { } interface RequestInit { - body?: any; + signal?: AbortSignal; + body?: Blob | BufferSource | FormData | string | null; cache?: RequestCache; credentials?: RequestCredentials; headers?: HeadersInit; @@ -1088,7 +1089,7 @@ interface RTCTransportStats extends RTCStats { } interface ScopedCredentialDescriptor { - id: any; + id: BufferSource; transports?: Transport[]; type: ScopedCredentialType; } @@ -3599,8 +3600,8 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec getAttributeNode(name: string): Attr | null; getAttributeNodeNS(namespaceURI: string, localName: string): Attr | null; getAttributeNS(namespaceURI: string, localName: string): string; - getBoundingClientRect(): ClientRect; - getClientRects(): ClientRectList; + getBoundingClientRect(): ClientRect | DOMRect; + getClientRects(): ClientRectList | DOMRectList; getElementsByTagName(name: K): NodeListOf; getElementsByTagName(name: K): NodeListOf; getElementsByTagName(name: string): NodeListOf; @@ -4898,6 +4899,7 @@ interface HTMLFormElement extends HTMLElement { */ submit(): void; reportValidity(): boolean; + reportValidity(): boolean; addEventListener(type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; @@ -7370,10 +7372,10 @@ declare var IntersectionObserver: { }; interface IntersectionObserverEntry { - readonly boundingClientRect: ClientRect; + readonly boundingClientRect: ClientRect | DOMRect; readonly intersectionRatio: number; - readonly intersectionRect: ClientRect; - readonly rootBounds: ClientRect; + readonly intersectionRect: ClientRect | DOMRect; + readonly rootBounds: ClientRect | DOMRect; readonly target: Element; readonly time: number; readonly isIntersecting: boolean; @@ -7542,7 +7544,7 @@ declare var MediaKeyMessageEvent: { interface MediaKeys { createSession(sessionType?: MediaKeySessionType): MediaKeySession; - setServerCertificate(serverCertificate: any): Promise; + setServerCertificate(serverCertificate: BufferSource): Promise; } declare var MediaKeys: { @@ -7556,10 +7558,10 @@ interface MediaKeySession extends EventTarget { readonly keyStatuses: MediaKeyStatusMap; readonly sessionId: string; close(): Promise; - generateRequest(initDataType: string, initData: any): Promise; + generateRequest(initDataType: string, initData: BufferSource): Promise; load(sessionId: string): Promise; remove(): Promise; - update(response: any): Promise; + update(response: BufferSource): Promise; } declare var MediaKeySession: { @@ -7570,8 +7572,8 @@ declare var MediaKeySession: { interface MediaKeyStatusMap { readonly size: number; forEach(callback: ForEachCallback): void; - get(keyId: any): MediaKeyStatus; - has(keyId: any): boolean; + get(keyId: BufferSource): MediaKeyStatus; + has(keyId: BufferSource): boolean; } declare var MediaKeyStatusMap: { @@ -9171,8 +9173,8 @@ interface Range { detach(): void; expand(Unit: ExpandGranularity): boolean; extractContents(): DocumentFragment; - getBoundingClientRect(): ClientRect; - getClientRects(): ClientRectList; + getBoundingClientRect(): ClientRect | DOMRect; + getClientRects(): ClientRectList | DOMRectList; insertNode(newNode: Node): void; selectNode(refNode: Node): void; selectNodeContents(refNode: Node): void; @@ -9235,6 +9237,7 @@ interface Request extends Object, Body { readonly referrerPolicy: ReferrerPolicy; readonly type: RequestType; readonly url: string; + readonly signal: AbortSignal; clone(): Request; } @@ -12309,8 +12312,8 @@ declare var WaveShaperNode: { }; interface WebAuthentication { - getAssertion(assertionChallenge: any, options?: AssertionOptions): Promise; - makeCredential(accountInformation: Account, cryptoParameters: ScopedCredentialParameters[], attestationChallenge: any, options?: ScopedCredentialOptions): Promise; + getAssertion(assertionChallenge: BufferSource, options?: AssertionOptions): Promise; + makeCredential(accountInformation: Account, cryptoParameters: ScopedCredentialParameters[], attestationChallenge: BufferSource, options?: ScopedCredentialOptions): Promise; } declare var WebAuthentication: { @@ -14665,6 +14668,23 @@ declare var HTMLSummaryElement: { new(): HTMLSummaryElement; }; +interface DOMRectReadOnly { + readonly bottom: number; + readonly height: number; + readonly left: number; + readonly right: number; + readonly top: number; + readonly width: number; + readonly x: number; + readonly y: number; +} + +declare var DOMRectReadOnly: { + prototype: DOMRectReadOnly; + new (x?: number, y?: number, width?: number, height?: number): DOMRectReadOnly; + fromRect(rectangle?: DOMRectInit): DOMRectReadOnly; +}; + interface EXT_blend_minmax { readonly MIN_EXT: number; readonly MAX_EXT: number; @@ -14683,6 +14703,25 @@ interface EXT_sRGB { readonly FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: number; } +interface DOMRect extends DOMRectReadOnly { + height: number; + width: number; + x: number; + y: number; +} + +declare var DOMRect: { + prototype: DOMRect; + new (x?: number, y?: number, width?: number, height?: number): DOMRect; + fromRect(rectangle?: DOMRectInit): DOMRect; +}; + +interface DOMRectList { + readonly length: number; + item(index: number): DOMRect | null; + [index: number]: DOMRect; +} + interface OES_vertex_array_object { readonly VERTEX_ARRAY_BINDING_OES: number; createVertexArrayOES(): WebGLVertexArrayObjectOES; @@ -14787,6 +14826,43 @@ interface WEBGL_lose_context { restoreContext(): void; } +interface AbortController { + readonly signal: AbortSignal; + abort(): void; +} + +declare var AbortController: { + prototype: AbortController; + new(): AbortController; +}; + +interface AbortSignal extends EventTarget { + readonly aborted: boolean; + onabort: (ev: Event) => any; +} + +interface EventSource extends EventTarget { + readonly url: string; + readonly withCredentials: boolean; + readonly CONNECTING: number; + readonly OPEN: number; + readonly CLOSED: number; + readonly readyState: number; + onopen: (evt: MessageEvent) => any; + onmessage: (evt: MessageEvent) => any; + onerror: (evt: MessageEvent) => any; + close(): void; +} + +declare var EventSource: { + prototype: EventSource; + new(url: string, eventSourceInitDict?: EventSourceInit): EventSource; +}; + +interface EventSourceInit { + readonly withCredentials: boolean; +} + declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; interface DecodeErrorCallback { @@ -14799,7 +14875,7 @@ interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?: Error): void; } interface ForEachCallback { - (keyId: any, status: MediaKeyStatus): void; + (keyId: BufferSource, status: MediaKeyStatus): void; } interface FrameRequestCallback { (time: number): void; @@ -15255,7 +15331,7 @@ declare function removeEventListener(type: K, li declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; type AAGUID = string; type AlgorithmIdentifier = string | Algorithm; -type BodyInit = any; +type BodyInit = Blob | BufferSource | FormData | string; type ByteString = string; type ConstrainBoolean = boolean | ConstrainBooleanParameters; type ConstrainDOMString = string | string[] | ConstrainDOMStringParameters; diff --git a/src/lib/webworker.generated.d.ts b/src/lib/webworker.generated.d.ts index 4a582d3c9c6..1b0ce074f00 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -66,12 +66,13 @@ interface ObjectURLOptions { } interface PushSubscriptionOptionsInit { - applicationServerKey?: any; + applicationServerKey?: BufferSource | null; userVisibleOnly?: boolean; } interface RequestInit { - body?: any; + signal?: AbortSignal; + body?: Blob | BufferSource | FormData | string | null; cache?: RequestCache; credentials?: RequestCredentials; headers?: HeadersInit; @@ -119,7 +120,7 @@ interface NotificationEventInit extends ExtendableEventInit { } interface PushEventInit extends ExtendableEventInit { - data?: any; + data?: BufferSource | USVString; } interface SyncEventInit extends ExtendableEventInit { @@ -960,6 +961,7 @@ interface Request extends Object, Body { readonly referrerPolicy: ReferrerPolicy; readonly type: RequestType; readonly url: string; + readonly signal: AbortSignal; clone(): Request; } @@ -1822,6 +1824,43 @@ interface AddEventListenerOptions extends EventListenerOptions { once?: boolean; } +interface AbortController { + readonly signal: AbortSignal; + abort(): void; +} + +declare var AbortController: { + prototype: AbortController; + new(): AbortController; +}; + +interface AbortSignal extends EventTarget { + readonly aborted: boolean; + onabort: (ev: Event) => any; +} + +interface EventSource extends EventTarget { + readonly url: string; + readonly withCredentials: boolean; + readonly CONNECTING: number; + readonly OPEN: number; + readonly CLOSED: number; + readonly readyState: number; + onopen: (evt: MessageEvent) => any; + onmessage: (evt: MessageEvent) => any; + onerror: (evt: MessageEvent) => any; + close(): void; +} + +declare var EventSource: { + prototype: EventSource; + new(url: string, eventSourceInitDict?: EventSourceInit): EventSource; +}; + +interface EventSourceInit { + readonly withCredentials: boolean; +} + declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; interface DecodeErrorCallback { @@ -1834,7 +1873,7 @@ interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?: Error): void; } interface ForEachCallback { - (keyId: any, status: MediaKeyStatus): void; + (keyId: BufferSource, status: MediaKeyStatus): void; } interface FunctionStringCallback { (data: string): void; @@ -1884,7 +1923,7 @@ declare function addEventListener(type: string, listener: EventListenerOrEventLi declare function removeEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void; declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; type AlgorithmIdentifier = string | Algorithm; -type BodyInit = any; +type BodyInit = Blob | BufferSource | FormData | string; type IDBKeyPath = string; type RequestInfo = Request | string; type USVString = string; From 804eb32208eea6c9198106882d1c0a956f517bb2 Mon Sep 17 00:00:00 2001 From: benbraou Date: Mon, 8 Jan 2018 23:59:37 +0100 Subject: [PATCH 108/189] feat(es2018): add definitions for Array.prototype.flatten and Array.prototype.flatMap (#20431) * bug(esnext): add definitions for flatten and flatMap Fixes #20410 * bug(esnext) add overloads for flatten --- Gulpfile.ts | 1 + Jakefile.js | 1 + src/compiler/commandLineParser.ts | 1 + src/harness/unittests/commandLineParsing.ts | 6 +- .../convertCompilerOptionsFromJson.ts | 8 +- src/lib/es2018.d.ts | 2 +- src/lib/esnext.array.d.ts | 203 ++++++++++++++++++ src/lib/esnext.d.ts | 1 + 8 files changed, 215 insertions(+), 8 deletions(-) create mode 100644 src/lib/esnext.array.d.ts diff --git a/Gulpfile.ts b/Gulpfile.ts index 510c0d87631..2909b10471a 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -151,6 +151,7 @@ const es2018LibrarySourceMap = es2018LibrarySource.map(source => const esnextLibrarySource = [ "esnext.asynciterable.d.ts", + "esnext.array.d.ts", "esnext.promise.d.ts" ]; diff --git a/Jakefile.js b/Jakefile.js index 09155261434..38a16db0bb7 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -214,6 +214,7 @@ var es2018LibrarySourceMap = es2018LibrarySource.map(function (source) { var esnextLibrarySource = [ "esnext.asynciterable.d.ts", + "esnext.array.d.ts", "esnext.promise.d.ts" ]; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 33ecf570c03..b600e351d92 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -144,6 +144,7 @@ namespace ts { "es2017.string": "lib.es2017.string.d.ts", "es2017.intl": "lib.es2017.intl.d.ts", "es2017.typedarrays": "lib.es2017.typedarrays.d.ts", + "esnext.array": "lib.esnext.array.d.ts", "esnext.asynciterable": "lib.esnext.asynciterable.d.ts", "esnext.promise": "lib.esnext.promise.d.ts", }), diff --git a/src/harness/unittests/commandLineParsing.ts b/src/harness/unittests/commandLineParsing.ts index 8cfd4ad406c..050178f63b3 100644 --- a/src/harness/unittests/commandLineParsing.ts +++ b/src/harness/unittests/commandLineParsing.ts @@ -60,7 +60,7 @@ namespace ts { assertParseResult(["--lib", "es5,invalidOption", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -263,7 +263,7 @@ namespace ts { assertParseResult(["--lib", "es5,", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -283,7 +283,7 @@ namespace ts { assertParseResult(["--lib", "es5, ", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index 42e0903c93c..0bad2ba1e3a 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -266,7 +266,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -297,7 +297,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -328,7 +328,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -359,7 +359,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable', 'esnext.promise'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] diff --git a/src/lib/es2018.d.ts b/src/lib/es2018.d.ts index 71d6e190b15..90f6d4931f4 100644 --- a/src/lib/es2018.d.ts +++ b/src/lib/es2018.d.ts @@ -1 +1 @@ -/// \ No newline at end of file +/// diff --git a/src/lib/esnext.array.d.ts b/src/lib/esnext.array.d.ts new file mode 100644 index 00000000000..ddba47badaa --- /dev/null +++ b/src/lib/esnext.array.d.ts @@ -0,0 +1,203 @@ +interface ReadonlyArray { + + /** + * Calls a defined callback function on each element of an array. Then, flattens the result into + * a new array. + * This is identical to a map followed by a flatten of depth 1. + * + * @param callback A function that accepts up to three arguments. The flatMap method calls the + * callback function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callback function. If + * thisArg is omitted, undefined is used as the this value. + */ + flatMap ( + callback: (this: This, value: T, index: number, array: T[]) => U|U[], + thisArg?: This + ): U[] + + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray | + + ReadonlyArray> | + ReadonlyArray[]> | + ReadonlyArray[][]> | + ReadonlyArray[][][]> | + + ReadonlyArray>> | + ReadonlyArray[][]>> | + ReadonlyArray>[][]> | + ReadonlyArray[]>[]> | + ReadonlyArray>[]> | + ReadonlyArray[]>> | + + ReadonlyArray>>> | + ReadonlyArray[]>>> | + ReadonlyArray>[]>> | + ReadonlyArray>>[]> | + + ReadonlyArray>>>>, + depth: 4): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray | + + ReadonlyArray[][]> | + ReadonlyArray[]> | + ReadonlyArray> | + + ReadonlyArray>> | + ReadonlyArray[]>> | + ReadonlyArray>[]> | + + ReadonlyArray>>>, + depth: 3): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray | + + ReadonlyArray> | + ReadonlyArray[]> | + + ReadonlyArray>>, + depth: 2): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray | + ReadonlyArray>, + depth?: 1 + ): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray, + depth: 0 + ): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. If no depth is provided, flatten method defaults to the depth of 1. + * + * @param depth The maximum recursion depth + */ + flatten(depth?: number): any[]; + } + +interface Array { + + /** + * Calls a defined callback function on each element of an array. Then, flattens the result into + * a new array. + * This is identical to a map followed by a flatten of depth 1. + * + * @param callback A function that accepts up to three arguments. The flatMap method calls the + * callback function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callback function. If + * thisArg is omitted, undefined is used as the this value. + */ + flatMap ( + callback: (this: This, value: T, index: number, array: T[]) => U|U[], + thisArg?: This + ): U[] + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][][][][][], depth: 7): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][][][][], depth: 6): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][][][], depth: 5): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][][], depth: 4): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][], depth: 3): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][], depth: 2): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][], depth?: 1): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[], depth: 0): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. If no depth is provided, flatten method defaults to the depth of 1. + * + * @param depth The maximum recursion depth + */ + flatten(depth?: number): any[]; +} diff --git a/src/lib/esnext.d.ts b/src/lib/esnext.d.ts index 685a10ef4d7..bbfb9535aa7 100644 --- a/src/lib/esnext.d.ts +++ b/src/lib/esnext.d.ts @@ -1,3 +1,4 @@ /// /// +/// /// From 2869657da7767ceeaf91e434a2f74b66f1bbd87b Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 8 Jan 2018 15:22:14 -0800 Subject: [PATCH 109/189] Update failing test --- .../completionsImport_default_exportDefaultIdentifier.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/fourslash/completionsImport_default_exportDefaultIdentifier.ts b/tests/cases/fourslash/completionsImport_default_exportDefaultIdentifier.ts index 042da2fee39..7549c2e001b 100644 --- a/tests/cases/fourslash/completionsImport_default_exportDefaultIdentifier.ts +++ b/tests/cases/fourslash/completionsImport_default_exportDefaultIdentifier.ts @@ -10,7 +10,7 @@ ////f/**/; goTo.marker(""); -verify.completionListContains({ name: "foo", source: "/a" }, "export default foo", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ true, { +verify.completionListContains({ name: "foo", source: "/a" }, "(alias) const foo: 0\nexport default foo", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ true, { includeExternalModuleExports: true, sourceDisplay: "./a", }); From 39dfeb017621283b5460215d62d13d2ff4f3a440 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 15:33:33 -0800 Subject: [PATCH 110/189] Add stricter parameter types for Object.values and Object.entries (#20553) * Add stricter parameter types for Object.values and Object.entries * Use mapped type and constrain 'T extends object' * Revert everything but change to parameter types --- src/lib/es2017.object.d.ts | 4 +-- .../reference/useObjectValuesAndEntries1.js | 16 +++++------ .../useObjectValuesAndEntries1.symbols | 8 +++--- .../useObjectValuesAndEntries1.types | 28 +++++++++---------- .../useObjectValuesAndEntries4.types | 8 +++--- .../es2017/useObjectValuesAndEntries1.ts | 8 +++--- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/lib/es2017.object.d.ts b/src/lib/es2017.object.d.ts index 4014e8c2927..775aaece7f6 100644 --- a/src/lib/es2017.object.d.ts +++ b/src/lib/es2017.object.d.ts @@ -9,7 +9,7 @@ interface ObjectConstructor { * Returns an array of values of the enumerable properties of an object * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. */ - values(o: any): any[]; + values(o: {}): any[]; /** * Returns an array of key/values of the enumerable properties of an object @@ -21,7 +21,7 @@ interface ObjectConstructor { * Returns an array of key/values of the enumerable properties of an object * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. */ - entries(o: any): [string, any][]; + entries(o: {}): [string, any][]; /** * Returns an object containing all own property descriptors of an object diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.js b/tests/baselines/reference/useObjectValuesAndEntries1.js index c269e4f4c8e..a10fb9a2d32 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.js +++ b/tests/baselines/reference/useObjectValuesAndEntries1.js @@ -5,10 +5,10 @@ for (var x of Object.values(o)) { let y = x; } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] -var entries1 = Object.entries(1); // <-- entries: [string, any][] -var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][] -var entries3 = Object.entries({}) // [never, any][] +var entries = Object.entries(o); +var entries1 = Object.entries(1); +var entries2 = Object.entries({a: true, b: 2}) +var entries3 = Object.entries({}) //// [useObjectValuesAndEntries1.js] @@ -17,7 +17,7 @@ for (var _i = 0, _a = Object.values(o); _i < _a.length; _i++) { var x = _a[_i]; var y = x; } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] -var entries1 = Object.entries(1); // <-- entries: [string, any][] -var entries2 = Object.entries({ a: true, b: 2 }); // ['a' | 'b', number | boolean][] -var entries3 = Object.entries({}); // [never, any][] +var entries = Object.entries(o); +var entries1 = Object.entries(1); +var entries2 = Object.entries({ a: true, b: 2 }); +var entries3 = Object.entries({}); diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.symbols b/tests/baselines/reference/useObjectValuesAndEntries1.symbols index 2c412b7a8ff..538e3f69d78 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.symbols +++ b/tests/baselines/reference/useObjectValuesAndEntries1.symbols @@ -16,20 +16,20 @@ for (var x of Object.values(o)) { >x : Symbol(x, Decl(useObjectValuesAndEntries1.ts, 2, 8)) } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] +var entries = Object.entries(o); >entries : Symbol(entries, Decl(useObjectValuesAndEntries1.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, --, --)) >entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >o : Symbol(o, Decl(useObjectValuesAndEntries1.ts, 0, 3)) -var entries1 = Object.entries(1); // <-- entries: [string, any][] +var entries1 = Object.entries(1); >entries1 : Symbol(entries1, Decl(useObjectValuesAndEntries1.ts, 7, 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, --, --)) >entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) -var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][] +var entries2 = Object.entries({a: true, b: 2}) >entries2 : Symbol(entries2, Decl(useObjectValuesAndEntries1.ts, 8, 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, --, --)) @@ -37,7 +37,7 @@ var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][ >a : Symbol(a, Decl(useObjectValuesAndEntries1.ts, 8, 31)) >b : Symbol(b, Decl(useObjectValuesAndEntries1.ts, 8, 39)) -var entries3 = Object.entries({}) // [never, any][] +var entries3 = Object.entries({}) >entries3 : Symbol(entries3, Decl(useObjectValuesAndEntries1.ts, 9, 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, --, --)) diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.types b/tests/baselines/reference/useObjectValuesAndEntries1.types index 0cb080c6477..c52d0ce872e 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.types +++ b/tests/baselines/reference/useObjectValuesAndEntries1.types @@ -10,9 +10,9 @@ var o = { a: 1, b: 2 }; for (var x of Object.values(o)) { >x : number >Object.values(o) : number[] ->Object.values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: any): any[]; } +>Object.values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: {}): any[]; } >Object : ObjectConstructor ->values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: any): any[]; } +>values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: {}): any[]; } >o : { a: number; b: number; } let y = x; @@ -20,39 +20,39 @@ for (var x of Object.values(o)) { >x : number } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] +var entries = Object.entries(o); >entries : [string, number][] >Object.entries(o) : [string, number][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >o : { a: number; b: number; } -var entries1 = Object.entries(1); // <-- entries: [string, any][] +var entries1 = Object.entries(1); >entries1 : [string, any][] >Object.entries(1) : [string, any][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >1 : 1 -var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][] +var entries2 = Object.entries({a: true, b: 2}) >entries2 : [string, number | boolean][] >Object.entries({a: true, b: 2}) : [string, number | boolean][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >{a: true, b: 2} : { a: boolean; b: number; } >a : boolean >true : true >b : number >2 : 2 -var entries3 = Object.entries({}) // [never, any][] +var entries3 = Object.entries({}) >entries3 : [string, {}][] >Object.entries({}) : [string, {}][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >{} : {} diff --git a/tests/baselines/reference/useObjectValuesAndEntries4.types b/tests/baselines/reference/useObjectValuesAndEntries4.types index 245803a24d4..33a427760a8 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries4.types +++ b/tests/baselines/reference/useObjectValuesAndEntries4.types @@ -10,9 +10,9 @@ var o = { a: 1, b: 2 }; for (var x of Object.values(o)) { >x : number >Object.values(o) : number[] ->Object.values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: any): any[]; } +>Object.values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: {}): any[]; } >Object : ObjectConstructor ->values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: any): any[]; } +>values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: {}): any[]; } >o : { a: number; b: number; } let y = x; @@ -23,8 +23,8 @@ for (var x of Object.values(o)) { var entries = Object.entries(o); >entries : [string, number][] >Object.entries(o) : [string, number][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >o : { a: number; b: number; } diff --git a/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts b/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts index 60099bb1c0f..719f10bbbcc 100644 --- a/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts +++ b/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts @@ -7,7 +7,7 @@ for (var x of Object.values(o)) { let y = x; } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] -var entries1 = Object.entries(1); // <-- entries: [string, any][] -var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][] -var entries3 = Object.entries({}) // [never, any][] +var entries = Object.entries(o); +var entries1 = Object.entries(1); +var entries2 = Object.entries({a: true, b: 2}) +var entries3 = Object.entries({}) From 859f0e3070e1496cab93ad4fad3d6081e3b11119 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 15:44:33 -0800 Subject: [PATCH 111/189] Add noDoubleSpaceRule to jakefile (#21077) --- Jakefile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Jakefile.js b/Jakefile.js index 38a16db0bb7..2026544a249 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -1204,6 +1204,7 @@ var tslintRules = [ "debugAssertRule", "nextLineRule", "noBomRule", + "noDoubleSpaceRule", "noIncrementDecrementRule", "noInOperatorRule", "noTypeAssertionWhitespaceRule", From 7e6315075d535560a9271bf17c7db66b3c04bcf6 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 8 Jan 2018 16:36:23 -0800 Subject: [PATCH 112/189] Synthesize namespace records for proper esm interop (#19675) * Integrate importStar and importDefault helpers * Accept baselines * Support dynamic imports, write helpers for umd module (and amd is possible) kinds * Accept baselines * Support AMD, use same helper initialization as is normal * update typechecker to have errors on called imported namespaces and good error recovery with a quickfix * Overhaul allowSyntheticDefaultExports to be safer * Put the new behavior behind a flag * Rename strictESM to ESMInterop * ESMInterop -> ESModuleInterop, make default for tsc --init * Rename ESMInterop -> ESModuleInterop in module.ts, add emit test (since fourslash doesnt do that) * Remove erroneous semicolons from helper * Reword diagnostic * Change style * Edit followup diagnostic * Add secondary quickfix for call sites, tests forthcoming * Add synth default to namespace import type, enhance quickfix * Pair of spare tests for good measure * Fix typos in diagnostic message * Improve comment clarity * Actually accept the updated changes to the esmodule interop description * ESModule -> esModule * Use find and not forEach * Use guard * Rely on implicit falsiness of Result.False * These should have been emit flags --- src/compiler/checker.ts | 135 ++++++++++++++++-- src/compiler/commandLineParser.ts | 10 +- src/compiler/core.ts | 4 +- src/compiler/diagnosticMessages.json | 16 +++ src/compiler/program.ts | 1 + src/compiler/transformers/module/es2015.ts | 14 +- src/compiler/transformers/module/module.ts | 82 ++++++++++- src/compiler/transformers/utilities.ts | 1 + src/compiler/types.ts | 3 + .../codefixes/fixInvalidImportSyntax.ts | 98 +++++++++++++ src/services/codefixes/fixes.ts | 2 + .../allowSyntheticDefaultImports1.js | 11 +- .../allowSyntheticDefaultImports1.symbols | 10 +- .../allowSyntheticDefaultImports1.types | 2 +- .../allowSyntheticDefaultImports2.js | 19 +-- .../allowSyntheticDefaultImports2.symbols | 10 +- .../allowSyntheticDefaultImports2.types | 2 +- .../reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + tests/baselines/reference/esModuleInterop.js | 39 +++++ .../reference/esModuleInterop.symbols | 37 +++++ .../baselines/reference/esModuleInterop.types | 38 +++++ .../reference/esModuleInteropImportCall.js | 23 +++ .../esModuleInteropImportCall.symbols | 23 +++ .../reference/esModuleInteropImportCall.types | 26 ++++ .../esModuleInteropImportNamespace.js | 24 ++++ .../esModuleInteropImportNamespace.symbols | 19 +++ .../esModuleInteropImportNamespace.types | 19 +++ .../importCallExpressionAsyncES3System.types | 30 ++-- .../importCallExpressionAsyncES5System.types | 30 ++-- .../importCallExpressionAsyncES6System.types | 30 ++-- .../importCallExpressionES5System.types | 34 ++--- .../importCallExpressionES6System.types | 34 ++--- .../importCallExpressionInSystem1.types | 26 ++-- .../importCallExpressionInSystem2.types | 2 +- .../importCallExpressionInSystem3.types | 6 +- .../importCallExpressionInSystem4.types | 60 ++++---- ...eticDefaultExportsWithDynamicImports.types | 8 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../compiler/allowSyntheticDefaultImports1.ts | 2 +- .../compiler/allowSyntheticDefaultImports2.ts | 2 +- tests/cases/compiler/esModuleInterop.ts | 17 +++ .../compiler/esModuleInteropImportCall.ts | 11 ++ .../esModuleInteropImportNamespace.ts | 9 ++ .../fourslash/codeFixCalledES2015Import1.ts | 18 +++ .../fourslash/codeFixCalledES2015Import10.ts | 18 +++ .../fourslash/codeFixCalledES2015Import11.ts | 18 +++ .../fourslash/codeFixCalledES2015Import12.ts | 18 +++ .../fourslash/codeFixCalledES2015Import13.ts | 18 +++ .../fourslash/codeFixCalledES2015Import2.ts | 18 +++ .../fourslash/codeFixCalledES2015Import3.ts | 19 +++ .../fourslash/codeFixCalledES2015Import4.ts | 17 +++ .../fourslash/codeFixCalledES2015Import5.ts | 17 +++ .../fourslash/codeFixCalledES2015Import6.ts | 18 +++ .../fourslash/codeFixCalledES2015Import7.ts | 17 +++ .../fourslash/codeFixCalledES2015Import8.ts | 17 +++ .../fourslash/codeFixCalledES2015Import9.ts | 18 +++ .../findAllRefsImportStarOfExportEquals.ts | 5 +- 65 files changed, 1019 insertions(+), 212 deletions(-) create mode 100644 src/services/codefixes/fixInvalidImportSyntax.ts create mode 100644 tests/baselines/reference/esModuleInterop.js create mode 100644 tests/baselines/reference/esModuleInterop.symbols create mode 100644 tests/baselines/reference/esModuleInterop.types create mode 100644 tests/baselines/reference/esModuleInteropImportCall.js create mode 100644 tests/baselines/reference/esModuleInteropImportCall.symbols create mode 100644 tests/baselines/reference/esModuleInteropImportCall.types create mode 100644 tests/baselines/reference/esModuleInteropImportNamespace.js create mode 100644 tests/baselines/reference/esModuleInteropImportNamespace.symbols create mode 100644 tests/baselines/reference/esModuleInteropImportNamespace.types create mode 100644 tests/cases/compiler/esModuleInterop.ts create mode 100644 tests/cases/compiler/esModuleInteropImportCall.ts create mode 100644 tests/cases/compiler/esModuleInteropImportNamespace.ts create mode 100644 tests/cases/fourslash/codeFixCalledES2015Import1.ts create mode 100644 tests/cases/fourslash/codeFixCalledES2015Import10.ts create mode 100644 tests/cases/fourslash/codeFixCalledES2015Import11.ts create mode 100644 tests/cases/fourslash/codeFixCalledES2015Import12.ts create mode 100644 tests/cases/fourslash/codeFixCalledES2015Import13.ts create mode 100644 tests/cases/fourslash/codeFixCalledES2015Import2.ts create mode 100644 tests/cases/fourslash/codeFixCalledES2015Import3.ts create mode 100644 tests/cases/fourslash/codeFixCalledES2015Import4.ts create mode 100644 tests/cases/fourslash/codeFixCalledES2015Import5.ts create mode 100644 tests/cases/fourslash/codeFixCalledES2015Import6.ts create mode 100644 tests/cases/fourslash/codeFixCalledES2015Import7.ts create mode 100644 tests/cases/fourslash/codeFixCalledES2015Import8.ts create mode 100644 tests/cases/fourslash/codeFixCalledES2015Import9.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1eb2d1c25df..c66afe73d91 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1471,6 +1471,43 @@ namespace ts { return getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, dontResolveAlias); } + function resolveExportByName(moduleSymbol: Symbol, name: __String, dontResolveAlias: boolean) { + const exportValue = moduleSymbol.exports.get(InternalSymbolName.ExportEquals); + return exportValue + ? getPropertyOfType(getTypeOfSymbol(exportValue), name) + : resolveSymbol(moduleSymbol.exports.get(name), dontResolveAlias); + } + + function canHaveSyntheticDefault(file: SourceFile | undefined, moduleSymbol: Symbol, dontResolveAlias: boolean) { + if (!allowSyntheticDefaultImports) { + return false; + } + // Declaration files (and ambient modules) + if (!file || file.isDeclarationFile) { + // Definitely cannot have a synthetic default if they have a default member specified + if (resolveExportByName(moduleSymbol, InternalSymbolName.Default, dontResolveAlias)) { + return false; + } + // It _might_ still be incorrect to assume there is no __esModule marker on the import at runtime, even if there is no `default` member + // So we check a bit more, + if (resolveExportByName(moduleSymbol, escapeLeadingUnderscores("__esModule"), dontResolveAlias)) { + // If there is an `__esModule` specified in the declaration (meaning someone explicitly added it or wrote it in their code), + // it definitely is a module and does not have a synthetic default + return false; + } + // There are _many_ declaration files not written with esmodules in mind that still get compiled into a format with __esModule set + // Meaning there may be no default at runtime - however to be on the permissive side, we allow access to a synthetic default member + // as there is no marker to indicate if the accompanying JS has `__esModule` or not, or is even native esm + return true; + } + // TypeScript files never have a synthetic default (as they are always emitted with an __esModule marker) _unless_ they contain an export= statement + if (!isSourceFileJavaScript(file)) { + return hasExportAssignmentSymbol(moduleSymbol); + } + // JS files have a synthetic default if they do not contain ES2015+ module syntax (export = is not valid in js) _and_ do not have an __esModule marker + return !file.externalModuleIndicator && !resolveExportByName(moduleSymbol, escapeLeadingUnderscores("__esModule"), dontResolveAlias); + } + function getTargetOfImportClause(node: ImportClause, dontResolveAlias: boolean): Symbol { const moduleSymbol = resolveExternalModuleName(node, (node.parent).moduleSpecifier); @@ -1480,16 +1517,16 @@ namespace ts { exportDefaultSymbol = moduleSymbol; } else { - const exportValue = moduleSymbol.exports.get("export=" as __String); - exportDefaultSymbol = exportValue - ? getPropertyOfType(getTypeOfSymbol(exportValue), InternalSymbolName.Default) - : resolveSymbol(moduleSymbol.exports.get(InternalSymbolName.Default), dontResolveAlias); + exportDefaultSymbol = resolveExportByName(moduleSymbol, InternalSymbolName.Default, dontResolveAlias); } - if (!exportDefaultSymbol && !allowSyntheticDefaultImports) { + const file = find(moduleSymbol.declarations, isSourceFile); + const hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias); + if (!exportDefaultSymbol && !hasSyntheticDefault) { error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol)); } - else if (!exportDefaultSymbol && allowSyntheticDefaultImports) { + else if (!exportDefaultSymbol && hasSyntheticDefault) { + // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present return resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); } return exportDefaultSymbol; @@ -1889,8 +1926,40 @@ namespace ts { // combine other declarations with the module or variable (e.g. a class/module, function/module, interface/variable). function resolveESModuleSymbol(moduleSymbol: Symbol, moduleReferenceExpression: Expression, dontResolveAlias: boolean): Symbol { const symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias); - if (!dontResolveAlias && symbol && !(symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable))) { - error(moduleReferenceExpression, Diagnostics.Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct, symbolToString(moduleSymbol)); + if (!dontResolveAlias && symbol) { + if (!(symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable))) { + error(moduleReferenceExpression, Diagnostics.Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct, symbolToString(moduleSymbol)); + return symbol; + } + if (compilerOptions.esModuleInterop) { + const referenceParent = moduleReferenceExpression.parent; + if ( + (isImportDeclaration(referenceParent) && getNamespaceDeclarationNode(referenceParent)) || + isImportCall(referenceParent) + ) { + const type = getTypeOfSymbol(symbol); + let sigs = getSignaturesOfStructuredType(type, SignatureKind.Call); + if (!sigs || !sigs.length) { + sigs = getSignaturesOfStructuredType(type, SignatureKind.Construct); + } + if (sigs && sigs.length) { + const moduleType = getTypeWithSyntheticDefaultImportType(type, symbol, moduleSymbol); + // Create a new symbol which has the module's type less the call and construct signatures + const result = createSymbol(symbol.flags, symbol.escapedName); + result.declarations = symbol.declarations ? symbol.declarations.slice() : []; + result.parent = symbol.parent; + result.target = symbol; + result.originatingImport = referenceParent; + if (symbol.valueDeclaration) result.valueDeclaration = symbol.valueDeclaration; + if (symbol.constEnumOnlyModule) result.constEnumOnlyModule = true; + if (symbol.members) result.members = cloneMap(symbol.members); + if (symbol.exports) result.exports = cloneMap(symbol.exports); + const resolvedModuleType = resolveStructuredTypeMembers(moduleType as StructuredType); // Should already be resolved from the signature checks above + result.type = createAnonymousType(result, resolvedModuleType.members, emptyArray, emptyArray, resolvedModuleType.stringIndexInfo, resolvedModuleType.numberIndexInfo); + return result; + } + } + } } return symbol; } @@ -9452,6 +9521,17 @@ namespace ts { diagnostics.add(createDiagnosticForNodeFromMessageChain(errorNode, errorInfo)); } + // Check if we should issue an extra diagnostic to produce a quickfix for a slightly incorrect import statement + if (headMessage && errorNode && !result && source.symbol) { + const links = getSymbolLinks(source.symbol); + if (links.originatingImport && !isImportCall(links.originatingImport)) { + const helpfulRetry = checkTypeRelatedTo(getTypeOfSymbol(links.target), target, relation, /*errorNode*/ undefined); + if (helpfulRetry) { + // Likely an incorrect import. Issue a helpful diagnostic to produce a quickfix to change the import + diagnostics.add(createDiagnosticForNode(links.originatingImport, Diagnostics.A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime)); + } + } + } return result !== Ternary.False; function reportError(message: DiagnosticMessage, arg0?: string, arg1?: string, arg2?: string): void { @@ -17320,7 +17400,7 @@ namespace ts { error(node, Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType)); } else { - error(node, Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType)); + invocationError(node, apparentType, SignatureKind.Call); } return resolveErrorCall(node); } @@ -17410,7 +17490,7 @@ namespace ts { return signature; } - error(node, Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature); + invocationError(node, expressionType, SignatureKind.Construct); return resolveErrorCall(node); } @@ -17457,6 +17537,28 @@ namespace ts { return true; } + function invocationError(node: Node, apparentType: Type, kind: SignatureKind) { + error(node, kind === SignatureKind.Call + ? Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures + : Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature + , typeToString(apparentType)); + invocationErrorRecovery(apparentType, kind); + } + + function invocationErrorRecovery(apparentType: Type, kind: SignatureKind) { + if (!apparentType.symbol) { + return; + } + const importNode = getSymbolLinks(apparentType.symbol).originatingImport; + // Create a diagnostic on the originating import if possible onto which we can attach a quickfix + // An import call expression cannot be rewritten into another form to correct the error - the only solution is to use `.default` at the use-site + if (importNode && !isImportCall(importNode)) { + const sigs = getSignaturesOfType(getTypeOfSymbol(getSymbolLinks(apparentType.symbol).target), kind); + if (!sigs || !sigs.length) return; + error(importNode, Diagnostics.A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime); + } + } + function resolveTaggedTemplateExpression(node: TaggedTemplateExpression, candidatesOutArray: Signature[]): Signature { const tagType = checkExpression(node.tag); const apparentType = getApparentType(tagType); @@ -17474,7 +17576,7 @@ namespace ts { } if (!callSignatures.length) { - error(node, Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType)); + invocationError(node, apparentType, SignatureKind.Call); return resolveErrorCall(node); } @@ -17531,6 +17633,7 @@ namespace ts { errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType)); errorInfo = chainDiagnosticMessages(errorInfo, headMessage); diagnostics.add(createDiagnosticForNodeFromMessageChain(node, errorInfo)); + invocationErrorRecovery(apparentType, SignatureKind.Call); return resolveErrorCall(node); } @@ -17785,17 +17888,19 @@ namespace ts { if (moduleSymbol) { const esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true); if (esModuleSymbol) { - return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol)); + return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol)); } } return createPromiseReturnType(node, anyType); } - function getTypeWithSyntheticDefaultImportType(type: Type, symbol: Symbol): Type { + function getTypeWithSyntheticDefaultImportType(type: Type, symbol: Symbol, originalSymbol: Symbol): Type { if (allowSyntheticDefaultImports && type && type !== unknownType) { const synthType = type as SyntheticDefaultModuleType; if (!synthType.syntheticType) { - if (!getPropertyOfType(type, InternalSymbolName.Default)) { + const file = find(originalSymbol.declarations, isSourceFile); + const hasSyntheticDefault = canHaveSyntheticDefault(file, originalSymbol, /*dontResolveAlias*/ false); + if (hasSyntheticDefault) { const memberTable = createSymbolTable(); const newSymbol = createSymbol(SymbolFlags.Alias, InternalSymbolName.Default); newSymbol.target = resolveSymbol(symbol); @@ -17803,7 +17908,7 @@ namespace ts { const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type); const defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); anonymousSymbol.type = defaultContainingObject; - synthType.syntheticType = getIntersectionType([type, defaultContainingObject]); + synthType.syntheticType = (type.flags & TypeFlags.StructuredType && type.symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable)) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*propegatedFlags*/ 0) : defaultContainingObject; } else { synthType.syntheticType = type; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index b600e351d92..4813d4b4300 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -402,6 +402,13 @@ namespace ts { category: Diagnostics.Module_Resolution_Options, description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking }, + { + name: "esModuleInterop", + type: "boolean", + showInSimplifiedHelpView: true, + category: Diagnostics.Module_Resolution_Options, + description: Diagnostics.Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports + }, { name: "preserveSymlinks", type: "boolean", @@ -704,7 +711,8 @@ namespace ts { export const defaultInitCompilerOptions: CompilerOptions = { module: ModuleKind.CommonJS, target: ScriptTarget.ES5, - strict: true + strict: true, + esModuleInterop: true }; let optionNameMapCache: OptionNameMap; diff --git a/src/compiler/core.ts b/src/compiler/core.ts index d9218ecc01b..2e8106e44ba 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2005,7 +2005,9 @@ namespace ts { const moduleKind = getEmitModuleKind(compilerOptions); return compilerOptions.allowSyntheticDefaultImports !== undefined ? compilerOptions.allowSyntheticDefaultImports - : moduleKind === ModuleKind.System; + : compilerOptions.esModuleInterop + ? moduleKind !== ModuleKind.None && moduleKind < ModuleKind.ES2015 + : moduleKind === ModuleKind.System; } export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictPropertyInitialization" | "alwaysStrict"; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 95fd11fef01..d4641184f45 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3548,6 +3548,14 @@ "category": "Error", "code": 7036 }, + "Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'.": { + "category": "Message", + "code": 7037 + }, + "A namespace-style import cannot be called or constructed, and will cause a failure at runtime.": { + "category": "Error", + "code": 7038 + }, "You cannot rename this element.": { "category": "Error", @@ -3906,5 +3914,13 @@ "Install '{0}'": { "category": "Message", "code": 95014 + }, + "Replace import with '{0}'.": { + "category": "Message", + "code": 95015 + }, + "Use synthetic 'default' member.": { + "category": "Message", + "code": 95016 } } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 959dee19e03..88a2f5ee8f1 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1601,6 +1601,7 @@ namespace ts { // synthesize 'import "tslib"' declaration const externalHelpersModuleReference = createLiteral(externalHelpersModuleNameText); const importDecl = createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined); + addEmitFlags(importDecl, EmitFlags.NeverApplyImportHelper); externalHelpersModuleReference.parent = importDecl; importDecl.parent = file; imports = [externalHelpersModuleReference]; diff --git a/src/compiler/transformers/module/es2015.ts b/src/compiler/transformers/module/es2015.ts index 3951d08109d..4f218e4fdcf 100644 --- a/src/compiler/transformers/module/es2015.ts +++ b/src/compiler/transformers/module/es2015.ts @@ -25,14 +25,14 @@ namespace ts { if (externalHelpersModuleName) { const statements: Statement[] = []; const statementOffset = addPrologue(statements, node.statements); - append(statements, - createImportDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, - createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)), - createLiteral(externalHelpersModuleNameText) - ) + const tslibImport = createImportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)), + createLiteral(externalHelpersModuleNameText) ); + addEmitFlags(tslibImport, EmitFlags.NeverApplyImportHelper); + append(statements, tslibImport); addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset)); return updateSourceFileNode( diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 0c8e2cda0f5..0d4e5b6864a 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -148,7 +148,7 @@ namespace ts { // Create an updated SourceFile: // // define(moduleName?, ["module1", "module2"], function ... - return updateSourceFileNode(node, + const updated = updateSourceFileNode(node, setTextRange( createNodeArray([ createStatement( @@ -192,6 +192,9 @@ namespace ts { /*location*/ node.statements ) ); + + addEmitHelpers(updated, context.readEmitHelpers()); + return updated; } /** @@ -296,7 +299,7 @@ namespace ts { // } // })(function ...) - return updateSourceFileNode( + const updated = updateSourceFileNode( node, setTextRange( createNodeArray([ @@ -328,6 +331,9 @@ namespace ts { /*location*/ node.statements ) ); + + addEmitHelpers(updated, context.readEmitHelpers()); + return updated; } /** @@ -385,6 +391,18 @@ namespace ts { return { aliasedModuleNames, unaliasedModuleNames, importAliasNames }; } + function getAMDImportExpressionForImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration) { + if (isImportEqualsDeclaration(node) || isExportDeclaration(node) || !getExternalModuleNameLiteral(node, currentSourceFile, host, resolver, compilerOptions)) { + return undefined; + } + const name = getLocalNameForExternalImport(node, currentSourceFile); + const expr = getHelperExpressionForImport(node, name); + if (expr === name) { + return undefined; + } + return createStatement(createAssignment(name, expr)); + } + /** * Transforms a SourceFile into an AMD or UMD module body. * @@ -402,6 +420,9 @@ namespace ts { // Visit each statement of the module body. append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement)); + if (moduleKind === ModuleKind.AMD) { + addRange(statements, mapDefined(currentModuleInfo.externalImports, getAMDImportExpressionForImport)); + } addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset)); // Append the 'export =' statement if provided. @@ -617,7 +638,12 @@ namespace ts { } } - return createNew(createIdentifier("Promise"), /*typeArguments*/ undefined, [func]); + const promise = createNew(createIdentifier("Promise"), /*typeArguments*/ undefined, [func]); + if (compilerOptions.esModuleInterop) { + context.requestEmitHelper(importStarHelper); + return createCall(createPropertyAccess(promise, createIdentifier("then")), /*typeArguments*/ undefined, [getHelperName("__importStar")]); + } + return promise; } function createImportCallExpressionCommonJS(arg: Expression | undefined, containsLexicalThis: boolean): Expression { @@ -627,7 +653,11 @@ namespace ts { // We have to wrap require in then callback so that require is done in asynchronously // if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately const promiseResolveCall = createCall(createPropertyAccess(createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []); - const requireCall = createCall(createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []); + let requireCall = createCall(createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []); + if (compilerOptions.esModuleInterop) { + context.requestEmitHelper(importStarHelper); + requireCall = createCall(getHelperName("__importStar"), /*typeArguments*/ undefined, [requireCall]); + } let func: FunctionExpression | ArrowFunction; if (languageVersion >= ScriptTarget.ES2015) { @@ -660,6 +690,22 @@ namespace ts { return createCall(createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]); } + + function getHelperExpressionForImport(node: ImportDeclaration, innerExpr: Expression) { + if (!compilerOptions.esModuleInterop || getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) { + return innerExpr; + } + if (getNamespaceDeclarationNode(node)) { + context.requestEmitHelper(importStarHelper); + return createCall(getHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]); + } + if (isDefaultImport(node)) { + context.requestEmitHelper(importDefaultHelper); + return createCall(getHelperName("__importDefault"), /*typeArguments*/ undefined, [innerExpr]); + } + return innerExpr; + } + /** * Visits an ImportDeclaration node. * @@ -681,7 +727,7 @@ namespace ts { createVariableDeclaration( getSynthesizedClone(namespaceDeclaration.name), /*type*/ undefined, - createRequireCall(node) + getHelperExpressionForImport(node, createRequireCall(node)) ) ); } @@ -694,7 +740,7 @@ namespace ts { createVariableDeclaration( getGeneratedNameForNode(node), /*type*/ undefined, - createRequireCall(node) + getHelperExpressionForImport(node, createRequireCall(node)) ) ); @@ -1671,4 +1717,28 @@ namespace ts { text: ` var __syncRequire = typeof module === "object" && typeof module.exports === "object";` }; + + // emit helper for `import * as Name from "foo"` + const importStarHelper: EmitHelper = { + name: "typescript:commonjsimportstar", + scoped: false, + text: ` +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}` + }; + + // emit helper for `import Name from "foo"` + const importDefaultHelper: EmitHelper = { + name: "typescript:commonjsimportdefault", + scoped: false, + text: ` +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}` + }; } diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index a012c9be7db..15e91d755ca 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -143,6 +143,7 @@ namespace ts { createLiteral(externalHelpersModuleNameText)); if (externalHelpersImportDeclaration) { + addEmitFlags(externalHelpersImportDeclaration, EmitFlags.NeverApplyImportHelper); externalImports.unshift(externalHelpersImportDeclaration); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 21fe9537424..623efe08fe8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3248,6 +3248,7 @@ namespace ts { bindingElement?: BindingElement; // Binding element associated with property symbol exportsSomeValue?: boolean; // True if module exports some value (not just types) 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 } @@ -3978,6 +3979,7 @@ namespace ts { typeRoots?: string[]; /*@internal*/ version?: boolean; /*@internal*/ watch?: boolean; + esModuleInterop?: boolean; [option: string]: CompilerOptionsValue | JsonSourceFile | undefined; } @@ -4545,6 +4547,7 @@ namespace ts { Iterator = 1 << 23, // The expression to a `yield*` should be treated as an Iterator when down-leveling, not an Iterable. NoAsciiEscaping = 1 << 24, // When synthesizing nodes that lack an original node or textSourceNode, we want to write the text on the node with ASCII escaping substitutions. /*@internal*/ TypeScriptClassWrapper = 1 << 25, // The node is an IIFE class wrapper created by the ts transform. + /*@internal*/ NeverApplyImportHelper = 1 << 26, // Indicates the node should never be wrapped with an import star helper (because, for example, it imports tslib itself) } export interface EmitHelper { diff --git a/src/services/codefixes/fixInvalidImportSyntax.ts b/src/services/codefixes/fixInvalidImportSyntax.ts new file mode 100644 index 00000000000..f98f1eaea7c --- /dev/null +++ b/src/services/codefixes/fixInvalidImportSyntax.ts @@ -0,0 +1,98 @@ +/* @internal */ +namespace ts.codefix { + registerCodeFix({ + errorCodes: [Diagnostics.A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime.code], + getCodeActions: getActionsForInvalidImport + }); + + function getActionsForInvalidImport(context: CodeFixContext): CodeAction[] | undefined { + const sourceFile = context.sourceFile; + + // This is the whole import statement, eg: + // import * as Bluebird from 'bluebird'; + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + const node = getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false).parent as ImportDeclaration; + if (!isImportDeclaration(node)) { + // No import quick fix for import calls + return []; + } + return getCodeFixesForImportDeclaration(context, node); + } + + function getCodeFixesForImportDeclaration(context: CodeFixContext, node: ImportDeclaration) { + const sourceFile = getSourceFileOfNode(node); + const namespace = getNamespaceDeclarationNode(node) as NamespaceImport; + const opts = context.program.getCompilerOptions(); + const variations: CodeAction[] = []; + + // import Bluebird from "bluebird"; + const replacement = createImportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createImportClause(namespace.name, /*namedBindings*/ undefined), + node.moduleSpecifier + ); + const changeTracker = textChanges.ChangeTracker.fromContext(context); + changeTracker.replaceNode(sourceFile, node, replacement, { useNonAdjustedEndPosition: true }); + const changes = changeTracker.getChanges(); + variations.push({ + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Replace_import_with_0), [changes[0].textChanges[0].newText]), + changes + }); + + if (getEmitModuleKind(opts) === ModuleKind.CommonJS) { + // import Bluebird = require("bluebird"); + const replacement = createImportEqualsDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + namespace.name, + createExternalModuleReference(node.moduleSpecifier) + ); + const changeTracker = textChanges.ChangeTracker.fromContext(context); + changeTracker.replaceNode(sourceFile, node, replacement, { useNonAdjustedEndPosition: true }); + const changes = changeTracker.getChanges(); + variations.push({ + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Replace_import_with_0), [changes[0].textChanges[0].newText]), + changes + }); + } + + return variations; + } + + registerCodeFix({ + errorCodes: [ + Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures.code, + Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature.code, + ], + getCodeActions: getActionsForUsageOfInvalidImport + }); + + function getActionsForUsageOfInvalidImport(context: CodeFixContext): CodeAction[] | undefined { + const sourceFile = context.sourceFile; + const targetKind = Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures.code === context.errorCode ? SyntaxKind.CallExpression : SyntaxKind.NewExpression; + const node = findAncestor(getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false), a => a.kind === targetKind && a.getStart() === context.span.start && a.getEnd() === (context.span.start + context.span.length)) as CallExpression | NewExpression; + if (!node) { + return []; + } + const expr = node.expression; + const type = context.program.getTypeChecker().getTypeAtLocation(expr); + if (!(type.symbol && (type.symbol as TransientSymbol).originatingImport)) { + return []; + } + const fixes: CodeAction[] = []; + const relatedImport = (type.symbol as TransientSymbol).originatingImport; + if (!isImportCall(relatedImport)) { + addRange(fixes, getCodeFixesForImportDeclaration(context, relatedImport)); + } + const propertyAccess = createPropertyAccess(expr, "default"); + const changeTracker = textChanges.ChangeTracker.fromContext(context); + changeTracker.replaceNode(sourceFile, expr, propertyAccess, {}); + const changes = changeTracker.getChanges(); + fixes.push({ + description: getLocaleSpecificMessage(Diagnostics.Use_synthetic_default_member), + changes + }); + return fixes; + } +} diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts index 5b1ee8ec857..bdbd8311a76 100644 --- a/src/services/codefixes/fixes.ts +++ b/src/services/codefixes/fixes.ts @@ -15,3 +15,5 @@ /// /// /// +/// + diff --git a/tests/baselines/reference/allowSyntheticDefaultImports1.js b/tests/baselines/reference/allowSyntheticDefaultImports1.js index fee1d137706..8c5565a1fb7 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports1.js +++ b/tests/baselines/reference/allowSyntheticDefaultImports1.js @@ -4,21 +4,12 @@ import Namespace from "./b"; export var x = new Namespace.Foo(); -//// [b.ts] +//// [b.d.ts] export class Foo { member: string; } -//// [b.js] -"use strict"; -exports.__esModule = true; -var Foo = /** @class */ (function () { - function Foo() { - } - return Foo; -}()); -exports.Foo = Foo; //// [a.js] "use strict"; exports.__esModule = true; diff --git a/tests/baselines/reference/allowSyntheticDefaultImports1.symbols b/tests/baselines/reference/allowSyntheticDefaultImports1.symbols index ecbe9e4c205..5ee2812ab59 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports1.symbols +++ b/tests/baselines/reference/allowSyntheticDefaultImports1.symbols @@ -4,15 +4,15 @@ import Namespace from "./b"; export var x = new Namespace.Foo(); >x : Symbol(x, Decl(a.ts, 1, 10)) ->Namespace.Foo : Symbol(Namespace.Foo, Decl(b.ts, 0, 0)) +>Namespace.Foo : Symbol(Namespace.Foo, Decl(b.d.ts, 0, 0)) >Namespace : Symbol(Namespace, Decl(a.ts, 0, 6)) ->Foo : Symbol(Namespace.Foo, Decl(b.ts, 0, 0)) +>Foo : Symbol(Namespace.Foo, Decl(b.d.ts, 0, 0)) -=== tests/cases/compiler/b.ts === +=== tests/cases/compiler/b.d.ts === export class Foo { ->Foo : Symbol(Foo, Decl(b.ts, 0, 0)) +>Foo : Symbol(Foo, Decl(b.d.ts, 0, 0)) member: string; ->member : Symbol(Foo.member, Decl(b.ts, 0, 18)) +>member : Symbol(Foo.member, Decl(b.d.ts, 0, 18)) } diff --git a/tests/baselines/reference/allowSyntheticDefaultImports1.types b/tests/baselines/reference/allowSyntheticDefaultImports1.types index c2265d7611b..c8092331a47 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports1.types +++ b/tests/baselines/reference/allowSyntheticDefaultImports1.types @@ -9,7 +9,7 @@ export var x = new Namespace.Foo(); >Namespace : typeof Namespace >Foo : typeof Namespace.Foo -=== tests/cases/compiler/b.ts === +=== tests/cases/compiler/b.d.ts === export class Foo { >Foo : Foo diff --git a/tests/baselines/reference/allowSyntheticDefaultImports2.js b/tests/baselines/reference/allowSyntheticDefaultImports2.js index 5dc8472d58b..c1e43a4fc81 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports2.js +++ b/tests/baselines/reference/allowSyntheticDefaultImports2.js @@ -4,28 +4,11 @@ import Namespace from "./b"; export var x = new Namespace.Foo(); -//// [b.ts] +//// [b.d.ts] export class Foo { member: string; } -//// [b.js] -System.register([], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var Foo; - return { - setters: [], - execute: function () { - Foo = /** @class */ (function () { - function Foo() { - } - return Foo; - }()); - exports_1("Foo", Foo); - } - }; -}); //// [a.js] System.register(["./b"], function (exports_1, context_1) { "use strict"; diff --git a/tests/baselines/reference/allowSyntheticDefaultImports2.symbols b/tests/baselines/reference/allowSyntheticDefaultImports2.symbols index 615b1095c66..a2b33c94d82 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports2.symbols +++ b/tests/baselines/reference/allowSyntheticDefaultImports2.symbols @@ -4,14 +4,14 @@ import Namespace from "./b"; export var x = new Namespace.Foo(); >x : Symbol(x, Decl(a.ts, 1, 10)) ->Namespace.Foo : Symbol(Namespace.Foo, Decl(b.ts, 0, 0)) +>Namespace.Foo : Symbol(Namespace.Foo, Decl(b.d.ts, 0, 0)) >Namespace : Symbol(Namespace, Decl(a.ts, 0, 6)) ->Foo : Symbol(Namespace.Foo, Decl(b.ts, 0, 0)) +>Foo : Symbol(Namespace.Foo, Decl(b.d.ts, 0, 0)) -=== tests/cases/compiler/b.ts === +=== tests/cases/compiler/b.d.ts === export class Foo { ->Foo : Symbol(Foo, Decl(b.ts, 0, 0)) +>Foo : Symbol(Foo, Decl(b.d.ts, 0, 0)) member: string; ->member : Symbol(Foo.member, Decl(b.ts, 0, 18)) +>member : Symbol(Foo.member, Decl(b.d.ts, 0, 18)) } diff --git a/tests/baselines/reference/allowSyntheticDefaultImports2.types b/tests/baselines/reference/allowSyntheticDefaultImports2.types index c40fbc7e988..420c19b7c1d 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports2.types +++ b/tests/baselines/reference/allowSyntheticDefaultImports2.types @@ -9,7 +9,7 @@ export var x = new Namespace.Foo(); >Namespace : typeof Namespace >Foo : typeof Namespace.Foo -=== tests/cases/compiler/b.ts === +=== tests/cases/compiler/b.d.ts === export class Foo { >Foo : Foo diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index ab39eca1111..116bedfabb7 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2296,6 +2296,7 @@ declare namespace ts { types?: string[]; /** Paths used to compute primary types search locations */ typeRoots?: string[]; + esModuleInterop?: boolean; [option: string]: CompilerOptionsValue | JsonSourceFile | undefined; } interface TypeAcquisition { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index df6f3362c74..8a01bc3a896 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2296,6 +2296,7 @@ declare namespace ts { types?: string[]; /** Paths used to compute primary types search locations */ typeRoots?: string[]; + esModuleInterop?: boolean; [option: string]: CompilerOptionsValue | JsonSourceFile | undefined; } interface TypeAcquisition { diff --git a/tests/baselines/reference/esModuleInterop.js b/tests/baselines/reference/esModuleInterop.js new file mode 100644 index 00000000000..9a04ab01be6 --- /dev/null +++ b/tests/baselines/reference/esModuleInterop.js @@ -0,0 +1,39 @@ +//// [tests/cases/compiler/esModuleInterop.ts] //// + +//// [index.d.ts] +export function sayHello(): string; +//// [path.d.ts] +declare const anything: any; +export = anything; +//// [fs.d.ts] +declare const anything: any; +export = anything; +//// [mjts.ts] +import { sayHello } from "./hybrid"; +import path from "./path"; +import * as fs from "./fs"; + +path; +sayHello(); +fs; + + +//// [mjts.js] +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +} +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +} +exports.__esModule = true; +var hybrid_1 = require("./hybrid"); +var path_1 = __importDefault(require("./path")); +var fs = __importStar(require("./fs")); +path_1["default"]; +hybrid_1.sayHello(); +fs; diff --git a/tests/baselines/reference/esModuleInterop.symbols b/tests/baselines/reference/esModuleInterop.symbols new file mode 100644 index 00000000000..8e173220d43 --- /dev/null +++ b/tests/baselines/reference/esModuleInterop.symbols @@ -0,0 +1,37 @@ +=== tests/cases/compiler/hybrid/index.d.ts === +export function sayHello(): string; +>sayHello : Symbol(sayHello, Decl(index.d.ts, 0, 0)) + +=== tests/cases/compiler/path.d.ts === +declare const anything: any; +>anything : Symbol(anything, Decl(path.d.ts, 0, 13)) + +export = anything; +>anything : Symbol(anything, Decl(path.d.ts, 0, 13)) + +=== tests/cases/compiler/fs.d.ts === +declare const anything: any; +>anything : Symbol(anything, Decl(fs.d.ts, 0, 13)) + +export = anything; +>anything : Symbol(anything, Decl(fs.d.ts, 0, 13)) + +=== tests/cases/compiler/mjts.ts === +import { sayHello } from "./hybrid"; +>sayHello : Symbol(sayHello, Decl(mjts.ts, 0, 8)) + +import path from "./path"; +>path : Symbol(path, Decl(mjts.ts, 1, 6)) + +import * as fs from "./fs"; +>fs : Symbol(fs, Decl(mjts.ts, 2, 6)) + +path; +>path : Symbol(path, Decl(mjts.ts, 1, 6)) + +sayHello(); +>sayHello : Symbol(sayHello, Decl(mjts.ts, 0, 8)) + +fs; +>fs : Symbol(fs, Decl(mjts.ts, 2, 6)) + diff --git a/tests/baselines/reference/esModuleInterop.types b/tests/baselines/reference/esModuleInterop.types new file mode 100644 index 00000000000..98e39f596a8 --- /dev/null +++ b/tests/baselines/reference/esModuleInterop.types @@ -0,0 +1,38 @@ +=== tests/cases/compiler/hybrid/index.d.ts === +export function sayHello(): string; +>sayHello : () => string + +=== tests/cases/compiler/path.d.ts === +declare const anything: any; +>anything : any + +export = anything; +>anything : any + +=== tests/cases/compiler/fs.d.ts === +declare const anything: any; +>anything : any + +export = anything; +>anything : any + +=== tests/cases/compiler/mjts.ts === +import { sayHello } from "./hybrid"; +>sayHello : () => string + +import path from "./path"; +>path : any + +import * as fs from "./fs"; +>fs : any + +path; +>path : any + +sayHello(); +>sayHello() : string +>sayHello : () => string + +fs; +>fs : any + diff --git a/tests/baselines/reference/esModuleInteropImportCall.js b/tests/baselines/reference/esModuleInteropImportCall.js new file mode 100644 index 00000000000..2aa681ded7f --- /dev/null +++ b/tests/baselines/reference/esModuleInteropImportCall.js @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/esModuleInteropImportCall.ts] //// + +//// [foo.d.ts] +declare function foo(): void; +declare namespace foo {} +export = foo; + +//// [index.ts] +import("./foo").then(f => { + f.default; +}); + +//// [index.js] +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +} +Promise.resolve().then(function () { return __importStar(require("./foo")); }).then(function (f) { + f["default"]; +}); diff --git a/tests/baselines/reference/esModuleInteropImportCall.symbols b/tests/baselines/reference/esModuleInteropImportCall.symbols new file mode 100644 index 00000000000..58c5e066f86 --- /dev/null +++ b/tests/baselines/reference/esModuleInteropImportCall.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/foo.d.ts === +declare function foo(): void; +>foo : Symbol(foo, Decl(foo.d.ts, 0, 0), Decl(foo.d.ts, 0, 29)) + +declare namespace foo {} +>foo : Symbol(foo, Decl(foo.d.ts, 0, 0), Decl(foo.d.ts, 0, 29)) + +export = foo; +>foo : Symbol(foo, Decl(foo.d.ts, 0, 0), Decl(foo.d.ts, 0, 29)) + +=== tests/cases/compiler/index.ts === +import("./foo").then(f => { +>import("./foo").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>"./foo" : Symbol("tests/cases/compiler/foo", Decl(foo.d.ts, 0, 0)) +>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>f : Symbol(f, Decl(index.ts, 0, 21)) + + f.default; +>f.default : Symbol(default) +>f : Symbol(f, Decl(index.ts, 0, 21)) +>default : Symbol(default) + +}); diff --git a/tests/baselines/reference/esModuleInteropImportCall.types b/tests/baselines/reference/esModuleInteropImportCall.types new file mode 100644 index 00000000000..c194af96c53 --- /dev/null +++ b/tests/baselines/reference/esModuleInteropImportCall.types @@ -0,0 +1,26 @@ +=== tests/cases/compiler/foo.d.ts === +declare function foo(): void; +>foo : () => void + +declare namespace foo {} +>foo : () => void + +export = foo; +>foo : () => void + +=== tests/cases/compiler/index.ts === +import("./foo").then(f => { +>import("./foo").then(f => { f.default;}) : Promise +>import("./foo").then : void; }, TResult2 = never>(onfulfilled?: (value: { default: () => void; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>import("./foo") : Promise<{ default: () => void; }> +>"./foo" : "./foo" +>then : void; }, TResult2 = never>(onfulfilled?: (value: { default: () => void; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>f => { f.default;} : (f: { default: () => void; }) => void +>f : { default: () => void; } + + f.default; +>f.default : () => void +>f : { default: () => void; } +>default : () => void + +}); diff --git a/tests/baselines/reference/esModuleInteropImportNamespace.js b/tests/baselines/reference/esModuleInteropImportNamespace.js new file mode 100644 index 00000000000..605976faaaa --- /dev/null +++ b/tests/baselines/reference/esModuleInteropImportNamespace.js @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/esModuleInteropImportNamespace.ts] //// + +//// [foo.d.ts] +declare function foo(): void; +declare namespace foo {} +export = foo; + +//// [index.ts] +import * as foo from "./foo"; +foo.default; + + +//// [index.js] +"use strict"; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +} +exports.__esModule = true; +var foo = __importStar(require("./foo")); +foo["default"]; diff --git a/tests/baselines/reference/esModuleInteropImportNamespace.symbols b/tests/baselines/reference/esModuleInteropImportNamespace.symbols new file mode 100644 index 00000000000..d381d553568 --- /dev/null +++ b/tests/baselines/reference/esModuleInteropImportNamespace.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/foo.d.ts === +declare function foo(): void; +>foo : Symbol(foo, Decl(foo.d.ts, 0, 0), Decl(foo.d.ts, 0, 29)) + +declare namespace foo {} +>foo : Symbol(foo, Decl(foo.d.ts, 0, 0), Decl(foo.d.ts, 0, 29)) + +export = foo; +>foo : Symbol(foo, Decl(foo.d.ts, 0, 0), Decl(foo.d.ts, 0, 29)) + +=== tests/cases/compiler/index.ts === +import * as foo from "./foo"; +>foo : Symbol(foo, Decl(index.ts, 0, 6)) + +foo.default; +>foo.default : Symbol(default) +>foo : Symbol(foo, Decl(index.ts, 0, 6)) +>default : Symbol(default) + diff --git a/tests/baselines/reference/esModuleInteropImportNamespace.types b/tests/baselines/reference/esModuleInteropImportNamespace.types new file mode 100644 index 00000000000..e0a49db2794 --- /dev/null +++ b/tests/baselines/reference/esModuleInteropImportNamespace.types @@ -0,0 +1,19 @@ +=== tests/cases/compiler/foo.d.ts === +declare function foo(): void; +>foo : () => void + +declare namespace foo {} +>foo : () => void + +export = foo; +>foo : () => void + +=== tests/cases/compiler/index.ts === +import * as foo from "./foo"; +>foo : { default: () => void; } + +foo.default; +>foo.default : () => void +>foo : { default: () => void; } +>default : () => void + diff --git a/tests/baselines/reference/importCallExpressionAsyncES3System.types b/tests/baselines/reference/importCallExpressionAsyncES3System.types index 90c981c01ca..4f6a2bb31be 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES3System.types +++ b/tests/baselines/reference/importCallExpressionAsyncES3System.types @@ -3,9 +3,9 @@ export async function fn() { >fn : () => Promise const req = await import('./test') // ONE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } @@ -16,9 +16,9 @@ export class cl1 { >m : () => Promise const req = await import('./test') // TWO ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -32,9 +32,9 @@ export const obj = { >async () => { const req = await import('./test') // THREE } : () => Promise const req = await import('./test') // THREE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -51,9 +51,9 @@ export class cl2 { >async () => { const req = await import('./test') // FOUR } : () => Promise const req = await import('./test') // FOUR ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -64,9 +64,9 @@ export const l = async () => { >async () => { const req = await import('./test') // FIVE} : () => Promise const req = await import('./test') // FIVE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } diff --git a/tests/baselines/reference/importCallExpressionAsyncES5System.types b/tests/baselines/reference/importCallExpressionAsyncES5System.types index 90c981c01ca..4f6a2bb31be 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES5System.types +++ b/tests/baselines/reference/importCallExpressionAsyncES5System.types @@ -3,9 +3,9 @@ export async function fn() { >fn : () => Promise const req = await import('./test') // ONE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } @@ -16,9 +16,9 @@ export class cl1 { >m : () => Promise const req = await import('./test') // TWO ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -32,9 +32,9 @@ export const obj = { >async () => { const req = await import('./test') // THREE } : () => Promise const req = await import('./test') // THREE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -51,9 +51,9 @@ export class cl2 { >async () => { const req = await import('./test') // FOUR } : () => Promise const req = await import('./test') // FOUR ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -64,9 +64,9 @@ export const l = async () => { >async () => { const req = await import('./test') // FIVE} : () => Promise const req = await import('./test') // FIVE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } diff --git a/tests/baselines/reference/importCallExpressionAsyncES6System.types b/tests/baselines/reference/importCallExpressionAsyncES6System.types index 90c981c01ca..4f6a2bb31be 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES6System.types +++ b/tests/baselines/reference/importCallExpressionAsyncES6System.types @@ -3,9 +3,9 @@ export async function fn() { >fn : () => Promise const req = await import('./test') // ONE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } @@ -16,9 +16,9 @@ export class cl1 { >m : () => Promise const req = await import('./test') // TWO ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -32,9 +32,9 @@ export const obj = { >async () => { const req = await import('./test') // THREE } : () => Promise const req = await import('./test') // THREE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -51,9 +51,9 @@ export class cl2 { >async () => { const req = await import('./test') // FOUR } : () => Promise const req = await import('./test') // FOUR ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -64,9 +64,9 @@ export const l = async () => { >async () => { const req = await import('./test') // FIVE} : () => Promise const req = await import('./test') // FIVE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } diff --git a/tests/baselines/reference/importCallExpressionES5System.types b/tests/baselines/reference/importCallExpressionES5System.types index 02bd64142d4..e97f722b14f 100644 --- a/tests/baselines/reference/importCallExpressionES5System.types +++ b/tests/baselines/reference/importCallExpressionES5System.types @@ -5,41 +5,41 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); ->import("./0") : Promise +>import("./0") : Promise >"./0" : "./0" var p1 = import("./0"); ->p1 : Promise ->import("./0") : Promise +>p1 : Promise +>import("./0") : Promise >"./0" : "./0" p1.then(zero => { >p1.then(zero => { return zero.foo();}) : Promise ->p1.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->p1 : Promise ->then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->zero => { return zero.foo();} : (zero: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => string ->zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>p1.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>p1 : Promise +>then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>zero => { return zero.foo();} : (zero: typeof "tests/cases/conformance/dynamicImport/0") => string +>zero : typeof "tests/cases/conformance/dynamicImport/0" return zero.foo(); >zero.foo() : string >zero.foo : () => string ->zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>zero : typeof "tests/cases/conformance/dynamicImport/0" >foo : () => string }); export var p2 = import("./0"); ->p2 : Promise ->import("./0") : Promise +>p2 : Promise +>import("./0") : Promise >"./0" : "./0" function foo() { >foo : () => void const p2 = import("./0"); ->p2 : Promise ->import("./0") : Promise +>p2 : Promise +>import("./0") : Promise >"./0" : "./0" } @@ -50,8 +50,8 @@ class C { >method : () => void const loadAsync = import ("./0"); ->loadAsync : Promise ->import ("./0") : Promise +>loadAsync : Promise +>import ("./0") : Promise >"./0" : "./0" } } @@ -63,8 +63,8 @@ export class D { >method : () => void const loadAsync = import ("./0"); ->loadAsync : Promise ->import ("./0") : Promise +>loadAsync : Promise +>import ("./0") : Promise >"./0" : "./0" } } diff --git a/tests/baselines/reference/importCallExpressionES6System.types b/tests/baselines/reference/importCallExpressionES6System.types index 02bd64142d4..e97f722b14f 100644 --- a/tests/baselines/reference/importCallExpressionES6System.types +++ b/tests/baselines/reference/importCallExpressionES6System.types @@ -5,41 +5,41 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); ->import("./0") : Promise +>import("./0") : Promise >"./0" : "./0" var p1 = import("./0"); ->p1 : Promise ->import("./0") : Promise +>p1 : Promise +>import("./0") : Promise >"./0" : "./0" p1.then(zero => { >p1.then(zero => { return zero.foo();}) : Promise ->p1.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->p1 : Promise ->then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->zero => { return zero.foo();} : (zero: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => string ->zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>p1.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>p1 : Promise +>then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>zero => { return zero.foo();} : (zero: typeof "tests/cases/conformance/dynamicImport/0") => string +>zero : typeof "tests/cases/conformance/dynamicImport/0" return zero.foo(); >zero.foo() : string >zero.foo : () => string ->zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>zero : typeof "tests/cases/conformance/dynamicImport/0" >foo : () => string }); export var p2 = import("./0"); ->p2 : Promise ->import("./0") : Promise +>p2 : Promise +>import("./0") : Promise >"./0" : "./0" function foo() { >foo : () => void const p2 = import("./0"); ->p2 : Promise ->import("./0") : Promise +>p2 : Promise +>import("./0") : Promise >"./0" : "./0" } @@ -50,8 +50,8 @@ class C { >method : () => void const loadAsync = import ("./0"); ->loadAsync : Promise ->import ("./0") : Promise +>loadAsync : Promise +>import ("./0") : Promise >"./0" : "./0" } } @@ -63,8 +63,8 @@ export class D { >method : () => void const loadAsync = import ("./0"); ->loadAsync : Promise ->import ("./0") : Promise +>loadAsync : Promise +>import ("./0") : Promise >"./0" : "./0" } } diff --git a/tests/baselines/reference/importCallExpressionInSystem1.types b/tests/baselines/reference/importCallExpressionInSystem1.types index a82d8176753..661d27d1469 100644 --- a/tests/baselines/reference/importCallExpressionInSystem1.types +++ b/tests/baselines/reference/importCallExpressionInSystem1.types @@ -5,40 +5,40 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); ->import("./0") : Promise +>import("./0") : Promise >"./0" : "./0" var p1 = import("./0"); ->p1 : Promise ->import("./0") : Promise +>p1 : Promise +>import("./0") : Promise >"./0" : "./0" p1.then(zero => { >p1.then(zero => { return zero.foo();}) : Promise ->p1.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->p1 : Promise ->then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->zero => { return zero.foo();} : (zero: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => string ->zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>p1.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>p1 : Promise +>then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>zero => { return zero.foo();} : (zero: typeof "tests/cases/conformance/dynamicImport/0") => string +>zero : typeof "tests/cases/conformance/dynamicImport/0" return zero.foo(); >zero.foo() : string >zero.foo : () => string ->zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>zero : typeof "tests/cases/conformance/dynamicImport/0" >foo : () => string }); export var p2 = import("./0"); ->p2 : Promise ->import("./0") : Promise +>p2 : Promise +>import("./0") : Promise >"./0" : "./0" function foo() { >foo : () => void const p2 = import("./0"); ->p2 : Promise ->import("./0") : Promise +>p2 : Promise +>import("./0") : Promise >"./0" : "./0" } diff --git a/tests/baselines/reference/importCallExpressionInSystem2.types b/tests/baselines/reference/importCallExpressionInSystem2.types index 160da81b214..44b17eb51fd 100644 --- a/tests/baselines/reference/importCallExpressionInSystem2.types +++ b/tests/baselines/reference/importCallExpressionInSystem2.types @@ -41,6 +41,6 @@ function foo(x: Promise) { foo(import("./0")); >foo(import("./0")) : void >foo : (x: Promise) => void ->import("./0") : Promise +>import("./0") : Promise >"./0" : "./0" diff --git a/tests/baselines/reference/importCallExpressionInSystem3.types b/tests/baselines/reference/importCallExpressionInSystem3.types index 08bf03fb506..e517be6e722 100644 --- a/tests/baselines/reference/importCallExpressionInSystem3.types +++ b/tests/baselines/reference/importCallExpressionInSystem3.types @@ -14,9 +14,9 @@ async function foo() { class C extends (await import("./0")).B {} >C : C >(await import("./0")).B : B ->(await import("./0")) : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } ->await import("./0") : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } ->import("./0") : Promise +>(await import("./0")) : typeof "tests/cases/conformance/dynamicImport/0" +>await import("./0") : typeof "tests/cases/conformance/dynamicImport/0" +>import("./0") : Promise >"./0" : "./0" >B : typeof B diff --git a/tests/baselines/reference/importCallExpressionInSystem4.types b/tests/baselines/reference/importCallExpressionInSystem4.types index c9f2b2e5211..156247851c9 100644 --- a/tests/baselines/reference/importCallExpressionInSystem4.types +++ b/tests/baselines/reference/importCallExpressionInSystem4.types @@ -24,27 +24,27 @@ class C { >C : C private myModule = import("./0"); ->myModule : Promise ->import("./0") : Promise +>myModule : Promise +>import("./0") : Promise >"./0" : "./0" method() { >method : () => void const loadAsync = import("./0"); ->loadAsync : Promise ->import("./0") : Promise +>loadAsync : Promise +>import("./0") : Promise >"./0" : "./0" this.myModule.then(Zero => { >this.myModule.then(Zero => { console.log(Zero.foo()); }, async err => { console.log(err); let one = await import("./1"); console.log(one.backup()); }) : Promise ->this.myModule.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->this.myModule : Promise +>this.myModule.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>this.myModule : Promise >this : this ->myModule : Promise ->then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->Zero => { console.log(Zero.foo()); } : (Zero: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => void ->Zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>myModule : Promise +>then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>Zero => { console.log(Zero.foo()); } : (Zero: typeof "tests/cases/conformance/dynamicImport/0") => void +>Zero : typeof "tests/cases/conformance/dynamicImport/0" console.log(Zero.foo()); >console.log(Zero.foo()) : any @@ -53,7 +53,7 @@ class C { >log : any >Zero.foo() : string >Zero.foo : () => string ->Zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>Zero : typeof "tests/cases/conformance/dynamicImport/0" >foo : () => string }, async err => { @@ -68,9 +68,9 @@ class C { >err : any let one = await import("./1"); ->one : typeof "tests/cases/conformance/dynamicImport/1" & { default: typeof "tests/cases/conformance/dynamicImport/1"; } ->await import("./1") : typeof "tests/cases/conformance/dynamicImport/1" & { default: typeof "tests/cases/conformance/dynamicImport/1"; } ->import("./1") : Promise +>one : typeof "tests/cases/conformance/dynamicImport/1" +>await import("./1") : typeof "tests/cases/conformance/dynamicImport/1" +>import("./1") : Promise >"./1" : "./1" console.log(one.backup()); @@ -80,7 +80,7 @@ class C { >log : any >one.backup() : string >one.backup : () => string ->one : typeof "tests/cases/conformance/dynamicImport/1" & { default: typeof "tests/cases/conformance/dynamicImport/1"; } +>one : typeof "tests/cases/conformance/dynamicImport/1" >backup : () => string }); @@ -91,27 +91,27 @@ export class D { >D : D private myModule = import("./0"); ->myModule : Promise ->import("./0") : Promise +>myModule : Promise +>import("./0") : Promise >"./0" : "./0" method() { >method : () => void const loadAsync = import("./0"); ->loadAsync : Promise ->import("./0") : Promise +>loadAsync : Promise +>import("./0") : Promise >"./0" : "./0" this.myModule.then(Zero => { >this.myModule.then(Zero => { console.log(Zero.foo()); }, async err => { console.log(err); let one = await import("./1"); console.log(one.backup()); }) : Promise ->this.myModule.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->this.myModule : Promise +>this.myModule.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>this.myModule : Promise >this : this ->myModule : Promise ->then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->Zero => { console.log(Zero.foo()); } : (Zero: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => void ->Zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>myModule : Promise +>then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>Zero => { console.log(Zero.foo()); } : (Zero: typeof "tests/cases/conformance/dynamicImport/0") => void +>Zero : typeof "tests/cases/conformance/dynamicImport/0" console.log(Zero.foo()); >console.log(Zero.foo()) : any @@ -120,7 +120,7 @@ export class D { >log : any >Zero.foo() : string >Zero.foo : () => string ->Zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>Zero : typeof "tests/cases/conformance/dynamicImport/0" >foo : () => string }, async err => { @@ -135,9 +135,9 @@ export class D { >err : any let one = await import("./1"); ->one : typeof "tests/cases/conformance/dynamicImport/1" & { default: typeof "tests/cases/conformance/dynamicImport/1"; } ->await import("./1") : typeof "tests/cases/conformance/dynamicImport/1" & { default: typeof "tests/cases/conformance/dynamicImport/1"; } ->import("./1") : Promise +>one : typeof "tests/cases/conformance/dynamicImport/1" +>await import("./1") : typeof "tests/cases/conformance/dynamicImport/1" +>import("./1") : Promise >"./1" : "./1" console.log(one.backup()); @@ -147,7 +147,7 @@ export class D { >log : any >one.backup() : string >one.backup : () => string ->one : typeof "tests/cases/conformance/dynamicImport/1" & { default: typeof "tests/cases/conformance/dynamicImport/1"; } +>one : typeof "tests/cases/conformance/dynamicImport/1" >backup : () => string }); diff --git a/tests/baselines/reference/syntheticDefaultExportsWithDynamicImports.types b/tests/baselines/reference/syntheticDefaultExportsWithDynamicImports.types index 1c38ecc466c..3f1ef83a0ae 100644 --- a/tests/baselines/reference/syntheticDefaultExportsWithDynamicImports.types +++ b/tests/baselines/reference/syntheticDefaultExportsWithDynamicImports.types @@ -9,11 +9,11 @@ export = packageExport; === tests/cases/compiler/index.ts === import("package").then(({default: foo}) => foo(42)); >import("package").then(({default: foo}) => foo(42)) : Promise ->import("package").then : string) & { default: (x: number) => string; }, TResult2 = never>(onfulfilled?: (value: ((x: number) => string) & { default: (x: number) => string; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->import("package") : Promise<((x: number) => string) & { default: (x: number) => string; }> +>import("package").then : string; }, TResult2 = never>(onfulfilled?: (value: { default: (x: number) => string; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>import("package") : Promise<{ default: (x: number) => string; }> >"package" : "package" ->then : string) & { default: (x: number) => string; }, TResult2 = never>(onfulfilled?: (value: ((x: number) => string) & { default: (x: number) => string; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->({default: foo}) => foo(42) : ({ default: foo }: ((x: number) => string) & { default: (x: number) => string; }) => string +>then : string; }, TResult2 = never>(onfulfilled?: (value: { default: (x: number) => string; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>({default: foo}) => foo(42) : ({ default: foo }: { default: (x: number) => string; }) => string >default : any >foo : (x: number) => string >foo(42) : string diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index d66c75aaf4e..26cf24cc2e4 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -19,7 +19,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index 003ee7ff684..5d7960c8254 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -28,7 +28,7 @@ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ /* Additional Checks */ - "noUnusedLocals": true /* Report errors on unused locals. */ + "noUnusedLocals": true, /* Report errors on unused locals. */ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index c04ad57e297..353cb68ea95 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -19,7 +19,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 05524339c28..4a28e6f2491 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -19,7 +19,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index 1681d720285..46ae199430d 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -19,7 +19,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index d66c75aaf4e..26cf24cc2e4 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -19,7 +19,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index 11a8651947a..069305e2d35 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -19,7 +19,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index ed01f3e6abd..9e1c409f56e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -39,8 +39,9 @@ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ - "types": ["jquery","mocha"] /* Type declaration files to be included in compilation. */ + "types": ["jquery","mocha"], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/cases/compiler/allowSyntheticDefaultImports1.ts b/tests/cases/compiler/allowSyntheticDefaultImports1.ts index 4793da79136..a2aadfa0b6e 100644 --- a/tests/cases/compiler/allowSyntheticDefaultImports1.ts +++ b/tests/cases/compiler/allowSyntheticDefaultImports1.ts @@ -4,7 +4,7 @@ import Namespace from "./b"; export var x = new Namespace.Foo(); -// @Filename: b.ts +// @Filename: b.d.ts export class Foo { member: string; } diff --git a/tests/cases/compiler/allowSyntheticDefaultImports2.ts b/tests/cases/compiler/allowSyntheticDefaultImports2.ts index 8fa004be387..efdee90e817 100644 --- a/tests/cases/compiler/allowSyntheticDefaultImports2.ts +++ b/tests/cases/compiler/allowSyntheticDefaultImports2.ts @@ -3,7 +3,7 @@ import Namespace from "./b"; export var x = new Namespace.Foo(); -// @Filename: b.ts +// @Filename: b.d.ts export class Foo { member: string; } \ No newline at end of file diff --git a/tests/cases/compiler/esModuleInterop.ts b/tests/cases/compiler/esModuleInterop.ts new file mode 100644 index 00000000000..7dfd8ff8611 --- /dev/null +++ b/tests/cases/compiler/esModuleInterop.ts @@ -0,0 +1,17 @@ +// @esModuleInterop: true +// @filename: hybrid/index.d.ts +export function sayHello(): string; +// @filename: path.d.ts +declare const anything: any; +export = anything; +// @filename: fs.d.ts +declare const anything: any; +export = anything; +// @filename: mjts.ts +import { sayHello } from "./hybrid"; +import path from "./path"; +import * as fs from "./fs"; + +path; +sayHello(); +fs; diff --git a/tests/cases/compiler/esModuleInteropImportCall.ts b/tests/cases/compiler/esModuleInteropImportCall.ts new file mode 100644 index 00000000000..759d4f3f936 --- /dev/null +++ b/tests/cases/compiler/esModuleInteropImportCall.ts @@ -0,0 +1,11 @@ +// @esModuleInterop: true +// @lib: es6 +// @Filename: foo.d.ts +declare function foo(): void; +declare namespace foo {} +export = foo; + +// @Filename: index.ts +import("./foo").then(f => { + f.default; +}); \ No newline at end of file diff --git a/tests/cases/compiler/esModuleInteropImportNamespace.ts b/tests/cases/compiler/esModuleInteropImportNamespace.ts new file mode 100644 index 00000000000..0b3c92577ef --- /dev/null +++ b/tests/cases/compiler/esModuleInteropImportNamespace.ts @@ -0,0 +1,9 @@ +// @esModuleInterop: true +// @Filename: foo.d.ts +declare function foo(): void; +declare namespace foo {} +export = foo; + +// @Filename: index.ts +import * as foo from "./foo"; +foo.default; diff --git a/tests/cases/fourslash/codeFixCalledES2015Import1.ts b/tests/cases/fourslash/codeFixCalledES2015Import1.ts new file mode 100644 index 00000000000..45e88c19047 --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import1.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////function invoke(f: () => void) { f(); } +////invoke(foo); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo = require("./foo");'.`, + newRangeContent: `import foo = require("./foo");`, + index: 1, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import10.ts b/tests/cases/fourslash/codeFixCalledES2015Import10.ts new file mode 100644 index 00000000000..d82e345c56c --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import10.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////import * as foo from "./foo"; +////[|foo()|]; + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo = require("./foo");'.`, + newFileContent: `import foo = require("./foo"); +foo();`, + index: 1, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import11.ts b/tests/cases/fourslash/codeFixCalledES2015Import11.ts new file mode 100644 index 00000000000..14b02fa38bc --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import11.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////import * as foo from "./foo"; +////[|foo()|]; + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newFileContent: `import foo from "./foo"; +foo();`, + index: 0, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import12.ts b/tests/cases/fourslash/codeFixCalledES2015Import12.ts new file mode 100644 index 00000000000..6c31531d572 --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import12.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////import * as foo from "./foo"; +////[|foo()|]; + +goTo.file(1); +verify.codeFix({ + description: `Use synthetic 'default' member.`, + newFileContent: `import * as foo from "./foo"; +foo.default();`, + index: 4, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import13.ts b/tests/cases/fourslash/codeFixCalledES2015Import13.ts new file mode 100644 index 00000000000..a67371bd46a --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import13.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////import * as Foo from "./foo"; +////[|new Foo()|]; + +goTo.file(1); +verify.codeFix({ + description: `Use synthetic 'default' member.`, + newFileContent: `import * as Foo from "./foo"; +new Foo.default();`, + index: 2, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import2.ts b/tests/cases/fourslash/codeFixCalledES2015Import2.ts new file mode 100644 index 00000000000..80040cb4192 --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import2.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////function invoke(f: () => void) { f(); } +////invoke(foo); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newRangeContent: `import foo from "./foo";`, + index: 0, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import3.ts b/tests/cases/fourslash/codeFixCalledES2015Import3.ts new file mode 100644 index 00000000000..82f08fbc22f --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import3.ts @@ -0,0 +1,19 @@ +/// +// @esModuleInterop: true +// @module: amd +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////function invoke(f: () => void) { f(); } +////invoke(foo); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newRangeContent: `import foo from "./foo";`, + index: 0, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import4.ts b/tests/cases/fourslash/codeFixCalledES2015Import4.ts new file mode 100644 index 00000000000..ba6d90d6d41 --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import4.ts @@ -0,0 +1,17 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////foo(); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo = require("./foo");'.`, + newRangeContent: `import foo = require("./foo");`, + index: 1, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import5.ts b/tests/cases/fourslash/codeFixCalledES2015Import5.ts new file mode 100644 index 00000000000..63b2137b6ef --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import5.ts @@ -0,0 +1,17 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////foo(); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newRangeContent: `import foo from "./foo";`, + index: 0, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import6.ts b/tests/cases/fourslash/codeFixCalledES2015Import6.ts new file mode 100644 index 00000000000..b741831bce9 --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import6.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @module: amd +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////foo(); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newRangeContent: `import foo from "./foo";`, + index: 0, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import7.ts b/tests/cases/fourslash/codeFixCalledES2015Import7.ts new file mode 100644 index 00000000000..070a25254cb --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import7.ts @@ -0,0 +1,17 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare class foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////new foo(); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo = require("./foo");'.`, + newRangeContent: `import foo = require("./foo");`, + index: 1, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import8.ts b/tests/cases/fourslash/codeFixCalledES2015Import8.ts new file mode 100644 index 00000000000..41e547c8abb --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import8.ts @@ -0,0 +1,17 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare class foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////new foo(); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newRangeContent: `import foo from "./foo";`, + index: 0, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import9.ts b/tests/cases/fourslash/codeFixCalledES2015Import9.ts new file mode 100644 index 00000000000..1ce110f056a --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import9.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @module: amd +// @Filename: foo.d.ts +////declare class foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////new foo(); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newRangeContent: `import foo from "./foo";`, + index: 0, +}); diff --git a/tests/cases/fourslash/findAllRefsImportStarOfExportEquals.ts b/tests/cases/fourslash/findAllRefsImportStarOfExportEquals.ts index c1d3bd8c7f5..033532a18ad 100644 --- a/tests/cases/fourslash/findAllRefsImportStarOfExportEquals.ts +++ b/tests/cases/fourslash/findAllRefsImportStarOfExportEquals.ts @@ -1,5 +1,6 @@ /// +// @allowSyntheticDefaultimports: true // @Filename: /node_modules/a/index.d.ts ////declare function [|{| "isWriteAccess": true, "isDefinition": true |}a|](): void; ////declare namespace [|{| "isWriteAccess": true, "isDefinition": true |}a|] { @@ -9,13 +10,13 @@ // Import with different name and we find local refs // @Filename: /b.ts -////import * as [|{| "isWriteAccess": true, "isDefinition": true |}b|] from "a"; +////import [|{| "isWriteAccess": true, "isDefinition": true |}b|] from "a"; ////[|b|](); ////[|b|].x; // Import with same name and we find all refs // @Filename: /c.ts -////import * as [|{| "isWriteAccess": true, "isDefinition": true |}a|] from "a"; +////import [|{| "isWriteAccess": true, "isDefinition": true |}a|] from "a"; ////[|a|](); ////[|a|].x; From 37d4f6a69d25743b85541b8eb1221da4c670f2a2 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 16:44:58 -0800 Subject: [PATCH 113/189] Mark references to dynamically-named properties as used (#21010) * Mark references to dynamically-named properties as used * Avoid showing the symbol ID * Use symbolToString instead of showSymbol --- src/compiler/checker.ts | 6 ++- ..._writeOnlyProperty_dynamicNames.errors.txt | 17 ++++++++ ...edLocals_writeOnlyProperty_dynamicNames.js | 25 ++++++++++++ ...als_writeOnlyProperty_dynamicNames.symbols | 31 +++++++++++++++ ...ocals_writeOnlyProperty_dynamicNames.types | 39 +++++++++++++++++++ ...edLocals_writeOnlyProperty_dynamicNames.ts | 13 +++++++ 6 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.errors.txt create mode 100644 tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.js create mode 100644 tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.symbols create mode 100644 tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.types create mode 100644 tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c66afe73d91..2b8244ca06c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8252,6 +8252,7 @@ namespace ts { const prop = getPropertyOfType(objectType, propName); if (prop) { if (accessExpression) { + markPropertyAsReferenced(prop, accessExpression, /*isThisAccess*/ accessExpression.expression.kind === SyntaxKind.ThisKeyword); if (isAssignmentTarget(accessExpression) && (isReferenceToReadonlyEntity(accessExpression, prop) || isReferenceThroughNamespaceImport(accessExpression))) { error(accessExpression.argumentExpression, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, symbolToString(prop)); return unknownType; @@ -21356,8 +21357,9 @@ namespace ts { // Already would have reported an error on the getter. break; } - if (!member.symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) { - error(member.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(member.symbol)); + const symbol = getSymbolOfNode(member); + if (!symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) { + error(member.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol)); } break; case SyntaxKind.Constructor: diff --git a/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.errors.txt b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.errors.txt new file mode 100644 index 00000000000..9f95f4cfd2f --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts(4,13): error TS6133: '[x]' is declared but its value is never read. + + +==== tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts (1 errors) ==== + const x = Symbol("x"); + const y = Symbol("y"); + class C { + private [x]: number; + ~~~ +!!! error TS6133: '[x]' is declared but its value is never read. + private [y]: number; + m() { + this[x] = 0; // write-only + this[y]; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.js b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.js new file mode 100644 index 00000000000..6c5bf109b57 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.js @@ -0,0 +1,25 @@ +//// [noUnusedLocals_writeOnlyProperty_dynamicNames.ts] +const x = Symbol("x"); +const y = Symbol("y"); +class C { + private [x]: number; + private [y]: number; + m() { + this[x] = 0; // write-only + this[y]; + } +} + + +//// [noUnusedLocals_writeOnlyProperty_dynamicNames.js] +var x = Symbol("x"); +var y = Symbol("y"); +var C = /** @class */ (function () { + function C() { + } + C.prototype.m = function () { + this[x] = 0; // write-only + this[y]; + }; + return C; +}()); diff --git a/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.symbols b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.symbols new file mode 100644 index 00000000000..6a30e2a9fa9 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.symbols @@ -0,0 +1,31 @@ +=== tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts === +const x = Symbol("x"); +>x : Symbol(x, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 0, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) + +const y = Symbol("y"); +>y : Symbol(y, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 1, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) + +class C { +>C : Symbol(C, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 1, 22)) + + private [x]: number; +>x : Symbol(x, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 0, 5)) + + private [y]: number; +>y : Symbol(y, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 1, 5)) + + m() { +>m : Symbol(C.m, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 4, 24)) + + this[x] = 0; // write-only +>this : Symbol(C, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 1, 22)) +>x : Symbol(x, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 0, 5)) + + this[y]; +>this : Symbol(C, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 1, 22)) +>y : Symbol(y, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 1, 5)) + } +} + diff --git a/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.types b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.types new file mode 100644 index 00000000000..7b173395a99 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.types @@ -0,0 +1,39 @@ +=== tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts === +const x = Symbol("x"); +>x : unique symbol +>Symbol("x") : unique symbol +>Symbol : SymbolConstructor +>"x" : "x" + +const y = Symbol("y"); +>y : unique symbol +>Symbol("y") : unique symbol +>Symbol : SymbolConstructor +>"y" : "y" + +class C { +>C : C + + private [x]: number; +>x : unique symbol + + private [y]: number; +>y : unique symbol + + m() { +>m : () => void + + this[x] = 0; // write-only +>this[x] = 0 : 0 +>this[x] : number +>this : this +>x : unique symbol +>0 : 0 + + this[y]; +>this[y] : number +>this : this +>y : unique symbol + } +} + diff --git a/tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts b/tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts new file mode 100644 index 00000000000..065c6f89e7a --- /dev/null +++ b/tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts @@ -0,0 +1,13 @@ +// @noUnusedLocals: true +// @lib: es6 + +const x = Symbol("x"); +const y = Symbol("y"); +class C { + private [x]: number; + private [y]: number; + m() { + this[x] = 0; // write-only + this[y]; + } +} From 9efb3ac3a716ea2bf2747137006d651c3bf248d3 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 8 Jan 2018 16:52:58 -0800 Subject: [PATCH 114/189] Fix this.timeout not actually applying the timeout within it blocks (#21079) --- src/harness/parallel/host.ts | 4 +++- src/harness/parallel/worker.ts | 34 +++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/harness/parallel/host.ts b/src/harness/parallel/host.ts index 56b8df5ecfe..59105cd5b08 100644 --- a/src/harness/parallel/host.ts +++ b/src/harness/parallel/host.ts @@ -151,7 +151,7 @@ namespace Harness.Parallel.Host { let currentTimeout = defaultTimeout; const killChild = () => { child.kill(); - console.error(`Worker exceeded timeout ${child.currentTasks && child.currentTasks.length ? `while running test '${child.currentTasks[0].file}'.` : `during test setup.`}`); + console.error(`Worker exceeded ${currentTimeout}ms timeout ${child.currentTasks && child.currentTasks.length ? `while running test '${child.currentTasks[0].file}'.` : `during test setup.`}`); return process.exit(2); }; let timer = setTimeout(killChild, currentTimeout); @@ -176,6 +176,7 @@ namespace Harness.Parallel.Host { return process.exit(2); } case "timeout": { + clearTimeout(timer); if (data.payload.duration === "reset") { currentTimeout = timeoutStack.pop() || defaultTimeout; } @@ -183,6 +184,7 @@ namespace Harness.Parallel.Host { timeoutStack.push(currentTimeout); currentTimeout = data.payload.duration; } + timer = setTimeout(killChild, currentTimeout); // Reset timeout on timeout update, for when a timeout changes while a suite is executing break; } case "progress": diff --git a/src/harness/parallel/worker.ts b/src/harness/parallel/worker.ts index 00fbcd23ebb..1902ff70b19 100644 --- a/src/harness/parallel/worker.ts +++ b/src/harness/parallel/worker.ts @@ -128,6 +128,8 @@ namespace Harness.Parallel.Worker { skip() { return this; }, timeout(n) { timeout = n as number; + const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: timeout } }; + process.send(timeoutMsg); return this; }, retries() { return this; }, @@ -145,20 +147,22 @@ namespace Harness.Parallel.Worker { } } if (callback.length === 0) { - setTimeoutAndExecute(timeout, () => { - try { - // TODO: If we ever start using async test completions, polyfill promise return handling - callback.call(fakeContext); + try { + // TODO: If we ever start using async test completions, polyfill promise return handling + callback.call(fakeContext); + } + catch (error) { + errors.push({ error: error.message, stack: error.stack, name: [...namestack] }); + return; + } + finally { + namestack.pop(); + if (timeout !== undefined) { + const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: "reset" } }; + process.send(timeoutMsg); } - catch (error) { - errors.push({ error: error.message, stack: error.stack, name: [...namestack] }); - return; - } - finally { - namestack.pop(); - } - passing++; - }); + } + passing++; } else { // Uses `done` callback @@ -183,6 +187,10 @@ namespace Harness.Parallel.Worker { } finally { namestack.pop(); + if (timeout !== undefined) { + const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: "reset" } }; + process.send(timeoutMsg); + } } if (!completed) { errors.push({ error: "Test completes asynchronously, which is unsupported by the parallel harness", stack: "", name: [...namestack] }); From c4d76292f1b0c810cb1f8ae15dee9be3a195d9ad Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 17:22:32 -0800 Subject: [PATCH 115/189] Ensure visitor visits the awaitModifier of a ForOfStatement (#21078) --- src/compiler/visitor.ts | 2 +- .../cases/fourslash/extractMethod_forAwait.ts | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/extractMethod_forAwait.ts diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 0b40e20a7b7..2d678eb0eff 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -622,7 +622,7 @@ namespace ts { case SyntaxKind.ForOfStatement: return updateForOf(node, - (node).awaitModifier, + visitNode((node).awaitModifier, visitor, isToken), visitNode((node).initializer, visitor, isForInitializer), visitNode((node).expression, visitor, isExpression), visitNode((node).statement, visitor, isStatement, liftToBlock)); diff --git a/tests/cases/fourslash/extractMethod_forAwait.ts b/tests/cases/fourslash/extractMethod_forAwait.ts new file mode 100644 index 00000000000..238c5875a0d --- /dev/null +++ b/tests/cases/fourslash/extractMethod_forAwait.ts @@ -0,0 +1,25 @@ +/// + +////async function f(xs: AsyncIterable) { +//// /*a*/for await (const x of xs) { +//// x * 2; +//// }/*b*/ +////} + +goTo.select('a', 'b') +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to function in global scope", + newContent: +`async function f(xs: AsyncIterable) { + /*RENAME*/newFunction(xs); +} + +function newFunction(xs: any) { + for await (const x of xs) { + x * 2; + } +} +` +}); From 73e3e8d790410c982ea80fd786cb046b0b861989 Mon Sep 17 00:00:00 2001 From: "Remo H. Jansen" Date: Tue, 9 Jan 2018 01:25:56 +0000 Subject: [PATCH 116/189] Fixes #20026 (#20157) * Added test case for #20026 * Implemented #20026 * Addresed comments at Microsoft/TypeScript/pull/20157#discussion_r152086287 * Fixed merge issues * Fixed baseline issue * Merged upstream --- src/compiler/checker.ts | 40 +++++++++++++++---- src/compiler/diagnosticMessages.json | 13 +++++- .../nullableFunctionError.errors.txt | 17 ++++++++ .../reference/nullableFunctionError.js | 12 ++++++ .../reference/nullableFunctionError.symbols | 11 +++++ .../reference/nullableFunctionError.types | 17 ++++++++ tests/cases/compiler/nullableFunctionError.ts | 6 +++ 7 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 tests/baselines/reference/nullableFunctionError.errors.txt create mode 100644 tests/baselines/reference/nullableFunctionError.js create mode 100644 tests/baselines/reference/nullableFunctionError.symbols create mode 100644 tests/baselines/reference/nullableFunctionError.types create mode 100644 tests/cases/compiler/nullableFunctionError.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2b8244ca06c..ef107c2bc68 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15845,17 +15845,35 @@ namespace ts { }); } - function checkNonNullExpression(node: Expression | QualifiedName) { - return checkNonNullType(checkExpression(node), node); + function checkNonNullExpression( + node: Expression | QualifiedName, + nullDiagnostic?: DiagnosticMessage, + undefinedDiagnostic?: DiagnosticMessage, + nullOrUndefinedDiagnostic?: DiagnosticMessage, + ) { + return checkNonNullType( + checkExpression(node), + node, + nullDiagnostic, + undefinedDiagnostic, + nullOrUndefinedDiagnostic + ); } - function checkNonNullType(type: Type, errorNode: Node): Type { + function checkNonNullType( + type: Type, + node: Node, + nullDiagnostic?: DiagnosticMessage, + undefinedDiagnostic?: DiagnosticMessage, + nullOrUndefinedDiagnostic?: DiagnosticMessage + ): Type { const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable; if (kind) { - error(errorNode, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ? - Diagnostics.Object_is_possibly_null_or_undefined : - Diagnostics.Object_is_possibly_undefined : - Diagnostics.Object_is_possibly_null); + error(node, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ? + (nullOrUndefinedDiagnostic || Diagnostics.Object_is_possibly_null_or_undefined) : + (undefinedDiagnostic || Diagnostics.Object_is_possibly_undefined) : + (nullDiagnostic || Diagnostics.Object_is_possibly_null) + ); const t = getNonNullableType(type); return t.flags & (TypeFlags.Nullable | TypeFlags.Never) ? unknownType : t; } @@ -17364,7 +17382,13 @@ namespace ts { return resolveUntypedCall(node); } - const funcType = checkNonNullExpression(node.expression); + const funcType = checkNonNullExpression( + node.expression, + Diagnostics.Cannot_invoke_an_object_which_is_possibly_null, + Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined, + Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined + ); + if (funcType === silentNeverType) { return silentNeverSignature; } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d4641184f45..4fa32251549 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2288,7 +2288,18 @@ "category": "Error", "code": 2720 }, - + "Cannot invoke an object which is possibly 'null'.": { + "category": "Error", + "code": 2721 + }, + "Cannot invoke an object which is possibly 'undefined'.": { + "category": "Error", + "code": 2722 + }, + "Cannot invoke an object which is possibly 'null' or 'undefined'.": { + "category": "Error", + "code": 2723 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", "code": 4000 diff --git a/tests/baselines/reference/nullableFunctionError.errors.txt b/tests/baselines/reference/nullableFunctionError.errors.txt new file mode 100644 index 00000000000..074afdaee4f --- /dev/null +++ b/tests/baselines/reference/nullableFunctionError.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/nullableFunctionError.ts(1,1): error TS2721: Cannot invoke an object which is possibly 'null'. +tests/cases/compiler/nullableFunctionError.ts(2,1): error TS2722: Cannot invoke an object which is possibly 'undefined'. +tests/cases/compiler/nullableFunctionError.ts(4,1): error TS2723: Cannot invoke an object which is possibly 'null' or 'undefined'. + + +==== tests/cases/compiler/nullableFunctionError.ts (3 errors) ==== + null(); + ~~~~ +!!! error TS2721: Cannot invoke an object which is possibly 'null'. + undefined(); + ~~~~~~~~~ +!!! error TS2722: Cannot invoke an object which is possibly 'undefined'. + let f: null | undefined; + f(); + ~ +!!! error TS2723: Cannot invoke an object which is possibly 'null' or 'undefined'. + \ No newline at end of file diff --git a/tests/baselines/reference/nullableFunctionError.js b/tests/baselines/reference/nullableFunctionError.js new file mode 100644 index 00000000000..a8b1f28c51a --- /dev/null +++ b/tests/baselines/reference/nullableFunctionError.js @@ -0,0 +1,12 @@ +//// [nullableFunctionError.ts] +null(); +undefined(); +let f: null | undefined; +f(); + + +//// [nullableFunctionError.js] +null(); +undefined(); +var f; +f(); diff --git a/tests/baselines/reference/nullableFunctionError.symbols b/tests/baselines/reference/nullableFunctionError.symbols new file mode 100644 index 00000000000..cb066bdb32d --- /dev/null +++ b/tests/baselines/reference/nullableFunctionError.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/nullableFunctionError.ts === +null(); +undefined(); +>undefined : Symbol(undefined) + +let f: null | undefined; +>f : Symbol(f, Decl(nullableFunctionError.ts, 2, 3)) + +f(); +>f : Symbol(f, Decl(nullableFunctionError.ts, 2, 3)) + diff --git a/tests/baselines/reference/nullableFunctionError.types b/tests/baselines/reference/nullableFunctionError.types new file mode 100644 index 00000000000..97697fbb564 --- /dev/null +++ b/tests/baselines/reference/nullableFunctionError.types @@ -0,0 +1,17 @@ +=== tests/cases/compiler/nullableFunctionError.ts === +null(); +>null() : any +>null : null + +undefined(); +>undefined() : any +>undefined : undefined + +let f: null | undefined; +>f : null | undefined +>null : null + +f(); +>f() : any +>f : null | undefined + diff --git a/tests/cases/compiler/nullableFunctionError.ts b/tests/cases/compiler/nullableFunctionError.ts new file mode 100644 index 00000000000..5477d7fa29a --- /dev/null +++ b/tests/cases/compiler/nullableFunctionError.ts @@ -0,0 +1,6 @@ +// @strictNullChecks: true + +null(); +undefined(); +let f: null | undefined; +f(); From 89ceb4b9b5f009dac402838152e494eb2831a956 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 8 Jan 2018 18:57:46 -0800 Subject: [PATCH 117/189] Support completions that require changing from dot to bracket access (#20547) * Support completions that require changing from dot to bracket access * Use insertText and replacementSpan * Rename includeBracketCompletions to includeInsertTextCompletions * Don't add completions that start with space --- src/harness/fourslash.ts | 34 +- .../unittests/tsserverProjectSystem.ts | 12 +- src/server/protocol.ts | 11 + src/server/session.ts | 4 +- src/services/completions.ts | 384 ++++++++++-------- src/services/services.ts | 2 +- src/services/types.ts | 2 + .../reference/api/tsserverlibrary.d.ts | 13 + tests/baselines/reference/api/typescript.d.ts | 2 + .../completionListInvalidMemberNames.ts | 19 +- .../completionListInvalidMemberNames2.ts | 23 +- .../completionListInvalidMemberNames3.ts | 71 ---- ...onListInvalidMemberNames_startWithSpace.ts | 8 + ...validMemberNames_withExistingIdentifier.ts | 7 + ...entifiers-should-not-show-in-completion.ts | 13 - tests/cases/fourslash/completionsPaths.ts | 18 +- .../fourslash/completionsPaths_pathMapping.ts | 5 +- tests/cases/fourslash/fourslash.ts | 5 +- ...jsdocTypedefTagTypeExpressionCompletion.ts | 2 +- 19 files changed, 344 insertions(+), 291 deletions(-) delete mode 100644 tests/cases/fourslash/completionListInvalidMemberNames3.ts create mode 100644 tests/cases/fourslash/completionListInvalidMemberNames_startWithSpace.ts create mode 100644 tests/cases/fourslash/completionListInvalidMemberNames_withExistingIdentifier.ts delete mode 100644 tests/cases/fourslash/completion_enum-members-with-invalid-identifiers-should-not-show-in-completion.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index df103e9dafc..6a2f71df10e 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -511,7 +511,7 @@ namespace FourSlash { } } - private raiseError(message: string) { + private raiseError(message: string): never { throw new Error(this.messageAtLastKnownMarker(message)); } @@ -848,10 +848,10 @@ namespace FourSlash { } } - public verifyCompletionsAt(markerName: string, expected: string[], options?: FourSlashInterface.CompletionsAtOptions) { + public verifyCompletionsAt(markerName: string, expected: ReadonlyArray, options?: FourSlashInterface.CompletionsAtOptions) { this.goToMarker(markerName); - const actualCompletions = this.getCompletionListAtCaret(); + const actualCompletions = this.getCompletionListAtCaret(options); if (!actualCompletions) { this.raiseError(`No completions at position '${this.currentCaretPosition}'.`); } @@ -867,9 +867,20 @@ namespace FourSlash { } ts.zipWith(actual, expected, (completion, expectedCompletion, index) => { - if (completion.name !== expectedCompletion) { + const { name, insertText, replacementSpan } = typeof expectedCompletion === "string" ? { name: expectedCompletion, insertText: undefined, replacementSpan: undefined } : expectedCompletion; + if (completion.name !== name) { this.raiseError(`Expected completion at index ${index} to be ${expectedCompletion}, got ${completion.name}`); } + if (completion.insertText !== insertText) { + this.raiseError(`Expected completion insert text at index ${index} to be ${insertText}, got ${completion.insertText}`); + } + const convertedReplacementSpan = replacementSpan && textSpanFromRange(replacementSpan); + try { + assert.deepEqual(completion.replacementSpan, convertedReplacementSpan); + } + catch { + this.raiseError(`Expected completion replacementSpan at index ${index} to be ${stringify(convertedReplacementSpan)}, got ${stringify(completion.replacementSpan)}`); + } }); } @@ -1808,7 +1819,7 @@ Actual: ${stringify(fullActual)}`); } else if (prevChar === " " && /A-Za-z_/.test(ch)) { /* Completions */ - this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset, { includeExternalModuleExports: false }); + this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); } if (i % checkCadence === 0) { @@ -2383,7 +2394,8 @@ Actual: ${stringify(fullActual)}`); public applyCodeActionFromCompletion(markerName: string, options: FourSlashInterface.VerifyCompletionActionOptions) { this.goToMarker(markerName); - const actualCompletion = this.getCompletionListAtCaret({ includeExternalModuleExports: true }).entries.find(e => e.name === options.name && e.source === options.source); + const actualCompletion = this.getCompletionListAtCaret({ includeExternalModuleExports: true, includeInsertTextCompletions: false }).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.`); @@ -3195,8 +3207,7 @@ Actual: ${stringify(fullActual)}`); private getTextSpanForRangeAtIndex(index: number): ts.TextSpan { const ranges = this.getRanges(); if (ranges && ranges.length > index) { - const range = ranges[index]; - return { start: range.start, length: range.end - range.start }; + return textSpanFromRange(ranges[index]); } else { this.raiseError("Supplied span index: " + index + " does not exist in range list of size: " + (ranges ? 0 : ranges.length)); @@ -3226,6 +3237,10 @@ Actual: ${stringify(fullActual)}`); } } + function textSpanFromRange(range: FourSlash.Range): ts.TextSpan { + return ts.createTextSpanFromBounds(range.start, range.end); + } + export function runFourSlashTest(basePath: string, testType: FourSlashTestType, fileName: string) { const content = Harness.IO.readFile(fileName); runFourSlashTestContent(basePath, testType, content, fileName); @@ -3967,7 +3982,7 @@ namespace FourSlashInterface { super(state); } - public completionsAt(markerName: string, completions: string[], options?: CompletionsAtOptions) { + public completionsAt(markerName: string, completions: ReadonlyArray, options?: CompletionsAtOptions) { this.state.verifyCompletionsAt(markerName, completions, options); } @@ -4591,6 +4606,7 @@ namespace FourSlashInterface { newContent: string; } + export type ExpectedCompletionEntry = string | { name: string, insertText?: string, replacementSpan?: FourSlash.Range }; export interface CompletionsAtOptions extends ts.GetCompletionsAtPositionOptions { isNewIdentifierLocation?: boolean; } diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 34c8f9e9656..10c5aad92db 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1302,13 +1302,13 @@ namespace ts.projectSystem { service.checkNumberOfProjects({ externalProjects: 1 }); checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]); - const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false }); + const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); // should contain completions for string assert.isTrue(completions1.entries.some(e => e.name === "charAt"), "should contain 'charAt'"); assert.isFalse(completions1.entries.some(e => e.name === "toExponential"), "should not contain 'toExponential'"); service.closeClientFile(f2.path); - const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false }); + const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); // should contain completions for string assert.isFalse(completions2.entries.some(e => e.name === "charAt"), "should not contain 'charAt'"); assert.isTrue(completions2.entries.some(e => e.name === "toExponential"), "should contain 'toExponential'"); @@ -1334,11 +1334,11 @@ namespace ts.projectSystem { service.checkNumberOfProjects({ externalProjects: 1 }); checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]); - const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false }); + const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); assert.isTrue(completions1.entries.some(e => e.name === "somelongname"), "should contain 'somelongname'"); service.closeClientFile(f2.path); - const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false }); + const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); assert.isFalse(completions2.entries.some(e => e.name === "somelongname"), "should not contain 'somelongname'"); const sf2 = service.externalProjects[0].getLanguageService().getProgram().getSourceFile(f2.path); assert.equal(sf2.text, ""); @@ -1943,7 +1943,7 @@ namespace ts.projectSystem { // Check identifiers defined in HTML content are available in .ts file const project = configuredProjectAt(projectService, 0); - let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1, { includeExternalModuleExports: false }); + let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); assert(completions && completions.entries[0].name === "hello", `expected entry hello to be in completion list`); // Close HTML file @@ -1957,7 +1957,7 @@ namespace ts.projectSystem { checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]); // Check identifiers defined in HTML content are not available in .ts file - completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5, { includeExternalModuleExports: false }); + completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); assert(completions && completions.entries[0].name !== "hello", `unexpected hello entry in completion list`); }); diff --git a/src/server/protocol.ts b/src/server/protocol.ts index ef59cc16406..b3cbba27a20 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -1693,6 +1693,11 @@ namespace ts.server.protocol { * This affects lone identifier completions but not completions on the right hand side of `obj.`. */ includeExternalModuleExports: boolean; + /** + * If enabled, the completion list will include completions with invalid identifier names. + * For those entries, The `insertText` and `replacementSpan` properties will be set to change from `.x` property access to `["x"]`. + */ + includeInsertTextCompletions: boolean; } /** @@ -1768,6 +1773,12 @@ namespace ts.server.protocol { * is often the same as the name but may be different in certain circumstances. */ sortText: string; + /** + * Text to insert instead of `name`. + * This is used to support bracketed completions; If `name` might be "a-b" but `insertText` would be `["a-b"]`, + * coupled with `replacementSpan` to replace a dotted access with a bracket access. + */ + insertText?: string; /** * An optional span that indicates the text to be replaced by this completion item. * If present, this span should be used instead of the default one. diff --git a/src/server/session.ts b/src/server/session.ts index 9dcf58734a7..693d1651c91 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1207,10 +1207,10 @@ namespace ts.server { if (simplifiedResult) { return mapDefined(completions && completions.entries, entry => { if (completions.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) { - const { name, kind, kindModifiers, sortText, replacementSpan, hasAction, source, isRecommended } = entry; + const { name, kind, kindModifiers, sortText, insertText, replacementSpan, hasAction, source, isRecommended } = entry; const convertedSpan = replacementSpan ? this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined; // Use `hasAction || undefined` to avoid serializing `false`. - return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source, isRecommended }; + return { name, kind, kindModifiers, sortText, insertText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source, isRecommended }; } }).sort((a, b) => compareStringsCaseSensitiveUI(a.name, b.name)); } diff --git a/src/services/completions.ts b/src/services/completions.ts index b92dffb93cc..bdd5e4a86a2 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -50,40 +50,49 @@ namespace ts.Completions { return undefined; } - const { symbols, isGlobalCompletion, isMemberCompletion, allowStringLiteral, isNewIdentifierLocation, location, request, keywordFilters, symbolToOriginInfoMap, recommendedCompletion } = completionData; + switch (completionData.kind) { + case CompletionDataKind.Data: + return completionInfoFromData(sourceFile, typeChecker, compilerOptions, log, completionData, options.includeInsertTextCompletions); + case CompletionDataKind.JsDocTagName: + // If the current position is a jsDoc tag name, only tag names should be provided for completion + return jsdocCompletionInfo(JsDoc.getJSDocTagNameCompletions()); + case CompletionDataKind.JsDocTag: + // If the current position is a jsDoc tag, only tags should be provided for completion + return jsdocCompletionInfo(JsDoc.getJSDocTagCompletions()); + case CompletionDataKind.JsDocParameterName: + return jsdocCompletionInfo(JsDoc.getJSDocParameterNameCompletions(completionData.tag)); + default: + throw Debug.assertNever(completionData); + } + } - if (sourceFile.languageVariant === LanguageVariant.JSX && - location && location.parent && location.parent.kind === SyntaxKind.JsxClosingElement) { + function jsdocCompletionInfo(entries: CompletionEntry[]): CompletionInfo { + return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries }; + } + + function completionInfoFromData(sourceFile: SourceFile, typeChecker: TypeChecker, compilerOptions: CompilerOptions, log: Log, completionData: CompletionData, includeInsertTextCompletions: boolean): CompletionInfo { + const { symbols, completionKind, isNewIdentifierLocation, location, propertyAccessToConvert, keywordFilters, symbolToOriginInfoMap, recommendedCompletion } = completionData; + + if (sourceFile.languageVariant === LanguageVariant.JSX && location && location.parent && isJsxClosingElement(location.parent)) { // In the TypeScript JSX element, if such element is not defined. When users query for completion at closing tag, // instead of simply giving unknown value, the completion will return the tag-name of an associated opening-element. // For example: // var x =
// The completion list at "1" will contain "div" with type any - const tagName = (location.parent.parent).openingElement.tagName; + const tagName = location.parent.parent.openingElement.tagName; return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false, entries: [{ - name: (tagName).getFullText(), + name: tagName.getFullText(), kind: ScriptElementKind.classElement, kindModifiers: undefined, sortText: "0", }]}; } - if (request) { - const entries = request.kind === "JsDocTagName" - // If the current position is a jsDoc tag name, only tag names should be provided for completion - ? JsDoc.getJSDocTagNameCompletions() - : request.kind === "JsDocTag" - // If the current position is a jsDoc tag, only tags should be provided for completion - ? JsDoc.getJSDocTagCompletions() - : JsDoc.getJSDocParameterNameCompletions(request.tag); - return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries }; - } - const entries: CompletionEntry[] = []; if (isSourceFileJavaScript(sourceFile)) { - const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral, recommendedCompletion, symbolToOriginInfoMap); + const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, compilerOptions.target, log, completionKind, includeInsertTextCompletions, propertyAccessToConvert, recommendedCompletion, symbolToOriginInfoMap); getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames, compilerOptions.target, entries); } else { @@ -91,7 +100,7 @@ namespace ts.Completions { return undefined; } - getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral, recommendedCompletion, symbolToOriginInfoMap); + getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, compilerOptions.target, log, completionKind, includeInsertTextCompletions, propertyAccessToConvert, recommendedCompletion, symbolToOriginInfoMap); } // TODO add filter for keyword based on type/value/namespace and also location @@ -99,17 +108,29 @@ namespace ts.Completions { // Add all keywords if // - this is not a member completion list (all the keywords) // - other filters are enabled in required scenario so add those keywords + const isMemberCompletion = isMemberCompletionKind(completionKind); if (keywordFilters !== KeywordCompletionFilters.None || !isMemberCompletion) { addRange(entries, getKeywordCompletions(keywordFilters)); } - return { isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, entries }; + return { isGlobalCompletion: completionKind === CompletionKind.Global, isMemberCompletion, isNewIdentifierLocation, entries }; + } + + function isMemberCompletionKind(kind: CompletionKind): boolean { + switch (kind) { + case CompletionKind.ObjectPropertyDeclaration: + case CompletionKind.MemberLike: + case CompletionKind.PropertyAccess: + return true; + default: + return false; + } } function getJavaScriptCompletionEntries( sourceFile: SourceFile, position: number, - uniqueNames: Map<{}>, + uniqueNames: Map, target: ScriptTarget, entries: Push): void { getNameTable(sourceFile).forEach((pos, name) => { @@ -118,16 +139,9 @@ namespace ts.Completions { return; } const realName = unescapeLeadingUnderscores(name); - - if (uniqueNames.has(realName) || isStringANonContextualKeyword(realName)) { - return; - } - - uniqueNames.set(realName, true); - const displayName = getCompletionEntryDisplayName(realName, target, /*performCharacterChecks*/ true, /*allowStringLiteral*/ false); - if (displayName) { + if (addToSeen(uniqueNames, realName) && isIdentifierText(realName, target) && !isStringANonContextualKeyword(realName)) { entries.push({ - name: displayName, + name: realName, kind: ScriptElementKind.warning, kindModifiers: "", sortText: "1" @@ -139,18 +153,22 @@ namespace ts.Completions { function createCompletionEntry( symbol: Symbol, location: Node, - performCharacterChecks: boolean, + sourceFile: SourceFile, typeChecker: TypeChecker, target: ScriptTarget, - allowStringLiteral: boolean, + kind: CompletionKind, origin: SymbolOriginInfo | undefined, recommendedCompletion: Symbol | undefined, + propertyAccessToConvert: PropertyAccessExpression | undefined, + includeInsertTextCompletions: boolean, ): CompletionEntry | undefined { - // Try to get a valid display name for this symbol, if we could not find one, then ignore it. - // We would like to only show things that can be added after a dot, so for instance numeric properties can - // not be accessed with a dot (a.1 <- invalid) - const displayName = getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, allowStringLiteral, origin); - if (!displayName) { + const info = getCompletionEntryDisplayNameForSymbol(symbol, target, origin, kind); + if (!info) { + return undefined; + } + const { name, needsConvertPropertyAccess } = info; + Debug.assert(!(needsConvertPropertyAccess && !propertyAccessToConvert)); + if (needsConvertPropertyAccess && !includeInsertTextCompletions) { return undefined; } @@ -163,16 +181,22 @@ namespace ts.Completions { // Use a 'sortText' of 0' so that all symbol completion entries come before any other // entries (like JavaScript identifier entries). return { - name: displayName, + name, kind: SymbolDisplay.getSymbolKind(typeChecker, symbol, location), kindModifiers: SymbolDisplay.getSymbolModifiers(symbol), sortText: "0", source: getSourceFromOrigin(origin), - hasAction: trueOrUndefined(origin !== undefined), + // TODO: GH#20619 Use configured quote style + insertText: needsConvertPropertyAccess ? `["${name}"]` : undefined, + replacementSpan: needsConvertPropertyAccess + ? createTextSpanFromBounds(findChildOfKind(propertyAccessToConvert, SyntaxKind.DotToken, sourceFile)!.getStart(sourceFile), propertyAccessToConvert.name.end) + : undefined, + hasAction: trueOrUndefined(needsConvertPropertyAccess || origin !== undefined), isRecommended: trueOrUndefined(isRecommendedCompletionMatch(symbol, recommendedCompletion, typeChecker)), }; } + function isRecommendedCompletionMatch(localSymbol: Symbol, recommendedCompletion: Symbol, checker: TypeChecker): boolean { return localSymbol === recommendedCompletion || !!(localSymbol.flags & SymbolFlags.ExportValue) && checker.getExportSymbolOfSymbol(localSymbol) === recommendedCompletion; @@ -190,11 +214,13 @@ namespace ts.Completions { symbols: ReadonlyArray, entries: Push, location: Node, - performCharacterChecks: boolean, + sourceFile: SourceFile, typeChecker: TypeChecker, target: ScriptTarget, log: Log, - allowStringLiteral: boolean, + kind: CompletionKind, + includeInsertTextCompletions?: boolean, + propertyAccessToConvert?: PropertyAccessExpression | undefined, recommendedCompletion?: Symbol, symbolToOriginInfoMap?: SymbolOriginInfoMap, ): Map { @@ -206,7 +232,7 @@ namespace ts.Completions { const uniques = createMap(); for (const symbol of symbols) { const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[getSymbolId(symbol)] : undefined; - const entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral, origin, recommendedCompletion); + const entry = createCompletionEntry(symbol, location, sourceFile, typeChecker, target, kind, origin, recommendedCompletion, propertyAccessToConvert, includeInsertTextCompletions); if (!entry) { continue; } @@ -256,7 +282,7 @@ namespace ts.Completions { // foo({ // '/*completion position*/' // }); - return getStringLiteralCompletionEntriesFromPropertyAssignment(node.parent, typeChecker, compilerOptions.target, log); + return getStringLiteralCompletionEntriesFromPropertyAssignment(node.parent, sourceFile, typeChecker, compilerOptions.target, log); } else if (isElementAccessExpression(node.parent) && node.parent.argumentExpression === node) { // Get all names of properties on the expression @@ -266,7 +292,7 @@ namespace ts.Completions { // let a: A; // a['/*completion position*/'] const type = typeChecker.getTypeAtLocation(node.parent.expression); - return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, type, typeChecker, compilerOptions.target, log); + return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, sourceFile, type, typeChecker, compilerOptions.target, log); } else if (node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration || isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || isImportCall(node.parent) @@ -288,7 +314,7 @@ namespace ts.Completions { // } // let x: Foo["/*completion position*/"] const type = typeChecker.getTypeFromTypeNode(node.parent.parent.objectType); - return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, type, typeChecker, compilerOptions.target, log); + return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, sourceFile, type, typeChecker, compilerOptions.target, log); } else { const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile); @@ -317,11 +343,11 @@ namespace ts.Completions { }; } - function getStringLiteralCompletionEntriesFromPropertyAssignment(element: ObjectLiteralElement, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined { + function getStringLiteralCompletionEntriesFromPropertyAssignment(element: ObjectLiteralElement, sourceFile: SourceFile, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined { const type = typeChecker.getContextualType((element.parent)); const entries: CompletionEntry[] = []; if (type) { - getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true); + getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, sourceFile, typeChecker, target, log, CompletionKind.String); if (entries.length) { return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries }; } @@ -346,10 +372,10 @@ namespace ts.Completions { return undefined; } - function getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(stringLiteralNode: StringLiteral | NoSubstitutionTemplateLiteral, type: Type, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined { + function getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(stringLiteralNode: StringLiteral | NoSubstitutionTemplateLiteral, sourceFile: SourceFile, type: Type, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined { const entries: CompletionEntry[] = []; if (type) { - getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, stringLiteralNode, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true); + getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, stringLiteralNode, sourceFile, typeChecker, target, log, CompletionKind.String); if (entries.length) { return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries }; } @@ -420,6 +446,13 @@ namespace ts.Completions { } } + interface SymbolCompletion { + type: "symbol"; + symbol: Symbol; + location: Node; + symbolToOriginInfoMap: SymbolOriginInfoMap; + previousToken: Node; + } function getSymbolCompletionFromEntryId( typeChecker: TypeChecker, log: (message: string) => void, @@ -428,27 +461,26 @@ namespace ts.Completions { position: number, { name, source }: CompletionEntryIdentifier, allSourceFiles: ReadonlyArray, - ): { type: "symbol", symbol: Symbol, location: Node, symbolToOriginInfoMap: SymbolOriginInfoMap, previousToken: Node } | { type: "request", request: Request } | { type: "none" } { - const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, { includeExternalModuleExports: true }, compilerOptions.target); + ): SymbolCompletion | { type: "request", request: Request } | { type: "none" } { + const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, { includeExternalModuleExports: true, includeInsertTextCompletions: true }, compilerOptions.target); if (!completionData) { return { type: "none" }; } - - const { symbols, location, allowStringLiteral, symbolToOriginInfoMap, request, previousToken } = completionData; - if (request) { - return { type: "request", request }; + if (completionData.kind !== CompletionDataKind.Data) { + return { type: "request", request: completionData }; } + const { symbols, location, completionKind, symbolToOriginInfoMap, previousToken } = completionData; + // Find the symbol with the matching entry name. // We don't need to perform character checks here because we're only comparing the // name against 'entryName' (which is known to be good), not building a new // completion entry. - const symbol = find(symbols, s => { - const origin = symbolToOriginInfoMap[getSymbolId(s)]; - return getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral, origin) === name - && getSourceFromOrigin(origin) === source; - }); - return symbol ? { type: "symbol", symbol, location, symbolToOriginInfoMap, previousToken } : { type: "none" }; + return firstDefined(symbols, (symbol): SymbolCompletion => { // TODO: Shouldn't need return type annotation (GH#12632) + const origin = symbolToOriginInfoMap[getSymbolId(symbol)]; + const info = getCompletionEntryDisplayNameForSymbol(symbol, compilerOptions.target, origin, completionKind); + return info && info.name === name && getSourceFromOrigin(origin) === source ? { type: "symbol" as "symbol", symbol, location, symbolToOriginInfoMap, previousToken } : undefined; + }) || { type: "none" }; } function getSymbolName(symbol: Symbol, origin: SymbolOriginInfo | undefined, target: ScriptTarget): string { @@ -484,11 +516,11 @@ namespace ts.Completions { case "request": { const { request } = symbolCompletion; switch (request.kind) { - case "JsDocTagName": + case CompletionDataKind.JsDocTagName: return JsDoc.getJSDocTagNameCompletionDetails(name); - case "JsDocTag": + case CompletionDataKind.JsDocTag: return JsDoc.getJSDocTagCompletionDetails(name); - case "JsDocParameterName": + case CompletionDataKind.JsDocParameterName: return JsDoc.getJSDocParameterNameCompletionDetails(name); default: return Debug.assertNever(request); @@ -520,6 +552,10 @@ namespace ts.Completions { } } + interface CodeActionsAndSourceDisplay { + readonly codeActions: CodeAction[] | undefined; + readonly sourceDisplay: SymbolDisplayPart[] | undefined; + } function getCompletionEntryCodeActionsAndSourceDisplay( symbolToOriginInfoMap: SymbolOriginInfoMap, symbol: Symbol, @@ -532,12 +568,26 @@ namespace ts.Completions { formatContext: formatting.FormatContext, getCanonicalFileName: GetCanonicalFileName, allSourceFiles: ReadonlyArray, - ): { codeActions: CodeAction[] | undefined, sourceDisplay: SymbolDisplayPart[] | undefined } { + ): CodeActionsAndSourceDisplay { const symbolOriginInfo = symbolToOriginInfoMap[getSymbolId(symbol)]; - if (!symbolOriginInfo) { - return { codeActions: undefined, sourceDisplay: undefined }; - } + return symbolOriginInfo + ? getCodeActionsAndSourceDisplayForImport(symbolOriginInfo, symbol, program, checker, host, compilerOptions, sourceFile, previousToken, formatContext, getCanonicalFileName, allSourceFiles) + : { codeActions: undefined, sourceDisplay: undefined }; + } + function getCodeActionsAndSourceDisplayForImport( + symbolOriginInfo: SymbolOriginInfo, + symbol: Symbol, + program: Program, + checker: TypeChecker, + host: LanguageServiceHost, + compilerOptions: CompilerOptions, + sourceFile: SourceFile, + previousToken: Node, + formatContext: formatting.FormatContext, + getCanonicalFileName: GetCanonicalFileName, + allSourceFiles: ReadonlyArray + ): CodeActionsAndSourceDisplay { const { moduleSymbol, isDefaultExport } = symbolOriginInfo; const exportedSymbol = skipAlias(symbol.exportSymbol || symbol, checker); const moduleSymbols = getAllReExportingModules(exportedSymbol, checker, allSourceFiles); @@ -585,21 +635,30 @@ namespace ts.Completions { return completion.type === "symbol" ? completion.symbol : undefined; } + const enum CompletionDataKind { Data, JsDocTagName, JsDocTag, JsDocParameterName } interface CompletionData { - symbols: ReadonlyArray; - isGlobalCompletion: boolean; - isMemberCompletion: boolean; - allowStringLiteral: boolean; - isNewIdentifierLocation: boolean; - location: Node | undefined; - isRightOfDot: boolean; - request?: Request; - keywordFilters: KeywordCompletionFilters; - symbolToOriginInfoMap: SymbolOriginInfoMap; - recommendedCompletion: Symbol | undefined; - previousToken: Node; + readonly kind: CompletionDataKind.Data; + readonly symbols: ReadonlyArray; + readonly completionKind: CompletionKind; + /** Note that the presence of this alone doesn't mean that we need a conversion. Only do that if the completion is not an ordinary identifier. */ + readonly propertyAccessToConvert: PropertyAccessExpression | undefined; + readonly isNewIdentifierLocation: boolean; + readonly location: Node | undefined; + readonly keywordFilters: KeywordCompletionFilters; + readonly symbolToOriginInfoMap: SymbolOriginInfoMap; + readonly recommendedCompletion: Symbol | undefined; + readonly previousToken: Node | undefined; + } + type Request = { readonly kind: CompletionDataKind.JsDocTagName | CompletionDataKind.JsDocTag } | { readonly kind: CompletionDataKind.JsDocParameterName, tag: JSDocParameterTag }; + + const enum CompletionKind { + ObjectPropertyDeclaration, + Global, + PropertyAccess, + MemberLike, + String, + None, } - type Request = { kind: "JsDocTagName" } | { kind: "JsDocTag" } | { kind: "JsDocParameterName", tag: JSDocParameterTag }; function getRecommendedCompletion(currentToken: Node, checker: TypeChecker): Symbol | undefined { const ty = getContextualType(currentToken, checker); @@ -670,9 +729,7 @@ namespace ts.Completions { allSourceFiles: ReadonlyArray, options: GetCompletionsAtPositionOptions, target: ScriptTarget, - ): CompletionData | undefined { - let request: Request | undefined; - + ): CompletionData | Request | undefined { let start = timestamp(); let currentToken = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); // TODO: GH#15853 // We will check for jsdoc comments with insideComment and getJsDocTagAtPosition. (TODO: that seems rather inefficient to check the same thing so many times.) @@ -690,7 +747,7 @@ namespace ts.Completions { if (sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) { // The current position is next to the '@' sign, when no tag name being provided yet. // Provide a full list of tag names - request = { kind: "JsDocTagName" }; + return { kind: CompletionDataKind.JsDocTagName }; } else { // When completion is requested without "@", we will have check to make sure that @@ -711,7 +768,7 @@ namespace ts.Completions { // */ const lineStart = getLineStartPositionForPosition(position, sourceFile); if (!(sourceFile.text.substring(lineStart, position).match(/[^\*|\s|(/\*\*)]/))) { - request = { kind: "JsDocTag" }; + return { kind: CompletionDataKind.JsDocTag }; } } } @@ -722,7 +779,7 @@ namespace ts.Completions { const tag = getJsDocTagAtPosition(currentToken, position); if (tag) { if (tag.tagName.pos <= position && position <= tag.tagName.end) { - request = { kind: "JsDocTagName" }; + return { kind: CompletionDataKind.JsDocTagName }; } if (isTagWithTypeExpression(tag) && tag.typeExpression && tag.typeExpression.kind === SyntaxKind.JSDocTypeExpression) { currentToken = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ true); @@ -735,27 +792,10 @@ namespace ts.Completions { } } if (isJSDocParameterTag(tag) && (nodeIsMissing(tag.name) || tag.name.pos <= position && position <= tag.name.end)) { - request = { kind: "JsDocParameterName", tag }; + return { kind: CompletionDataKind.JsDocParameterName, tag }; } } - if (request) { - return { - symbols: emptyArray, - isGlobalCompletion: false, - isMemberCompletion: false, - allowStringLiteral: false, - isNewIdentifierLocation: false, - location: undefined, - isRightOfDot: false, - request, - keywordFilters: KeywordCompletionFilters.None, - symbolToOriginInfoMap: undefined, - recommendedCompletion: undefined, - previousToken: undefined, - }; - } - if (!insideJsDocTagTypeExpression) { // Proceed if the current position is in jsDoc tag expression; otherwise it is a normal // comment or the plain text part of a jsDoc comment, so no completion should be available @@ -784,6 +824,7 @@ namespace ts.Completions { // Also determine whether we are trying to complete with members of that node // or attributes of a JSX tag. let node = currentToken; + let propertyAccessToConvert: PropertyAccessExpression | undefined; let isRightOfDot = false; let isRightOfOpenTag = false; let isStartingCloseTag = false; @@ -798,18 +839,19 @@ namespace ts.Completions { let parent = contextToken.parent; if (contextToken.kind === SyntaxKind.DotToken) { - if (parent.kind === SyntaxKind.PropertyAccessExpression) { - node = (contextToken.parent).expression; - isRightOfDot = true; - } - else if (parent.kind === SyntaxKind.QualifiedName) { - node = (contextToken.parent).left; - isRightOfDot = true; - } - else { - // There is nothing that precedes the dot, so this likely just a stray character - // or leading into a '...' token. Just bail out instead. - return undefined; + isRightOfDot = true; + switch (parent.kind) { + case SyntaxKind.PropertyAccessExpression: + propertyAccessToConvert = parent as PropertyAccessExpression; + node = propertyAccessToConvert.expression; + break; + case SyntaxKind.QualifiedName: + node = (parent as QualifiedName).left; + break; + default: + // There is nothing that precedes the dot, so this likely just a stray character + // or leading into a '...' token. Just bail out instead. + return undefined; } } else if (sourceFile.languageVariant === LanguageVariant.JSX) { @@ -849,10 +891,8 @@ namespace ts.Completions { } const semanticStart = timestamp(); - let isGlobalCompletion = false; - let isMemberCompletion: boolean; - let allowStringLiteral = false; - let isNewIdentifierLocation: boolean; + let completionKind = CompletionKind.None; + let isNewIdentifierLocation = false; let keywordFilters = KeywordCompletionFilters.None; let symbols: Symbol[] = []; const symbolToOriginInfoMap: SymbolOriginInfoMap = []; @@ -868,8 +908,7 @@ namespace ts.Completions { else { symbols = tagSymbols; } - isMemberCompletion = true; - isNewIdentifierLocation = false; + completionKind = CompletionKind.MemberLike; } else if (isStartingCloseTag) { const tagName = (contextToken.parent.parent).openingElement.tagName; @@ -878,8 +917,7 @@ namespace ts.Completions { if (!typeChecker.isUnknownSymbol(tagSymbol)) { symbols = [tagSymbol]; } - isMemberCompletion = true; - isNewIdentifierLocation = false; + completionKind = CompletionKind.MemberLike; } else { // For JavaScript or TypeScript, if we're not after a dot, then just try to get the @@ -893,7 +931,7 @@ namespace ts.Completions { log("getCompletionData: Semantic work: " + (timestamp() - semanticStart)); const recommendedCompletion = previousToken && getRecommendedCompletion(previousToken, typeChecker); - return { symbols, isGlobalCompletion, isMemberCompletion, allowStringLiteral, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), request, keywordFilters, symbolToOriginInfoMap, recommendedCompletion, previousToken }; + return { kind: CompletionDataKind.Data, symbols, completionKind, propertyAccessToConvert, isNewIdentifierLocation, location, keywordFilters, symbolToOriginInfoMap, recommendedCompletion, previousToken }; type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag; @@ -910,9 +948,7 @@ namespace ts.Completions { function getTypeScriptMemberSymbols(): void { // Right of dot member completion list - isGlobalCompletion = false; - isMemberCompletion = true; - isNewIdentifierLocation = false; + completionKind = CompletionKind.PropertyAccess; // Since this is qualified name check its a type node location const isTypeLocation = insideJsDocTagTypeExpression || isPartOfTypeNode(node.parent); @@ -988,7 +1024,7 @@ namespace ts.Completions { if (tryGetConstructorLikeCompletionContainer(contextToken)) { // no members, only keywords - isMemberCompletion = false; + completionKind = CompletionKind.None; // Declaring new property/method/accessor isNewIdentifierLocation = true; // Has keywords for constructor parameter @@ -1010,7 +1046,7 @@ namespace ts.Completions { if (attrsType) { symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (jsxContainer).attributes.properties); - isMemberCompletion = true; + completionKind = CompletionKind.MemberLike; isNewIdentifierLocation = false; return true; } @@ -1018,7 +1054,7 @@ namespace ts.Completions { } // Get all entities in the current scope. - isMemberCompletion = false; + completionKind = CompletionKind.None; isNewIdentifierLocation = isNewIdentifierDefinitionLocation(contextToken); if (previousToken !== contextToken) { @@ -1054,13 +1090,8 @@ namespace ts.Completions { position; const scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; - if (scopeNode) { - isGlobalCompletion = - scopeNode.kind === SyntaxKind.SourceFile || - scopeNode.kind === SyntaxKind.TemplateExpression || - scopeNode.kind === SyntaxKind.JsxExpression || - scopeNode.kind === SyntaxKind.Block || // Some blocks aren't statements, but all get global completions - isStatement(scopeNode); + if (isGlobalCompletionScope(scopeNode)) { + completionKind = CompletionKind.Global; } const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; @@ -1074,6 +1105,18 @@ namespace ts.Completions { return true; } + function isGlobalCompletionScope(scopeNode: Node): boolean { + switch (scopeNode.kind) { + case SyntaxKind.SourceFile: + case SyntaxKind.TemplateExpression: + case SyntaxKind.JsxExpression: + case SyntaxKind.Block: + return true; + default: + return isStatement(scopeNode); + } + } + function filterGlobalCompletion(symbols: Symbol[]): void { filterMutate(symbols, symbol => { if (!isSourceFile(location)) { @@ -1333,8 +1376,7 @@ namespace ts.Completions { */ function tryGetObjectLikeCompletionSymbols(objectLikeContainer: ObjectLiteralExpression | ObjectBindingPattern): boolean { // We're looking up possible property names from contextual/inferred/declared type. - isMemberCompletion = true; - allowStringLiteral = true; + completionKind = CompletionKind.ObjectPropertyDeclaration; let typeMembers: Symbol[]; let existingMembers: ReadonlyArray; @@ -1412,7 +1454,7 @@ namespace ts.Completions { return false; } - isMemberCompletion = true; + completionKind = CompletionKind.MemberLike; isNewIdentifierLocation = false; const moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(moduleSpecifier); @@ -1432,7 +1474,7 @@ namespace ts.Completions { */ function getGetClassLikeCompletionSymbols(classLikeDeclaration: ClassLikeDeclaration) { // We're looking up possible property names from parent type. - isMemberCompletion = true; + completionKind = CompletionKind.MemberLike; // Declaring new property/method/accessor isNewIdentifierLocation = true; // Has keywords for class elements @@ -1986,36 +2028,44 @@ namespace ts.Completions { } } - /** - * Get the name to be display in completion from a given symbol. - */ - function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean, allowStringLiteral: boolean, origin: SymbolOriginInfo | undefined): string | undefined { + interface CompletionEntryDisplayNameForSymbol { + readonly name: string; + readonly needsConvertPropertyAccess: boolean; + } + function getCompletionEntryDisplayNameForSymbol( + symbol: Symbol, + target: ScriptTarget, + origin: SymbolOriginInfo | undefined, + kind: CompletionKind, + ): CompletionEntryDisplayNameForSymbol | undefined { const name = getSymbolName(symbol, origin, target); - return name === undefined + if (name === undefined // If the symbol is external module, don't show it in the completion list // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there) || symbol.flags & SymbolFlags.Module && startsWithQuote(name) // If the symbol is the internal name of an ES symbol, it is not a valid entry. Internal names for ES symbols start with "__@" - || isKnownSymbol(symbol) - ? undefined - : getCompletionEntryDisplayName(name, target, performCharacterChecks, allowStringLiteral); - } - - /** - * Get a displayName from a given for completion list, performing any necessary quotes stripping - * and checking whether the name is valid identifier name. - */ - function getCompletionEntryDisplayName(name: string, target: ScriptTarget, performCharacterChecks: boolean, allowStringLiteral: boolean): string { - // If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an - // invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name. - // e.g "b a" is valid quoted name but when we strip off the quotes, it is invalid. - // We, thus, need to check if whatever was inside the quotes is actually a valid identifier name. - if (performCharacterChecks && !isIdentifierText(name, target)) { - // TODO: GH#18169 - return allowStringLiteral ? JSON.stringify(name) : undefined; + || isKnownSymbol(symbol)) { + return undefined; } - return name; + const validIdentiferResult: CompletionEntryDisplayNameForSymbol = { name, needsConvertPropertyAccess: false }; + if (isIdentifierText(name, target)) return validIdentiferResult; + switch (kind) { + case CompletionKind.None: + case CompletionKind.Global: + case CompletionKind.MemberLike: + return undefined; + case CompletionKind.ObjectPropertyDeclaration: + // TODO: GH#18169 + return { name: JSON.stringify(name), needsConvertPropertyAccess: false }; + case CompletionKind.PropertyAccess: + // Don't add a completion for a name starting with a space. See https://github.com/Microsoft/TypeScript/pull/20547 + return name.charCodeAt(0) === CharacterCodes.space ? undefined : { name, needsConvertPropertyAccess: true }; + case CompletionKind.String: + return validIdentiferResult; + default: + Debug.assertNever(kind); + } } // A cache of completion entries for keywords, these do not change between sessions @@ -2028,7 +2078,7 @@ namespace ts.Completions { return _keywordCompletions[keywordFilter] = generateKeywordCompletions(keywordFilter); type FilterKeywordCompletions = (entryName: string) => boolean; - function generateKeywordCompletions(keywordFilter: KeywordCompletionFilters) { + function generateKeywordCompletions(keywordFilter: KeywordCompletionFilters): CompletionEntry[] { switch (keywordFilter) { case KeywordCompletionFilters.None: return getAllKeywordCompletions(); @@ -2036,6 +2086,8 @@ namespace ts.Completions { return getFilteredKeywordCompletions(isClassMemberCompletionKeywordText); case KeywordCompletionFilters.ConstructorParameterKeywords: return getFilteredKeywordCompletions(isConstructorParameterCompletionKeywordText); + default: + Debug.assertNever(keywordFilter); } } diff --git a/src/services/services.ts b/src/services/services.ts index 94862980ca7..eb5e3ae5743 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1432,7 +1432,7 @@ namespace ts { return [...program.getOptionsDiagnostics(cancellationToken), ...program.getGlobalDiagnostics(cancellationToken)]; } - function getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions = { includeExternalModuleExports: false }): CompletionInfo { + function getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions = { includeExternalModuleExports: false, includeInsertTextCompletions: false }): CompletionInfo { synchronizeHostData(); return Completions.getCompletionsAtPosition( host, diff --git a/src/services/types.ts b/src/services/types.ts index 8e670486649..597709a7c79 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -333,6 +333,7 @@ namespace ts { export interface GetCompletionsAtPositionOptions { includeExternalModuleExports: boolean; + includeInsertTextCompletions: boolean; } export interface ApplyCodeActionCommandResult { @@ -748,6 +749,7 @@ namespace ts { kind: ScriptElementKind; kindModifiers: string; // see ScriptElementKindModifier, comma separated sortText: string; + insertText?: string; /** * An optional span that indicates the text to be replaced by this completion item. * If present, this span should be used instead of the default one. diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 116bedfabb7..b0dc9e3b6eb 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4001,6 +4001,7 @@ declare namespace ts { } interface GetCompletionsAtPositionOptions { includeExternalModuleExports: boolean; + includeInsertTextCompletions: boolean; } interface ApplyCodeActionCommandResult { successMessage: string; @@ -4345,6 +4346,7 @@ declare namespace ts { kind: ScriptElementKind; kindModifiers: string; sortText: string; + insertText?: string; /** * An optional span that indicates the text to be replaced by this completion item. * If present, this span should be used instead of the default one. @@ -6108,6 +6110,11 @@ declare namespace ts.server.protocol { * This affects lone identifier completions but not completions on the right hand side of `obj.`. */ includeExternalModuleExports: boolean; + /** + * If enabled, the completion list will include completions with invalid identifier names. + * For those entries, The `insertText` and `replacementSpan` properties will be set to change from `.x` property access to `["x"]`. + */ + includeInsertTextCompletions: boolean; } /** * Completions request; value of command field is "completions". @@ -6176,6 +6183,12 @@ declare namespace ts.server.protocol { * is often the same as the name but may be different in certain circumstances. */ sortText: string; + /** + * Text to insert instead of `name`. + * This is used to support bracketed completions; If `name` might be "a-b" but `insertText` would be `["a-b"]`, + * coupled with `replacementSpan` to replace a dotted access with a bracket access. + */ + insertText?: string; /** * An optional span that indicates the text to be replaced by this completion item. * If present, this span should be used instead of the default one. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 8a01bc3a896..f839deabcfb 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4001,6 +4001,7 @@ declare namespace ts { } interface GetCompletionsAtPositionOptions { includeExternalModuleExports: boolean; + includeInsertTextCompletions: boolean; } interface ApplyCodeActionCommandResult { successMessage: string; @@ -4345,6 +4346,7 @@ declare namespace ts { kind: ScriptElementKind; kindModifiers: string; sortText: string; + insertText?: string; /** * An optional span that indicates the text to be replaced by this completion item. * If present, this span should be used instead of the default one. diff --git a/tests/cases/fourslash/completionListInvalidMemberNames.ts b/tests/cases/fourslash/completionListInvalidMemberNames.ts index 8e62ba2fb67..3dc54274e83 100644 --- a/tests/cases/fourslash/completionListInvalidMemberNames.ts +++ b/tests/cases/fourslash/completionListInvalidMemberNames.ts @@ -11,8 +11,21 @@ //// "\u0031\u0062": "invalid unicode identifer name (1b)" ////}; //// -////x./*a*/; +////x[|./*a*/|]; ////x["/*b*/"]; -verify.completionsAt("a", ["bar", "break", "any", "$", "b"]); -verify.completionsAt("b", ["foo ", "bar", "break", "any", "#", "$", "b", "\u0031\u0062"]); +verify.completionsAt("b", ["foo ", "bar", "break", "any", "#", "$", "b", "1b"]); + +const replacementSpan = test.ranges()[0]; +verify.completionsAt("a", [ + { name: "foo ", insertText: '["foo "]', replacementSpan }, + "bar", + "break", + "any", + { name: "#", insertText: '["#"]', replacementSpan }, + "$", + "b", + { name: "1b", insertText: '["1b"]', replacementSpan }, +], { + includeInsertTextCompletions: true, +}); diff --git a/tests/cases/fourslash/completionListInvalidMemberNames2.ts b/tests/cases/fourslash/completionListInvalidMemberNames2.ts index 753f9bbcb30..153ed3bdb5e 100644 --- a/tests/cases/fourslash/completionListInvalidMemberNames2.ts +++ b/tests/cases/fourslash/completionListInvalidMemberNames2.ts @@ -1,10 +1,19 @@ /// -////enum Foo { -//// X, Y, '☆' -////} -////Foo./*a*/; -////Foo["/*b*/"]; +// TODO: we should probably support this like we do in completionListInvalidMemberNames.ts -verify.completionsAt("a", ["X", "Y"]); -verify.completionsAt("b", ["X", "Y", "☆"]); +////declare var Symbol: SymbolConstructor; +////interface SymbolConstructor { +//// readonly hasInstance: symbol; +////} +////interface Function { +//// [Symbol.hasInstance](value: any): boolean; +////} +////interface SomeInterface { +//// (value: number): any; +////} +////var _ : SomeInterface; +////_./**/ + +goTo.marker(); +verify.not.completionListContains("[Symbol.hasInstance]"); diff --git a/tests/cases/fourslash/completionListInvalidMemberNames3.ts b/tests/cases/fourslash/completionListInvalidMemberNames3.ts deleted file mode 100644 index cf1141b4094..00000000000 --- a/tests/cases/fourslash/completionListInvalidMemberNames3.ts +++ /dev/null @@ -1,71 +0,0 @@ -/// - -// @allowjs: true - -// @Filename: test.js -////interface Symbol { -//// /** Returns a string representation of an object. */ -//// toString(): string; - -//// /** Returns the primitive value of the specified object. */ -//// valueOf(): Object; -////} - -////interface SymbolConstructor { -//// /** -//// * A reference to the prototype. -//// */ -//// readonly prototype: Symbol; - -//// /** -//// * Returns a new unique Symbol value. -//// * @param description Description of the new Symbol object. -//// */ -//// (description?: string | number): symbol; - -//// /** -//// * Returns a Symbol object from the global symbol registry matching the given key if found. -//// * Otherwise, returns a new symbol with this key. -//// * @param key key to search for. -//// */ -//// for(key: string): symbol; - -//// /** -//// * Returns a key from the global symbol registry matching the given Symbol if found. -//// * Otherwise, returns a undefined. -//// * @param sym Symbol to find the key for. -//// */ -//// keyFor(sym: symbol): string | undefined; -////} - -////declare var Symbol: SymbolConstructor;/// - -////interface SymbolConstructor { -//// /** -//// * A method that determines if a constructor object recognizes an object as one of the -//// * constructors instances. Called by the semantics of the instanceof operator. -//// */ -//// readonly hasInstance: symbol; -////} - -////interface Function { -//// /** -//// * Determines whether the given value inherits from this function if this function was used -//// * as a constructor function. -//// * -//// * A constructor function can control which objects are recognized as its instances by -//// * 'instanceof' by overriding this method. -//// */ -//// [Symbol.hasInstance](value: any): boolean; -////} - -////interface SomeInterface { -//// (value: number): any; -////} - -////var _ : SomeInterface; -////_./**/ - -goTo.marker(); - -verify.not.completionListContains("[Symbol.hasInstance]"); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInvalidMemberNames_startWithSpace.ts b/tests/cases/fourslash/completionListInvalidMemberNames_startWithSpace.ts new file mode 100644 index 00000000000..f86c8a5a813 --- /dev/null +++ b/tests/cases/fourslash/completionListInvalidMemberNames_startWithSpace.ts @@ -0,0 +1,8 @@ +/// + +////declare const x: { " foo": 0, "foo ": 1 }; +////x[|./**/|]; + +const replacementSpan = test.ranges()[0]; +// No completion for " foo" because it starts with a space. See https://github.com/Microsoft/TypeScript/pull/20547 +verify.completionsAt("", [{ name: "foo ", insertText: '["foo "]', replacementSpan }], { includeInsertTextCompletions: true }); diff --git a/tests/cases/fourslash/completionListInvalidMemberNames_withExistingIdentifier.ts b/tests/cases/fourslash/completionListInvalidMemberNames_withExistingIdentifier.ts new file mode 100644 index 00000000000..8463a710b01 --- /dev/null +++ b/tests/cases/fourslash/completionListInvalidMemberNames_withExistingIdentifier.ts @@ -0,0 +1,7 @@ +/// + +////declare const x: { "foo ": "space in the name", }; +////x[|.fo/**/|]; + +const replacementSpan = test.ranges()[0]; +verify.completionsAt("", [{ name: "foo ", insertText: '["foo "]', replacementSpan }], { includeInsertTextCompletions: true }); diff --git a/tests/cases/fourslash/completion_enum-members-with-invalid-identifiers-should-not-show-in-completion.ts b/tests/cases/fourslash/completion_enum-members-with-invalid-identifiers-should-not-show-in-completion.ts deleted file mode 100644 index 6d5b3167198..00000000000 --- a/tests/cases/fourslash/completion_enum-members-with-invalid-identifiers-should-not-show-in-completion.ts +++ /dev/null @@ -1,13 +0,0 @@ -/// - -//// enum e { -//// "1", -//// 2 = 3, -//// 3, -//// a, -//// b -//// } -//// -//// e./**/ - -verify.completionsAt("", ["a", "b"]); diff --git a/tests/cases/fourslash/completionsPaths.ts b/tests/cases/fourslash/completionsPaths.ts index 454ef78eef8..6bb2fb38706 100644 --- a/tests/cases/fourslash/completionsPaths.ts +++ b/tests/cases/fourslash/completionsPaths.ts @@ -12,19 +12,19 @@ ////not read // @Filename: /src/a.ts -////import {} from "/*1*/"; +////import {} from "[|/*1*/|]"; // @Filename: /src/folder/b.ts -////import {} from "x//*2*/"; +////import {} from "x/[|/*2*/|]"; // @Filename: /src/folder/c.ts -////const foo = require("x//*3*/"); +////const foo = require("x/[|/*3*/|]"); // @Filename: /src/folder/4.ts -////const foo = require(`x//*4*/`); - -verify.completionsAt("1", ["y", "x"]); -verify.completionsAt("2", ["bar", "foo"]); -verify.completionsAt("3", ["bar", "foo"]); -verify.completionsAt("4", ["bar", "foo"]); +////const foo = require(`x/[|/*4*/|]`); +const [r0, r1, r2, r3] = test.ranges(); +verify.completionsAt("1", [{ name: "y", replacementSpan: r0 }, { name: "x", replacementSpan: r0 }]); +verify.completionsAt("2", [{ name: "bar", replacementSpan: r1 }, { name: "foo", replacementSpan: r1 }]); +verify.completionsAt("3", [{ name: "bar", replacementSpan: r2 }, { name: "foo", replacementSpan: r2 }]); +verify.completionsAt("4", [{ name: "bar", replacementSpan: r3 }, { name: "foo", replacementSpan: r3 }]); diff --git a/tests/cases/fourslash/completionsPaths_pathMapping.ts b/tests/cases/fourslash/completionsPaths_pathMapping.ts index 61ea3d5d936..b2ec9ac6198 100644 --- a/tests/cases/fourslash/completionsPaths_pathMapping.ts +++ b/tests/cases/fourslash/completionsPaths_pathMapping.ts @@ -4,7 +4,7 @@ ////export const x = 0; // @Filename: /src/a.ts -////import {} from "foo//**/"; +////import {} from "foo/[|/**/|]"; // @Filename: /tsconfig.json ////{ @@ -16,4 +16,5 @@ //// } ////} -verify.completionsAt("", ["a", "b"]); +const [replacementSpan] = test.ranges(); +verify.completionsAt("", [{ name: "a", replacementSpan }, { name: "b", replacementSpan }]); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index ec2a5d1a2ea..426518794bd 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -188,7 +188,10 @@ declare namespace FourSlashInterface { class verify extends verifyNegatable { assertHasRanges(ranges: Range[]): void; caretAtMarker(markerName?: string): void; - completionsAt(markerName: string, completions: string[], options?: { isNewIdentifierLocation?: boolean }): void; + completionsAt(markerName: string, completions: ReadonlyArray, options?: { + isNewIdentifierLocation?: boolean; + includeInsertTextCompletions?: boolean; + }): void; completionsAndDetailsAt( markerName: string, completions: { diff --git a/tests/cases/fourslash/jsdocTypedefTagTypeExpressionCompletion.ts b/tests/cases/fourslash/jsdocTypedefTagTypeExpressionCompletion.ts index 379cc60e058..b7a2b7d8993 100644 --- a/tests/cases/fourslash/jsdocTypedefTagTypeExpressionCompletion.ts +++ b/tests/cases/fourslash/jsdocTypedefTagTypeExpressionCompletion.ts @@ -11,7 +11,7 @@ //// /** //// * @param {string} foo A value. //// * @returns {number} Another value -//// * @mytag +//// * @mytag //// */ //// method4(foo: string) { return 3; } //// } From 062f97a6fa4532487a8d78e2eb798bdd2aa06103 Mon Sep 17 00:00:00 2001 From: Wenlu Wang <805037171@163.com> Date: Wed, 10 Jan 2018 01:24:00 +0800 Subject: [PATCH 118/189] allow const enum in type query (#21083) --- src/compiler/checker.ts | 5 ++- src/compiler/diagnosticMessages.json | 2 +- tests/baselines/reference/constEnum3.js | 20 +++++++++ tests/baselines/reference/constEnum3.symbols | 38 ++++++++++++++++ tests/baselines/reference/constEnum3.types | 44 +++++++++++++++++++ .../reference/constEnumErrors.errors.txt | 12 ++--- .../constEnumPropertyAccess2.errors.txt | 4 +- .../conformance/constEnums/constEnum3.ts | 10 +++++ 8 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 tests/baselines/reference/constEnum3.js create mode 100644 tests/baselines/reference/constEnum3.symbols create mode 100644 tests/baselines/reference/constEnum3.types create mode 100644 tests/cases/conformance/constEnums/constEnum3.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ef107c2bc68..9455b659c08 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19474,10 +19474,11 @@ namespace ts { const ok = (node.parent.kind === SyntaxKind.PropertyAccessExpression && (node.parent).expression === node) || (node.parent.kind === SyntaxKind.ElementAccessExpression && (node.parent).expression === node) || - ((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(node)); + ((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(node) || + (node.parent.kind === SyntaxKind.TypeQuery && (node.parent).exprName === node)); if (!ok) { - error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment); + error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query); } } return type; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4fa32251549..3fc415b37a0 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1620,7 +1620,7 @@ "category": "Error", "code": 2474 }, - "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment.": { + "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.": { "category": "Error", "code": 2475 }, diff --git a/tests/baselines/reference/constEnum3.js b/tests/baselines/reference/constEnum3.js new file mode 100644 index 00000000000..c219975d10f --- /dev/null +++ b/tests/baselines/reference/constEnum3.js @@ -0,0 +1,20 @@ +//// [constEnum3.ts] +const enum TestType { foo, bar } +type TestTypeStr = keyof typeof TestType; + +function f1(f: TestType) { } +function f2(f: TestTypeStr) { } + +f1(TestType.foo) +f1(TestType.bar) +f2('foo') +f2('bar') + + +//// [constEnum3.js] +function f1(f) { } +function f2(f) { } +f1(0 /* foo */); +f1(1 /* bar */); +f2('foo'); +f2('bar'); diff --git a/tests/baselines/reference/constEnum3.symbols b/tests/baselines/reference/constEnum3.symbols new file mode 100644 index 00000000000..159d866c9a6 --- /dev/null +++ b/tests/baselines/reference/constEnum3.symbols @@ -0,0 +1,38 @@ +=== tests/cases/conformance/constEnums/constEnum3.ts === +const enum TestType { foo, bar } +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) +>foo : Symbol(TestType.foo, Decl(constEnum3.ts, 0, 21)) +>bar : Symbol(TestType.bar, Decl(constEnum3.ts, 0, 26)) + +type TestTypeStr = keyof typeof TestType; +>TestTypeStr : Symbol(TestTypeStr, Decl(constEnum3.ts, 0, 32)) +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) + +function f1(f: TestType) { } +>f1 : Symbol(f1, Decl(constEnum3.ts, 1, 41)) +>f : Symbol(f, Decl(constEnum3.ts, 3, 12)) +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) + +function f2(f: TestTypeStr) { } +>f2 : Symbol(f2, Decl(constEnum3.ts, 3, 28)) +>f : Symbol(f, Decl(constEnum3.ts, 4, 12)) +>TestTypeStr : Symbol(TestTypeStr, Decl(constEnum3.ts, 0, 32)) + +f1(TestType.foo) +>f1 : Symbol(f1, Decl(constEnum3.ts, 1, 41)) +>TestType.foo : Symbol(TestType.foo, Decl(constEnum3.ts, 0, 21)) +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) +>foo : Symbol(TestType.foo, Decl(constEnum3.ts, 0, 21)) + +f1(TestType.bar) +>f1 : Symbol(f1, Decl(constEnum3.ts, 1, 41)) +>TestType.bar : Symbol(TestType.bar, Decl(constEnum3.ts, 0, 26)) +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) +>bar : Symbol(TestType.bar, Decl(constEnum3.ts, 0, 26)) + +f2('foo') +>f2 : Symbol(f2, Decl(constEnum3.ts, 3, 28)) + +f2('bar') +>f2 : Symbol(f2, Decl(constEnum3.ts, 3, 28)) + diff --git a/tests/baselines/reference/constEnum3.types b/tests/baselines/reference/constEnum3.types new file mode 100644 index 00000000000..fd14b87e0da --- /dev/null +++ b/tests/baselines/reference/constEnum3.types @@ -0,0 +1,44 @@ +=== tests/cases/conformance/constEnums/constEnum3.ts === +const enum TestType { foo, bar } +>TestType : TestType +>foo : TestType.foo +>bar : TestType.bar + +type TestTypeStr = keyof typeof TestType; +>TestTypeStr : "foo" | "bar" +>TestType : typeof TestType + +function f1(f: TestType) { } +>f1 : (f: TestType) => void +>f : TestType +>TestType : TestType + +function f2(f: TestTypeStr) { } +>f2 : (f: "foo" | "bar") => void +>f : "foo" | "bar" +>TestTypeStr : "foo" | "bar" + +f1(TestType.foo) +>f1(TestType.foo) : void +>f1 : (f: TestType) => void +>TestType.foo : TestType.foo +>TestType : typeof TestType +>foo : TestType.foo + +f1(TestType.bar) +>f1(TestType.bar) : void +>f1 : (f: TestType) => void +>TestType.bar : TestType.bar +>TestType : typeof TestType +>bar : TestType.bar + +f2('foo') +>f2('foo') : void +>f2 : (f: "foo" | "bar") => void +>'foo' : "foo" + +f2('bar') +>f2('bar') : void +>f2 : (f: "foo" | "bar") => void +>'bar' : "bar" + diff --git a/tests/baselines/reference/constEnumErrors.errors.txt b/tests/baselines/reference/constEnumErrors.errors.txt index 586652d41eb..c2642c9b1ac 100644 --- a/tests/baselines/reference/constEnumErrors.errors.txt +++ b/tests/baselines/reference/constEnumErrors.errors.txt @@ -5,9 +5,9 @@ tests/cases/compiler/constEnumErrors.ts(14,9): error TS2474: In 'const' enum dec tests/cases/compiler/constEnumErrors.ts(15,10): error TS2474: In 'const' enum declarations member initializer must be constant expression. tests/cases/compiler/constEnumErrors.ts(22,13): error TS2476: A const enum member can only be accessed using a string literal. tests/cases/compiler/constEnumErrors.ts(24,13): error TS2476: A const enum member can only be accessed using a string literal. -tests/cases/compiler/constEnumErrors.ts(26,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. -tests/cases/compiler/constEnumErrors.ts(27,10): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. -tests/cases/compiler/constEnumErrors.ts(32,5): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. +tests/cases/compiler/constEnumErrors.ts(26,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. +tests/cases/compiler/constEnumErrors.ts(27,10): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. +tests/cases/compiler/constEnumErrors.ts(32,5): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. tests/cases/compiler/constEnumErrors.ts(40,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value. tests/cases/compiler/constEnumErrors.ts(41,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value. tests/cases/compiler/constEnumErrors.ts(42,9): error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'. @@ -55,17 +55,17 @@ tests/cases/compiler/constEnumErrors.ts(42,9): error TS2478: 'const' enum member var x = E2; ~~ -!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. +!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. var y = [E2]; ~~ -!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. +!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. function foo(t: any): void { } foo(E2); ~~ -!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. +!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. const enum NaNOrInfinity { A = 9007199254740992, diff --git a/tests/baselines/reference/constEnumPropertyAccess2.errors.txt b/tests/baselines/reference/constEnumPropertyAccess2.errors.txt index aa08c11c7a2..40731d3ad54 100644 --- a/tests/baselines/reference/constEnumPropertyAccess2.errors.txt +++ b/tests/baselines/reference/constEnumPropertyAccess2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(13,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. +tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(13,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(14,12): error TS2476: A const enum member can only be accessed using a string literal. tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(16,1): error TS2322: Type '"string"' is not assignable to type 'G'. tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(18,3): error TS2540: Cannot assign to 'B' because it is a constant or a read-only property. @@ -19,7 +19,7 @@ tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(18,3): error TS25 // Error from referring constant enum in any other context than a property access var z = G; ~ -!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. +!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. var z1 = G[G.A]; ~~~ !!! error TS2476: A const enum member can only be accessed using a string literal. diff --git a/tests/cases/conformance/constEnums/constEnum3.ts b/tests/cases/conformance/constEnums/constEnum3.ts new file mode 100644 index 00000000000..ffc6bb1c5f5 --- /dev/null +++ b/tests/cases/conformance/constEnums/constEnum3.ts @@ -0,0 +1,10 @@ +const enum TestType { foo, bar } +type TestTypeStr = keyof typeof TestType; + +function f1(f: TestType) { } +function f2(f: TestTypeStr) { } + +f1(TestType.foo) +f1(TestType.bar) +f2('foo') +f2('bar') From 5ab5694a5b4766216ecd39ef3f47b4add92d3f32 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 9 Jan 2018 09:53:39 -0800 Subject: [PATCH 119/189] Don't count self-reference in more cases (skip more nodes when setting lastNonBlockLocation) (#21095) --- src/compiler/checker.ts | 18 ++++++++-- ...lfReference_skipsBlockLocations.errors.txt | 29 +++++++++++++++ ...ocals_selfReference_skipsBlockLocations.js | 36 +++++++++++++++++++ ..._selfReference_skipsBlockLocations.symbols | 29 +++++++++++++++ ...ls_selfReference_skipsBlockLocations.types | 33 +++++++++++++++++ ...ocals_selfReference_skipsBlockLocations.ts | 18 ++++++++++ 6 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.errors.txt create mode 100644 tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.js create mode 100644 tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.symbols create mode 100644 tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.types create mode 100644 tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9455b659c08..ca5ce39cef7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1187,7 +1187,7 @@ namespace ts { } break; } - if (location.kind !== SyntaxKind.Block) { + if (isNonBlockLocation(location)) { lastNonBlockLocation = location; } lastLocation = location; @@ -1195,7 +1195,7 @@ namespace ts { } // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`. - // If `result === lastLocation.symbol`, that means that we are somewhere inside `lastLocation` looking up a name, and resolving to `lastLocation` itself. + // If `result === lastNonBlockLocation.symbol`, that means that we are somewhere inside `lastNonBlockLocation` looking up a name, and resolving to `lastLocation` itself. // That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used. if (isUse && result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastNonBlockLocation.symbol) { result.isReferenced = true; @@ -1278,6 +1278,20 @@ namespace ts { return result; } + function isNonBlockLocation({ kind }: Node): boolean { + switch (kind) { + case SyntaxKind.Block: + case SyntaxKind.ModuleBlock: + case SyntaxKind.SwitchStatement: + case SyntaxKind.CaseBlock: + case SyntaxKind.CaseClause: + case SyntaxKind.DefaultClause: + return false; + default: + return true; + } + } + function diagnosticName(nameArg: __String | Identifier) { return isString(nameArg) ? unescapeLeadingUnderscores(nameArg as __String) : declarationNameToString(nameArg as Identifier); } diff --git a/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.errors.txt b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.errors.txt new file mode 100644 index 00000000000..9ea0147978a --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.errors.txt @@ -0,0 +1,29 @@ +tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(2,14): error TS6133: 'f' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(8,22): error TS6133: 'g' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(12,22): error TS6133: 'h' is declared but its value is never read. + + +==== tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts (3 errors) ==== + namespace n { + function f() { + ~ +!!! error TS6133: 'f' is declared but its value is never read. + f; + } + + switch (0) { + case 0: + function g() { + ~ +!!! error TS6133: 'g' is declared but its value is never read. + g; + } + default: + function h() { + ~ +!!! error TS6133: 'h' is declared but its value is never read. + h; + } + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.js b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.js new file mode 100644 index 00000000000..2b33ed8c31d --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.js @@ -0,0 +1,36 @@ +//// [noUnusedLocals_selfReference_skipsBlockLocations.ts] +namespace n { + function f() { + f; + } + + switch (0) { + case 0: + function g() { + g; + } + default: + function h() { + h; + } + } +} + + +//// [noUnusedLocals_selfReference_skipsBlockLocations.js] +var n; +(function (n) { + function f() { + f; + } + switch (0) { + case 0: + function g() { + g; + } + default: + function h() { + h; + } + } +})(n || (n = {})); diff --git a/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.symbols b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.symbols new file mode 100644 index 00000000000..7607caf3d7e --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts === +namespace n { +>n : Symbol(n, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 0, 0)) + + function f() { +>f : Symbol(f, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 0, 13)) + + f; +>f : Symbol(f, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 0, 13)) + } + + switch (0) { + case 0: + function g() { +>g : Symbol(g, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 6, 15)) + + g; +>g : Symbol(g, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 6, 15)) + } + default: + function h() { +>h : Symbol(h, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 10, 16)) + + h; +>h : Symbol(h, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 10, 16)) + } + } +} + diff --git a/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.types b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.types new file mode 100644 index 00000000000..6675db4f1c3 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts === +namespace n { +>n : typeof n + + function f() { +>f : () => void + + f; +>f : () => void + } + + switch (0) { +>0 : 0 + + case 0: +>0 : 0 + + function g() { +>g : () => void + + g; +>g : () => void + } + default: + function h() { +>h : () => void + + h; +>h : () => void + } + } +} + diff --git a/tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts b/tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts new file mode 100644 index 00000000000..bcaa9010715 --- /dev/null +++ b/tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts @@ -0,0 +1,18 @@ +// @noUnusedLocals: true + +namespace n { + function f() { + f; + } + + switch (0) { + case 0: + function g() { + g; + } + default: + function h() { + h; + } + } +} From ba979fa5370734889a47617495eccf389209dde6 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 9 Jan 2018 10:11:28 -0800 Subject: [PATCH 120/189] Delete redundant test (#21085) The same test already exists for TS. --- .../importNameCodeFixDefaultExport3.ts | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 tests/cases/fourslash/importNameCodeFixDefaultExport3.ts diff --git a/tests/cases/fourslash/importNameCodeFixDefaultExport3.ts b/tests/cases/fourslash/importNameCodeFixDefaultExport3.ts deleted file mode 100644 index 1d4c6bae8c2..00000000000 --- a/tests/cases/fourslash/importNameCodeFixDefaultExport3.ts +++ /dev/null @@ -1,21 +0,0 @@ -/// - -// @allowJs: true -// @checkJs: true - -// @Filename: /lib.js -////class Base { } -////export { Base as default }; - -// @Filename: /test.js -////[|class Derived extends Base { }|] - -goTo.file("/test.js"); -verify.importFixAtPosition([ -`// @ts-ignore -class Derived extends Base { }`, -`// @ts-nocheck -class Derived extends Base { }`, -`import Base from "./lib"; - -class Derived extends Base { }`,]); From fdd8a52240e1576cc349d2ff73eeb44264f1d862 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 9 Jan 2018 10:20:07 -0800 Subject: [PATCH 121/189] Offer per-member diagnostics for incorrectly implemented inherited members (#21036) * Offer per-member diagnostics for incorrectly implemented inherited members on classes * Revise error message, make containingChain a thunk * Fix typo in comment --- src/compiler/checker.ts | 66 ++++- src/compiler/diagnosticMessages.json | 4 + .../abstractPropertyNegative.errors.txt | 36 ++- .../apparentTypeSubtyping.errors.txt | 16 +- .../apparentTypeSupertype.errors.txt | 20 +- ...baseClassImprovedMismatchErrors.errors.txt | 73 ++++++ .../baseClassImprovedMismatchErrors.js | 57 +++++ .../baseClassImprovedMismatchErrors.symbols | 42 +++ .../baseClassImprovedMismatchErrors.types | 47 ++++ .../classIsSubtypeOfBaseType.errors.txt | 16 +- ...ctionOverridesBaseClassAccessor.errors.txt | 12 +- ...tructuringParameterDeclaration2.errors.txt | 24 +- .../reference/elaboratedErrors.errors.txt | 12 +- .../reference/genericImplements.errors.txt | 16 +- .../genericSpecializations1.errors.txt | 40 ++- .../genericSpecializations2.errors.txt | 40 ++- .../genericSpecializations3.errors.txt | 20 +- ...cTypeWithNonGenericBaseMisMatch.errors.txt | 20 +- ...ementGenericWithMismatchedTypes.errors.txt | 36 ++- ...mplementsIncorrectlyNoAssertion.errors.txt | 14 +- .../reference/incompatibleTypes.errors.txt | 62 ++--- .../reference/inheritance.errors.txt | 12 +- ...eMemberAccessorOverridingMethod.errors.txt | 19 +- ...nceMemberFuncOverridingAccessor.errors.txt | 12 +- .../instanceSubtypeCheck2.errors.txt | 12 +- .../interfaceDeclaration3.errors.txt | 24 +- ...terfaceExtendsClassWithPrivate2.errors.txt | 17 +- ...ExtendsObjectIntersectionErrors.errors.txt | 62 ++--- .../interfaceImplementation7.errors.txt | 16 +- .../mismatchedGenericArguments1.errors.txt | 40 ++- .../reference/multipleInheritance.errors.txt | 12 +- .../requiredInitializedParameter2.errors.txt | 12 +- .../subtypesOfTypeParameter.errors.txt | 12 +- ...sOfTypeParameterWithConstraints.errors.txt | 140 +++++----- ...OfTypeParameterWithConstraints4.errors.txt | 68 +++-- ...rameterWithRecursiveConstraints.errors.txt | 240 ++++++++---------- .../subtypingWithObjectMembers.errors.txt | 72 +++--- .../baseClassImprovedMismatchErrors.ts | 18 ++ tests/cases/fourslash/incompatibleOverride.ts | 4 +- .../squiggleIllegalSubclassOverride.ts | 4 +- 40 files changed, 799 insertions(+), 670 deletions(-) create mode 100644 tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt create mode 100644 tests/baselines/reference/baseClassImprovedMismatchErrors.js create mode 100644 tests/baselines/reference/baseClassImprovedMismatchErrors.symbols create mode 100644 tests/baselines/reference/baseClassImprovedMismatchErrors.types create mode 100644 tests/cases/compiler/baseClassImprovedMismatchErrors.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ca5ce39cef7..d153eee3034 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9169,7 +9169,7 @@ namespace ts { return isTypeComparableTo(type1, type2) || isTypeComparableTo(type2, type1); } - function checkTypeAssignableTo(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: DiagnosticMessageChain): boolean { + function checkTypeAssignableTo(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean { return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain); } @@ -9177,7 +9177,7 @@ namespace ts { * This is *not* a bi-directional relationship. * If one needs to check both directions for comparability, use a second call to this function or 'isTypeComparableTo'. */ - function checkTypeComparableTo(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: DiagnosticMessageChain): boolean { + function checkTypeComparableTo(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean { return checkTypeRelatedTo(source, target, comparableRelation, errorNode, headMessage, containingMessageChain); } @@ -9511,7 +9511,7 @@ namespace ts { relation: Map, errorNode: Node, headMessage?: DiagnosticMessage, - containingMessageChain?: DiagnosticMessageChain): boolean { + containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean { let errorInfo: DiagnosticMessageChain; let maybeKeys: string[]; @@ -9531,7 +9531,10 @@ namespace ts { } else if (errorInfo) { if (containingMessageChain) { - errorInfo = concatenateDiagnosticMessageChains(containingMessageChain, errorInfo); + const chain = containingMessageChain(); + if (chain) { + errorInfo = concatenateDiagnosticMessageChains(chain, errorInfo); + } } diagnostics.add(createDiagnosticForNodeFromMessageChain(errorNode, errorInfo)); @@ -16675,7 +16678,7 @@ namespace ts { const constraint = getConstraintOfTypeParameter(typeParameters[i]); if (!constraint) continue; - const errorInfo = reportErrors && headMessage && chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Type_0_does_not_satisfy_the_constraint_1); + const errorInfo = reportErrors && headMessage && (() => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Type_0_does_not_satisfy_the_constraint_1)); const typeArgumentHeadMessage = headMessage || Diagnostics.Type_0_does_not_satisfy_the_constraint_1; if (!mapper) { mapper = createTypeMapper(typeParameters, typeArgumentTypes); @@ -19697,7 +19700,7 @@ namespace ts { Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter); } else { - const leadingError = chainDiagnosticMessages(/*details*/ undefined, Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); + const leadingError = () => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); checkTypeAssignableTo(typePredicate.type, getTypeOfNode(parent.parameters[typePredicate.parameterIndex]), node.type, @@ -20984,7 +20987,7 @@ namespace ts { expectedReturnType, node, headMessage, - errorInfo); + () => errorInfo); } /** @@ -22907,7 +22910,10 @@ namespace ts { } } } - checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name || node, Diagnostics.Class_0_incorrectly_extends_base_class_1); + const baseWithThis = getTypeWithThisArgument(baseType, type.thisType); + if (!checkTypeAssignableTo(typeWithThis, baseWithThis, /*errorNode*/ undefined)) { + issueMemberSpecificError(node, typeWithThis, baseWithThis, Diagnostics.Class_0_incorrectly_extends_base_class_1); + } checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1); if (baseConstructorType.flags & TypeFlags.TypeVariable && !isMixinConstructorType(staticType)) { @@ -22939,12 +22945,13 @@ namespace ts { const t = getTypeFromTypeNode(typeRefNode); if (t !== unknownType) { if (isValidBaseType(t)) { - checkTypeAssignableTo(typeWithThis, - getTypeWithThisArgument(t, type.thisType), - node.name || node, - t.symbol && t.symbol.flags & SymbolFlags.Class ? - Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass : - Diagnostics.Class_0_incorrectly_implements_interface_1); + const genericDiag = t.symbol && t.symbol.flags & SymbolFlags.Class ? + Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass : + Diagnostics.Class_0_incorrectly_implements_interface_1; + const baseWithThis = getTypeWithThisArgument(t, type.thisType); + if (!checkTypeAssignableTo(typeWithThis, baseWithThis, /*errorNode*/ undefined)) { + issueMemberSpecificError(node, typeWithThis, baseWithThis, genericDiag); + } } else { error(typeRefNode, Diagnostics.A_class_may_only_implement_another_class_or_interface); @@ -22961,6 +22968,37 @@ namespace ts { } } + function issueMemberSpecificError(node: ClassLikeDeclaration, typeWithThis: Type, baseWithThis: Type, broadDiag: DiagnosticMessage) { + // iterate over all implemented properties and issue errors on each one which isn't compatible, rather than the class as a whole, if possible + let issuedMemberError = false; + for (const member of node.members) { + if (hasStaticModifier(member)) { + continue; + } + const declaredProp = member.name && getSymbolAtLocation(member.name) || getSymbolAtLocation(member); + if (declaredProp) { + const prop = getPropertyOfType(typeWithThis, declaredProp.escapedName); + const baseProp = getPropertyOfType(baseWithThis, declaredProp.escapedName); + if (prop && baseProp) { + const rootChain = () => chainDiagnosticMessages( + /*details*/ undefined, + Diagnostics.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2, + unescapeLeadingUnderscores(declaredProp.escapedName), + typeToString(typeWithThis), + typeToString(getTypeOfSymbol(baseProp)) + ); + if (!checkTypeAssignableTo(getTypeOfSymbol(prop), getTypeOfSymbol(baseProp), member.name || member, /*message*/ undefined, rootChain)) { + issuedMemberError = true; + } + } + } + } + if (!issuedMemberError) { + // check again with diagnostics to generate a less-specific error + checkTypeAssignableTo(typeWithThis, baseWithThis, node.name || node, broadDiag); + } + } + function checkBaseTypeAccessibility(type: Type, node: ExpressionWithTypeArguments) { const signatures = getSignaturesOfType(type, SignatureKind.Construct); if (signatures.length) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 3fc415b37a0..4a705ce97fe 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1404,6 +1404,10 @@ "category": "Error", "code": 2415 }, + "Property '{0}' in type '{1}' is not assignable to the same property in base type '{2}'.": { + "category": "Error", + "code": 2416 + }, "Class static side '{0}' incorrectly extends base class static side '{1}'.": { "category": "Error", "code": 2417 diff --git a/tests/baselines/reference/abstractPropertyNegative.errors.txt b/tests/baselines/reference/abstractPropertyNegative.errors.txt index 314ab842ded..6e4cae81db9 100644 --- a/tests/baselines/reference/abstractPropertyNegative.errors.txt +++ b/tests/baselines/reference/abstractPropertyNegative.errors.txt @@ -7,15 +7,12 @@ tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS2515: Non-abstra tests/cases/compiler/abstractPropertyNegative.ts(15,5): error TS1244: Abstract methods can only appear within an abstract class. tests/cases/compiler/abstractPropertyNegative.ts(16,37): error TS1005: '{' expected. tests/cases/compiler/abstractPropertyNegative.ts(19,3): error TS2540: Cannot assign to 'ro' because it is a constant or a read-only property. -tests/cases/compiler/abstractPropertyNegative.ts(24,7): error TS2415: Class 'WrongTypePropertyImpl' incorrectly extends base class 'WrongTypeProperty'. - Types of property 'num' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/compiler/abstractPropertyNegative.ts(30,7): error TS2415: Class 'WrongTypeAccessorImpl' incorrectly extends base class 'WrongTypeAccessor'. - Types of property 'num' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/compiler/abstractPropertyNegative.ts(33,7): error TS2415: Class 'WrongTypeAccessorImpl2' incorrectly extends base class 'WrongTypeAccessor'. - Types of property 'num' are incompatible. - Type 'string' is not assignable to type 'number'. +tests/cases/compiler/abstractPropertyNegative.ts(25,5): error TS2416: Property 'num' in type 'WrongTypePropertyImpl' is not assignable to the same property in base type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/abstractPropertyNegative.ts(31,9): error TS2416: Property 'num' in type 'WrongTypeAccessorImpl' is not assignable to the same property in base type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/abstractPropertyNegative.ts(34,5): error TS2416: Property 'num' in type 'WrongTypeAccessorImpl2' is not assignable to the same property in base type 'number'. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/abstractPropertyNegative.ts(38,18): error TS2676: Accessors must both be abstract or non-abstract. tests/cases/compiler/abstractPropertyNegative.ts(39,9): error TS2676: Accessors must both be abstract or non-abstract. tests/cases/compiler/abstractPropertyNegative.ts(40,9): error TS2676: Accessors must both be abstract or non-abstract. @@ -65,28 +62,25 @@ tests/cases/compiler/abstractPropertyNegative.ts(41,18): error TS2676: Accessors abstract num: number; } class WrongTypePropertyImpl extends WrongTypeProperty { - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2415: Class 'WrongTypePropertyImpl' incorrectly extends base class 'WrongTypeProperty'. -!!! error TS2415: Types of property 'num' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'number'. num = "nope, wrong"; + ~~~ +!!! error TS2416: Property 'num' in type 'WrongTypePropertyImpl' is not assignable to the same property in base type 'number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. } abstract class WrongTypeAccessor { abstract get num(): number; } class WrongTypeAccessorImpl extends WrongTypeAccessor { - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2415: Class 'WrongTypeAccessorImpl' incorrectly extends base class 'WrongTypeAccessor'. -!!! error TS2415: Types of property 'num' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'number'. get num() { return "nope, wrong"; } + ~~~ +!!! error TS2416: Property 'num' in type 'WrongTypeAccessorImpl' is not assignable to the same property in base type 'number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. } class WrongTypeAccessorImpl2 extends WrongTypeAccessor { - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2415: Class 'WrongTypeAccessorImpl2' incorrectly extends base class 'WrongTypeAccessor'. -!!! error TS2415: Types of property 'num' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'number'. num = "nope, wrong"; + ~~~ +!!! error TS2416: Property 'num' in type 'WrongTypeAccessorImpl2' is not assignable to the same property in base type 'number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. } abstract class AbstractAccessorMismatch { diff --git a/tests/baselines/reference/apparentTypeSubtyping.errors.txt b/tests/baselines/reference/apparentTypeSubtyping.errors.txt index 01fffeb3824..cde65657778 100644 --- a/tests/baselines/reference/apparentTypeSubtyping.errors.txt +++ b/tests/baselines/reference/apparentTypeSubtyping.errors.txt @@ -1,7 +1,6 @@ -tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts(9,7): error TS2415: Class 'Derived' incorrectly extends base class 'Base'. - Types of property 'x' are incompatible. - Type 'String' is not assignable to type 'string'. - 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. +tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts(10,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'string'. + Type 'String' is not assignable to type 'string'. + 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. ==== tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts (1 errors) ==== @@ -14,12 +13,11 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtypi // is String (S) a subtype of U extends String (T)? Would only be true if we used the apparent type of U (T) class Derived extends Base { // error - ~~~~~~~ -!!! error TS2415: Class 'Derived' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'x' are incompatible. -!!! error TS2415: Type 'String' is not assignable to type 'string'. -!!! error TS2415: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. x: String; + ~ +!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'string'. +!!! error TS2416: Type 'String' is not assignable to type 'string'. +!!! error TS2416: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. } class Base2 { diff --git a/tests/baselines/reference/apparentTypeSupertype.errors.txt b/tests/baselines/reference/apparentTypeSupertype.errors.txt index c7610a80f2f..066d0be2710 100644 --- a/tests/baselines/reference/apparentTypeSupertype.errors.txt +++ b/tests/baselines/reference/apparentTypeSupertype.errors.txt @@ -1,8 +1,7 @@ -tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts(9,7): error TS2415: Class 'Derived' incorrectly extends base class 'Base'. - Types of property 'x' are incompatible. - Type 'U' is not assignable to type 'string'. - Type 'String' is not assignable to type 'string'. - 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. +tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts(10,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'string'. + Type 'U' is not assignable to type 'string'. + Type 'String' is not assignable to type 'string'. + 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. ==== tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts (1 errors) ==== @@ -15,11 +14,10 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSuperty // is String (S) a subtype of U extends String (T)? Would only be true if we used the apparent type of U (T) class Derived extends Base { // error - ~~~~~~~ -!!! error TS2415: Class 'Derived' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'x' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'string'. -!!! error TS2415: Type 'String' is not assignable to type 'string'. -!!! error TS2415: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. x: U; + ~ +!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'string'. +!!! error TS2416: Type 'U' is not assignable to type 'string'. +!!! error TS2416: Type 'String' is not assignable to type 'string'. +!!! error TS2416: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. } \ No newline at end of file diff --git a/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt b/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt new file mode 100644 index 00000000000..585c929d9a4 --- /dev/null +++ b/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt @@ -0,0 +1,73 @@ +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(8,5): error TS2416: Property 'n' in type 'Derived' is not assignable to the same property in base type 'string | Base'. + Type 'string | Derived' is not assignable to type 'string | Base'. + Type 'Derived' is not assignable to type 'string | Base'. + Type 'Derived' is not assignable to type 'Base'. + Types of property 'n' are incompatible. + Type 'string | Derived' is not assignable to type 'string | Base'. + Type 'Derived' is not assignable to type 'string | Base'. + Type 'Derived' is not assignable to type 'Base'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(9,5): error TS2416: Property 'fn' in type 'Derived' is not assignable to the same property in base type '() => number'. + Type '() => string | number' is not assignable to type '() => number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(14,5): error TS2416: Property 'n' in type 'DerivedInterface' is not assignable to the same property in base type 'string | Base'. + Type 'string | DerivedInterface' is not assignable to type 'string | Base'. + Type 'DerivedInterface' is not assignable to type 'string | Base'. + Type 'DerivedInterface' is not assignable to type 'Base'. + Types of property 'n' are incompatible. + Type 'string | DerivedInterface' is not assignable to type 'string | Base'. + Type 'DerivedInterface' is not assignable to type 'string | Base'. + Type 'DerivedInterface' is not assignable to type 'Base'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Property 'fn' in type 'DerivedInterface' is not assignable to the same property in base type '() => number'. + Type '() => string | number' is not assignable to type '() => number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. + + +==== tests/cases/compiler/baseClassImprovedMismatchErrors.ts (4 errors) ==== + class Base { + n: Base | string; + fn() { + return 10; + } + } + class Derived extends Base { + n: Derived | string; + ~ +!!! error TS2416: Property 'n' in type 'Derived' is not assignable to the same property in base type 'string | Base'. +!!! error TS2416: Type 'string | Derived' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'Derived' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'Derived' is not assignable to type 'Base'. +!!! error TS2416: Types of property 'n' are incompatible. +!!! error TS2416: Type 'string | Derived' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'Derived' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'Derived' is not assignable to type 'Base'. + fn() { + ~~ +!!! error TS2416: Property 'fn' in type 'Derived' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Type '() => string | number' is not assignable to type '() => number'. +!!! error TS2416: Type 'string | number' is not assignable to type 'number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. + return 10 as number | string; + } + } + class DerivedInterface implements Base { + n: DerivedInterface | string; + ~ +!!! error TS2416: Property 'n' in type 'DerivedInterface' is not assignable to the same property in base type 'string | Base'. +!!! error TS2416: Type 'string | DerivedInterface' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'DerivedInterface' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'DerivedInterface' is not assignable to type 'Base'. +!!! error TS2416: Types of property 'n' are incompatible. +!!! error TS2416: Type 'string | DerivedInterface' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'DerivedInterface' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'DerivedInterface' is not assignable to type 'Base'. + fn() { + ~~ +!!! error TS2416: Property 'fn' in type 'DerivedInterface' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Type '() => string | number' is not assignable to type '() => number'. +!!! error TS2416: Type 'string | number' is not assignable to type 'number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. + return 10 as number | string; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/baseClassImprovedMismatchErrors.js b/tests/baselines/reference/baseClassImprovedMismatchErrors.js new file mode 100644 index 00000000000..296f9e6eb1c --- /dev/null +++ b/tests/baselines/reference/baseClassImprovedMismatchErrors.js @@ -0,0 +1,57 @@ +//// [baseClassImprovedMismatchErrors.ts] +class Base { + n: Base | string; + fn() { + return 10; + } +} +class Derived extends Base { + n: Derived | string; + fn() { + return 10 as number | string; + } +} +class DerivedInterface implements Base { + n: DerivedInterface | string; + fn() { + return 10 as number | string; + } +} + +//// [baseClassImprovedMismatchErrors.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 Base = /** @class */ (function () { + function Base() { + } + Base.prototype.fn = function () { + return 10; + }; + return Base; +}()); +var Derived = /** @class */ (function (_super) { + __extends(Derived, _super); + function Derived() { + return _super !== null && _super.apply(this, arguments) || this; + } + Derived.prototype.fn = function () { + return 10; + }; + return Derived; +}(Base)); +var DerivedInterface = /** @class */ (function () { + function DerivedInterface() { + } + DerivedInterface.prototype.fn = function () { + return 10; + }; + return DerivedInterface; +}()); diff --git a/tests/baselines/reference/baseClassImprovedMismatchErrors.symbols b/tests/baselines/reference/baseClassImprovedMismatchErrors.symbols new file mode 100644 index 00000000000..19ac124a2e0 --- /dev/null +++ b/tests/baselines/reference/baseClassImprovedMismatchErrors.symbols @@ -0,0 +1,42 @@ +=== tests/cases/compiler/baseClassImprovedMismatchErrors.ts === +class Base { +>Base : Symbol(Base, Decl(baseClassImprovedMismatchErrors.ts, 0, 0)) + + n: Base | string; +>n : Symbol(Base.n, Decl(baseClassImprovedMismatchErrors.ts, 0, 12)) +>Base : Symbol(Base, Decl(baseClassImprovedMismatchErrors.ts, 0, 0)) + + fn() { +>fn : Symbol(Base.fn, Decl(baseClassImprovedMismatchErrors.ts, 1, 21)) + + return 10; + } +} +class Derived extends Base { +>Derived : Symbol(Derived, Decl(baseClassImprovedMismatchErrors.ts, 5, 1)) +>Base : Symbol(Base, Decl(baseClassImprovedMismatchErrors.ts, 0, 0)) + + n: Derived | string; +>n : Symbol(Derived.n, Decl(baseClassImprovedMismatchErrors.ts, 6, 28)) +>Derived : Symbol(Derived, Decl(baseClassImprovedMismatchErrors.ts, 5, 1)) + + fn() { +>fn : Symbol(Derived.fn, Decl(baseClassImprovedMismatchErrors.ts, 7, 24)) + + return 10 as number | string; + } +} +class DerivedInterface implements Base { +>DerivedInterface : Symbol(DerivedInterface, Decl(baseClassImprovedMismatchErrors.ts, 11, 1)) +>Base : Symbol(Base, Decl(baseClassImprovedMismatchErrors.ts, 0, 0)) + + n: DerivedInterface | string; +>n : Symbol(DerivedInterface.n, Decl(baseClassImprovedMismatchErrors.ts, 12, 40)) +>DerivedInterface : Symbol(DerivedInterface, Decl(baseClassImprovedMismatchErrors.ts, 11, 1)) + + fn() { +>fn : Symbol(DerivedInterface.fn, Decl(baseClassImprovedMismatchErrors.ts, 13, 33)) + + return 10 as number | string; + } +} diff --git a/tests/baselines/reference/baseClassImprovedMismatchErrors.types b/tests/baselines/reference/baseClassImprovedMismatchErrors.types new file mode 100644 index 00000000000..0ca00a02248 --- /dev/null +++ b/tests/baselines/reference/baseClassImprovedMismatchErrors.types @@ -0,0 +1,47 @@ +=== tests/cases/compiler/baseClassImprovedMismatchErrors.ts === +class Base { +>Base : Base + + n: Base | string; +>n : string | Base +>Base : Base + + fn() { +>fn : () => number + + return 10; +>10 : 10 + } +} +class Derived extends Base { +>Derived : Derived +>Base : Base + + n: Derived | string; +>n : string | Derived +>Derived : Derived + + fn() { +>fn : () => string | number + + return 10 as number | string; +>10 as number | string : string | number +>10 : 10 + } +} +class DerivedInterface implements Base { +>DerivedInterface : DerivedInterface +>Base : Base + + n: DerivedInterface | string; +>n : string | DerivedInterface +>DerivedInterface : DerivedInterface + + fn() { +>fn : () => string | number + + return 10 as number | string; +>10 as number | string : string | number +>10 : 10 + } +} diff --git a/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt b/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt index 88176d95026..3070a041748 100644 --- a/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt +++ b/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt @@ -1,7 +1,6 @@ -tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classIsSubtypeOfBaseType.ts(11,7): error TS2415: Class 'Derived2' incorrectly extends base class 'Base<{ bar: string; }>'. - Types of property 'foo' are incompatible. - Type '{ bar?: string; }' is not assignable to type '{ bar: string; }'. - Property 'bar' is optional in type '{ bar?: string; }' but required in type '{ bar: string; }'. +tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classIsSubtypeOfBaseType.ts(12,5): error TS2416: Property 'foo' in type 'Derived2' is not assignable to the same property in base type '{ bar: string; }'. + Type '{ bar?: string; }' is not assignable to type '{ bar: string; }'. + Property 'bar' is optional in type '{ bar?: string; }' but required in type '{ bar: string; }'. ==== tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classIsSubtypeOfBaseType.ts (1 errors) ==== @@ -16,12 +15,11 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla } class Derived2 extends Base<{ bar: string; }> { - ~~~~~~~~ -!!! error TS2415: Class 'Derived2' incorrectly extends base class 'Base<{ bar: string; }>'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type '{ bar?: string; }' is not assignable to type '{ bar: string; }'. -!!! error TS2415: Property 'bar' is optional in type '{ bar?: string; }' but required in type '{ bar: string; }'. foo: { + ~~~ +!!! error TS2416: Property 'foo' in type 'Derived2' is not assignable to the same property in base type '{ bar: string; }'. +!!! error TS2416: Type '{ bar?: string; }' is not assignable to type '{ bar: string; }'. +!!! error TS2416: Property 'bar' is optional in type '{ bar?: string; }' but required in type '{ bar: string; }'. bar?: string; // error } } \ No newline at end of file diff --git a/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt b/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt index f8e237a83ce..ca154600c9f 100644 --- a/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt +++ b/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt @@ -1,8 +1,7 @@ tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(2,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(5,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(10,7): error TS2415: Class 'Derived' incorrectly extends base class 'Base'. - Types of property 'x' are incompatible. - Type '() => number' is not assignable to type 'number'. +tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(11,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'number'. + Type '() => number' is not assignable to type 'number'. tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(11,5): error TS2426: Class 'Base' defines instance member accessor 'x', but extended class 'Derived' defines it as instance member function. @@ -21,12 +20,11 @@ tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFun // error class Derived extends Base { - ~~~~~~~ -!!! error TS2415: Class 'Derived' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'x' are incompatible. -!!! error TS2415: Type '() => number' is not assignable to type 'number'. x() { ~ +!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'number'. +!!! error TS2416: Type '() => number' is not assignable to type 'number'. + ~ !!! error TS2426: Class 'Base' defines instance member accessor 'x', but extended class 'Derived' defines it as instance member function. return 1; } diff --git a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt index 96b93423660..9cc122c7588 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt @@ -34,13 +34,12 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( Type 'string' is not assignable to type 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(46,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(47,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(55,7): error TS2420: Class 'C4' incorrectly implements interface 'F2'. - Types of property 'd4' are incompatible. - Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. - Types of parameters '__0' and '__0' are incompatible. - Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'. - Property 'c' is missing in type '{ x: any; y: any; z: any; }'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(56,8): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(57,5): error TS2416: Property 'd4' in type 'C4' is not assignable to the same property in base type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. + Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. + Types of parameters '__0' and '__0' are incompatible. + Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'. + Property 'c' is missing in type '{ x: any; y: any; z: any; }'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(65,18): error TS2300: Duplicate identifier 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(65,26): error TS2300: Duplicate identifier 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(65,34): error TS2300: Duplicate identifier 'number'. @@ -155,17 +154,16 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( } class C4 implements F2 { - ~~ -!!! error TS2420: Class 'C4' incorrectly implements interface 'F2'. -!!! error TS2420: Types of property 'd4' are incompatible. -!!! error TS2420: Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. -!!! error TS2420: Types of parameters '__0' and '__0' are incompatible. -!!! error TS2420: Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'. -!!! error TS2420: Property 'c' is missing in type '{ x: any; y: any; z: any; }'. d3([a, b, c]?) { } // Error, binding pattern can't be optional in implementation signature ~~~~~~~~~~ !!! error TS2463: A binding pattern parameter cannot be optional in an implementation signature. d4({x, y, c}) { } + ~~ +!!! error TS2416: Property 'd4' in type 'C4' is not assignable to the same property in base type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. +!!! error TS2416: Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. +!!! error TS2416: Types of parameters '__0' and '__0' are incompatible. +!!! error TS2416: Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'. +!!! error TS2416: Property 'c' is missing in type '{ x: any; y: any; z: any; }'. e0([a, b, q]) { } } diff --git a/tests/baselines/reference/elaboratedErrors.errors.txt b/tests/baselines/reference/elaboratedErrors.errors.txt index 7bc83a19a50..9a05bdc1d1b 100644 --- a/tests/baselines/reference/elaboratedErrors.errors.txt +++ b/tests/baselines/reference/elaboratedErrors.errors.txt @@ -1,6 +1,5 @@ -tests/cases/compiler/elaboratedErrors.ts(10,7): error TS2420: Class 'WorkerFS' incorrectly implements interface 'FileSystem'. - Types of property 'read' are incompatible. - Type 'string' is not assignable to type 'number'. +tests/cases/compiler/elaboratedErrors.ts(11,3): error TS2416: Property 'read' in type 'WorkerFS' is not assignable to the same property in base type 'number'. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/elaboratedErrors.ts(20,1): error TS2322: Type 'Beta' is not assignable to type 'Alpha'. Property 'x' is missing in type 'Beta'. tests/cases/compiler/elaboratedErrors.ts(21,1): error TS2322: Type 'Beta' is not assignable to type 'Alpha'. @@ -20,11 +19,10 @@ tests/cases/compiler/elaboratedErrors.ts(25,1): error TS2322: Type 'Alpha' is no // This should issue a large error, not a small one class WorkerFS implements FileSystem { - ~~~~~~~~ -!!! error TS2420: Class 'WorkerFS' incorrectly implements interface 'FileSystem'. -!!! error TS2420: Types of property 'read' are incompatible. -!!! error TS2420: Type 'string' is not assignable to type 'number'. read: string; + ~~~~ +!!! error TS2416: Property 'read' in type 'WorkerFS' is not assignable to the same property in base type 'number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. } interface Alpha { x: string; } diff --git a/tests/baselines/reference/genericImplements.errors.txt b/tests/baselines/reference/genericImplements.errors.txt index 7add57989ce..04ae8d0f0cb 100644 --- a/tests/baselines/reference/genericImplements.errors.txt +++ b/tests/baselines/reference/genericImplements.errors.txt @@ -1,7 +1,6 @@ -tests/cases/compiler/genericImplements.ts(8,7): error TS2420: Class 'X' incorrectly implements interface 'I'. - Types of property 'f' are incompatible. - Type '() => T' is not assignable to type '() => T'. - Type 'B' is not assignable to type 'T'. +tests/cases/compiler/genericImplements.ts(9,5): error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type '() => T'. + Type '() => T' is not assignable to type '() => T'. + Type 'B' is not assignable to type 'T'. ==== tests/cases/compiler/genericImplements.ts (1 errors) ==== @@ -13,12 +12,11 @@ tests/cases/compiler/genericImplements.ts(8,7): error TS2420: Class 'X' incorrec // OK class X implements I { - ~ -!!! error TS2420: Class 'X' incorrectly implements interface 'I'. -!!! error TS2420: Types of property 'f' are incompatible. -!!! error TS2420: Type '() => T' is not assignable to type '() => T'. -!!! error TS2420: Type 'B' is not assignable to type 'T'. f(): T { return undefined; } + ~ +!!! error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type '() => T'. +!!! error TS2416: Type '() => T' is not assignable to type '() => T'. +!!! error TS2416: Type 'B' is not assignable to type 'T'. } // { f: () => { b; } } // OK diff --git a/tests/baselines/reference/genericSpecializations1.errors.txt b/tests/baselines/reference/genericSpecializations1.errors.txt index dd7e540661e..b56cc0d7865 100644 --- a/tests/baselines/reference/genericSpecializations1.errors.txt +++ b/tests/baselines/reference/genericSpecializations1.errors.txt @@ -1,13 +1,11 @@ -tests/cases/compiler/genericSpecializations1.ts(5,7): error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo'. - Types of property 'foo' are incompatible. - Type '(x: string) => string' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. -tests/cases/compiler/genericSpecializations1.ts(9,7): error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo'. - Types of property 'foo' are incompatible. - Type '(x: string) => string' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. +tests/cases/compiler/genericSpecializations1.ts(6,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: T) => T'. + Type '(x: string) => string' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. +tests/cases/compiler/genericSpecializations1.ts(10,5): error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type '(x: T) => T'. + Type '(x: string) => string' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. ==== tests/cases/compiler/genericSpecializations1.ts (2 errors) ==== @@ -16,23 +14,21 @@ tests/cases/compiler/genericSpecializations1.ts(9,7): error TS2420: Class 'Strin } class IntFooBad implements IFoo { - ~~~~~~~~~ -!!! error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: string) => string' is not assignable to type '(x: T) => T'. -!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2420: Type 'T' is not assignable to type 'string'. foo(x: string): string { return null; } + ~~~ +!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. } class StringFoo2 implements IFoo { - ~~~~~~~~~~ -!!! error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: string) => string' is not assignable to type '(x: T) => T'. -!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2420: Type 'T' is not assignable to type 'string'. foo(x: string): string { return null; } + ~~~ +!!! error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. } class StringFoo3 implements IFoo { diff --git a/tests/baselines/reference/genericSpecializations2.errors.txt b/tests/baselines/reference/genericSpecializations2.errors.txt index 99a6e2a6985..dc59c200d4f 100644 --- a/tests/baselines/reference/genericSpecializations2.errors.txt +++ b/tests/baselines/reference/genericSpecializations2.errors.txt @@ -1,14 +1,12 @@ -tests/cases/compiler/genericSpecializations2.ts(7,7): error TS2720: Class 'IntFooBad' incorrectly implements class 'IFoo'. Did you mean to extend 'IFoo' and inherit its members as a subclass? - Types of property 'foo' are incompatible. - Type '(x: string) => string' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. +tests/cases/compiler/genericSpecializations2.ts(8,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: T) => T'. + Type '(x: string) => string' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. tests/cases/compiler/genericSpecializations2.ts(8,9): error TS2368: Type parameter name cannot be 'string'. -tests/cases/compiler/genericSpecializations2.ts(11,7): error TS2720: Class 'StringFoo2' incorrectly implements class 'IFoo'. Did you mean to extend 'IFoo' and inherit its members as a subclass? - Types of property 'foo' are incompatible. - Type '(x: string) => string' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. +tests/cases/compiler/genericSpecializations2.ts(12,5): error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type '(x: T) => T'. + Type '(x: string) => string' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parameter name cannot be 'string'. @@ -20,25 +18,23 @@ tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parame } class IntFooBad implements IFoo { - ~~~~~~~~~ -!!! error TS2720: Class 'IntFooBad' incorrectly implements class 'IFoo'. Did you mean to extend 'IFoo' and inherit its members as a subclass? -!!! error TS2720: Types of property 'foo' are incompatible. -!!! error TS2720: Type '(x: string) => string' is not assignable to type '(x: T) => T'. -!!! error TS2720: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2720: Type 'T' is not assignable to type 'string'. foo(x: string): string { return null; } + ~~~ +!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. ~~~~~~ !!! error TS2368: Type parameter name cannot be 'string'. } class StringFoo2 implements IFoo { - ~~~~~~~~~~ -!!! error TS2720: Class 'StringFoo2' incorrectly implements class 'IFoo'. Did you mean to extend 'IFoo' and inherit its members as a subclass? -!!! error TS2720: Types of property 'foo' are incompatible. -!!! error TS2720: Type '(x: string) => string' is not assignable to type '(x: T) => T'. -!!! error TS2720: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2720: Type 'T' is not assignable to type 'string'. foo(x: string): string { return null; } + ~~~ +!!! error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. ~~~~~~ !!! error TS2368: Type parameter name cannot be 'string'. } diff --git a/tests/baselines/reference/genericSpecializations3.errors.txt b/tests/baselines/reference/genericSpecializations3.errors.txt index 87a7d5bcce7..f99872539a9 100644 --- a/tests/baselines/reference/genericSpecializations3.errors.txt +++ b/tests/baselines/reference/genericSpecializations3.errors.txt @@ -1,8 +1,7 @@ -tests/cases/compiler/genericSpecializations3.ts(8,7): error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo'. - Types of property 'foo' are incompatible. - Type '(x: string) => string' is not assignable to type '(x: number) => number'. - Types of parameters 'x' and 'x' are incompatible. - Type 'number' is not assignable to type 'string'. +tests/cases/compiler/genericSpecializations3.ts(9,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: number) => number'. + Type '(x: string) => string' is not assignable to type '(x: number) => number'. + Types of parameters 'x' and 'x' are incompatible. + Type 'number' is not assignable to type 'string'. tests/cases/compiler/genericSpecializations3.ts(28,1): error TS2322: Type 'StringFoo2' is not assignable to type 'IntFoo'. Types of property 'foo' are incompatible. Type '(x: string) => string' is not assignable to type '(x: number) => number'. @@ -24,13 +23,12 @@ tests/cases/compiler/genericSpecializations3.ts(29,1): error TS2322: Type 'IntFo iFoo.foo(1); class IntFooBad implements IFoo { // error - ~~~~~~~~~ -!!! error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: string) => string' is not assignable to type '(x: number) => number'. -!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2420: Type 'number' is not assignable to type 'string'. foo(x: string): string { return null; } + ~~~ +!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: number) => number'. +!!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: number) => number'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'number' is not assignable to type 'string'. } var intFooBad: IntFooBad; diff --git a/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt b/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt index 3ec6fa5e9f6..d91eb2b864e 100644 --- a/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt +++ b/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt @@ -1,8 +1,7 @@ -tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(4,7): error TS2420: Class 'X' incorrectly implements interface 'I'. - Types of property 'f' are incompatible. - Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. - Types of parameters 'a' and 'a' are incompatible. - Type '{ a: number; }' is not assignable to type 'T'. +tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(5,2): error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type '(a: { a: number; }) => void'. + Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. + Types of parameters 'a' and 'a' are incompatible. + Type '{ a: number; }' is not assignable to type 'T'. tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(8,5): error TS2322: Type 'X<{ a: string; }>' is not assignable to type 'I'. Types of property 'f' are incompatible. Type '(a: { a: string; }) => void' is not assignable to type '(a: { a: number; }) => void'. @@ -17,13 +16,12 @@ tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(8,5): error TS2322 f: (a: { a: number }) => void } class X implements I { - ~ -!!! error TS2420: Class 'X' incorrectly implements interface 'I'. -!!! error TS2420: Types of property 'f' are incompatible. -!!! error TS2420: Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. -!!! error TS2420: Types of parameters 'a' and 'a' are incompatible. -!!! error TS2420: Type '{ a: number; }' is not assignable to type 'T'. f(a: T): void { } + ~ +!!! error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type '(a: { a: number; }) => void'. +!!! error TS2416: Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. +!!! error TS2416: Types of parameters 'a' and 'a' are incompatible. +!!! error TS2416: Type '{ a: number; }' is not assignable to type 'T'. } var x = new X<{ a: string }>(); var i: I = x; // Should not be allowed -- type of 'f' is incompatible with 'I' diff --git a/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt b/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt index 4652acc8d10..994174eb84c 100644 --- a/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt +++ b/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt @@ -1,12 +1,10 @@ -tests/cases/compiler/implementGenericWithMismatchedTypes.ts(7,7): error TS2420: Class 'C' incorrectly implements interface 'IFoo'. - Types of property 'foo' are incompatible. - Type '(x: string) => number' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. -tests/cases/compiler/implementGenericWithMismatchedTypes.ts(16,7): error TS2420: Class 'C2' incorrectly implements interface 'IFoo2'. - Types of property 'foo' are incompatible. - Type '(x: Tstring) => number' is not assignable to type '(x: T) => T'. - Type 'number' is not assignable to type 'T'. +tests/cases/compiler/implementGenericWithMismatchedTypes.ts(8,5): error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type '(x: T) => T'. + Type '(x: string) => number' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. +tests/cases/compiler/implementGenericWithMismatchedTypes.ts(17,5): error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type '(x: T) => T'. + Type '(x: Tstring) => number' is not assignable to type '(x: T) => T'. + Type 'number' is not assignable to type 'T'. ==== tests/cases/compiler/implementGenericWithMismatchedTypes.ts (2 errors) ==== @@ -17,13 +15,12 @@ tests/cases/compiler/implementGenericWithMismatchedTypes.ts(16,7): error TS2420: foo(x: T): T; } class C implements IFoo { // error - ~ -!!! error TS2420: Class 'C' incorrectly implements interface 'IFoo'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: string) => number' is not assignable to type '(x: T) => T'. -!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2420: Type 'T' is not assignable to type 'string'. foo(x: string): number { + ~~~ +!!! error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Type '(x: string) => number' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. return null; } } @@ -32,12 +29,11 @@ tests/cases/compiler/implementGenericWithMismatchedTypes.ts(16,7): error TS2420: foo(x: T): T; } class C2 implements IFoo2 { // error - ~~ -!!! error TS2420: Class 'C2' incorrectly implements interface 'IFoo2'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: Tstring) => number' is not assignable to type '(x: T) => T'. -!!! error TS2420: Type 'number' is not assignable to type 'T'. foo(x: Tstring): number { + ~~~ +!!! error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Type '(x: Tstring) => number' is not assignable to type '(x: T) => T'. +!!! error TS2416: Type 'number' is not assignable to type 'T'. return null; } } \ No newline at end of file diff --git a/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt b/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt index a1c0f21b8c4..7b717545e77 100644 --- a/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt +++ b/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt @@ -1,7 +1,5 @@ -tests/cases/compiler/implementsIncorrectlyNoAssertion.ts(8,7): error TS2420: Class 'Baz' incorrectly implements interface 'Foo & Bar'. - Type 'Baz' is not assignable to type 'Foo'. - Types of property 'x' are incompatible. - Type 'number' is not assignable to type 'string'. +tests/cases/compiler/implementsIncorrectlyNoAssertion.ts(9,5): error TS2416: Property 'x' in type 'Baz' is not assignable to the same property in base type 'string'. + Type 'number' is not assignable to type 'string'. ==== tests/cases/compiler/implementsIncorrectlyNoAssertion.ts (1 errors) ==== @@ -13,12 +11,10 @@ tests/cases/compiler/implementsIncorrectlyNoAssertion.ts(8,7): error TS2420: Cla } type Wrapper = Foo & Bar; class Baz implements Wrapper { - ~~~ -!!! error TS2420: Class 'Baz' incorrectly implements interface 'Foo & Bar'. -!!! error TS2420: Type 'Baz' is not assignable to type 'Foo'. -!!! error TS2420: Types of property 'x' are incompatible. -!!! error TS2420: Type 'number' is not assignable to type 'string'. x: number; + ~ +!!! error TS2416: Property 'x' in type 'Baz' is not assignable to the same property in base type 'string'. +!!! error TS2416: Type 'number' is not assignable to type 'string'. y: string; } \ No newline at end of file diff --git a/tests/baselines/reference/incompatibleTypes.errors.txt b/tests/baselines/reference/incompatibleTypes.errors.txt index 4cd68470007..1feed1a3fb6 100644 --- a/tests/baselines/reference/incompatibleTypes.errors.txt +++ b/tests/baselines/reference/incompatibleTypes.errors.txt @@ -1,19 +1,15 @@ -tests/cases/compiler/incompatibleTypes.ts(5,7): error TS2420: Class 'C1' incorrectly implements interface 'IFoo1'. - Types of property 'p1' are incompatible. - Type '() => string' is not assignable to type '() => number'. +tests/cases/compiler/incompatibleTypes.ts(6,12): error TS2416: Property 'p1' in type 'C1' is not assignable to the same property in base type '() => number'. + Type '() => string' is not assignable to type '() => number'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/incompatibleTypes.ts(16,12): error TS2416: Property 'p1' in type 'C2' is not assignable to the same property in base type '(s: string) => number'. + Type '(n: number) => number' is not assignable to type '(s: string) => number'. + Types of parameters 'n' and 's' are incompatible. Type 'string' is not assignable to type 'number'. -tests/cases/compiler/incompatibleTypes.ts(15,7): error TS2420: Class 'C2' incorrectly implements interface 'IFoo2'. - Types of property 'p1' are incompatible. - Type '(n: number) => number' is not assignable to type '(s: string) => number'. - Types of parameters 'n' and 's' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/compiler/incompatibleTypes.ts(25,7): error TS2420: Class 'C3' incorrectly implements interface 'IFoo3'. - Types of property 'p1' are incompatible. - Type 'number' is not assignable to type 'string'. -tests/cases/compiler/incompatibleTypes.ts(33,7): error TS2420: Class 'C4' incorrectly implements interface 'IFoo4'. - Types of property 'p1' are incompatible. - Type '{ c: { b: string; }; d: string; }' is not assignable to type '{ a: { a: string; }; b: string; }'. - Property 'a' is missing in type '{ c: { b: string; }; d: string; }'. +tests/cases/compiler/incompatibleTypes.ts(26,12): error TS2416: Property 'p1' in type 'C3' is not assignable to the same property in base type 'string'. + Type 'number' is not assignable to type 'string'. +tests/cases/compiler/incompatibleTypes.ts(34,12): error TS2416: Property 'p1' in type 'C4' is not assignable to the same property in base type '{ a: { a: string; }; b: string; }'. + Type '{ c: { b: string; }; d: string; }' is not assignable to type '{ a: { a: string; }; b: string; }'. + Property 'a' is missing in type '{ c: { b: string; }; d: string; }'. tests/cases/compiler/incompatibleTypes.ts(42,5): error TS2345: Argument of type 'C1' is not assignable to parameter of type 'IFoo2'. Types of property 'p1' are incompatible. Type '() => string' is not assignable to type '(s: string) => number'. @@ -32,12 +28,11 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => } class C1 implements IFoo1 { // incompatible on the return type - ~~ -!!! error TS2420: Class 'C1' incorrectly implements interface 'IFoo1'. -!!! error TS2420: Types of property 'p1' are incompatible. -!!! error TS2420: Type '() => string' is not assignable to type '() => number'. -!!! error TS2420: Type 'string' is not assignable to type 'number'. public p1() { + ~~ +!!! error TS2416: Property 'p1' in type 'C1' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Type '() => string' is not assignable to type '() => number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. return "s"; } } @@ -47,13 +42,12 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => } class C2 implements IFoo2 { // incompatible on the param type - ~~ -!!! error TS2420: Class 'C2' incorrectly implements interface 'IFoo2'. -!!! error TS2420: Types of property 'p1' are incompatible. -!!! error TS2420: Type '(n: number) => number' is not assignable to type '(s: string) => number'. -!!! error TS2420: Types of parameters 'n' and 's' are incompatible. -!!! error TS2420: Type 'string' is not assignable to type 'number'. public p1(n:number) { + ~~ +!!! error TS2416: Property 'p1' in type 'C2' is not assignable to the same property in base type '(s: string) => number'. +!!! error TS2416: Type '(n: number) => number' is not assignable to type '(s: string) => number'. +!!! error TS2416: Types of parameters 'n' and 's' are incompatible. +!!! error TS2416: Type 'string' is not assignable to type 'number'. return 0; } } @@ -63,11 +57,10 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => } class C3 implements IFoo3 { // incompatible on the property type - ~~ -!!! error TS2420: Class 'C3' incorrectly implements interface 'IFoo3'. -!!! error TS2420: Types of property 'p1' are incompatible. -!!! error TS2420: Type 'number' is not assignable to type 'string'. public p1: number; + ~~ +!!! error TS2416: Property 'p1' in type 'C3' is not assignable to the same property in base type 'string'. +!!! error TS2416: Type 'number' is not assignable to type 'string'. } interface IFoo4 { @@ -75,12 +68,11 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => } class C4 implements IFoo4 { // incompatible on the property type - ~~ -!!! error TS2420: Class 'C4' incorrectly implements interface 'IFoo4'. -!!! error TS2420: Types of property 'p1' are incompatible. -!!! error TS2420: Type '{ c: { b: string; }; d: string; }' is not assignable to type '{ a: { a: string; }; b: string; }'. -!!! error TS2420: Property 'a' is missing in type '{ c: { b: string; }; d: string; }'. public p1: { c: { b: string; }; d: string; }; + ~~ +!!! error TS2416: Property 'p1' in type 'C4' is not assignable to the same property in base type '{ a: { a: string; }; b: string; }'. +!!! error TS2416: Type '{ c: { b: string; }; d: string; }' is not assignable to type '{ a: { a: string; }; b: string; }'. +!!! error TS2416: Property 'a' is missing in type '{ c: { b: string; }; d: string; }'. } function if1(i: IFoo1): void; diff --git a/tests/baselines/reference/inheritance.errors.txt b/tests/baselines/reference/inheritance.errors.txt index c667e8b001e..429eb2674df 100644 --- a/tests/baselines/reference/inheritance.errors.txt +++ b/tests/baselines/reference/inheritance.errors.txt @@ -1,7 +1,6 @@ -tests/cases/compiler/inheritance.ts(30,7): error TS2415: Class 'Baad' incorrectly extends base class 'Good'. - Types of property 'g' are incompatible. - Type '(n: number) => number' is not assignable to type '() => number'. tests/cases/compiler/inheritance.ts(31,12): error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. +tests/cases/compiler/inheritance.ts(32,12): error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type '() => number'. + Type '(n: number) => number' is not assignable to type '() => number'. ==== tests/cases/compiler/inheritance.ts (2 errors) ==== @@ -35,13 +34,12 @@ tests/cases/compiler/inheritance.ts(31,12): error TS2425: Class 'Good' defines i } class Baad extends Good { - ~~~~ -!!! error TS2415: Class 'Baad' incorrectly extends base class 'Good'. -!!! error TS2415: Types of property 'g' are incompatible. -!!! error TS2415: Type '(n: number) => number' is not assignable to type '() => number'. public f(): number { return 0; } ~ !!! error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. public g(n: number) { return 0; } + ~ +!!! error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Type '(n: number) => number' is not assignable to type '() => number'. } \ No newline at end of file diff --git a/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt b/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt index 6fde83e08b0..a0c20277333 100644 --- a/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt +++ b/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt @@ -1,12 +1,13 @@ -tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(7,7): error TS2415: Class 'b' incorrectly extends base class 'a'. - Types of property 'x' are incompatible. - Type 'string' is not assignable to type '() => string'. tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. +tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type '() => string'. + Type 'string' is not assignable to type '() => string'. tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS2423: Class 'a' defines instance member function 'x', but extended class 'b' defines it as instance member accessor. tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. +tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type '() => string'. + Type 'string' is not assignable to type '() => string'. -==== tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts (4 errors) ==== +==== tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts (5 errors) ==== class a { x() { return "20"; @@ -14,20 +15,22 @@ tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error T } class b extends a { - ~ -!!! error TS2415: Class 'b' incorrectly extends base class 'a'. -!!! error TS2415: Types of property 'x' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type '() => string'. get x() { ~ !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. ~ +!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type '() => string'. +!!! error TS2416: Type 'string' is not assignable to type '() => string'. + ~ !!! error TS2423: Class 'a' defines instance member function 'x', but extended class 'b' defines it as instance member accessor. return "20"; } set x(aValue: string) { ~ !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + ~ +!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type '() => string'. +!!! error TS2416: Type 'string' is not assignable to type '() => string'. } } \ No newline at end of file diff --git a/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt b/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt index 283e7ce3f18..b31d5d12ec6 100644 --- a/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt +++ b/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt @@ -1,8 +1,7 @@ tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(2,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(5,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(10,7): error TS2415: Class 'b' incorrectly extends base class 'a'. - Types of property 'x' are incompatible. - Type '() => string' is not assignable to type 'string'. +tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'string'. + Type '() => string' is not assignable to type 'string'. tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2426: Class 'a' defines instance member accessor 'x', but extended class 'b' defines it as instance member function. @@ -21,12 +20,11 @@ tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2 } class b extends a { - ~ -!!! error TS2415: Class 'b' incorrectly extends base class 'a'. -!!! error TS2415: Types of property 'x' are incompatible. -!!! error TS2415: Type '() => string' is not assignable to type 'string'. x() { ~ +!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'string'. +!!! error TS2416: Type '() => string' is not assignable to type 'string'. + ~ !!! error TS2426: Class 'a' defines instance member accessor 'x', but extended class 'b' defines it as instance member function. return "20"; } diff --git a/tests/baselines/reference/instanceSubtypeCheck2.errors.txt b/tests/baselines/reference/instanceSubtypeCheck2.errors.txt index 81982ac3ec7..b1d0f33af08 100644 --- a/tests/baselines/reference/instanceSubtypeCheck2.errors.txt +++ b/tests/baselines/reference/instanceSubtypeCheck2.errors.txt @@ -1,6 +1,5 @@ -tests/cases/compiler/instanceSubtypeCheck2.ts(5,7): error TS2415: Class 'C2' incorrectly extends base class 'C1'. - Types of property 'x' are incompatible. - Type 'string' is not assignable to type 'C2'. +tests/cases/compiler/instanceSubtypeCheck2.ts(6,5): error TS2416: Property 'x' in type 'C2' is not assignable to the same property in base type 'C2'. + Type 'string' is not assignable to type 'C2'. ==== tests/cases/compiler/instanceSubtypeCheck2.ts (1 errors) ==== @@ -9,9 +8,8 @@ tests/cases/compiler/instanceSubtypeCheck2.ts(5,7): error TS2415: Class 'C2' } class C2 extends C1 { - ~~ -!!! error TS2415: Class 'C2' incorrectly extends base class 'C1'. -!!! error TS2415: Types of property 'x' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'C2'. x: string + ~ +!!! error TS2416: Property 'x' in type 'C2' is not assignable to the same property in base type 'C2'. +!!! error TS2416: Type 'string' is not assignable to type 'C2'. } \ No newline at end of file diff --git a/tests/baselines/reference/interfaceDeclaration3.errors.txt b/tests/baselines/reference/interfaceDeclaration3.errors.txt index a9bd1d42647..2c29b6a86f2 100644 --- a/tests/baselines/reference/interfaceDeclaration3.errors.txt +++ b/tests/baselines/reference/interfaceDeclaration3.errors.txt @@ -1,9 +1,7 @@ -tests/cases/compiler/interfaceDeclaration3.ts(6,11): error TS2420: Class 'C1' incorrectly implements interface 'I1'. - Types of property 'item' are incompatible. - Type 'number' is not assignable to type 'string'. -tests/cases/compiler/interfaceDeclaration3.ts(31,11): error TS2420: Class 'C1' incorrectly implements interface 'I1'. - Types of property 'item' are incompatible. - Type 'number' is not assignable to type 'string'. +tests/cases/compiler/interfaceDeclaration3.ts(7,16): error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'string'. + Type 'number' is not assignable to type 'string'. +tests/cases/compiler/interfaceDeclaration3.ts(32,16): error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'string'. + Type 'number' is not assignable to type 'string'. tests/cases/compiler/interfaceDeclaration3.ts(54,11): error TS2430: Interface 'I2' incorrectly extends interface 'I1'. Types of property 'item' are incompatible. Type 'string' is not assignable to type 'number'. @@ -16,11 +14,10 @@ tests/cases/compiler/interfaceDeclaration3.ts(54,11): error TS2430: Interface 'I interface I1 { item:string; } interface I2 { item:number; } class C1 implements I1 { - ~~ -!!! error TS2420: Class 'C1' incorrectly implements interface 'I1'. -!!! error TS2420: Types of property 'item' are incompatible. -!!! error TS2420: Type 'number' is not assignable to type 'string'. public item:number; + ~~~~ +!!! error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'string'. +!!! error TS2416: Type 'number' is not assignable to type 'string'. } class C2 implements I1 { public item:string; @@ -45,11 +42,10 @@ tests/cases/compiler/interfaceDeclaration3.ts(54,11): error TS2430: Interface 'I export interface I1 { item:string; } } class C1 implements I1 { - ~~ -!!! error TS2420: Class 'C1' incorrectly implements interface 'I1'. -!!! error TS2420: Types of property 'item' are incompatible. -!!! error TS2420: Type 'number' is not assignable to type 'string'. public item:number; + ~~~~ +!!! error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'string'. +!!! error TS2416: Type 'number' is not assignable to type 'string'. } class C2 implements I1 { public item:string; diff --git a/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt b/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt index 035fe89cd35..cac4ba6def7 100644 --- a/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt +++ b/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt @@ -2,13 +2,11 @@ tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(10,7): error TS2415: C Types have separate declarations of a private property 'x'. tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(10,7): error TS2420: Class 'D' incorrectly implements interface 'I'. Types have separate declarations of a private property 'x'. -tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(18,7): error TS2415: Class 'D2' incorrectly extends base class 'C'. - Types have separate declarations of a private property 'x'. -tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(18,7): error TS2420: Class 'D2' incorrectly implements interface 'I'. - Types have separate declarations of a private property 'x'. +tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(20,13): error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'number'. + Type 'string' is not assignable to type 'number'. -==== tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts (4 errors) ==== +==== tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts (3 errors) ==== class C { public foo(x: any) { return x; } private x = 1; @@ -33,14 +31,11 @@ tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(18,7): error TS2420: C } class D2 extends C implements I { // error - ~~ -!!! error TS2415: Class 'D2' incorrectly extends base class 'C'. -!!! error TS2415: Types have separate declarations of a private property 'x'. - ~~ -!!! error TS2420: Class 'D2' incorrectly implements interface 'I'. -!!! error TS2420: Types have separate declarations of a private property 'x'. public foo(x: any) { return x; } private x = ""; + ~ +!!! error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. other(x: any) { return x; } bar() { } } \ No newline at end of file diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt index 155cf4bd5ad..6a53fc01c0d 100644 --- a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt +++ b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt @@ -14,22 +14,16 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectI tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(11,11): error TS2430: Interface 'I5' incorrectly extends interface 'T5'. Types of property 'c' are incompatible. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(16,7): error TS2415: Class 'C1' incorrectly extends base class 'T1'. - Types of property 'a' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(17,7): error TS2415: Class 'C2' incorrectly extends base class 'T2'. - Type 'C2' is not assignable to type '{ b: number; }'. - Types of property 'b' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(18,7): error TS2415: Class 'C3' incorrectly extends base class 'number[]'. - Types of property 'length' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(19,7): error TS2415: Class 'C4' incorrectly extends base class '[string, number]'. - Types of property '0' are incompatible. - Type 'number' is not assignable to type 'string'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(20,7): error TS2415: Class 'C5' incorrectly extends base class 'T5'. - Types of property 'c' are incompatible. - Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(16,38): error TS2416: Property 'a' in type 'C1' is not assignable to the same property in base type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(17,38): error TS2416: Property 'b' in type 'C2' is not assignable to the same property in base type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(18,38): error TS2416: Property 'length' in type 'C3' is not assignable to the same property in base type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(19,38): error TS2416: Property '0' in type 'C4' is not assignable to the same property in base type 'string'. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(20,38): error TS2416: Property 'c' in type 'C5' is not assignable to the same property in base type 'string'. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(30,11): error TS2430: Interface 'I10' incorrectly extends interface 'typeof CX'. Types of property 'a' are incompatible. Type 'number' is not assignable to type 'string'. @@ -99,31 +93,25 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectI declare function Constructor(): Constructor; class C1 extends Constructor() { a: string } - ~~ -!!! error TS2415: Class 'C1' incorrectly extends base class 'T1'. -!!! error TS2415: Types of property 'a' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'number'. + ~ +!!! error TS2416: Property 'a' in type 'C1' is not assignable to the same property in base type 'number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. class C2 extends Constructor() { b: string } - ~~ -!!! error TS2415: Class 'C2' incorrectly extends base class 'T2'. -!!! error TS2415: Type 'C2' is not assignable to type '{ b: number; }'. -!!! error TS2415: Types of property 'b' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'number'. + ~ +!!! error TS2416: Property 'b' in type 'C2' is not assignable to the same property in base type 'number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. class C3 extends Constructor() { length: string } - ~~ -!!! error TS2415: Class 'C3' incorrectly extends base class 'number[]'. -!!! error TS2415: Types of property 'length' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'number'. + ~~~~~~ +!!! error TS2416: Property 'length' in type 'C3' is not assignable to the same property in base type 'number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. class C4 extends Constructor() { 0: number } - ~~ -!!! error TS2415: Class 'C4' incorrectly extends base class '[string, number]'. -!!! error TS2415: Types of property '0' are incompatible. -!!! error TS2415: Type 'number' is not assignable to type 'string'. + ~ +!!! error TS2416: Property '0' in type 'C4' is not assignable to the same property in base type 'string'. +!!! error TS2416: Type 'number' is not assignable to type 'string'. class C5 extends Constructor() { c: number } - ~~ -!!! error TS2415: Class 'C5' incorrectly extends base class 'T5'. -!!! error TS2415: Types of property 'c' are incompatible. -!!! error TS2415: Type 'number' is not assignable to type 'string'. + ~ +!!! error TS2416: Property 'c' in type 'C5' is not assignable to the same property in base type 'string'. +!!! error TS2416: Type 'number' is not assignable to type 'string'. declare class CX { static a: string } declare enum EX { A, B, C } diff --git a/tests/baselines/reference/interfaceImplementation7.errors.txt b/tests/baselines/reference/interfaceImplementation7.errors.txt index 1025a1f5296..de9bbdae835 100644 --- a/tests/baselines/reference/interfaceImplementation7.errors.txt +++ b/tests/baselines/reference/interfaceImplementation7.errors.txt @@ -1,9 +1,8 @@ tests/cases/compiler/interfaceImplementation7.ts(4,11): error TS2320: Interface 'i3' cannot simultaneously extend types 'i1' and 'i2'. Named property 'name' of types 'i1' and 'i2' are not identical. -tests/cases/compiler/interfaceImplementation7.ts(7,7): error TS2420: Class 'C1' incorrectly implements interface 'i4'. - Types of property 'name' are incompatible. - Type '() => string' is not assignable to type '() => { s: string; n: number; }'. - Type 'string' is not assignable to type '{ s: string; n: number; }'. +tests/cases/compiler/interfaceImplementation7.ts(8,12): error TS2416: Property 'name' in type 'C1' is not assignable to the same property in base type '() => { s: string; n: number; }'. + Type '() => string' is not assignable to type '() => { s: string; n: number; }'. + Type 'string' is not assignable to type '{ s: string; n: number; }'. ==== tests/cases/compiler/interfaceImplementation7.ts (2 errors) ==== @@ -17,11 +16,10 @@ tests/cases/compiler/interfaceImplementation7.ts(7,7): error TS2420: Class 'C1' interface i4 extends i1, i2 { name(): { s: string; n: number; }; } class C1 implements i4 { - ~~ -!!! error TS2420: Class 'C1' incorrectly implements interface 'i4'. -!!! error TS2420: Types of property 'name' are incompatible. -!!! error TS2420: Type '() => string' is not assignable to type '() => { s: string; n: number; }'. -!!! error TS2420: Type 'string' is not assignable to type '{ s: string; n: number; }'. public name(): string { return ""; } + ~~~~ +!!! error TS2416: Property 'name' in type 'C1' is not assignable to the same property in base type '() => { s: string; n: number; }'. +!!! error TS2416: Type '() => string' is not assignable to type '() => { s: string; n: number; }'. +!!! error TS2416: Type 'string' is not assignable to type '{ s: string; n: number; }'. } \ No newline at end of file diff --git a/tests/baselines/reference/mismatchedGenericArguments1.errors.txt b/tests/baselines/reference/mismatchedGenericArguments1.errors.txt index 13618c926ef..4b2d13986ce 100644 --- a/tests/baselines/reference/mismatchedGenericArguments1.errors.txt +++ b/tests/baselines/reference/mismatchedGenericArguments1.errors.txt @@ -1,13 +1,11 @@ -tests/cases/compiler/mismatchedGenericArguments1.ts(4,7): error TS2420: Class 'C' incorrectly implements interface 'IFoo'. - Types of property 'foo' are incompatible. - Type '(x: string) => number' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. -tests/cases/compiler/mismatchedGenericArguments1.ts(10,7): error TS2420: Class 'C2' incorrectly implements interface 'IFoo'. - Types of property 'foo' are incompatible. - Type '(x: string) => number' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. +tests/cases/compiler/mismatchedGenericArguments1.ts(5,4): error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type '(x: T) => T'. + Type '(x: string) => number' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. +tests/cases/compiler/mismatchedGenericArguments1.ts(11,4): error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type '(x: T) => T'. + Type '(x: string) => number' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. ==== tests/cases/compiler/mismatchedGenericArguments1.ts (2 errors) ==== @@ -15,25 +13,23 @@ tests/cases/compiler/mismatchedGenericArguments1.ts(10,7): error TS2420: Class ' foo(x: T): T; } class C implements IFoo { - ~ -!!! error TS2420: Class 'C' incorrectly implements interface 'IFoo'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: string) => number' is not assignable to type '(x: T) => T'. -!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2420: Type 'T' is not assignable to type 'string'. foo(x: string): number { + ~~~ +!!! error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Type '(x: string) => number' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. return null; } } class C2 implements IFoo { - ~~ -!!! error TS2420: Class 'C2' incorrectly implements interface 'IFoo'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: string) => number' is not assignable to type '(x: T) => T'. -!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2420: Type 'T' is not assignable to type 'string'. foo(x: string): number { + ~~~ +!!! error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Type '(x: string) => number' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. return null; } } diff --git a/tests/baselines/reference/multipleInheritance.errors.txt b/tests/baselines/reference/multipleInheritance.errors.txt index 19ef1e755e3..72e44dc999c 100644 --- a/tests/baselines/reference/multipleInheritance.errors.txt +++ b/tests/baselines/reference/multipleInheritance.errors.txt @@ -1,9 +1,8 @@ tests/cases/compiler/multipleInheritance.ts(9,21): error TS1174: Classes can only extend a single class. tests/cases/compiler/multipleInheritance.ts(18,21): error TS1174: Classes can only extend a single class. -tests/cases/compiler/multipleInheritance.ts(34,7): error TS2415: Class 'Baad' incorrectly extends base class 'Good'. - Types of property 'g' are incompatible. - Type '(n: number) => number' is not assignable to type '() => number'. tests/cases/compiler/multipleInheritance.ts(35,12): error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. +tests/cases/compiler/multipleInheritance.ts(36,12): error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type '() => number'. + Type '(n: number) => number' is not assignable to type '() => number'. ==== tests/cases/compiler/multipleInheritance.ts (4 errors) ==== @@ -45,13 +44,12 @@ tests/cases/compiler/multipleInheritance.ts(35,12): error TS2425: Class 'Good' d } class Baad extends Good { - ~~~~ -!!! error TS2415: Class 'Baad' incorrectly extends base class 'Good'. -!!! error TS2415: Types of property 'g' are incompatible. -!!! error TS2415: Type '(n: number) => number' is not assignable to type '() => number'. public f(): number { return 0; } ~ !!! error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. public g(n:number) { return 0; } + ~ +!!! error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Type '(n: number) => number' is not assignable to type '() => number'. } \ No newline at end of file diff --git a/tests/baselines/reference/requiredInitializedParameter2.errors.txt b/tests/baselines/reference/requiredInitializedParameter2.errors.txt index 5dcec536e1b..cdb659f251a 100644 --- a/tests/baselines/reference/requiredInitializedParameter2.errors.txt +++ b/tests/baselines/reference/requiredInitializedParameter2.errors.txt @@ -1,6 +1,5 @@ -tests/cases/compiler/requiredInitializedParameter2.ts(5,7): error TS2420: Class 'C1' incorrectly implements interface 'I1'. - Types of property 'method' are incompatible. - Type '(a: number, b: any) => void' is not assignable to type '() => any'. +tests/cases/compiler/requiredInitializedParameter2.ts(6,5): error TS2416: Property 'method' in type 'C1' is not assignable to the same property in base type '() => any'. + Type '(a: number, b: any) => void' is not assignable to type '() => any'. ==== tests/cases/compiler/requiredInitializedParameter2.ts (1 errors) ==== @@ -9,9 +8,8 @@ tests/cases/compiler/requiredInitializedParameter2.ts(5,7): error TS2420: Class } class C1 implements I1 { - ~~ -!!! error TS2420: Class 'C1' incorrectly implements interface 'I1'. -!!! error TS2420: Types of property 'method' are incompatible. -!!! error TS2420: Type '(a: number, b: any) => void' is not assignable to type '() => any'. method(a = 0, b) { } + ~~~~~~ +!!! error TS2416: Property 'method' in type 'C1' is not assignable to the same property in base type '() => any'. +!!! error TS2416: Type '(a: number, b: any) => void' is not assignable to type '() => any'. } \ No newline at end of file diff --git a/tests/baselines/reference/subtypesOfTypeParameter.errors.txt b/tests/baselines/reference/subtypesOfTypeParameter.errors.txt index 14e2275cbf9..f0bed548c97 100644 --- a/tests/baselines/reference/subtypesOfTypeParameter.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameter.errors.txt @@ -1,6 +1,5 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameter.ts(7,7): error TS2415: Class 'D1' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameter.ts(8,5): error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'T'. + Type 'U' is not assignable to type 'T'. ==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameter.ts (1 errors) ==== @@ -11,11 +10,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D1 extends C3 { - ~~ -!!! error TS2415: Class 'D1' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'T'. foo: U; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'T'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. } function f1(x: T, y: U) { diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt index bd7bbeb007e..7019967d204 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt @@ -1,47 +1,37 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(17,7): error TS2415: Class 'D3' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(19,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'T'. + Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(19,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(48,7): error TS2415: Class 'D8' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'T'. - Type 'V' is not assignable to type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(65,7): error TS2415: Class 'D11' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'T'. + Type 'U' is not assignable to type 'T'. Type 'V' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(67,5): error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'T'. + Type 'V' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(67,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(70,7): error TS2415: Class 'D12' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(72,5): error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'U'. + Type 'V' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(72,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(110,7): error TS2415: Class 'D19' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'T'. - Type 'V' is not assignable to type 'T'. - Type 'Date' is not assignable to type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(132,7): error TS2415: Class 'D23' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'T'. + Type 'U' is not assignable to type 'T'. Type 'V' is not assignable to type 'T'. Type 'Date' is not assignable to type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(137,7): error TS2415: Class 'D24' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'U'. - Type 'Date' is not assignable to type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(154,7): error TS2415: Class 'D27' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'T'. + Type 'V' is not assignable to type 'T'. Type 'Date' is not assignable to type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(159,7): error TS2415: Class 'D28' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'U'. + Type 'V' is not assignable to type 'U'. Type 'Date' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'T'. + Type 'Date' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(161,5): error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'U'. + Type 'Date' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(161,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(164,7): error TS2415: Class 'D29' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'Date' is not assignable to type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(166,5): error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'V'. + Type 'Date' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(166,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'V'. @@ -63,12 +53,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D3 extends C3 { - ~~ -!!! error TS2415: Class 'D3' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'T'. [x: string]: T; foo: U; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'T'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. } @@ -100,13 +89,12 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf // test if U is a subtype of T, U, V // only a subtype of V and itself class D8 extends C3 { - ~~ -!!! error TS2415: Class 'D8' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'T'. -!!! error TS2415: Type 'V' is not assignable to type 'T'. [x: string]: T; foo: U; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'T'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. } @@ -124,23 +112,21 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf // test if V is a subtype of T, U, V // only a subtype of itself class D11 extends C3 { - ~~~ -!!! error TS2415: Class 'D11' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'T'. [x: string]: T; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'T'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. } class D12 extends C3 { - ~~~ -!!! error TS2415: Class 'D12' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'U'. [x: string]: U; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'U'. +!!! error TS2416: Type 'V' is not assignable to type 'U'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. } @@ -181,14 +167,13 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D19 extends C3 { - ~~~ -!!! error TS2415: Class 'D19' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'T'. -!!! error TS2415: Type 'V' is not assignable to type 'T'. -!!! error TS2415: Type 'Date' is not assignable to type 'T'. [x: string]: T; foo: U; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'T'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. +!!! error TS2416: Type 'Date' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. } @@ -211,25 +196,23 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D23 extends C3 { - ~~~ -!!! error TS2415: Class 'D23' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'T'. -!!! error TS2415: Type 'Date' is not assignable to type 'T'. [x: string]: T; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'T'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. +!!! error TS2416: Type 'Date' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. } class D24 extends C3 { - ~~~ -!!! error TS2415: Class 'D24' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'U'. -!!! error TS2415: Type 'Date' is not assignable to type 'U'. [x: string]: U; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'U'. +!!! error TS2416: Type 'V' is not assignable to type 'U'. +!!! error TS2416: Type 'Date' is not assignable to type 'U'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. } @@ -247,34 +230,31 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D27 extends C3 { - ~~~ -!!! error TS2415: Class 'D27' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'Date' is not assignable to type 'T'. [x: string]: T; foo: Date; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'T'. +!!! error TS2416: Type 'Date' is not assignable to type 'T'. ~~~~~~~~~~ !!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'T'. } class D28 extends C3 { - ~~~ -!!! error TS2415: Class 'D28' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'Date' is not assignable to type 'U'. [x: string]: U; foo: Date; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'U'. +!!! error TS2416: Type 'Date' is not assignable to type 'U'. ~~~~~~~~~~ !!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'U'. } class D29 extends C3 { - ~~~ -!!! error TS2415: Class 'D29' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'Date' is not assignable to type 'V'. [x: string]: V; foo: Date; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'V'. +!!! error TS2416: Type 'Date' is not assignable to type 'V'. ~~~~~~~~~~ !!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'V'. } \ No newline at end of file diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt index 7b3d706606d..5b1cd0dffa3 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt @@ -1,24 +1,19 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(45,7): error TS2415: Class 'D3' incorrectly extends base class 'B1'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Foo'. + Type 'V' is not assignable to type 'Foo'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'Foo'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(55,7): error TS2415: Class 'D5' incorrectly extends base class 'B1'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'T'. - Type 'Foo' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'T'. + Type 'U' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(60,7): error TS2415: Class 'D6' incorrectly extends base class 'B1'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(62,5): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'T'. + Type 'V' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(62,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(65,7): error TS2415: Class 'D7' incorrectly extends base class 'B1'. - Types of property 'foo' are incompatible. - Type 'T' is not assignable to type 'U'. - Type 'Foo' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'U'. + Type 'T' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(75,7): error TS2415: Class 'D9' incorrectly extends base class 'B1'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(77,5): error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'U'. + Type 'V' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(77,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. @@ -68,12 +63,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D3 extends B1 { - ~~ -!!! error TS2415: Class 'D3' incorrectly extends base class 'B1'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'Foo'. [x: string]: Foo; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Type 'V' is not assignable to type 'Foo'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'Foo'. } @@ -84,36 +78,33 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D5 extends B1 { - ~~ -!!! error TS2415: Class 'D5' incorrectly extends base class 'B1'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'T'. -!!! error TS2415: Type 'Foo' is not assignable to type 'T'. [x: string]: T; foo: U; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'T'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. +!!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. } class D6 extends B1 { - ~~ -!!! error TS2415: Class 'D6' incorrectly extends base class 'B1'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'T'. [x: string]: T; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'T'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. } class D7 extends B1 { - ~~ -!!! error TS2415: Class 'D7' incorrectly extends base class 'B1'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'T' is not assignable to type 'U'. -!!! error TS2415: Type 'Foo' is not assignable to type 'U'. [x: string]: U; foo: T; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'U'. +!!! error TS2416: Type 'T' is not assignable to type 'U'. +!!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. } @@ -124,12 +115,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D9 extends B1 { - ~~ -!!! error TS2415: Class 'D9' incorrectly extends base class 'B1'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'U'. [x: string]: U; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'U'. +!!! error TS2416: Type 'V' is not assignable to type 'U'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. } \ No newline at end of file diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt index a7f9d3fad7f..35c086e52a2 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt @@ -1,74 +1,62 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(66,11): error TS2415: Class 'D2' incorrectly extends base class 'Base'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'T'. - Type 'Foo' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(68,9): error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'T'. + Type 'U' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(68,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(71,11): error TS2415: Class 'D3' incorrectly extends base class 'Base'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'T'. - Type 'Foo' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(73,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'T'. + Type 'V' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(73,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(76,11): error TS2415: Class 'D4' incorrectly extends base class 'Base'. - Types of property 'foo' are incompatible. - Type 'T' is not assignable to type 'U'. - Type 'Foo' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(78,9): error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'U'. + Type 'T' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(78,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(86,11): error TS2415: Class 'D6' incorrectly extends base class 'Base'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'U'. - Type 'Foo' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(88,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'U'. + Type 'V' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(88,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(91,11): error TS2415: Class 'D7' incorrectly extends base class 'Base'. - Types of property 'foo' are incompatible. - Type 'T' is not assignable to type 'V'. - Type 'Foo' is not assignable to type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(93,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'V'. + Type 'T' is not assignable to type 'V'. + Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(93,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(96,11): error TS2415: Class 'D8' incorrectly extends base class 'Base'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'V'. - Type 'Foo' is not assignable to type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(98,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'V'. + Type 'U' is not assignable to type 'V'. + Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(98,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(113,11): error TS2415: Class 'D1' incorrectly extends base class 'Base2'. - Types of property 'foo' are incompatible. - Type 'T' is not assignable to type 'Foo'. - Type 'Foo' is not assignable to type 'Foo'. - Type 'U' is not assignable to type 'T'. - Type 'Foo' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(115,9): error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'Foo'. + Type 'T' is not assignable to type 'Foo'. + Type 'Foo' is not assignable to type 'Foo'. + Type 'U' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(120,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(123,11): error TS2415: Class 'D3' incorrectly extends base class 'Base2'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'Foo'. - Type 'Foo' is not assignable to type 'Foo'. - Type 'V' is not assignable to type 'T'. - Type 'Foo' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(125,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Foo'. + Type 'V' is not assignable to type 'Foo'. + Type 'Foo' is not assignable to type 'Foo'. + Type 'V' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(125,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(130,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(133,11): error TS2415: Class 'D5' incorrectly extends base class 'Base2'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'Foo'. - Type 'Foo' is not assignable to type 'Foo'. - Type 'T' is not assignable to type 'U'. - Type 'Foo' is not assignable to type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(138,11): error TS2415: Class 'D6' incorrectly extends base class 'Base2'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'Foo'. - Type 'Foo' is not assignable to type 'Foo'. - Type 'V' is not assignable to type 'U'. - Type 'Foo' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(135,9): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'Foo'. + Type 'U' is not assignable to type 'Foo'. + Type 'Foo' is not assignable to type 'Foo'. + Type 'T' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(140,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Foo'. + Type 'V' is not assignable to type 'Foo'. + Type 'Foo' is not assignable to type 'Foo'. + Type 'V' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(140,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(143,11): error TS2415: Class 'D7' incorrectly extends base class 'Base2'. - Types of property 'foo' are incompatible. - Type 'T' is not assignable to type 'Foo'. - Type 'Foo' is not assignable to type 'Foo'. - Type 'U' is not assignable to type 'V'. - Type 'Foo' is not assignable to type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(145,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Foo'. + Type 'T' is not assignable to type 'Foo'. + Type 'Foo' is not assignable to type 'Foo'. + Type 'U' is not assignable to type 'V'. + Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(145,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(148,11): error TS2415: Class 'D8' incorrectly extends base class 'Base2'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'Foo'. - Type 'Foo' is not assignable to type 'Foo'. - Type 'T' is not assignable to type 'V'. - Type 'Foo' is not assignable to type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(150,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Foo'. + Type 'U' is not assignable to type 'Foo'. + Type 'Foo' is not assignable to type 'Foo'. + Type 'T' is not assignable to type 'V'. + Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(150,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. @@ -139,37 +127,34 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D2, U extends Foo, V extends Foo> extends Base { - ~~ -!!! error TS2415: Class 'D2' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'T'. -!!! error TS2415: Type 'Foo' is not assignable to type 'T'. [x: string]: T; foo: U + ~~~ +!!! error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'T'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. +!!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. } class D3, U extends Foo, V extends Foo> extends Base { - ~~ -!!! error TS2415: Class 'D3' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'T'. -!!! error TS2415: Type 'Foo' is not assignable to type 'T'. [x: string]: T; foo: V + ~~~ +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'T'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. +!!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. } class D4, U extends Foo, V extends Foo> extends Base { - ~~ -!!! error TS2415: Class 'D4' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'T' is not assignable to type 'U'. -!!! error TS2415: Type 'Foo' is not assignable to type 'U'. [x: string]: U; foo: T + ~~~ +!!! error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'U'. +!!! error TS2416: Type 'T' is not assignable to type 'U'. +!!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. } @@ -180,37 +165,34 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D6, U extends Foo, V extends Foo> extends Base { - ~~ -!!! error TS2415: Class 'D6' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'U'. -!!! error TS2415: Type 'Foo' is not assignable to type 'U'. [x: string]: U; foo: V + ~~~ +!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'U'. +!!! error TS2416: Type 'V' is not assignable to type 'U'. +!!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. } class D7, U extends Foo, V extends Foo> extends Base { - ~~ -!!! error TS2415: Class 'D7' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'T' is not assignable to type 'V'. -!!! error TS2415: Type 'Foo' is not assignable to type 'V'. [x: string]: V; foo: T + ~~~ +!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'V'. +!!! error TS2416: Type 'T' is not assignable to type 'V'. +!!! error TS2416: Type 'Foo' is not assignable to type 'V'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. } class D8, U extends Foo, V extends Foo> extends Base { - ~~ -!!! error TS2415: Class 'D8' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'V'. -!!! error TS2415: Type 'Foo' is not assignable to type 'V'. [x: string]: V; foo: U + ~~~ +!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'V'. +!!! error TS2416: Type 'U' is not assignable to type 'V'. +!!! error TS2416: Type 'Foo' is not assignable to type 'V'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. } @@ -228,15 +210,14 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D1, U extends Foo, V extends Foo> extends Base2 { - ~~ -!!! error TS2415: Class 'D1' incorrectly extends base class 'Base2'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'T' is not assignable to type 'Foo'. -!!! error TS2415: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2415: Type 'U' is not assignable to type 'T'. -!!! error TS2415: Type 'Foo' is not assignable to type 'T'. [x: string]: T; foo: T + ~~~ +!!! error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Type 'T' is not assignable to type 'Foo'. +!!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. +!!! error TS2416: Type 'Foo' is not assignable to type 'T'. } class D2, U extends Foo, V extends Foo> extends Base2 { @@ -247,15 +228,14 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D3, U extends Foo, V extends Foo> extends Base2 { - ~~ -!!! error TS2415: Class 'D3' incorrectly extends base class 'Base2'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'Foo'. -!!! error TS2415: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2415: Type 'V' is not assignable to type 'T'. -!!! error TS2415: Type 'Foo' is not assignable to type 'T'. [x: string]: T; foo: V + ~~~ +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Type 'V' is not assignable to type 'Foo'. +!!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. +!!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. } @@ -268,55 +248,51 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D5, U extends Foo, V extends Foo> extends Base2 { - ~~ -!!! error TS2415: Class 'D5' incorrectly extends base class 'Base2'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'Foo'. -!!! error TS2415: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2415: Type 'T' is not assignable to type 'U'. -!!! error TS2415: Type 'Foo' is not assignable to type 'U'. [x: string]: U; foo: U + ~~~ +!!! error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Type 'U' is not assignable to type 'Foo'. +!!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. +!!! error TS2416: Type 'T' is not assignable to type 'U'. +!!! error TS2416: Type 'Foo' is not assignable to type 'U'. } class D6, U extends Foo, V extends Foo> extends Base2 { - ~~ -!!! error TS2415: Class 'D6' incorrectly extends base class 'Base2'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'Foo'. -!!! error TS2415: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2415: Type 'V' is not assignable to type 'U'. -!!! error TS2415: Type 'Foo' is not assignable to type 'U'. [x: string]: U; foo: V + ~~~ +!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Type 'V' is not assignable to type 'Foo'. +!!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. +!!! error TS2416: Type 'V' is not assignable to type 'U'. +!!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. } class D7, U extends Foo, V extends Foo> extends Base2 { - ~~ -!!! error TS2415: Class 'D7' incorrectly extends base class 'Base2'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'T' is not assignable to type 'Foo'. -!!! error TS2415: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2415: Type 'U' is not assignable to type 'V'. -!!! error TS2415: Type 'Foo' is not assignable to type 'V'. [x: string]: V; foo: T + ~~~ +!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Type 'T' is not assignable to type 'Foo'. +!!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. +!!! error TS2416: Type 'U' is not assignable to type 'V'. +!!! error TS2416: Type 'Foo' is not assignable to type 'V'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. } class D8, U extends Foo, V extends Foo> extends Base2 { - ~~ -!!! error TS2415: Class 'D8' incorrectly extends base class 'Base2'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'Foo'. -!!! error TS2415: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2415: Type 'T' is not assignable to type 'V'. -!!! error TS2415: Type 'Foo' is not assignable to type 'V'. [x: string]: V; foo: U + ~~~ +!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Type 'U' is not assignable to type 'Foo'. +!!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. +!!! error TS2416: Type 'T' is not assignable to type 'V'. +!!! error TS2416: Type 'Foo' is not assignable to type 'V'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. } diff --git a/tests/baselines/reference/subtypingWithObjectMembers.errors.txt b/tests/baselines/reference/subtypingWithObjectMembers.errors.txt index a5d4152b451..2be672f5c03 100644 --- a/tests/baselines/reference/subtypingWithObjectMembers.errors.txt +++ b/tests/baselines/reference/subtypingWithObjectMembers.errors.txt @@ -1,21 +1,15 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(12,7): error TS2415: Class 'B' incorrectly extends base class 'A'. - Types of property 'bar' are incompatible. - Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(22,7): error TS2415: Class 'B2' incorrectly extends base class 'A2'. - Types of property '2.0' are incompatible. - Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(32,7): error TS2415: Class 'B3' incorrectly extends base class 'A3'. - Types of property ''2.0'' are incompatible. - Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(43,11): error TS2415: Class 'B' incorrectly extends base class 'A'. - Types of property 'bar' are incompatible. - Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(53,11): error TS2415: Class 'B2' incorrectly extends base class 'A2'. - Types of property '2.0' are incompatible. - Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(63,11): error TS2415: Class 'B3' incorrectly extends base class 'A3'. - Types of property ''2.0'' are incompatible. - Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(14,5): error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'Base'. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(24,5): error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'Base'. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(34,5): error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'Base'. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(45,9): error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'Base'. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(55,9): error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'Base'. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(65,9): error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'Base'. + Type 'string' is not assignable to type 'Base'. ==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts (6 errors) ==== @@ -31,12 +25,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } class B extends A { - ~ -!!! error TS2415: Class 'B' incorrectly extends base class 'A'. -!!! error TS2415: Types of property 'bar' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'Base'. foo: Derived; // ok bar: string; // error + ~~~ +!!! error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'string' is not assignable to type 'Base'. } class A2 { @@ -45,12 +38,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } class B2 extends A2 { - ~~ -!!! error TS2415: Class 'B2' incorrectly extends base class 'A2'. -!!! error TS2415: Types of property '2.0' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'Base'. 1: Derived; // ok 2: string; // error + ~ +!!! error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'string' is not assignable to type 'Base'. } class A3 { @@ -59,12 +51,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } class B3 extends A3 { - ~~ -!!! error TS2415: Class 'B3' incorrectly extends base class 'A3'. -!!! error TS2415: Types of property ''2.0'' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'Base'. '1': Derived; // ok '2.0': string; // error + ~~~~~ +!!! error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'string' is not assignable to type 'Base'. } module TwoLevels { @@ -74,12 +65,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } class B extends A { - ~ -!!! error TS2415: Class 'B' incorrectly extends base class 'A'. -!!! error TS2415: Types of property 'bar' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'Base'. foo: Derived2; // ok bar: string; // error + ~~~ +!!! error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'string' is not assignable to type 'Base'. } class A2 { @@ -88,12 +78,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } class B2 extends A2 { - ~~ -!!! error TS2415: Class 'B2' incorrectly extends base class 'A2'. -!!! error TS2415: Types of property '2.0' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'Base'. 1: Derived2; // ok 2: string; // error + ~ +!!! error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'string' is not assignable to type 'Base'. } class A3 { @@ -102,11 +91,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } class B3 extends A3 { - ~~ -!!! error TS2415: Class 'B3' incorrectly extends base class 'A3'. -!!! error TS2415: Types of property ''2.0'' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'Base'. '1': Derived2; // ok '2.0': string; // error + ~~~~~ +!!! error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'string' is not assignable to type 'Base'. } } \ No newline at end of file diff --git a/tests/cases/compiler/baseClassImprovedMismatchErrors.ts b/tests/cases/compiler/baseClassImprovedMismatchErrors.ts new file mode 100644 index 00000000000..5b59d2bc96a --- /dev/null +++ b/tests/cases/compiler/baseClassImprovedMismatchErrors.ts @@ -0,0 +1,18 @@ +class Base { + n: Base | string; + fn() { + return 10; + } +} +class Derived extends Base { + n: Derived | string; + fn() { + return 10 as number | string; + } +} +class DerivedInterface implements Base { + n: DerivedInterface | string; + fn() { + return 10 as number | string; + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/incompatibleOverride.ts b/tests/cases/fourslash/incompatibleOverride.ts index f33e7f226b6..0b3dd323015 100644 --- a/tests/cases/fourslash/incompatibleOverride.ts +++ b/tests/cases/fourslash/incompatibleOverride.ts @@ -3,8 +3,8 @@ // Squiggle for implementing a derived class with an incompatible override is too large //// class Foo { xyz: string; } -//// class /*1*/Bar/*2*/ extends Foo { xyz: number; } -//// class /*3*/Baz/*4*/ extends Foo { public xyz: number; } +//// class Bar extends Foo { /*1*/xyz/*2*/: number; } +//// class Baz extends Foo { public /*3*/xyz/*4*/: number; } //// class /*5*/Baf/*6*/ extends Foo { //// constructor(public xyz: number) { //// super(); diff --git a/tests/cases/fourslash/squiggleIllegalSubclassOverride.ts b/tests/cases/fourslash/squiggleIllegalSubclassOverride.ts index bb7b40fd259..955d461b9f1 100644 --- a/tests/cases/fourslash/squiggleIllegalSubclassOverride.ts +++ b/tests/cases/fourslash/squiggleIllegalSubclassOverride.ts @@ -4,8 +4,8 @@ //// public x: number; ////} //// -////class /*1*/Bar/*2*/ extends Foo { -//// public x: string; +////class Bar extends Foo { +//// public /*1*/x/*2*/: string; ////} verify.errorExistsBetweenMarkers("1", "2"); From 82fb294924c6a9a8775a1342cc4933b4918df56d Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 9 Jan 2018 10:34:35 -0800 Subject: [PATCH 122/189] For import fix, support path mapping value that begins in "./" or ends in ".ts" (#21035) * For import fix, support path mapping value that begins in "./" or ends in ".ts" * Handle repeated "./" in path * Rename parameters to indicate that they're relative to baseUrl * Support relative path beginning with `..\` * Remove unused function --- src/services/codefixes/importFixes.ts | 32 +++++++++++++------ ...NameCodeFixNewImportPaths_withExtension.ts | 23 +++++++++++++ ...deFixNewImportPaths_withLeadingDotSlash.ts | 23 +++++++++++++ ...ixNewImportPaths_withParentRelativePath.ts | 23 +++++++++++++ 4 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts create mode 100644 tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts create mode 100644 tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 32bf64d5c53..34ebd2417c9 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -363,6 +363,10 @@ namespace ts.codefix { } } + if (isPathRelativeToParent(relativeToBaseUrl)) { + return [relativePath]; + } + /* Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl. @@ -424,9 +428,10 @@ namespace ts.codefix { } } - function tryGetModuleNameFromPaths(relativeNameWithIndex: string, relativeName: string, paths: MapLike>): string | undefined { + function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex: string, relativeToBaseUrl: string, paths: MapLike>): string | undefined { for (const key in paths) { - for (const pattern of paths[key]) { + for (const patternText of paths[key]) { + const pattern = removeFileExtension(normalizePath(patternText)); const indexOfStar = pattern.indexOf("*"); if (indexOfStar === 0 && pattern.length === 1) { continue; @@ -434,14 +439,14 @@ namespace ts.codefix { else if (indexOfStar !== -1) { const prefix = pattern.substr(0, indexOfStar); const suffix = pattern.substr(indexOfStar + 1); - if (relativeName.length >= prefix.length + suffix.length && - startsWith(relativeName, prefix) && - endsWith(relativeName, suffix)) { - const matchedStar = relativeName.substr(prefix.length, relativeName.length - suffix.length); - return key.replace("\*", matchedStar); + if (relativeToBaseUrl.length >= prefix.length + suffix.length && + startsWith(relativeToBaseUrl, prefix) && + endsWith(relativeToBaseUrl, suffix)) { + const matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length); + return key.replace("*", matchedStar); } } - else if (pattern === relativeName || pattern === relativeNameWithIndex) { + else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) { return key; } } @@ -601,7 +606,10 @@ namespace ts.codefix { } function getPathRelativeToRootDirs(path: string, rootDirs: ReadonlyArray, getCanonicalFileName: GetCanonicalFileName): string | undefined { - return firstDefined(rootDirs, rootDir => getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName)); + return firstDefined(rootDirs, rootDir => { + const relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); + return isPathRelativeToParent(relativePath) ? undefined : relativePath; + }); } function removeExtensionAndIndexPostFix(fileName: string, options: CompilerOptions, addJsExtension: boolean): string { @@ -615,7 +623,11 @@ namespace ts.codefix { function getRelativePathIfInDirectory(path: string, directoryPath: string, getCanonicalFileName: GetCanonicalFileName): string | undefined { const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); - return isRootedDiskPath(relativePath) || startsWith(relativePath, "..") ? undefined : relativePath; + return isRootedDiskPath(relativePath) ? undefined : relativePath; + } + + function isPathRelativeToParent(path: string): boolean { + return startsWith(path, ".."); } function getRelativePath(path: string, directoryPath: string, getCanonicalFileName: GetCanonicalFileName) { diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts new file mode 100644 index 00000000000..c383b09862e --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts @@ -0,0 +1,23 @@ +/// + +// @Filename: /src/a.ts +////[|foo|] + +// @Filename: /src/thisHasPathMapping.ts +////export function foo() {}; + +// @Filename: /tsconfig.json +////{ +//// "compilerOptions": { +//// "baseUrl": ".", +//// "paths": { +//// "foo": ["src/thisHasPathMapping.ts"] +//// } +//// } +////} + +verify.importFixAtPosition([ +`import { foo } from "foo"; + +foo` +]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts new file mode 100644 index 00000000000..f29932eed73 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts @@ -0,0 +1,23 @@ +/// + +// @Filename: /a.ts +////[|foo|] + +// @Filename: /thisHasPathMapping.ts +////export function foo() {}; + +// @Filename: /tsconfig.json +////{ +//// "compilerOptions": { +//// "baseUrl": ".", +//// "paths": { +//// "foo": ["././thisHasPathMapping"] +//// } +//// } +////} + +verify.importFixAtPosition([ +`import { foo } from "foo"; + +foo` +]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts new file mode 100644 index 00000000000..4bd938ae0b9 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts @@ -0,0 +1,23 @@ +/// + +// @Filename: /src/a.ts +////[|foo|] + +// @Filename: /thisHasPathMapping.ts +////export function foo() {}; + +// @Filename: /tsconfig.json +////{ +//// "compilerOptions": { +//// "baseUrl": "src", +//// "paths": { +//// "foo": ["..\\thisHasPathMapping"] +//// } +//// } +////} + +verify.importFixAtPosition([ +`import { foo } from "foo"; + +foo` +]); From 191b9750c3f7880f4b33c5c08024832068117ca0 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 9 Jan 2018 11:22:15 -0800 Subject: [PATCH 123/189] Clear jsDocCache for reused nodes (#21099) --- src/compiler/parser.ts | 5 +++++ tests/cases/fourslash/editClearsJsDocCache.ts | 14 ++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 tests/cases/fourslash/editClearsJsDocCache.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 6503e6bf421..bae9f0594ed 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1679,6 +1679,11 @@ namespace ts { return undefined; } + if ((node as JSDocContainer).jsDocCache) { + // jsDocCache may include tags from parent nodes, which might have been modified. + (node as JSDocContainer).jsDocCache = undefined; + } + return node; } diff --git a/tests/cases/fourslash/editClearsJsDocCache.ts b/tests/cases/fourslash/editClearsJsDocCache.ts new file mode 100644 index 00000000000..0ffc351300f --- /dev/null +++ b/tests/cases/fourslash/editClearsJsDocCache.ts @@ -0,0 +1,14 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////** @type {/*type*/number} */ +////let /*x*/x; + +verify.quickInfoAt("x", "let x: number"); + +goTo.marker("type"); +edit.replace(test.markers()[0].position, "number".length, "string"); + +verify.quickInfoAt("x", "let x: string"); From fed34cd6163b49bfb2bd519a8885ffb6dafc8ac4 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 9 Jan 2018 11:54:35 -0800 Subject: [PATCH 124/189] Fix bug: normalize path after combining (#21100) --- src/services/pathCompletions.ts | 3 ++- ...etionsPaths_pathMapping_parentDirectory.ts | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/completionsPaths_pathMapping_parentDirectory.ts diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index e9c8b48a7c4..97569e0bae9 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -216,7 +216,8 @@ namespace ts.Completions.PathCompletions { const expandedPrefixDirectory = fragmentHasPath ? combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + getDirectoryPath(fragment)) : normalizedPrefixDirectory; const normalizedSuffix = normalizePath(parsed.suffix); - const baseDirectory = combinePaths(baseUrl, expandedPrefixDirectory); + // Need to normalize after combining: If we combinePaths("a", "../b"), we want "b" and not "a/../b". + const baseDirectory = normalizePath(combinePaths(baseUrl, expandedPrefixDirectory)); const completePrefix = fragmentHasPath ? baseDirectory : ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase; // If we have a suffix, then we need to read the directory all the way down. We could create a glob diff --git a/tests/cases/fourslash/completionsPaths_pathMapping_parentDirectory.ts b/tests/cases/fourslash/completionsPaths_pathMapping_parentDirectory.ts new file mode 100644 index 00000000000..7dcd6e3adb1 --- /dev/null +++ b/tests/cases/fourslash/completionsPaths_pathMapping_parentDirectory.ts @@ -0,0 +1,20 @@ +/// + +// @Filename: /src/a.ts +////import { } from "foo/[|/**/|]"; + +// @Filename: /oof/x.ts +////export const x = 0; + +// @Filename: /tsconfig.json +////{ +//// "compilerOptions": { +//// "baseUrl": "src", +//// "paths": { +//// "foo/*": ["../oof/*"] +//// } +//// } +////} + +const [replacementSpan] = test.ranges(); +verify.completionsAt("", [{ name: "x", replacementSpan }]); From 9aa99b90c72917347e781d146af577090c0b584d Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 9 Jan 2018 13:15:30 -0800 Subject: [PATCH 125/189] Include directories in completions for path mapping (#21103) --- src/services/pathCompletions.ts | 9 +++++---- tests/cases/fourslash/completionsPaths_pathMapping.ts | 9 ++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 97569e0bae9..65d288e7f8d 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -94,7 +94,7 @@ namespace ts.Completions.PathCompletions { * * both foo.ts and foo.tsx become foo */ - const foundFiles = createMap(); + const foundFiles = createMap(); for (let filePath of files) { filePath = normalizePath(filePath); if (exclude && comparePaths(filePath, exclude, scriptPath, ignoreCase) === Comparison.EqualTo) { @@ -103,7 +103,7 @@ namespace ts.Completions.PathCompletions { const foundFileName = includeExtensions ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath)); - if (!foundFiles.get(foundFileName)) { + if (!foundFiles.has(foundFileName)) { foundFiles.set(foundFileName, true); } } @@ -226,8 +226,9 @@ namespace ts.Completions.PathCompletions { const includeGlob = normalizedSuffix ? "**/*" : "./*"; const matches = tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]); + const directories = tryGetDirectories(host, baseDirectory); // Trim away prefix and suffix - return mapDefined(matches, match => { + return mapDefined(concatenate(matches, directories), match => { const normalizedMatch = normalizePath(match); if (!endsWith(normalizedMatch, normalizedSuffix) || !startsWith(normalizedMatch, completePrefix)) { return; @@ -468,7 +469,7 @@ namespace ts.Completions.PathCompletions { return tryIOAndConsumeErrors(host, host.getDirectories, directoryName); } - function tryReadDirectory(host: LanguageServiceHost, path: string, extensions?: ReadonlyArray, exclude?: ReadonlyArray, include?: ReadonlyArray): string[] { + function tryReadDirectory(host: LanguageServiceHost, path: string, extensions?: ReadonlyArray, exclude?: ReadonlyArray, include?: ReadonlyArray): string[] | undefined { return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include); } diff --git a/tests/cases/fourslash/completionsPaths_pathMapping.ts b/tests/cases/fourslash/completionsPaths_pathMapping.ts index b2ec9ac6198..7a6283bce3a 100644 --- a/tests/cases/fourslash/completionsPaths_pathMapping.ts +++ b/tests/cases/fourslash/completionsPaths_pathMapping.ts @@ -3,6 +3,9 @@ // @Filename: /src/b.ts ////export const x = 0; +// @Filename: /src/dir/x.ts +/////export const x = 0; + // @Filename: /src/a.ts ////import {} from "foo/[|/**/|]"; @@ -17,4 +20,8 @@ ////} const [replacementSpan] = test.ranges(); -verify.completionsAt("", [{ name: "a", replacementSpan }, { name: "b", replacementSpan }]); +verify.completionsAt("", [ + { name: "a", replacementSpan }, + { name: "b", replacementSpan }, + { name: "dir", replacementSpan }, +]); From 8bce69e6bd6bdfe8c2a92a5db6da86ea22bb52a3 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 9 Jan 2018 13:15:47 -0800 Subject: [PATCH 126/189] Add refactoring to convert CommonJS module to ES6 module (#19916) * Add refactoring to convert CommonJS module to ES6 module * Code review * includeGlobals -> excludeGlobals * Improve handling of `module.exports = require("...")` * Allow NoSubstitutionTemplateLiteral as argument to createLiteral --- src/compiler/binder.ts | 54 +- src/compiler/checker.ts | 15 +- src/compiler/core.ts | 27 +- src/compiler/diagnosticMessages.json | 4 + src/compiler/emitter.ts | 28 +- src/compiler/factory.ts | 8 +- src/compiler/types.ts | 8 +- src/compiler/utilities.ts | 5 +- src/harness/fourslash.ts | 11 +- src/services/codefixes/importFixes.ts | 4 +- src/services/refactors/convertToEs6Module.ts | 582 ++++++++++++++++++ src/services/refactors/extractSymbol.ts | 2 +- src/services/refactors/refactors.ts | 1 + src/services/refactors/useDefaultImport.ts | 4 +- src/services/utilities.ts | 4 + .../reference/api/tsserverlibrary.d.ts | 4 +- tests/baselines/reference/api/typescript.d.ts | 4 +- tests/cases/fourslash/fourslash.ts | 1 + ...refactorConvertToEs6Module_export_alias.ts | 18 + ...torConvertToEs6Module_export_dotDefault.ts | 19 + ...orConvertToEs6Module_export_invalidName.ts | 19 + ...vertToEs6Module_export_moduleDotExports.ts | 26 + ...le_export_moduleDotExportsEqualsRequire.ts | 43 ++ ..._export_moduleDotExports_changesImports.ts | 26 + ...refactorConvertToEs6Module_export_named.ts | 19 + ...efactorConvertToEs6Module_export_object.ts | 25 + ...vertToEs6Module_export_object_shorthand.ts | 18 + ...torConvertToEs6Module_export_referenced.ts | 36 ++ ...vertToEs6Module_expressionToDeclaration.ts | 18 + ...tToEs6Module_import_arrayBindingPattern.ts | 15 + ...rtToEs6Module_import_includeDefaultUses.ts | 18 + ...Module_import_multipleUniqueIdentifiers.ts | 20 + ...ule_import_multipleVariableDeclarations.ts | 18 + ...s6Module_import_nameFromModuleSpecifier.ts | 21 + ...ule_import_objectBindingPattern_complex.ts | 15 + ...odule_import_objectBindingPattern_plain.ts | 14 + ...vertToEs6Module_import_onlyNamedImports.ts | 16 + ...onvertToEs6Module_import_propertyAccess.ts | 24 + ...ctorConvertToEs6Module_import_shadowing.ts | 18 + ...torConvertToEs6Module_import_sideEffect.ts | 16 + .../refactorConvertToEs6Module_triggers.ts | 13 + 41 files changed, 1170 insertions(+), 71 deletions(-) create mode 100644 src/services/refactors/convertToEs6Module.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 701b1bfb249..4e4b4f12705 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2289,30 +2289,13 @@ namespace ts { declareSymbol(file.symbol.exports, file.symbol, node.left, SymbolFlags.Property | SymbolFlags.ExportValue, SymbolFlags.None); } - function isExportsOrModuleExportsOrAlias(node: Node): boolean { - return isExportsIdentifier(node) || - isModuleExportsPropertyAccessExpression(node) || - isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(node); - } - - function isNameOfExportsOrModuleExportsAliasDeclaration(node: Identifier): boolean { - const symbol = lookupSymbolForName(node.escapedText); - return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) && - symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(symbol.valueDeclaration.initializer); - } - - function isExportsOrModuleExportsOrAliasOrAssignment(node: Node): boolean { - return isExportsOrModuleExportsOrAlias(node) || - (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && (isExportsOrModuleExportsOrAliasOrAssignment(node.left) || isExportsOrModuleExportsOrAliasOrAssignment(node.right))); - } - function bindModuleExportsAssignment(node: BinaryExpression) { // A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports' // is still pointing to 'module.exports'. // We do not want to consider this as 'export=' since a module can have only one of these. // Similarly we do not want to treat 'module.exports = exports' as an 'export='. const assignedExpression = getRightMostAssignedExpression(node.right); - if (isEmptyObjectLiteral(assignedExpression) || isExportsOrModuleExportsOrAlias(assignedExpression)) { + if (isEmptyObjectLiteral(assignedExpression) || container === file && isExportsOrModuleExportsOrAlias(file, assignedExpression)) { // Mark it as a module in case there are no other exports in the file setCommonJsModuleIndicator(node); return; @@ -2393,7 +2376,7 @@ namespace ts { if (node.kind === SyntaxKind.BinaryExpression) { leftSideOfAssignment.parent = node; } - if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) { + if (container === file && isNameOfExportsOrModuleExportsAliasDeclaration(file, target)) { // This can be an alias for the 'exports' or 'module.exports' names, e.g. // var util = module.exports; // util.property = function ... @@ -2406,11 +2389,7 @@ namespace ts { } function lookupSymbolForName(name: __String) { - const local = container.locals && container.locals.get(name); - if (local) { - return local.exportSymbol || local; - } - return container.symbol && container.symbol.exports && container.symbol.exports.get(name); + return lookupSymbolForNameWorker(container, name); } function bindPropertyAssignment(functionName: __String, propertyAccess: PropertyAccessExpression, isPrototypeProperty: boolean) { @@ -2649,6 +2628,33 @@ namespace ts { } } + /* @internal */ + export function isExportsOrModuleExportsOrAlias(sourceFile: SourceFile, node: Expression): boolean { + return isExportsIdentifier(node) || + isModuleExportsPropertyAccessExpression(node) || + isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(sourceFile, node); + } + + function isNameOfExportsOrModuleExportsAliasDeclaration(sourceFile: SourceFile, node: Identifier): boolean { + const symbol = lookupSymbolForNameWorker(sourceFile, node.escapedText); + return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) && + symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, symbol.valueDeclaration.initializer); + } + + function isExportsOrModuleExportsOrAliasOrAssignment(sourceFile: SourceFile, node: Expression): boolean { + return isExportsOrModuleExportsOrAlias(sourceFile, node) || + (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && ( + isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, node.left) || isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, node.right))); + } + + function lookupSymbolForNameWorker(container: Node, name: __String): Symbol | undefined { + const local = container.locals && container.locals.get(name); + if (local) { + return local.exportSymbol || local; + } + return container.symbol && container.symbol.exports && container.symbol.exports.get(name); + } + /** * Computes the transform flags for a node, given the transform flags of its subtree * diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d153eee3034..16bfd7fa7e2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -268,8 +268,8 @@ namespace ts { getSuggestionForNonexistentSymbol: (location, name, meaning) => getSuggestionForNonexistentSymbol(location, escapeLeadingUnderscores(name), meaning), getBaseConstraintOfType, getDefaultFromTypeParameter: type => type && type.flags & TypeFlags.TypeParameter ? getDefaultFromTypeParameter(type as TypeParameter) : undefined, - resolveName(name, location, meaning) { - return resolveName(location, escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); + resolveName(name, location, meaning, excludeGlobals) { + return resolveName(location, escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false, excludeGlobals); }, getJsxNamespace: () => unescapeLeadingUnderscores(getJsxNamespace()), getAccessibleSymbolChain, @@ -952,8 +952,9 @@ namespace ts { nameNotFoundMessage: DiagnosticMessage | undefined, nameArg: __String | Identifier, isUse: boolean, + excludeGlobals = false, suggestedNameNotFoundMessage?: DiagnosticMessage): Symbol { - return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, getSymbol, suggestedNameNotFoundMessage); + return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSymbol, suggestedNameNotFoundMessage); } function resolveNameHelper( @@ -963,6 +964,7 @@ namespace ts { nameNotFoundMessage: DiagnosticMessage, nameArg: __String | Identifier, isUse: boolean, + excludeGlobals: boolean, lookup: typeof getSymbol, suggestedNameNotFoundMessage?: DiagnosticMessage): Symbol { const originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location @@ -1209,7 +1211,9 @@ namespace ts { } } - result = lookup(globals, name, meaning); + if (!excludeGlobals) { + result = lookup(globals, name, meaning); + } } if (!result) { @@ -11889,6 +11893,7 @@ namespace ts { Diagnostics.Cannot_find_name_0, node, !isWriteOnlyAccess(node), + /*excludeGlobals*/ false, Diagnostics.Cannot_find_name_0_Did_you_mean_1) || unknownSymbol; } return links.resolvedSymbol; @@ -16068,7 +16073,7 @@ namespace ts { function getSuggestionForNonexistentSymbol(location: Node, outerName: __String, meaning: SymbolFlags): string { Debug.assert(outerName !== undefined, "outername should always be defined"); - const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, (symbols, name, meaning) => { + const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, /*excludeGlobals*/ false, (symbols, name, meaning) => { Debug.assertEqual(outerName, name, "name should equal outerName"); const symbol = getSymbol(symbols, name, meaning); // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 2e8106e44ba..918dbbd51c0 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -412,12 +412,14 @@ namespace ts { return result; } + export function mapIterator(iter: Iterator, mapFn: (x: T) => U): Iterator { - return { next }; - function next(): { value: U, done: false } | { value: never, done: true } { - const iterRes = iter.next(); - return iterRes.done ? iterRes : { value: mapFn(iterRes.value), done: false }; - } + return { + next() { + const iterRes = iter.next(); + return iterRes.done ? iterRes : { value: mapFn(iterRes.value), done: false }; + } + }; } // Maps from T to T and avoids allocation if all elements map to themselves @@ -551,12 +553,23 @@ namespace ts { return result || array; } + export function mapAllOrFail(array: ReadonlyArray, mapFn: (x: T, i: number) => U | undefined): U[] | undefined { + const result: U[] = []; + for (let i = 0; i < array.length; i++) { + const mapped = mapFn(array[i], i); + if (mapped === undefined) { + return undefined; + } + result.push(mapped); + } + return result; + } + export function mapDefined(array: ReadonlyArray | undefined, mapFn: (x: T, i: number) => U | undefined): U[] { const result: U[] = []; if (array) { for (let i = 0; i < array.length; i++) { - const item = array[i]; - const mapped = mapFn(item, i); + const mapped = mapFn(array[i], i); if (mapped !== undefined) { result.push(mapped); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4a705ce97fe..96be3e99fdc 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3937,5 +3937,9 @@ "Use synthetic 'default' member.": { "category": "Message", "code": 95016 + }, + "Convert to ES6 module": { + "category": "Message", + "code": 95017 } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 7a1d88d3bfd..909dd0feede 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1194,27 +1194,15 @@ namespace ts { // function emitObjectBindingPattern(node: ObjectBindingPattern) { - const elements = node.elements; - if (elements.length === 0) { - write("{}"); - } - else { - write("{"); - emitList(node, elements, ListFormat.ObjectBindingPatternElements); - write("}"); - } + write("{"); + emitList(node, node.elements, ListFormat.ObjectBindingPatternElements); + write("}"); } function emitArrayBindingPattern(node: ArrayBindingPattern) { - const elements = node.elements; - if (elements.length === 0) { - write("[]"); - } - else { - write("["); - emitList(node, node.elements, ListFormat.ArrayBindingPatternElements); - write("]"); - } + write("["); + emitList(node, node.elements, ListFormat.ArrayBindingPatternElements); + write("]"); } function emitBindingElement(node: BindingElement) { @@ -3167,8 +3155,8 @@ namespace ts { TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented, UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine, IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine, - ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings, - ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings, + ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty, + ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty, ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty, ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets, CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine, diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 65c17911488..7ddc8a0cd5f 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -71,11 +71,11 @@ namespace ts { // Literals /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ - export function createLiteral(value: string | StringLiteral | NumericLiteral | Identifier): StringLiteral; + export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; export function createLiteral(value: number): NumericLiteral; export function createLiteral(value: boolean): BooleanLiteral; export function createLiteral(value: string | number | boolean): PrimaryExpression; - export function createLiteral(value: string | number | boolean | StringLiteral | NumericLiteral | Identifier): PrimaryExpression { + export function createLiteral(value: string | number | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): PrimaryExpression { if (typeof value === "number") { return createNumericLiteral(value + ""); } @@ -101,7 +101,7 @@ namespace ts { return node; } - function createLiteralFromNode(sourceNode: StringLiteral | NumericLiteral | Identifier): StringLiteral { + function createLiteralFromNode(sourceNode: StringLiteralLike | NumericLiteral | Identifier): StringLiteral { const node = createStringLiteral(getTextOfIdentifierOrLiteral(sourceNode)); node.textSourceNode = sourceNode; return node; @@ -3626,7 +3626,7 @@ namespace ts { return qualifiedName; } - export function convertToFunctionBody(node: ConciseBody, multiLine?: boolean) { + export function convertToFunctionBody(node: ConciseBody, multiLine?: boolean): Block { return isBlock(node) ? node : setTextRange(createBlock([setTextRange(createReturn(node), node)], multiLine), node); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 623efe08fe8..23798635671 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1149,11 +1149,13 @@ namespace ts { export interface StringLiteral extends LiteralExpression { kind: SyntaxKind.StringLiteral; - /* @internal */ textSourceNode?: Identifier | StringLiteral | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms). + /* @internal */ textSourceNode?: Identifier | StringLiteralLike | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms). /** Note: this is only set when synthesizing a node, not during parsing. */ /* @internal */ singleQuote?: boolean; } + /* @internal */ export type StringLiteralLike = StringLiteral | NoSubstitutionTemplateLiteral; + // Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing. // Consider 'Expression'. Without the brand, 'Expression' is actually no different // (structurally) than 'Node'. Because of this you can pass any Node to a function that @@ -1499,6 +1501,7 @@ namespace ts { kind: SyntaxKind.ArrowFunction; equalsGreaterThanToken: EqualsGreaterThanToken; body: ConciseBody; + name: never; } // The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral, @@ -2156,6 +2159,7 @@ namespace ts { export interface ExportDeclaration extends DeclarationStatement { kind: SyntaxKind.ExportDeclaration; parent?: SourceFile | ModuleBlock; + /** Will not be assigned in the case of `export * from "foo";` */ exportClause?: NamedExports; /** If this is not a StringLiteral it will be a grammar error. */ moduleSpecifier?: Expression; @@ -2878,7 +2882,7 @@ namespace ts { */ /* @internal */ isArrayLikeType(type: Type): boolean; /* @internal */ getAllPossiblePropertiesOfTypes(type: ReadonlyArray): Symbol[]; - /* @internal */ resolveName(name: string, location: Node, meaning: SymbolFlags): Symbol | undefined; + /* @internal */ resolveName(name: string, location: Node, meaning: SymbolFlags, excludeGlobals: boolean): Symbol | undefined; /* @internal */ getJsxNamespace(): string; /** diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a6e8af7e706..37b62fd5d85 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5,6 +5,7 @@ namespace ts { export const emptyArray: never[] = [] as never[]; export const resolvingEmptyArray: never[] = [] as never[]; export const emptyMap: ReadonlyMap = createMap(); + export const emptyUnderscoreEscapedMap: ReadonlyUnderscoreEscapedMap = emptyMap as ReadonlyUnderscoreEscapedMap; export const externalHelpersModuleNameText = "tslib"; @@ -1419,6 +1420,8 @@ namespace ts { * exactly one argument (of the form 'require("name")'). * This function does not test if the node is in a JavaScript file or not. */ + export function isRequireCall(callExpression: Node, checkArgumentIsStringLiteral: true): callExpression is CallExpression & { expression: Identifier, arguments: [StringLiteralLike] }; + export function isRequireCall(callExpression: Node, checkArgumentIsStringLiteral: boolean): callExpression is CallExpression; export function isRequireCall(callExpression: Node, checkArgumentIsStringLiteral: boolean): callExpression is CallExpression { if (callExpression.kind !== SyntaxKind.CallExpression) { return false; @@ -1456,7 +1459,7 @@ namespace ts { return false; } - export function getRightMostAssignedExpression(node: Node) { + export function getRightMostAssignedExpression(node: Expression): Expression { while (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true)) { node = node.right; } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 6a2f71df10e..8c5570f730c 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -454,7 +454,7 @@ namespace FourSlash { const ranges = this.getRanges(); assert(ranges.length); for (const range of ranges) { - this.goToRangeStart(range); + this.selectRange(range); action(); } } @@ -482,6 +482,11 @@ namespace FourSlash { this.selectionEnd = end.position; } + public selectRange(range: Range): void { + this.goToRangeStart(range); + this.selectionEnd = range.end; + } + public moveCaretRight(count = 1) { this.currentCaretPosition += count; this.currentCaretPosition = Math.min(this.currentCaretPosition, this.getFileContent(this.activeFile.fileName).length); @@ -3835,6 +3840,10 @@ namespace FourSlashInterface { public select(startMarker: string, endMarker: string) { this.state.select(startMarker, endMarker); } + + public selectRange(range: FourSlash.Range): void { + this.state.selectRange(range); + } } export class VerifyNegatable { diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 34ebd2417c9..8f69cd95c11 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -746,7 +746,7 @@ namespace ts.codefix { } else if (isJsxOpeningLikeElement(symbolToken.parent) && symbolToken.parent.tagName === symbolToken) { // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`. - symbol = checker.getAliasedSymbol(checker.resolveName(checker.getJsxNamespace(), symbolToken.parent.tagName, SymbolFlags.Value)); + symbol = checker.getAliasedSymbol(checker.resolveName(checker.getJsxNamespace(), symbolToken.parent.tagName, SymbolFlags.Value, /*excludeGlobals*/ false)); symbolName = symbol.name; } else { @@ -867,7 +867,7 @@ namespace ts.codefix { return moduleSpecifierToValidIdentifier(removeFileExtension(getBaseFileName(moduleSymbol.name)), target); } - function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target: ScriptTarget): string { + export function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target: ScriptTarget): string { let res = ""; let lastCharWasValid = true; const firstCharCode = moduleSpecifier.charCodeAt(0); diff --git a/src/services/refactors/convertToEs6Module.ts b/src/services/refactors/convertToEs6Module.ts new file mode 100644 index 00000000000..1046bf90aa6 --- /dev/null +++ b/src/services/refactors/convertToEs6Module.ts @@ -0,0 +1,582 @@ +/* @internal */ +namespace ts.refactor { + const actionName = "Convert to ES6 module"; + + const convertToEs6Module: Refactor = { + name: actionName, + description: getLocaleSpecificMessage(Diagnostics.Convert_to_ES6_module), + getEditsForAction, + getAvailableActions, + }; + + registerRefactor(convertToEs6Module); + + function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { + const { file, startPosition } = context; + if (!isSourceFileJavaScript(file) || !file.commonJsModuleIndicator) { + return undefined; + } + + const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); + return !isAtTriggerLocation(file, node) ? undefined : [ + { + name: convertToEs6Module.name, + description: convertToEs6Module.description, + actions: [ + { + description: convertToEs6Module.description, + name: actionName, + }, + ], + }, + ]; + } + + function isAtTriggerLocation(sourceFile: SourceFile, node: Node, onSecondTry = false): boolean { + switch (node.kind) { + case SyntaxKind.CallExpression: + return isAtTopLevelRequire(node as CallExpression); + case SyntaxKind.PropertyAccessExpression: + return isExportsOrModuleExportsOrAlias(sourceFile, node as PropertyAccessExpression) + || isExportsOrModuleExportsOrAlias(sourceFile, (node as PropertyAccessExpression).expression); + case SyntaxKind.VariableDeclarationList: + const decl = (node as VariableDeclarationList).declarations[0]; + return isExportsOrModuleExportsOrAlias(sourceFile, decl.initializer); + case SyntaxKind.VariableDeclaration: + return isExportsOrModuleExportsOrAlias(sourceFile, (node as VariableDeclaration).initializer); + default: + return isExpression(node) && isExportsOrModuleExportsOrAlias(sourceFile, node) + || !onSecondTry && isAtTriggerLocation(sourceFile, node.parent, /*onSecondTry*/ true); + } + } + + function isAtTopLevelRequire(call: CallExpression): boolean { + if (!isRequireCall(call, /*checkArgumentIsStringLiteral*/ true)) { + return false; + } + const { parent: propAccess } = call; + const varDecl = isPropertyAccessExpression(propAccess) ? propAccess.parent : propAccess; + if (isExpressionStatement(varDecl) && isSourceFile(varDecl.parent)) { // `require("x");` as a statement + return true; + } + if (!isVariableDeclaration(varDecl)) { + return false; + } + const { parent: varDeclList } = varDecl; + if (varDeclList.kind !== SyntaxKind.VariableDeclarationList) { + return false; + } + const { parent: varStatement } = varDeclList; + return varStatement.kind === SyntaxKind.VariableStatement && varStatement.parent.kind === SyntaxKind.SourceFile; + } + + function getEditsForAction(context: RefactorContext, _actionName: string): RefactorEditInfo | undefined { + Debug.assertEqual(actionName, _actionName); + const { file, program } = context; + Debug.assert(isSourceFileJavaScript(file)); + const edits = textChanges.ChangeTracker.with(context, changes => { + const moduleExportsChangedToDefault = convertFileToEs6Module(file, program.getTypeChecker(), changes, program.getCompilerOptions().target); + if (moduleExportsChangedToDefault) { + for (const importingFile of program.getSourceFiles()) { + fixImportOfModuleExports(importingFile, file, changes); + } + } + }); + return { edits, renameFilename: undefined, renameLocation: undefined }; + } + + function fixImportOfModuleExports(importingFile: ts.SourceFile, exportingFile: ts.SourceFile, changes: textChanges.ChangeTracker) { + for (const moduleSpecifier of importingFile.imports) { + const imported = getResolvedModule(importingFile, moduleSpecifier.text); + if (!imported || imported.resolvedFileName !== exportingFile.fileName) { + continue; + } + + const { parent } = moduleSpecifier; + switch (parent.kind) { + case SyntaxKind.ExternalModuleReference: { + const importEq = (parent as ExternalModuleReference).parent; + changes.replaceNode(importingFile, importEq, makeImport(importEq.name, /*namedImports*/ undefined, moduleSpecifier.text)); + break; + } + case SyntaxKind.CallExpression: { + const call = parent as CallExpression; + if (isRequireCall(call, /*checkArgumentIsStringLiteral*/ false)) { + changes.replaceNode(importingFile, parent, createPropertyAccess(getSynthesizedDeepClone(call), "default")); + } + break; + } + } + } + } + + /** @returns Whether we converted a `module.exports =` to a default export. */ + function convertFileToEs6Module(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, target: ScriptTarget): ModuleExportsChanged { + const identifiers: Identifiers = { original: collectFreeIdentifiers(sourceFile), additional: createMap() }; + const exports = collectExportRenames(sourceFile, checker, identifiers); + convertExportsAccesses(sourceFile, exports, changes); + let moduleExportsChangedToDefault = false; + for (const statement of sourceFile.statements) { + const moduleExportsChanged = convertStatement(sourceFile, statement, checker, changes, identifiers, target, exports); + moduleExportsChangedToDefault = moduleExportsChangedToDefault || moduleExportsChanged; + } + return moduleExportsChangedToDefault; + } + + /** + * Contains an entry for each renamed export. + * This is necessary because `exports.x = 0;` does not declare a local variable. + * Converting this to `export const x = 0;` would declare a local, so we must be careful to avoid shadowing. + * If there would be shadowing at either the declaration or at any reference to `exports.x` (now just `x`), we must convert to: + * const _x = 0; + * export { _x as x }; + * This conversion also must place if the exported name is not a valid identifier, e.g. `exports.class = 0;`. + */ + type ExportRenames = ReadonlyMap; + + function collectExportRenames(sourceFile: SourceFile, checker: TypeChecker, identifiers: Identifiers): ExportRenames { + const res = createMap(); + forEachExportReference(sourceFile, node => { + const { text, originalKeywordKind } = node.name; + if (!res.has(text) && (originalKeywordKind !== undefined && isNonContextualKeyword(originalKeywordKind) + || checker.resolveName(node.name.text, node, SymbolFlags.Value, /*excludeGlobals*/ true))) { + // Unconditionally add an underscore in case `text` is a keyword. + res.set(text, makeUniqueName(`_${text}`, identifiers)); + } + }); + return res; + } + + function convertExportsAccesses(sourceFile: SourceFile, exports: ExportRenames, changes: textChanges.ChangeTracker): void { + forEachExportReference(sourceFile, (node, isAssignmentLhs) => { + if (isAssignmentLhs) { + return; + } + const { text } = node.name; + changes.replaceNode(sourceFile, node, createIdentifier(exports.get(text) || text)); + }); + } + + function forEachExportReference(sourceFile: SourceFile, cb: (node: PropertyAccessExpression, isAssignmentLhs: boolean) => void): void { + sourceFile.forEachChild(function recur(node) { + if (isPropertyAccessExpression(node) && isExportsOrModuleExportsOrAlias(sourceFile, node.expression)) { + const { parent } = node; + cb(node, isBinaryExpression(parent) && parent.left === node && parent.operatorToken.kind === SyntaxKind.EqualsToken); + } + node.forEachChild(recur); + }); + } + + /** Whether `module.exports =` was changed to `export default` */ + type ModuleExportsChanged = boolean; + + function convertStatement(sourceFile: SourceFile, statement: Statement, checker: TypeChecker, changes: textChanges.ChangeTracker, identifiers: Identifiers, target: ScriptTarget, exports: ExportRenames): ModuleExportsChanged { + switch (statement.kind) { + case SyntaxKind.VariableStatement: + convertVariableStatement(sourceFile, statement as VariableStatement, changes, checker, identifiers, target); + return false; + case SyntaxKind.ExpressionStatement: { + const { expression } = statement as ExpressionStatement; + switch (expression.kind) { + case SyntaxKind.CallExpression: { + if (isRequireCall(expression, /*checkArgumentIsStringLiteral*/ true)) { + // For side-effecting require() call, just make a side-effecting import. + changes.replaceNode(sourceFile, statement, makeImport(/*name*/ undefined, /*namedImports*/ undefined, expression.arguments[0].text)); + } + 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); + } + } + } + // falls through + default: + return false; + } + } + + function convertVariableStatement(sourceFile: SourceFile, statement: VariableStatement, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers, target: ScriptTarget): void { + const { declarationList } = statement as VariableStatement; + 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, /*checkArgumentIsStringLiteral*/ true)) { + foundImport = true; + return convertSingleImport(sourceFile, name, initializer.arguments[0].text, changes, checker, identifiers, target); + } + else if (isPropertyAccessExpression(initializer) && isRequireCall(initializer.expression, /*checkArgumentIsStringLiteral*/ true)) { + foundImport = true; + return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0].text, identifiers); + } + else { + // Move it out to its own variable statement. + return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([decl], declarationList.flags)); + } + }); + if (foundImport) { + // useNonAdjustedEndPosition to ensure we don't eat the newline after the statement. + changes.replaceNodeWithNodes(sourceFile, statement, newNodes); + } + } + + /** Converts `const name = require("moduleSpecifier").propertyName` */ + function convertPropertyAccessImport(name: BindingName, propertyName: string, moduleSpecifier: string, identifiers: Identifiers): ReadonlyArray { + switch (name.kind) { + case SyntaxKind.ObjectBindingPattern: + case SyntaxKind.ArrayBindingPattern: { + // `const [a, b] = require("c").d` --> `import { d } from "c"; const [a, b] = d;` + const tmp = makeUniqueName(propertyName, identifiers); + return [ + makeSingleImport(tmp, propertyName, moduleSpecifier), + makeConst(/*modifiers*/ undefined, name, createIdentifier(tmp)), + ]; + } + case SyntaxKind.Identifier: + // `const a = require("b").c` --> `import { c as a } from "./b"; + return [makeSingleImport(name.text, propertyName, moduleSpecifier)]; + default: + Debug.assertNever(name); + } + } + + function convertAssignment( + sourceFile: SourceFile, + checker: TypeChecker, + statement: ExpressionStatement, + left: Expression, + right: Expression, + changes: textChanges.ChangeTracker, + exports: ExportRenames, + ): ModuleExportsChanged { + if (!isPropertyAccessExpression(left)) { + return false; + } + + if (isExportsOrModuleExportsOrAlias(sourceFile, left)) { + if (isExportsOrModuleExportsOrAlias(sourceFile, right)) { + // `const alias = module.exports;` or `module.exports = alias;` can be removed. + changes.deleteNode(sourceFile, statement); + } + else { + let newNodes = isObjectLiteralExpression(right) ? tryChangeModuleExportsObject(right) : undefined; + let changedToDefaultExport = false; + if (!newNodes) { + ([newNodes, changedToDefaultExport] = convertModuleExportsToExportDefault(right, checker)); + } + changes.replaceNodeWithNodes(sourceFile, statement, newNodes); + return changedToDefaultExport; + } + } + else if (isExportsOrModuleExportsOrAlias(sourceFile, left.expression)) { + convertNamedExport(sourceFile, statement, left.name, right, changes, exports); + } + + return false; + } + + /** + * Convert `module.exports = { ... }` to individual exports.. + * We can't always do this if the module has interesting members -- then it will be a default export instead. + */ + function tryChangeModuleExportsObject(object: ObjectLiteralExpression): ReadonlyArray | undefined { + return mapAllOrFail(object.properties, prop => { + switch (prop.kind) { + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + // TODO: Maybe we should handle this? See fourslash test `refactorConvertToEs6Module_export_object_shorthand.ts`. + case SyntaxKind.ShorthandPropertyAssignment: + case SyntaxKind.SpreadAssignment: + return undefined; + case SyntaxKind.PropertyAssignment: { + const { name, initializer } = prop as PropertyAssignment; + return !isIdentifier(name) ? undefined : convertExportsDotXEquals(name.text, initializer); + } + case SyntaxKind.MethodDeclaration: { + const m = prop as MethodDeclaration; + return !isIdentifier(m.name) ? undefined : functionExpressionToDeclaration(m.name.text, [createToken(SyntaxKind.ExportKeyword)], m); + } + default: + Debug.assertNever(prop); + } + }); + } + + function convertNamedExport( + sourceFile: SourceFile, + statement: Statement, + propertyName: Identifier, + right: Expression, + changes: textChanges.ChangeTracker, + exports: ExportRenames, + ): void { + // If "originalKeywordKind" was set, this is e.g. `exports. + const { text } = propertyName; + const rename = exports.get(text); + if (rename !== undefined) { + /* + const _class = 0; + export { _class as class }; + */ + const newNodes = [ + makeConst(/*modifiers*/ undefined, rename, right), + makeExportDeclaration([createExportSpecifier(rename, text)]), + ]; + changes.replaceNodeWithNodes(sourceFile, statement, newNodes); + } + else { + changes.replaceNode(sourceFile, statement, convertExportsDotXEquals(text, right), { useNonAdjustedEndPosition: true }); + } + } + + function convertModuleExportsToExportDefault(exported: Expression, checker: TypeChecker): [ReadonlyArray, ModuleExportsChanged] { + const modifiers = [createToken(SyntaxKind.ExportKeyword), createToken(SyntaxKind.DefaultKeyword)]; + switch (exported.kind) { + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: { + // `module.exports = function f() {}` --> `export default function f() {}` + const fn = exported as FunctionExpression | ArrowFunction; + return [[functionExpressionToDeclaration(fn.name && fn.name.text, modifiers, fn)], true]; + } + case SyntaxKind.ClassExpression: { + // `module.exports = class C {}` --> `export default class C {}` + const cls = exported as ClassExpression; + return [[classExpressionToDeclaration(cls.name && cls.name.text, modifiers, cls)], true]; + } + case SyntaxKind.CallExpression: + if (isRequireCall(exported, /*checkArgumentIsStringLiteral*/ true)) { + return convertReExportAll(exported.arguments[0], checker); + } + // falls through + default: + // `module.exports = 0;` --> `export default 0;` + return [[createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, exported)], true]; + } + } + + function convertReExportAll(reExported: StringLiteralLike, checker: TypeChecker): [ReadonlyArray, ModuleExportsChanged] { + // `module.exports = require("x");` ==> `export * from "x"; export { default } from "x";` + const moduleSpecifier = reExported.text; + const moduleSymbol = checker.getSymbolAtLocation(reExported); + const exports = moduleSymbol ? moduleSymbol.exports : emptyUnderscoreEscapedMap; + return exports.has("export=" as __String) + ? [[reExportDefault(moduleSpecifier)], true] + : !exports.has("default" as __String) + ? [[reExportStar(moduleSpecifier)], false] + // If there's some non-default export, must include both `export *` and `export default`. + : exports.size > 1 ? [[reExportStar(moduleSpecifier), reExportDefault(moduleSpecifier)], true] : [[reExportDefault(moduleSpecifier)], true]; + } + function reExportStar(moduleSpecifier: string): ExportDeclaration { + return makeExportDeclaration(/*exportClause*/ undefined, moduleSpecifier); + } + function reExportDefault(moduleSpecifier: string): ExportDeclaration { + return makeExportDeclaration([createExportSpecifier(/*propertyName*/ undefined, "default")], moduleSpecifier); + } + + function convertExportsDotXEquals(name: string | undefined, exported: Expression): Statement { + const modifiers = [createToken(SyntaxKind.ExportKeyword)]; + switch (exported.kind) { + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + // `exports.f = function() {}` --> `export function f() {}` + return functionExpressionToDeclaration(name, modifiers, exported as FunctionExpression | ArrowFunction); + case SyntaxKind.ClassExpression: + // `exports.C = class {}` --> `export class C {}` + return classExpressionToDeclaration(name, modifiers, exported as ClassExpression); + default: + // `exports.x = 0;` --> `export const x = 0;` + return makeConst(modifiers, createIdentifier(name), exported); + } + } + + /** + * Converts `const <> = require("x");`. + * Returns nodes that will replace the variable declaration for the commonjs import. + * May also make use `changes` to remove qualifiers at the use sites of imports, to change `mod.x` to `x`. + */ + function convertSingleImport( + file: SourceFile, + name: BindingName, + moduleSpecifier: string, + changes: textChanges.ChangeTracker, + checker: TypeChecker, + identifiers: Identifiers, + target: ScriptTarget, + ): ReadonlyArray { + switch (name.kind) { + case SyntaxKind.ObjectBindingPattern: { + const importSpecifiers = mapAllOrFail(name.elements, e => + e.dotDotDotToken || e.initializer || e.propertyName && !isIdentifier(e.propertyName) || !isIdentifier(e.name) + ? undefined + : makeImportSpecifier(e.propertyName && (e.propertyName as Identifier).text, e.name.text)); + if (importSpecifiers) { + return [makeImport(/*name*/ undefined, importSpecifiers, moduleSpecifier)]; + } + } + // falls through -- object destructuring has an interesting pattern and must be a variable declaration + case SyntaxKind.ArrayBindingPattern: { + /* + import x from "x"; + const [a, b, c] = x; + */ + const tmp = makeUniqueName(codefix.moduleSpecifierToValidIdentifier(moduleSpecifier, target), identifiers); + return [ + makeImport(createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier), + makeConst(/*modifiers*/ undefined, getSynthesizedDeepClone(name), createIdentifier(tmp)), + ]; + } + case SyntaxKind.Identifier: + return convertSingleIdentifierImport(file, name, moduleSpecifier, changes, checker, identifiers); + default: + Debug.assertNever(name); + } + } + + /** + * Convert `import x = require("x").` + * Also converts uses like `x.y()` to `y()` and uses a named import. + */ + function convertSingleIdentifierImport(file: SourceFile, name: Identifier, moduleSpecifier: string, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers): ReadonlyArray { + const nameSymbol = checker.getSymbolAtLocation(name); + // Maps from module property name to name actually used. (The same if there isn't shadowing.) + const namedBindingsNames = createMap(); + // True if there is some non-property use like `x()` or `f(x)`. + let needDefaultImport = false; + + for (const use of identifiers.original.get(name.text)) { + if (checker.getSymbolAtLocation(use) !== nameSymbol || use === name) { + // This was a use of a different symbol with the same name, due to shadowing. Ignore. + continue; + } + + const { parent } = use; + if (isPropertyAccessExpression(parent)) { + const { expression, name: { text: propertyName } } = parent; + Debug.assert(expression === use); // Else shouldn't have been in `collectIdentifiers` + let idName = namedBindingsNames.get(propertyName); + if (idName === undefined) { + idName = makeUniqueName(propertyName, identifiers); + namedBindingsNames.set(propertyName, idName); + } + changes.replaceNode(file, parent, createIdentifier(idName)); + } + else { + needDefaultImport = true; + } + } + + const namedBindings = namedBindingsNames.size === 0 ? undefined : arrayFrom(mapIterator(namedBindingsNames.entries(), ([propertyName, idName]) => + createImportSpecifier(propertyName === idName ? undefined : createIdentifier(propertyName), createIdentifier(idName)))); + if (!namedBindings) { + // If it was unused, ensure that we at least import *something*. + needDefaultImport = true; + } + return [makeImport(needDefaultImport ? getSynthesizedDeepClone(name) : undefined, namedBindings, moduleSpecifier)]; + } + + // Identifiers helpers + + function makeUniqueName(name: string, identifiers: Identifiers): string { + while (identifiers.original.has(name) || identifiers.additional.has(name)) { + name = `_${name}`; + } + identifiers.additional.set(name, true); + return name; + } + + /** + * Helps us create unique identifiers. + * `original` refers to the local variable names in the original source file. + * `additional` is any new unique identifiers we've generated. (e.g., we'll generate `_x`, then `__x`.) + */ + interface Identifiers { + readonly original: FreeIdentifiers; + // Additional identifiers we've added. Mutable! + readonly additional: Map; + } + + type FreeIdentifiers = ReadonlyMap>; + function collectFreeIdentifiers(file: SourceFile): FreeIdentifiers { + const map = createMultiMap(); + file.forEachChild(function recur(node) { + if (isIdentifier(node) && isFreeIdentifier(node)) { + map.add(node.text, node); + } + node.forEachChild(recur); + }); + return map; + } + + function isFreeIdentifier(node: Identifier): boolean { + const { parent } = node; + switch (parent.kind) { + case SyntaxKind.PropertyAccessExpression: + return (parent as PropertyAccessExpression).name !== node; + case SyntaxKind.BindingElement: + return (parent as BindingElement).propertyName !== node; + default: + return true; + } + } + + // Node helpers + + function functionExpressionToDeclaration(name: string | undefined, additionalModifiers: ReadonlyArray, fn: FunctionExpression | ArrowFunction | MethodDeclaration): FunctionDeclaration { + return createFunctionDeclaration( + getSynthesizedDeepClones(fn.decorators), // TODO: GH#19915 Don't think this is even legal. + concatenate(additionalModifiers, getSynthesizedDeepClones(fn.modifiers)), + getSynthesizedDeepClone(fn.asteriskToken), + name, + getSynthesizedDeepClones(fn.typeParameters), + getSynthesizedDeepClones(fn.parameters), + getSynthesizedDeepClone(fn.type), + convertToFunctionBody(getSynthesizedDeepClone(fn.body))); + } + + function classExpressionToDeclaration(name: string | undefined, additionalModifiers: ReadonlyArray, cls: ClassExpression): ClassDeclaration { + return createClassDeclaration( + getSynthesizedDeepClones(cls.decorators), // TODO: GH#19915 Don't think this is even legal. + concatenate(additionalModifiers, getSynthesizedDeepClones(cls.modifiers)), + name, + getSynthesizedDeepClones(cls.typeParameters), + getSynthesizedDeepClones(cls.heritageClauses), + getSynthesizedDeepClones(cls.members)); + } + + function makeSingleImport(localName: string, propertyName: string, moduleSpecifier: string): ImportDeclaration { + return propertyName === "default" + ? makeImport(createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier) + : makeImport(/*name*/ undefined, [makeImportSpecifier(propertyName, localName)], moduleSpecifier); + } + + function makeImport(name: Identifier | undefined, namedImports: ReadonlyArray, moduleSpecifier: string): ImportDeclaration { + const importClause = (name || namedImports) && createImportClause(name, namedImports && createNamedImports(namedImports)); + return createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, importClause, createLiteral(moduleSpecifier)); + } + + function makeImportSpecifier(propertyName: string | undefined, name: string): ImportSpecifier { + return createImportSpecifier(propertyName !== undefined && propertyName !== name ? createIdentifier(propertyName) : undefined, createIdentifier(name)); + } + + function makeConst(modifiers: ReadonlyArray | undefined, name: string | BindingName, init: Expression): VariableStatement { + return createVariableStatement( + modifiers, + createVariableDeclarationList( + [createVariableDeclaration(name, /*type*/ undefined, init)], + NodeFlags.Const)); + } + + function makeExportDeclaration(exportSpecifiers: ExportSpecifier[] | undefined, moduleSpecifier?: string): ExportDeclaration { + return createExportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + exportSpecifiers && createNamedExports(exportSpecifiers), + moduleSpecifier === undefined ? undefined : createLiteral(moduleSpecifier)); + } +} diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index b7aa5ac33d1..b3110a0ca36 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1692,7 +1692,7 @@ namespace ts.refactor.extractSymbol { } for (let i = 0; i < scopes.length; i++) { const scope = scopes[i]; - const resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags); + const resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags, /*excludeGlobals*/ false); if (resolvedSymbol === symbol) { continue; } diff --git a/src/services/refactors/refactors.ts b/src/services/refactors/refactors.ts index 3858b198743..8b4561700d5 100644 --- a/src/services/refactors/refactors.ts +++ b/src/services/refactors/refactors.ts @@ -1,5 +1,6 @@ /// /// +/// /// /// /// diff --git a/src/services/refactors/useDefaultImport.ts b/src/services/refactors/useDefaultImport.ts index 56faf082a49..a103168f67b 100644 --- a/src/services/refactors/useDefaultImport.ts +++ b/src/services/refactors/useDefaultImport.ts @@ -23,7 +23,7 @@ namespace ts.refactor.installTypesForPackage { return undefined; } - const module = ts.getResolvedModule(file, importInfo.moduleSpecifier.text); + const module = getResolvedModule(file, importInfo.moduleSpecifier.text); const resolvedFile = program.getSourceFile(module.resolvedFileName); if (!(resolvedFile.externalModuleIndicator && isExportAssignment(resolvedFile.externalModuleIndicator) && resolvedFile.externalModuleIndicator.isExportEquals)) { return undefined; @@ -52,7 +52,7 @@ namespace ts.refactor.installTypesForPackage { } const { importStatement, name, moduleSpecifier } = importInfo; const newImportClause = createImportClause(name, /*namedBindings*/ undefined); - const newImportStatement = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newImportClause, moduleSpecifier); + const newImportStatement = createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newImportClause, moduleSpecifier); return { edits: textChanges.ChangeTracker.with(context, t => t.replaceNode(file, importStatement, newImportStatement)), renameFilename: undefined, diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 9a208ddff9f..8fe12d29313 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1354,6 +1354,10 @@ namespace ts { return visited; } + export function getSynthesizedDeepClones(nodes: NodeArray | undefined): NodeArray | undefined { + return nodes && createNodeArray(nodes.map(getSynthesizedDeepClone), nodes.hasTrailingComma); + } + /** * Sets EmitFlags to suppress leading and trailing trivia on the node. */ diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index b0dc9e3b6eb..3eabea4435a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -901,6 +901,7 @@ declare namespace ts { kind: SyntaxKind.ArrowFunction; equalsGreaterThanToken: EqualsGreaterThanToken; body: ConciseBody; + name: never; } interface LiteralLikeNode extends Node { text: string; @@ -1362,6 +1363,7 @@ declare namespace ts { interface ExportDeclaration extends DeclarationStatement { kind: SyntaxKind.ExportDeclaration; parent?: SourceFile | ModuleBlock; + /** Will not be assigned in the case of `export * from "foo";` */ exportClause?: NamedExports; /** If this is not a StringLiteral it will be a grammar error. */ moduleSpecifier?: Expression; @@ -3288,7 +3290,7 @@ declare namespace ts { declare namespace ts { function createNodeArray(elements?: ReadonlyArray, hasTrailingComma?: boolean): NodeArray; /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ - function createLiteral(value: string | StringLiteral | NumericLiteral | Identifier): StringLiteral; + function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; function createLiteral(value: number): NumericLiteral; function createLiteral(value: boolean): BooleanLiteral; function createLiteral(value: string | number | boolean): PrimaryExpression; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index f839deabcfb..630b7a08a28 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -901,6 +901,7 @@ declare namespace ts { kind: SyntaxKind.ArrowFunction; equalsGreaterThanToken: EqualsGreaterThanToken; body: ConciseBody; + name: never; } interface LiteralLikeNode extends Node { text: string; @@ -1362,6 +1363,7 @@ declare namespace ts { interface ExportDeclaration extends DeclarationStatement { kind: SyntaxKind.ExportDeclaration; parent?: SourceFile | ModuleBlock; + /** Will not be assigned in the case of `export * from "foo";` */ exportClause?: NamedExports; /** If this is not a StringLiteral it will be a grammar error. */ moduleSpecifier?: Expression; @@ -3235,7 +3237,7 @@ declare namespace ts { declare namespace ts { function createNodeArray(elements?: ReadonlyArray, hasTrailingComma?: boolean): NodeArray; /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ - function createLiteral(value: string | StringLiteral | NumericLiteral | Identifier): StringLiteral; + function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; function createLiteral(value: number): NumericLiteral; function createLiteral(value: boolean): BooleanLiteral; function createLiteral(value: string | number | boolean): PrimaryExpression; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 426518794bd..97379957cbf 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -135,6 +135,7 @@ declare namespace FourSlashInterface { file(index: number, content?: string, scriptKindName?: string): any; file(name: string, content?: string, scriptKindName?: string): any; select(startMarker: string, endMarker: string): void; + selectRange(range: Range): void; } class verifyNegatable { private negative; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts new file mode 100644 index 00000000000..6529bb64af0 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const exportsAlias = exports; +////exportsAlias.f = function() {}; +/////*a*/module/*b*/.exports = exportsAlias; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: ` +export function f() { } +`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts new file mode 100644 index 00000000000..1c8633eb4eb --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts @@ -0,0 +1,19 @@ +/// + +// Test that we leave it alone if the name is a keyword. + +// @allowJs: true + +// @Filename: /a.js +/////*a*/exports/*b*/.default = 0; +////exports.default; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `const _default = 0; +export { _default as default }; +_default;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts new file mode 100644 index 00000000000..16b48fcd204 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts @@ -0,0 +1,19 @@ +/// + +// Test that we leave it alone if the name is a keyword. + +// @allowJs: true + +// @Filename: /a.js +/////*a*/exports/*b*/.class = 0; +////exports.async = 1; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `const _class = 0; +export { _class as class }; +export const async = 1;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts new file mode 100644 index 00000000000..ddcf79d0114 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts @@ -0,0 +1,26 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/module/*b*/.exports = function() {} +////module.exports = function f() {} +////module.exports = class {} +////module.exports = class C {} +////module.exports = 0; + +// See also `refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts` + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export default function() { } +export default function f() { } +export default class { +} +export default class C { +} +export default 0;` +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts new file mode 100644 index 00000000000..8d22ea77c2b --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts @@ -0,0 +1,43 @@ +/// + +// @allowJs: true + +// @Filename: /a.d.ts +////export const x: number; + +// @Filename: /b.d.ts +////export default function f() {} + +// @Filename: /c.d.ts +////export default function f(): void; +////export function g(): void; + +// @Filename: /d.ts +////declare const x: number; +////export = x; + +// @Filename: /z.js +// Normally -- just `export *` +/////*a*/module/*b*/.exports = require("./a"); +// If just a default is exported, just `export { default }` +////module.exports = require("./b"); +// May need both +////module.exports = require("./c"); +// For `export =` re-export the "default" since that's what it will be converted to. +////module.exports = require("./d"); +// In untyped case just go with `export *` +////module.exports = require("./unknown"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: +`export * from "./a"; +export { default } from "./b"; +export * from "./c"; +export { default } from "./c"; +export { default } from "./d"; +export * from "./unknown";`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts new file mode 100644 index 00000000000..7b48bd5f91e --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts @@ -0,0 +1,26 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/module/*b*/.exports = 0; + +// @Filename: /b.ts +////import a = require("./a"); + +// @Filename: /c.js +////const a = require("./a"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export default 0;`, +}); + +goTo.file("/b.ts"); +verify.currentFileContentIs('import a from "./a";'); + +goTo.file("/c.js"); +verify.currentFileContentIs('const a = require("./a").default;'); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts new file mode 100644 index 00000000000..8251f90fc0d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts @@ -0,0 +1,19 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/exports/*b*/.f = function() {} +////exports.C = class {} +////exports.x = 0; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export function f() { } +export class C { +} +export const x = 0;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts new file mode 100644 index 00000000000..b18bc94579d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts @@ -0,0 +1,25 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/module/*b*/.exports = { +//// x: 0, +//// f: function() {}, +//// g: () => {}, +//// h() {}, +//// C: class {}, +////}; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export const x = 0; +export function f() { } +export function g() { } +export function h() { } +export class C { +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts new file mode 100644 index 00000000000..05b4903eda3 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts @@ -0,0 +1,18 @@ +/// + +// TODO: Maybe we could transform this to `export function f() {}`. + +// @allowJs: true + +// @Filename: /a.js +////function f() {} +/////*a*/module/*b*/.exports = { f }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `function f() {} +export default { f };`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts new file mode 100644 index 00000000000..da9976fa7d0 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts @@ -0,0 +1,36 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////exports.x = 0; +////exports.x; +//// +////const y = 1; +/////*a*/exports/*b*/.y = y; +////exports.y; +//// +////exports.z = 2; +////function f(z) { +//// exports.z; +////} + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export const x = 0; +x; + +const y = 1; +const _y = y; +export { _y as y }; +_y; + +const _z = 2; +export { _z as z }; +function f(z) { + _z; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts new file mode 100644 index 00000000000..b3b7fbf94c6 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/exports/*b*/.f = async function* f(p) {} +////exports.C = class C extends D { m() {} } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export async function* f(p) { } +export class C extends D { + m() { } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts new file mode 100644 index 00000000000..b33b0a1a160 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts @@ -0,0 +1,15 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const [x, y] = /*a*/require/*b*/("x"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import _x from "x"; +const [x, y] = _x;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts new file mode 100644 index 00000000000..7c5415c1451 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const x = /*a*/require/*b*/("x"); +////x(); +////x.y; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x, { y } from "x"; +x(); +y;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts new file mode 100644 index 00000000000..321a9cccf8b --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts @@ -0,0 +1,20 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const x = require("x"); +////const [a, b] = /*a*/require/*b*/("x"); +////const {c, ...d} = require("x"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x from "x"; +import _x from "x"; +const [a, b] = _x; +import __x from "x"; +const { c, ...d } = __x;` +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts new file mode 100644 index 00000000000..37d65ddc622 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts @@ -0,0 +1,18 @@ +/// + +// Test that we leave it alone if the name is a keyword. + +// @allowJs: true + +// @Filename: /a.js +////const x = /*a*/require/*b*/("x"), y = 0, { z } = require("z"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x from "x"; +const y = 0; +import { z } from "z";`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts new file mode 100644 index 00000000000..0c953b2e7e6 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts @@ -0,0 +1,21 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const [] = /*a0*/require/*b0*/("a-b"); +////const [] = /*a1*/require/*b1*/("0a"); +////const [] = /*a2*/require/*b2*/("1a"); + +goTo.select("a0", "b0"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import aB from "a-b"; +const [] = aB; +import A from "0a"; +const [] = A; +import _A from "1a"; +const [] = _A;` +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts new file mode 100644 index 00000000000..f757db2164a --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts @@ -0,0 +1,15 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const { x: { a, b } } = /*a*/require/*b*/("x"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x from "x"; +const { x: { a, b } } = x;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts new file mode 100644 index 00000000000..474fd4b0f0f --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts @@ -0,0 +1,14 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const { x, y: z } = /*a*/require/*b*/("x"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: 'import { x, y as z } from "x";', +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts new file mode 100644 index 00000000000..bf7e207550e --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts @@ -0,0 +1,16 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const x = /*a*/require/*b*/("x"); +////x.y; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import { y } from "x"; +y;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts new file mode 100644 index 00000000000..57efd5370f2 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts @@ -0,0 +1,24 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const x = /*a*/require/*b*/("x").default; +////const a = require("b").c; +////const a = require("a").a; +////const [a, b] = require("c").d; +////const [a, b] = require("c").a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'. + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x from "x"; +import { c as a } from "b"; +import { a } from "a"; +import { d } from "c"; +const [a, b] = d; +import { a as _a } from "c"; +const [a, b] = _a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'.`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts new file mode 100644 index 00000000000..c389280d75c --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const mod = /*a*/require/*b*/("mod"); +////const x = 0; +////mod.x(x); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import { x as _x } from "mod"; +const x = 0; +_x(x);` +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts new file mode 100644 index 00000000000..2b81c816e20 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts @@ -0,0 +1,16 @@ +/// + +// Test that we leave it alone if the name is a keyword. + +// @allowJs: true + +// @Filename: /a.js +/////*a*/require/*b*/("foo"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: 'import "foo";', +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts b/tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts new file mode 100644 index 00000000000..8d441f47dc3 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts @@ -0,0 +1,13 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////c[|o|]nst [|a|]lias [|=|] [|m|]odule[|.|]export[|s|]; +////[|a|]lias[|.|][|x|] = 0; +////[|module.exports|]; +////[|require("x")|]; +////[|require("x").y;|]; + +goTo.eachRange(() => verify.refactorAvailable("Convert to ES6 module")); + From fa758cc357e72c6705da956eb41858db51840bb3 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 9 Jan 2018 15:33:54 -0800 Subject: [PATCH 127/189] Tidy up code to make it harder to call incorrectly --- src/services/pathCompletions.ts | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index e9c8b48a7c4..584a83ad95c 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -326,29 +326,28 @@ namespace ts.Completions.PathCompletions { if (typeRoots) { for (const root of typeRoots) { - getCompletionEntriesFromDirectories(host, root, span, result); + getCompletionEntriesFromDirectories(root); } } - } - if (host.getDirectories) { // Also get all @types typings installed in visible node_modules directories for (const packageJson of findPackageJsons(scriptPath, host)) { const typesDir = combinePaths(getDirectoryPath(packageJson), "node_modules/@types"); - getCompletionEntriesFromDirectories(host, typesDir, span, result); + getCompletionEntriesFromDirectories(typesDir); } } return result; - } - function getCompletionEntriesFromDirectories(host: LanguageServiceHost, directory: string, span: TextSpan, result: Push) { - if (host.getDirectories && tryDirectoryExists(host, directory)) { - const directories = tryGetDirectories(host, directory); - if (directories) { - for (let typeDirectory of directories) { - typeDirectory = normalizePath(typeDirectory); - result.push(createCompletionEntryForModule(getBaseFileName(typeDirectory), ScriptElementKind.externalModuleName, span)); + function getCompletionEntriesFromDirectories(directory: string) { + Debug.assert(!!host.getDirectories); + if (tryDirectoryExists(host, directory)) { + const directories = tryGetDirectories(host, directory); + if (directories) { + for (let typeDirectory of directories) { + typeDirectory = normalizePath(typeDirectory); + result.push(createCompletionEntryForModule(getBaseFileName(typeDirectory), ScriptElementKind.externalModuleName, span)); + } } } } From 90a1df9d92a086ae1d5331790100e94a85e98a26 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 9 Jan 2018 15:43:50 -0800 Subject: [PATCH 128/189] Add test for failure to use correct current directory in inferred project Test for #21040 --- .../unittests/tsserverProjectSystem.ts | 69 +++++++++++++++++++ src/harness/virtualFileSystemWithWatch.ts | 2 +- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 10c5aad92db..188a663b650 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -6488,4 +6488,73 @@ namespace ts.projectSystem { verifyWatchedDirectories(/*useProjectAtRoot*/ false); }); }); + + describe("tsserverProjectSystem typingsInstaller on inferred Project", () => { + it("when projectRootPath is provided", () => { + const projects = "/users/username/projects"; + const projectRootPath = `${projects}/san2`; + const file: FileOrFolder = { + path: `${projectRootPath}/x.js`, + content: "const aaaaaaav = 1;" + }; + + const currentDirectory = `${projects}/anotherProject`; + const packageJsonInCurrentDirectory: FileOrFolder = { + path: `${currentDirectory}/package.json`, + content: JSON.stringify({ + devDependencies: { + "pkgcurrentdirectory": "" + }, + }) + }; + const packageJsonOfPkgcurrentdirectory: FileOrFolder = { + path: `${currentDirectory}/node_modules/pkgcurrentdirectory/package.json`, + content: JSON.stringify({ + name: "pkgcurrentdirectory", + main: "index.js", + typings: "index.d.ts" + }) + }; + const indexOfPkgcurrentdirectory: FileOrFolder = { + path: `${currentDirectory}/node_modules/pkgcurrentdirectory/index.d.ts`, + content: "export function foo() { }" + }; + + const typingsCache = `/users/username/Library/Caches/typescript/2.7`; + const typingsCachePackageJson: FileOrFolder = { + path: `${typingsCache}/package.json`, + content: JSON.stringify({ + devDependencies: { + }, + }) + }; + + const files = [file, packageJsonInCurrentDirectory, packageJsonOfPkgcurrentdirectory, indexOfPkgcurrentdirectory, typingsCachePackageJson]; + const host = createServerHost(files, { currentDirectory }); + + const typesRegistry = createMap(); + typesRegistry.set("pkgcurrentdirectory", void 0); + const typingsInstaller = new TestTypingsInstaller(typingsCache, /*throttleLimit*/ 5, host, typesRegistry); + + const projectService = createProjectService(host, { typingsInstaller }); + + projectService.setCompilerOptionsForInferredProjects({ + module: ModuleKind.CommonJS, + target: ScriptTarget.ES2016, + jsx: JsxEmit.Preserve, + experimentalDecorators: true, + allowJs: true, + allowSyntheticDefaultImports: true, + allowNonTsExtensions: true + }); + + projectService.openClientFile(file.path, file.content, ScriptKind.JS, projectRootPath); + + const project = projectService.inferredProjects[0]; + assert.isDefined(project); + + // Ensure that we use result from types cache when getting ls + assert.isDefined(project.getLanguageService()); + }); + }); } diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index a6fe27ca9c6..921d4674231 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -547,7 +547,7 @@ interface Array {}` } readDirectory(path: string, extensions?: ReadonlyArray, exclude?: ReadonlyArray, include?: ReadonlyArray, depth?: number): string[] { - return ts.matchFiles(this.toNormalizedAbsolutePath(path), extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, (dir) => { + return ts.matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, (dir) => { const directories: string[] = []; const files: string[] = []; const dirEntry = this.fs.get(this.toPath(dir)); From 667751df2ade1f7236b8e462d4ec286773d09762 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 9 Jan 2018 15:59:23 -0800 Subject: [PATCH 129/189] When sending typings request use project's current directory as project root path This ensures that we arent picking typings from folder different from the current directory for the project --- src/harness/unittests/tsserverProjectSystem.ts | 5 ++++- src/server/utilities.ts | 15 +-------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 188a663b650..fe7a2095b86 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -6503,7 +6503,7 @@ namespace ts.projectSystem { path: `${currentDirectory}/package.json`, content: JSON.stringify({ devDependencies: { - "pkgcurrentdirectory": "" + pkgcurrentdirectory: "" }, }) }; @@ -6555,6 +6555,9 @@ namespace ts.projectSystem { // Ensure that we use result from types cache when getting ls assert.isDefined(project.getLanguageService()); + + // Verify that the pkgcurrentdirectory from the current directory isnt picked up + checkProjectActualFiles(project, [file.path]); }); }); } diff --git a/src/server/utilities.ts b/src/server/utilities.ts index d76ff1bf6d0..c44419f8cf3 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -34,19 +34,6 @@ namespace ts.server { export type Types = Msg; } - function getProjectRootPath(project: Project): Path { - switch (project.projectKind) { - case ProjectKind.Configured: - return getDirectoryPath(project.getProjectName()); - case ProjectKind.Inferred: - // TODO: fixme - return ""; - case ProjectKind.External: - const projectName = normalizeSlashes(project.getProjectName()); - return getDirectoryPath(projectName); - } - } - export function createInstallTypingsRequest(project: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray, cachePath?: string): DiscoverTypings { return { projectName: project.getProjectName(), @@ -54,7 +41,7 @@ namespace ts.server { compilerOptions: project.getCompilationSettings(), typeAcquisition, unresolvedImports, - projectRootPath: getProjectRootPath(project), + projectRootPath: project.getCurrentDirectory() as Path, cachePath, kind: "discover" }; From db09a593d3e4d50cf6a218192a417bc9b7ebc761 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 9 Jan 2018 15:40:32 -0800 Subject: [PATCH 130/189] Unmangle package names from typings during completion --- src/compiler/moduleNameResolver.ts | 11 ++++++++--- src/services/pathCompletions.ts | 7 +++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 1cc11acd32d..532d076504b 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -1097,13 +1097,18 @@ namespace ts { export function getPackageNameFromAtTypesDirectory(mangledName: string): string { const withoutAtTypePrefix = removePrefix(mangledName, "@types/"); if (withoutAtTypePrefix !== mangledName) { - return stringContains(withoutAtTypePrefix, mangledScopedPackageSeparator) ? - "@" + withoutAtTypePrefix.replace(mangledScopedPackageSeparator, ts.directorySeparator) : - withoutAtTypePrefix; + return getPackageNameFromAtTypesDirectoryWithoutPrefix(withoutAtTypePrefix); } return mangledName; } + /* @internal */ + export function getPackageNameFromAtTypesDirectoryWithoutPrefix(withoutAtTypePrefix: string): string { + return stringContains(withoutAtTypePrefix, mangledScopedPackageSeparator) ? + "@" + withoutAtTypePrefix.replace(mangledScopedPackageSeparator, ts.directorySeparator) : + withoutAtTypePrefix; + } + function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, traceEnabled: boolean, host: ModuleResolutionHost): SearchResult { const result = cache && cache.get(containingDirectory); if (result) { diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 584a83ad95c..f6f6667bbec 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -313,7 +313,8 @@ namespace ts.Completions.PathCompletions { function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] { // Check for typings specified in compiler options if (options.types) { - for (const moduleName of options.types) { + for (const typesName of options.types) { + const moduleName = getPackageNameFromAtTypesDirectoryWithoutPrefix(typesName); result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span)); } } @@ -346,7 +347,9 @@ namespace ts.Completions.PathCompletions { if (directories) { for (let typeDirectory of directories) { typeDirectory = normalizePath(typeDirectory); - result.push(createCompletionEntryForModule(getBaseFileName(typeDirectory), ScriptElementKind.externalModuleName, span)); + const directoryName = getBaseFileName(typeDirectory); + const moduleName = getPackageNameFromAtTypesDirectoryWithoutPrefix(directoryName); + result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span)); } } } From e48312df54be770f7c097fad1bca77dc407be260 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 9 Jan 2018 16:54:58 -0800 Subject: [PATCH 131/189] De-dup typing module completions --- src/services/pathCompletions.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index f6f6667bbec..98b1737adf3 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -312,10 +312,11 @@ namespace ts.Completions.PathCompletions { function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] { // Check for typings specified in compiler options + let seen = createMap(); if (options.types) { for (const typesName of options.types) { const moduleName = getPackageNameFromAtTypesDirectoryWithoutPrefix(typesName); - result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span)); + pushResult(moduleName); } } else if (host.getDirectories) { @@ -349,11 +350,18 @@ namespace ts.Completions.PathCompletions { typeDirectory = normalizePath(typeDirectory); const directoryName = getBaseFileName(typeDirectory); const moduleName = getPackageNameFromAtTypesDirectoryWithoutPrefix(directoryName); - result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span)); + pushResult(moduleName); } } } } + + function pushResult(moduleName: string) { + if (!seen.has(moduleName)) { + result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span)); + seen.set(moduleName, true); + } + } } function findPackageJsons(directory: string, host: LanguageServiceHost): string[] { From 03fd77657d06398cd55f56c6622ae8584d8a3497 Mon Sep 17 00:00:00 2001 From: Stanislav Iliev Date: Wed, 10 Jan 2018 03:11:57 +0200 Subject: [PATCH 132/189] Issue implicit any errors for mapped types without annotations (#21104) * Fixed #21011 * Updated code of merged message * Reversed message code change and moved error to it's appropriate position * Applied suggested improvements * Fixed wrong diagnostics message in checker * Reverted diagnostic message change --- src/compiler/checker.ts | 8 ++++++++ src/compiler/diagnosticMessages.json | 5 ++++- tests/baselines/reference/anyMappedTypesError.errors.txt | 7 +++++++ tests/baselines/reference/anyMappedTypesError.js | 4 ++++ tests/baselines/reference/anyMappedTypesError.symbols | 5 +++++ tests/baselines/reference/anyMappedTypesError.types | 5 +++++ tests/cases/compiler/anyMappedTypesError.ts | 3 +++ 7 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/anyMappedTypesError.errors.txt create mode 100644 tests/baselines/reference/anyMappedTypesError.js create mode 100644 tests/baselines/reference/anyMappedTypesError.symbols create mode 100644 tests/baselines/reference/anyMappedTypesError.types create mode 100644 tests/cases/compiler/anyMappedTypesError.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 16bfd7fa7e2..540f3722f92 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11281,6 +11281,9 @@ namespace ts { } diagnostic = Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type; break; + case SyntaxKind.MappedType: + error(declaration, Diagnostics.Mapped_object_type_implicitly_has_an_any_template_type); + return; default: diagnostic = Diagnostics.Variable_0_implicitly_has_an_1_type; } @@ -20312,6 +20315,11 @@ namespace ts { function checkMappedType(node: MappedTypeNode) { checkSourceElement(node.typeParameter); checkSourceElement(node.type); + + if (noImplicitAny && !node.type) { + reportImplicitAnyError(node, anyType); + } + const type = getTypeFromMappedTypeNode(node); const constraintType = getConstraintTypeFromMappedType(type); checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 96be3e99fdc..4c091673137 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3571,7 +3571,10 @@ "category": "Error", "code": 7038 }, - + "Mapped object type implicitly has an 'any' template type.": { + "category": "Error", + "code": 7039 + }, "You cannot rename this element.": { "category": "Error", "code": 8000 diff --git a/tests/baselines/reference/anyMappedTypesError.errors.txt b/tests/baselines/reference/anyMappedTypesError.errors.txt new file mode 100644 index 00000000000..e1442c15723 --- /dev/null +++ b/tests/baselines/reference/anyMappedTypesError.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/anyMappedTypesError.ts(1,12): error TS7039: Mapped object type implicitly has an 'any' template type. + + +==== tests/cases/compiler/anyMappedTypesError.ts (1 errors) ==== + type Foo = {[P in "bar"]}; + ~~~~~~~~~~~~~~ +!!! error TS7039: Mapped object type implicitly has an 'any' template type. \ No newline at end of file diff --git a/tests/baselines/reference/anyMappedTypesError.js b/tests/baselines/reference/anyMappedTypesError.js new file mode 100644 index 00000000000..8797d2cfc0e --- /dev/null +++ b/tests/baselines/reference/anyMappedTypesError.js @@ -0,0 +1,4 @@ +//// [anyMappedTypesError.ts] +type Foo = {[P in "bar"]}; + +//// [anyMappedTypesError.js] diff --git a/tests/baselines/reference/anyMappedTypesError.symbols b/tests/baselines/reference/anyMappedTypesError.symbols new file mode 100644 index 00000000000..0e9a425aad3 --- /dev/null +++ b/tests/baselines/reference/anyMappedTypesError.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/anyMappedTypesError.ts === +type Foo = {[P in "bar"]}; +>Foo : Symbol(Foo, Decl(anyMappedTypesError.ts, 0, 0)) +>P : Symbol(P, Decl(anyMappedTypesError.ts, 0, 13)) + diff --git a/tests/baselines/reference/anyMappedTypesError.types b/tests/baselines/reference/anyMappedTypesError.types new file mode 100644 index 00000000000..290ea6883b1 --- /dev/null +++ b/tests/baselines/reference/anyMappedTypesError.types @@ -0,0 +1,5 @@ +=== tests/cases/compiler/anyMappedTypesError.ts === +type Foo = {[P in "bar"]}; +>Foo : Foo +>P : P + diff --git a/tests/cases/compiler/anyMappedTypesError.ts b/tests/cases/compiler/anyMappedTypesError.ts new file mode 100644 index 00000000000..6b37b286046 --- /dev/null +++ b/tests/cases/compiler/anyMappedTypesError.ts @@ -0,0 +1,3 @@ +// @noImplicitAny: true + +type Foo = {[P in "bar"]}; \ No newline at end of file From c0bdd12c4c730291aa6470762fc953639c754498 Mon Sep 17 00:00:00 2001 From: Sharon Rolel Date: Tue, 9 Jan 2018 20:15:08 -0500 Subject: [PATCH 133/189] add fixAwaitInSyncFunction code fix (#21069) * add fixAwaitInSyncFunction code fix * Just insert the keyword * only one codefix * remove comment * Change explicit return type T to Promise * Review changes * Change codefix message --- src/compiler/diagnosticMessages.json | 4 + .../codefixes/fixAwaitInSyncFunction.ts | 74 +++++++++++++++++++ src/services/codefixes/fixes.ts | 1 + src/services/textChanges.ts | 5 ++ .../fourslash/codeFixAwaitInSyncFunction1.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction10.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction11.ts | 14 ++++ .../fourslash/codeFixAwaitInSyncFunction12.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction13.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction14.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction15.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction2.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction3.ts | 12 +++ .../fourslash/codeFixAwaitInSyncFunction4.ts | 9 +++ .../fourslash/codeFixAwaitInSyncFunction5.ts | 17 +++++ .../codeFixAwaitInSyncFunction6.5.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction6.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction7.ts | 17 +++++ .../fourslash/codeFixAwaitInSyncFunction8.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction9.ts | 17 +++++ .../codeFixAwaitInSyncFunction_all.ts | 21 ++++++ 21 files changed, 321 insertions(+) create mode 100644 src/services/codefixes/fixAwaitInSyncFunction.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction1.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction12.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction13.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction14.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction15.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction2.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction3.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction4.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction5.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction6.5.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction6.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction7.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction8.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction9.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4c091673137..cf5ccb1397d 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3877,6 +3877,10 @@ "category": "Message", "code": 90028 }, + "Add async modifier to containing function": { + "category": "Message", + "code": 90029 + }, "Convert function to an ES2015 class": { "category": "Message", "code": 95001 diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts new file mode 100644 index 00000000000..883993e7b51 --- /dev/null +++ b/src/services/codefixes/fixAwaitInSyncFunction.ts @@ -0,0 +1,74 @@ +/* @internal */ +namespace ts.codefix { + const fixId = "fixAwaitInSyncFunction"; + const errorCodes = [ + Diagnostics.await_expression_is_only_allowed_within_an_async_function.code, + Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator.code, + ]; + registerCodeFix({ + errorCodes, + getCodeActions(context) { + const { sourceFile, span } = context; + const nodes = getNodes(sourceFile, span.start); + if (!nodes) return undefined; + const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, nodes)); + return [{ description: getLocaleSpecificMessage(Diagnostics.Add_async_modifier_to_containing_function), changes, fixId }]; + }, + fixIds: [fixId], + getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { + const nodes = getNodes(diag.file, diag.start); + if (!nodes) return; + doChange(changes, context.sourceFile, nodes); + }), + }); + + function getReturnType(expr: FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction) { + if (expr.type) { + return expr.type; + } + if (isVariableDeclaration(expr.parent) && + expr.parent.type && + isFunctionTypeNode(expr.parent.type)) { + return expr.parent.type.type; + } + } + + function getNodes(sourceFile: SourceFile, start: number): { insertBefore: Node, returnType: TypeNode | undefined } | undefined { + const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); + const containingFunction = getContainingFunction(token); + let insertBefore: Node | undefined; + switch (containingFunction.kind) { + case SyntaxKind.MethodDeclaration: + insertBefore = containingFunction.name; + break; + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + insertBefore = findChildOfKind(containingFunction, SyntaxKind.FunctionKeyword, sourceFile); + break; + case SyntaxKind.ArrowFunction: + insertBefore = findChildOfKind(containingFunction, SyntaxKind.OpenParenToken, sourceFile) || first(containingFunction.parameters); + break; + default: + return; + } + + return { + insertBefore, + returnType: getReturnType(containingFunction) + }; + } + + function doChange( + changes: textChanges.ChangeTracker, + sourceFile: SourceFile, + { insertBefore, returnType }: { insertBefore: Node | undefined, returnType: TypeNode | undefined }): void { + + if (returnType) { + const entityName = getEntityNameFromTypeNode(returnType); + if (!entityName || entityName.kind !== SyntaxKind.Identifier || entityName.text !== "Promise") { + changes.replaceNode(sourceFile, returnType, createTypeReferenceNode("Promise", createNodeArray([returnType]))); + } + } + changes.insertModifierBefore(sourceFile, SyntaxKind.AsyncKeyword, insertBefore); + } +} diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts index bdbd8311a76..317c65b15ee 100644 --- a/src/services/codefixes/fixes.ts +++ b/src/services/codefixes/fixes.ts @@ -11,6 +11,7 @@ /// /// /// +/// /// /// /// diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index e73c639ba79..b0efef44642 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -345,6 +345,11 @@ namespace ts.textChanges { return this.replaceWithSingle(sourceFile, startPosition, startPosition, newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween)); } + public insertModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void { + const pos = before.getStart(sourceFile); + this.replaceWithSingle(sourceFile, pos, pos, createToken(modifier), { suffix: " " }); + } + public changeIdentifierToPropertyAccess(sourceFile: SourceFile, prefix: string, node: Identifier): void { const startPosition = getAdjustedStartPosition(sourceFile, node, {}, Position.Start); this.replaceWithSingle(sourceFile, startPosition, startPosition, createPropertyAccess(createIdentifier(prefix), ""), {}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction1.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction1.ts new file mode 100644 index 00000000000..e64d4072757 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction1.ts @@ -0,0 +1,13 @@ +/// + +////function f() { +//// await Promise.resolve(); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`async function f() { + await Promise.resolve(); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts new file mode 100644 index 00000000000..42e0bc5be78 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts @@ -0,0 +1,13 @@ +/// + +////const f: () => number | string = () => { +//// await Promise.resolve('foo'); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f: () => Promise = async () => { + await Promise.resolve('foo'); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts new file mode 100644 index 00000000000..bc7b17f8db5 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts @@ -0,0 +1,14 @@ +/// + +////const f: string = () => { +//// await Promise.resolve('foo'); +////} + +// should not change type if it's incorrectly set +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f: string = async () => { + await Promise.resolve('foo'); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction12.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction12.ts new file mode 100644 index 00000000000..ee694a80e9f --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction12.ts @@ -0,0 +1,13 @@ +/// + +////const f: () => Array = function() { +//// await Promise.resolve([]); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f: () => Promise> = async function() { + await Promise.resolve([]); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction13.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction13.ts new file mode 100644 index 00000000000..06f54d29eeb --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction13.ts @@ -0,0 +1,13 @@ +/// + +////const f: () => Promise = () => { +//// await Promise.resolve('foo'); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f: () => Promise = async () => { + await Promise.resolve('foo'); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction14.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction14.ts new file mode 100644 index 00000000000..c798af5f5ab --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction14.ts @@ -0,0 +1,13 @@ +/// + +////const f = function(): number { +//// await Promise.resolve(1); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async function(): Promise { + await Promise.resolve(1); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction15.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction15.ts new file mode 100644 index 00000000000..a2c6f7dcb1a --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction15.ts @@ -0,0 +1,13 @@ +/// + +////const f = (): number[] => { +//// await Promise.resolve([1]); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async (): Promise => { + await Promise.resolve([1]); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction2.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction2.ts new file mode 100644 index 00000000000..e8da351af5d --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction2.ts @@ -0,0 +1,13 @@ +/// + +////const f = function() { +//// await Promise.resolve(); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async function() { + await Promise.resolve(); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction3.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction3.ts new file mode 100644 index 00000000000..54d0aba103b --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction3.ts @@ -0,0 +1,12 @@ +/// + +////const f = { +//// get a() { +//// return await Promise.resolve(); +//// }, +//// get a() { +//// await Promise.resolve(); +//// }, +////} + +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction4.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction4.ts new file mode 100644 index 00000000000..dd123e25d0b --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction4.ts @@ -0,0 +1,9 @@ +/// + +////class Foo { +//// constructor { +//// await Promise.resolve(); +//// } +////} + +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction5.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction5.ts new file mode 100644 index 00000000000..a1c58b53831 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction5.ts @@ -0,0 +1,17 @@ +/// + +////class Foo { +//// bar() { +//// await Promise.resolve(); +//// } +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`class Foo { + async bar() { + await Promise.resolve(); + } +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction6.5.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction6.5.ts new file mode 100644 index 00000000000..c1b06811113 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction6.5.ts @@ -0,0 +1,13 @@ +/// + +////const f = promise => { +//// await promise; +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async promise => { + await promise; +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction6.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction6.ts new file mode 100644 index 00000000000..0b0aa098164 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction6.ts @@ -0,0 +1,13 @@ +/// + +////const f = (promise) => { +//// await promise; +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async (promise) => { + await promise; +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction7.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction7.ts new file mode 100644 index 00000000000..a467e9ee0ce --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction7.ts @@ -0,0 +1,17 @@ +/// + +////function f() { +//// for await (const x of g()) { +//// console.log(x); +//// } +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`async function f() { + for await (const x of g()) { + console.log(x); + } +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction8.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction8.ts new file mode 100644 index 00000000000..7c43add3edd --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction8.ts @@ -0,0 +1,13 @@ +/// + +////function f(): number | string { +//// await Promise.resolve(8); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`async function f(): Promise { + await Promise.resolve(8); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction9.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction9.ts new file mode 100644 index 00000000000..f93603e69c4 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction9.ts @@ -0,0 +1,17 @@ +/// + +////class Foo { +//// bar(): string { +//// await Promise.resolve('baz'); +//// } +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`class Foo { + async bar(): Promise { + await Promise.resolve('baz'); + } +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts new file mode 100644 index 00000000000..e6314a3a5f0 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts @@ -0,0 +1,21 @@ +/// + +////function f() { +//// await Promise.resolve(); +////} +//// +////const g = () => { +//// await f(); +////} + +verify.codeFixAll({ + fixId: "fixAwaitInSyncFunction", + newFileContent: +`async function f() { + await Promise.resolve(); +} + +const g = async () => { + await f(); +}`, +}); From c9ef52b9d818f1192ac3146385bbaddb599d5afe Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 9 Jan 2018 17:22:19 -0800 Subject: [PATCH 134/189] Do not always instantiate jsx signatures (#21108) --- src/compiler/checker.ts | 35 +++++++++++-------- .../baselines/reference/jsxHasLiteralType.js | 32 +++++++++++++++++ .../reference/jsxHasLiteralType.symbols | 25 +++++++++++++ .../reference/jsxHasLiteralType.types | 26 ++++++++++++++ tests/cases/compiler/jsxHasLiteralType.tsx | 11 ++++++ 5 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 tests/baselines/reference/jsxHasLiteralType.js create mode 100644 tests/baselines/reference/jsxHasLiteralType.symbols create mode 100644 tests/baselines/reference/jsxHasLiteralType.types create mode 100644 tests/cases/compiler/jsxHasLiteralType.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 540f3722f92..5e247c1ce2c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15162,7 +15162,7 @@ namespace ts { * element is not a class element, or the class element type cannot be determined, returns 'undefined'. * For example, in the element , the element instance type is `MyClass` (not `typeof MyClass`). */ - function getJsxElementInstanceType(node: JsxOpeningLikeElement, valueType: Type, sourceAttributesType: Type) { + function getJsxElementInstanceType(node: JsxOpeningLikeElement, valueType: Type, sourceAttributesType: Type | undefined) { Debug.assert(!(valueType.flags & TypeFlags.Union)); if (isTypeAny(valueType)) { // Short-circuit if the class tag is using an element type 'any' @@ -15181,20 +15181,27 @@ namespace ts { } } - const instantiatedSignatures = []; - for (const signature of signatures) { - if (signature.typeParameters) { - const isJavascript = isInJavaScriptFile(node); - const inferenceContext = createInferenceContext(signature, /*flags*/ isJavascript ? InferenceFlags.AnyDefault : 0); - const typeArguments = inferJsxTypeArguments(signature, sourceAttributesType, inferenceContext); - instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript)); + if (sourceAttributesType) { + // Instantiate in context of source type + const instantiatedSignatures = []; + for (const signature of signatures) { + if (signature.typeParameters) { + const isJavascript = isInJavaScriptFile(node); + const inferenceContext = createInferenceContext(signature, /*flags*/ isJavascript ? InferenceFlags.AnyDefault : 0); + const typeArguments = inferJsxTypeArguments(signature, sourceAttributesType, inferenceContext); + instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript)); + } + else { + instantiatedSignatures.push(signature); + } } - else { - instantiatedSignatures.push(signature); - } - } - return getUnionType(map(instantiatedSignatures, getReturnTypeOfSignature), UnionReduction.Subtype); + return getUnionType(map(instantiatedSignatures, getReturnTypeOfSignature), UnionReduction.Subtype); + } + else { + // Do not instantiate if no source type is provided - type parameters and their constraints will be used by contextual typing + return getUnionType(map(signatures, getReturnTypeOfSignature), UnionReduction.Subtype); + } } /** @@ -15418,7 +15425,7 @@ namespace ts { } // Get the element instance type (the result of newing or invoking this tag) - const elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType, sourceAttributesType || emptyObjectType); + const elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType, sourceAttributesType); // If we should include all stateless attributes type, then get all attributes type from all stateless function signature. // Otherwise get only attributes type from the signature picked by choose-overload logic. diff --git a/tests/baselines/reference/jsxHasLiteralType.js b/tests/baselines/reference/jsxHasLiteralType.js new file mode 100644 index 00000000000..491f58eebb1 --- /dev/null +++ b/tests/baselines/reference/jsxHasLiteralType.js @@ -0,0 +1,32 @@ +//// [jsxHasLiteralType.tsx] +import * as React from "react"; + +interface Props { + x?: "a" | "b"; +} +class MyComponent

extends React.Component {} +const m = + + +//// [jsxHasLiteralType.js] +"use strict"; +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 __()); + }; +})(); +exports.__esModule = true; +var React = require("react"); +var MyComponent = /** @class */ (function (_super) { + __extends(MyComponent, _super); + function MyComponent() { + return _super !== null && _super.apply(this, arguments) || this; + } + return MyComponent; +}(React.Component)); +var m = React.createElement(MyComponent, { x: "a" }); diff --git a/tests/baselines/reference/jsxHasLiteralType.symbols b/tests/baselines/reference/jsxHasLiteralType.symbols new file mode 100644 index 00000000000..a7106f2699e --- /dev/null +++ b/tests/baselines/reference/jsxHasLiteralType.symbols @@ -0,0 +1,25 @@ +=== tests/cases/compiler/jsxHasLiteralType.tsx === +import * as React from "react"; +>React : Symbol(React, Decl(jsxHasLiteralType.tsx, 0, 6)) + +interface Props { +>Props : Symbol(Props, Decl(jsxHasLiteralType.tsx, 0, 31)) + + x?: "a" | "b"; +>x : Symbol(Props.x, Decl(jsxHasLiteralType.tsx, 2, 17)) +} +class MyComponent

extends React.Component {} +>MyComponent : Symbol(MyComponent, Decl(jsxHasLiteralType.tsx, 4, 1)) +>P : Symbol(P, Decl(jsxHasLiteralType.tsx, 5, 18)) +>Props : Symbol(Props, Decl(jsxHasLiteralType.tsx, 0, 31)) +>Props : Symbol(Props, Decl(jsxHasLiteralType.tsx, 0, 31)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66)) +>React : Symbol(React, Decl(jsxHasLiteralType.tsx, 0, 6)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66)) +>P : Symbol(P, Decl(jsxHasLiteralType.tsx, 5, 18)) + +const m = +>m : Symbol(m, Decl(jsxHasLiteralType.tsx, 6, 5)) +>MyComponent : Symbol(MyComponent, Decl(jsxHasLiteralType.tsx, 4, 1)) +>x : Symbol(x, Decl(jsxHasLiteralType.tsx, 6, 22)) + diff --git a/tests/baselines/reference/jsxHasLiteralType.types b/tests/baselines/reference/jsxHasLiteralType.types new file mode 100644 index 00000000000..61120edcea6 --- /dev/null +++ b/tests/baselines/reference/jsxHasLiteralType.types @@ -0,0 +1,26 @@ +=== tests/cases/compiler/jsxHasLiteralType.tsx === +import * as React from "react"; +>React : typeof React + +interface Props { +>Props : Props + + x?: "a" | "b"; +>x : "a" | "b" | undefined +} +class MyComponent

extends React.Component {} +>MyComponent : MyComponent

+>P : P +>Props : Props +>Props : Props +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>P : P + +const m = +>m : JSX.Element +> : JSX.Element +>MyComponent : typeof MyComponent +>x : "a" + diff --git a/tests/cases/compiler/jsxHasLiteralType.tsx b/tests/cases/compiler/jsxHasLiteralType.tsx new file mode 100644 index 00000000000..17132fdad40 --- /dev/null +++ b/tests/cases/compiler/jsxHasLiteralType.tsx @@ -0,0 +1,11 @@ +// @strictNullChecks: true +// @jsx: react +// @skipLibCheck: true +// @libFiles: lib.d.ts,react.d.ts +import * as React from "react"; + +interface Props { + x?: "a" | "b"; +} +class MyComponent

extends React.Component {} +const m = From da593ca7a81611d37a8ea29b9668e5bb6da51ba5 Mon Sep 17 00:00:00 2001 From: falsandtru Date: Wed, 10 Jan 2018 15:06:06 +0900 Subject: [PATCH 135/189] Fix WeakSet interface (#19756) --- src/lib/es2015.collection.d.ts | 2 +- src/lib/es2015.iterable.d.ts | 2 +- src/lib/es2015.symbol.wellknown.d.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/es2015.collection.d.ts b/src/lib/es2015.collection.d.ts index f6087eb4405..74759107851 100644 --- a/src/lib/es2015.collection.d.ts +++ b/src/lib/es2015.collection.d.ts @@ -58,7 +58,7 @@ interface ReadonlySet { readonly size: number; } -interface WeakSet { +interface WeakSet { add(value: T): this; delete(value: T): boolean; has(value: T): boolean; diff --git a/src/lib/es2015.iterable.d.ts b/src/lib/es2015.iterable.d.ts index 26722b5ab2f..ccb7df6be69 100644 --- a/src/lib/es2015.iterable.d.ts +++ b/src/lib/es2015.iterable.d.ts @@ -180,7 +180,7 @@ interface SetConstructor { new (iterable: Iterable): Set; } -interface WeakSet { } +interface WeakSet { } interface WeakSetConstructor { new (iterable: Iterable): WeakSet; diff --git a/src/lib/es2015.symbol.wellknown.d.ts b/src/lib/es2015.symbol.wellknown.d.ts index 23d836c6515..681b6e8edfa 100644 --- a/src/lib/es2015.symbol.wellknown.d.ts +++ b/src/lib/es2015.symbol.wellknown.d.ts @@ -118,7 +118,7 @@ interface Set { readonly [Symbol.toStringTag]: "Set"; } -interface WeakSet { +interface WeakSet { readonly [Symbol.toStringTag]: "WeakSet"; } From 743d8dbe0a82c4db828bc657b8c3b2e34548249d Mon Sep 17 00:00:00 2001 From: Priyantha Lankapura <403912+lankaapura@users.noreply.github.com> Date: Wed, 10 Jan 2018 23:00:35 +0530 Subject: [PATCH 136/189] Fix to remove extra space between function and array index. (#21113) https://github.com/Microsoft/TypeScript/issues/21111 --- src/services/formatting/rules.ts | 14 +++++++------- ...formatSpaceBetweenFunctionAndArrayIndex.ts | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 tests/cases/fourslash/server/formatSpaceBetweenFunctionAndArrayIndex.ts diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 04f599039da..16270eda479 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -11,8 +11,8 @@ namespace ts.formatting { for (let token = SyntaxKind.FirstToken; token <= SyntaxKind.LastToken; token++) { allTokens.push(token); } - function anyTokenExcept(token: SyntaxKind): TokenRange { - return { tokens: allTokens.filter(t => t !== token), isSpecific: false }; + function anyTokenExcept(...tokens: SyntaxKind[]): TokenRange { + return { tokens: allTokens.filter(t => !tokens.some(t2 => t2 === t)), isSpecific: false }; } const anyToken: TokenRange = { tokens: allTokens, isSpecific: false }; @@ -316,6 +316,11 @@ namespace ts.formatting { rule("NoSpaceBeforeComma", anyToken, SyntaxKind.CommaToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + // No space before and after indexer `x[]` + rule("NoSpaceBeforeOpenBracket", anyTokenExcept(SyntaxKind.AsyncKeyword, SyntaxKind.CaseKeyword), SyntaxKind.OpenBracketToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceAfterCloseBracket", SyntaxKind.CloseBracketToken, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], RuleAction.Delete), + rule("SpaceAfterSemicolon", SyntaxKind.SemicolonToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space), + // Add a space between statements. All keywords except (do,else,case) has open/close parens after them. // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any] rule( @@ -326,11 +331,6 @@ namespace ts.formatting { RuleAction.Space), // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter. rule("SpaceAfterTryFinally", [SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword], SyntaxKind.OpenBraceToken, [isNonJsxSameLineTokenContext], RuleAction.Space), - - // No space before and after indexer `x[]` - rule("NoSpaceBeforeOpenBracket", anyTokenExcept(SyntaxKind.AsyncKeyword), SyntaxKind.OpenBracketToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), - rule("NoSpaceAfterCloseBracket", SyntaxKind.CloseBracketToken, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], RuleAction.Delete), - rule("SpaceAfterSemicolon", SyntaxKind.SemicolonToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space), ]; return [ diff --git a/tests/cases/fourslash/server/formatSpaceBetweenFunctionAndArrayIndex.ts b/tests/cases/fourslash/server/formatSpaceBetweenFunctionAndArrayIndex.ts new file mode 100644 index 00000000000..7f2cbb8148f --- /dev/null +++ b/tests/cases/fourslash/server/formatSpaceBetweenFunctionAndArrayIndex.ts @@ -0,0 +1,19 @@ +/// + +//// +////function test() { +//// return []; +////} +//// +////test() [0] +//// + +format.document(); +verify.currentFileContentIs( +` +function test() { + return []; +} + +test()[0] +`); From ddd8e759c1a166e6dbc7de2be669791fda24ba64 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 10 Jan 2018 11:13:47 -0800 Subject: [PATCH 137/189] Use 'append' helper (#21101) --- src/compiler/parser.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index bae9f0594ed..0e2118af52a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -786,15 +786,7 @@ namespace ts { const comments = getJSDocCommentRanges(node, sourceFile.text); if (comments) { for (const comment of comments) { - const jsDoc = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); - if (jsDoc) { - if (!node.jsDoc) { - node.jsDoc = [jsDoc]; - } - else { - node.jsDoc.push(jsDoc); - } - } + node.jsDoc = append(node.jsDoc, JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos)); } } From 102368332eb43682c2c964af08d49ffa3e3f6da4 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 10 Jan 2018 11:31:13 -0800 Subject: [PATCH 138/189] Use 'append' helper more (#21125) --- src/compiler/parser.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 0e2118af52a..f0685b7372e 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6603,10 +6603,7 @@ namespace ts { const start = scanner.getStartPos(); let children: JSDocParameterTag[]; while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.Parameter, name))) { - if (!children) { - children = []; - } - children.push(child); + children = append(children, child); } if (children) { jsdocTypeLiteral = createNode(SyntaxKind.JSDocTypeLiteral, start); @@ -6723,10 +6720,7 @@ namespace ts { } } else { - if (!jsdocTypeLiteral.jsDocPropertyTags) { - jsdocTypeLiteral.jsDocPropertyTags = [] as MutableNodeArray; - } - (jsdocTypeLiteral.jsDocPropertyTags as MutableNodeArray).push(child); + jsdocTypeLiteral.jsDocPropertyTags = append(jsdocTypeLiteral.jsDocPropertyTags as MutableNodeArray, child); } } if (jsdocTypeLiteral) { From ee87cf409b52a9e51ee66dbb2b86204ed66fc8df Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 10 Jan 2018 11:41:14 -0800 Subject: [PATCH 139/189] Print the correct type in the top level chain as the message indicates (#21127) --- src/compiler/checker.ts | 2 +- .../abstractPropertyNegative.errors.txt | 12 ++--- .../apparentTypeSubtyping.errors.txt | 4 +- .../apparentTypeSupertype.errors.txt | 4 +- ...baseClassImprovedMismatchErrors.errors.txt | 16 +++---- .../classIsSubtypeOfBaseType.errors.txt | 4 +- ...ctionOverridesBaseClassAccessor.errors.txt | 4 +- ...tructuringParameterDeclaration2.errors.txt | 4 +- .../reference/elaboratedErrors.errors.txt | 4 +- .../reference/genericImplements.errors.txt | 4 +- .../genericSpecializations1.errors.txt | 8 ++-- .../genericSpecializations2.errors.txt | 8 ++-- .../genericSpecializations3.errors.txt | 4 +- ...cTypeWithNonGenericBaseMisMatch.errors.txt | 4 +- ...ementGenericWithMismatchedTypes.errors.txt | 8 ++-- ...mplementsIncorrectlyNoAssertion.errors.txt | 4 +- .../reference/incompatibleTypes.errors.txt | 16 +++---- .../reference/inheritance.errors.txt | 4 +- ...eMemberAccessorOverridingMethod.errors.txt | 8 ++-- ...nceMemberFuncOverridingAccessor.errors.txt | 4 +- .../instanceSubtypeCheck2.errors.txt | 4 +- .../interfaceDeclaration3.errors.txt | 8 ++-- ...terfaceExtendsClassWithPrivate2.errors.txt | 11 +++-- ...ExtendsObjectIntersectionErrors.errors.txt | 20 ++++---- .../interfaceImplementation7.errors.txt | 4 +- .../mismatchedGenericArguments1.errors.txt | 8 ++-- .../reference/multipleInheritance.errors.txt | 4 +- .../requiredInitializedParameter2.errors.txt | 4 +- .../subtypesOfTypeParameter.errors.txt | 4 +- ...sOfTypeParameterWithConstraints.errors.txt | 40 ++++++++-------- ...OfTypeParameterWithConstraints4.errors.txt | 20 ++++---- ...rameterWithRecursiveConstraints.errors.txt | 48 +++++++++---------- .../subtypingWithObjectMembers.errors.txt | 24 +++++----- 33 files changed, 165 insertions(+), 160 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5e247c1ce2c..fd6a033653a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23005,7 +23005,7 @@ namespace ts { Diagnostics.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2, unescapeLeadingUnderscores(declaredProp.escapedName), typeToString(typeWithThis), - typeToString(getTypeOfSymbol(baseProp)) + typeToString(baseWithThis) ); if (!checkTypeAssignableTo(getTypeOfSymbol(prop), getTypeOfSymbol(baseProp), member.name || member, /*message*/ undefined, rootChain)) { issuedMemberError = true; diff --git a/tests/baselines/reference/abstractPropertyNegative.errors.txt b/tests/baselines/reference/abstractPropertyNegative.errors.txt index 6e4cae81db9..be1c85374fb 100644 --- a/tests/baselines/reference/abstractPropertyNegative.errors.txt +++ b/tests/baselines/reference/abstractPropertyNegative.errors.txt @@ -7,11 +7,11 @@ tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS2515: Non-abstra tests/cases/compiler/abstractPropertyNegative.ts(15,5): error TS1244: Abstract methods can only appear within an abstract class. tests/cases/compiler/abstractPropertyNegative.ts(16,37): error TS1005: '{' expected. tests/cases/compiler/abstractPropertyNegative.ts(19,3): error TS2540: Cannot assign to 'ro' because it is a constant or a read-only property. -tests/cases/compiler/abstractPropertyNegative.ts(25,5): error TS2416: Property 'num' in type 'WrongTypePropertyImpl' is not assignable to the same property in base type 'number'. +tests/cases/compiler/abstractPropertyNegative.ts(25,5): error TS2416: Property 'num' in type 'WrongTypePropertyImpl' is not assignable to the same property in base type 'WrongTypeProperty'. Type 'string' is not assignable to type 'number'. -tests/cases/compiler/abstractPropertyNegative.ts(31,9): error TS2416: Property 'num' in type 'WrongTypeAccessorImpl' is not assignable to the same property in base type 'number'. +tests/cases/compiler/abstractPropertyNegative.ts(31,9): error TS2416: Property 'num' in type 'WrongTypeAccessorImpl' is not assignable to the same property in base type 'WrongTypeAccessor'. Type 'string' is not assignable to type 'number'. -tests/cases/compiler/abstractPropertyNegative.ts(34,5): error TS2416: Property 'num' in type 'WrongTypeAccessorImpl2' is not assignable to the same property in base type 'number'. +tests/cases/compiler/abstractPropertyNegative.ts(34,5): error TS2416: Property 'num' in type 'WrongTypeAccessorImpl2' is not assignable to the same property in base type 'WrongTypeAccessor'. Type 'string' is not assignable to type 'number'. tests/cases/compiler/abstractPropertyNegative.ts(38,18): error TS2676: Accessors must both be abstract or non-abstract. tests/cases/compiler/abstractPropertyNegative.ts(39,9): error TS2676: Accessors must both be abstract or non-abstract. @@ -64,7 +64,7 @@ tests/cases/compiler/abstractPropertyNegative.ts(41,18): error TS2676: Accessors class WrongTypePropertyImpl extends WrongTypeProperty { num = "nope, wrong"; ~~~ -!!! error TS2416: Property 'num' in type 'WrongTypePropertyImpl' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'num' in type 'WrongTypePropertyImpl' is not assignable to the same property in base type 'WrongTypeProperty'. !!! error TS2416: Type 'string' is not assignable to type 'number'. } abstract class WrongTypeAccessor { @@ -73,13 +73,13 @@ tests/cases/compiler/abstractPropertyNegative.ts(41,18): error TS2676: Accessors class WrongTypeAccessorImpl extends WrongTypeAccessor { get num() { return "nope, wrong"; } ~~~ -!!! error TS2416: Property 'num' in type 'WrongTypeAccessorImpl' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'num' in type 'WrongTypeAccessorImpl' is not assignable to the same property in base type 'WrongTypeAccessor'. !!! error TS2416: Type 'string' is not assignable to type 'number'. } class WrongTypeAccessorImpl2 extends WrongTypeAccessor { num = "nope, wrong"; ~~~ -!!! error TS2416: Property 'num' in type 'WrongTypeAccessorImpl2' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'num' in type 'WrongTypeAccessorImpl2' is not assignable to the same property in base type 'WrongTypeAccessor'. !!! error TS2416: Type 'string' is not assignable to type 'number'. } diff --git a/tests/baselines/reference/apparentTypeSubtyping.errors.txt b/tests/baselines/reference/apparentTypeSubtyping.errors.txt index cde65657778..ca2f0765d62 100644 --- a/tests/baselines/reference/apparentTypeSubtyping.errors.txt +++ b/tests/baselines/reference/apparentTypeSubtyping.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts(10,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'string'. +tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts(10,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. Type 'String' is not assignable to type 'string'. 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. @@ -15,7 +15,7 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtypi class Derived extends Base { // error x: String; ~ -!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'String' is not assignable to type 'string'. !!! error TS2416: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. } diff --git a/tests/baselines/reference/apparentTypeSupertype.errors.txt b/tests/baselines/reference/apparentTypeSupertype.errors.txt index 066d0be2710..a4a8ccc0a8b 100644 --- a/tests/baselines/reference/apparentTypeSupertype.errors.txt +++ b/tests/baselines/reference/apparentTypeSupertype.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts(10,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'string'. +tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts(10,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. Type 'U' is not assignable to type 'string'. Type 'String' is not assignable to type 'string'. 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. @@ -16,7 +16,7 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSuperty class Derived extends Base { // error x: U; ~ -!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'U' is not assignable to type 'string'. !!! error TS2416: Type 'String' is not assignable to type 'string'. !!! error TS2416: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. diff --git a/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt b/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt index 585c929d9a4..031fe183754 100644 --- a/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt +++ b/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/baseClassImprovedMismatchErrors.ts(8,5): error TS2416: Property 'n' in type 'Derived' is not assignable to the same property in base type 'string | Base'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(8,5): error TS2416: Property 'n' in type 'Derived' is not assignable to the same property in base type 'Base'. Type 'string | Derived' is not assignable to type 'string | Base'. Type 'Derived' is not assignable to type 'string | Base'. Type 'Derived' is not assignable to type 'Base'. @@ -6,11 +6,11 @@ tests/cases/compiler/baseClassImprovedMismatchErrors.ts(8,5): error TS2416: Prop Type 'string | Derived' is not assignable to type 'string | Base'. Type 'Derived' is not assignable to type 'string | Base'. Type 'Derived' is not assignable to type 'Base'. -tests/cases/compiler/baseClassImprovedMismatchErrors.ts(9,5): error TS2416: Property 'fn' in type 'Derived' is not assignable to the same property in base type '() => number'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(9,5): error TS2416: Property 'fn' in type 'Derived' is not assignable to the same property in base type 'Base'. Type '() => string | number' is not assignable to type '() => number'. Type 'string | number' is not assignable to type 'number'. Type 'string' is not assignable to type 'number'. -tests/cases/compiler/baseClassImprovedMismatchErrors.ts(14,5): error TS2416: Property 'n' in type 'DerivedInterface' is not assignable to the same property in base type 'string | Base'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(14,5): error TS2416: Property 'n' in type 'DerivedInterface' is not assignable to the same property in base type 'Base'. Type 'string | DerivedInterface' is not assignable to type 'string | Base'. Type 'DerivedInterface' is not assignable to type 'string | Base'. Type 'DerivedInterface' is not assignable to type 'Base'. @@ -18,7 +18,7 @@ tests/cases/compiler/baseClassImprovedMismatchErrors.ts(14,5): error TS2416: Pro Type 'string | DerivedInterface' is not assignable to type 'string | Base'. Type 'DerivedInterface' is not assignable to type 'string | Base'. Type 'DerivedInterface' is not assignable to type 'Base'. -tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Property 'fn' in type 'DerivedInterface' is not assignable to the same property in base type '() => number'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Property 'fn' in type 'DerivedInterface' is not assignable to the same property in base type 'Base'. Type '() => string | number' is not assignable to type '() => number'. Type 'string | number' is not assignable to type 'number'. Type 'string' is not assignable to type 'number'. @@ -34,7 +34,7 @@ tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Pro class Derived extends Base { n: Derived | string; ~ -!!! error TS2416: Property 'n' in type 'Derived' is not assignable to the same property in base type 'string | Base'. +!!! error TS2416: Property 'n' in type 'Derived' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'string | Derived' is not assignable to type 'string | Base'. !!! error TS2416: Type 'Derived' is not assignable to type 'string | Base'. !!! error TS2416: Type 'Derived' is not assignable to type 'Base'. @@ -44,7 +44,7 @@ tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Pro !!! error TS2416: Type 'Derived' is not assignable to type 'Base'. fn() { ~~ -!!! error TS2416: Property 'fn' in type 'Derived' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Property 'fn' in type 'Derived' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type '() => string | number' is not assignable to type '() => number'. !!! error TS2416: Type 'string | number' is not assignable to type 'number'. !!! error TS2416: Type 'string' is not assignable to type 'number'. @@ -54,7 +54,7 @@ tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Pro class DerivedInterface implements Base { n: DerivedInterface | string; ~ -!!! error TS2416: Property 'n' in type 'DerivedInterface' is not assignable to the same property in base type 'string | Base'. +!!! error TS2416: Property 'n' in type 'DerivedInterface' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'string | DerivedInterface' is not assignable to type 'string | Base'. !!! error TS2416: Type 'DerivedInterface' is not assignable to type 'string | Base'. !!! error TS2416: Type 'DerivedInterface' is not assignable to type 'Base'. @@ -64,7 +64,7 @@ tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Pro !!! error TS2416: Type 'DerivedInterface' is not assignable to type 'Base'. fn() { ~~ -!!! error TS2416: Property 'fn' in type 'DerivedInterface' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Property 'fn' in type 'DerivedInterface' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type '() => string | number' is not assignable to type '() => number'. !!! error TS2416: Type 'string | number' is not assignable to type 'number'. !!! error TS2416: Type 'string' is not assignable to type 'number'. diff --git a/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt b/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt index 3070a041748..8b84602b807 100644 --- a/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt +++ b/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classIsSubtypeOfBaseType.ts(12,5): error TS2416: Property 'foo' in type 'Derived2' is not assignable to the same property in base type '{ bar: string; }'. +tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classIsSubtypeOfBaseType.ts(12,5): error TS2416: Property 'foo' in type 'Derived2' is not assignable to the same property in base type 'Base<{ bar: string; }>'. Type '{ bar?: string; }' is not assignable to type '{ bar: string; }'. Property 'bar' is optional in type '{ bar?: string; }' but required in type '{ bar: string; }'. @@ -17,7 +17,7 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla class Derived2 extends Base<{ bar: string; }> { foo: { ~~~ -!!! error TS2416: Property 'foo' in type 'Derived2' is not assignable to the same property in base type '{ bar: string; }'. +!!! error TS2416: Property 'foo' in type 'Derived2' is not assignable to the same property in base type 'Base<{ bar: string; }>'. !!! error TS2416: Type '{ bar?: string; }' is not assignable to type '{ bar: string; }'. !!! error TS2416: Property 'bar' is optional in type '{ bar?: string; }' but required in type '{ bar: string; }'. bar?: string; // error diff --git a/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt b/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt index ca154600c9f..fa8c7f2bc7a 100644 --- a/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt +++ b/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(2,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(5,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(11,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'number'. +tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(11,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. Type '() => number' is not assignable to type 'number'. tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(11,5): error TS2426: Class 'Base' defines instance member accessor 'x', but extended class 'Derived' defines it as instance member function. @@ -22,7 +22,7 @@ tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFun class Derived extends Base { x() { ~ -!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type '() => number' is not assignable to type 'number'. ~ !!! error TS2426: Class 'Base' defines instance member accessor 'x', but extended class 'Derived' defines it as instance member function. diff --git a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt index 9cc122c7588..46a816af349 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt @@ -35,7 +35,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(46,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(47,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(56,8): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(57,5): error TS2416: Property 'd4' in type 'C4' is not assignable to the same property in base type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(57,5): error TS2416: Property 'd4' in type 'C4' is not assignable to the same property in base type 'F2'. Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. Types of parameters '__0' and '__0' are incompatible. Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'. @@ -159,7 +159,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( !!! error TS2463: A binding pattern parameter cannot be optional in an implementation signature. d4({x, y, c}) { } ~~ -!!! error TS2416: Property 'd4' in type 'C4' is not assignable to the same property in base type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. +!!! error TS2416: Property 'd4' in type 'C4' is not assignable to the same property in base type 'F2'. !!! error TS2416: Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. !!! error TS2416: Types of parameters '__0' and '__0' are incompatible. !!! error TS2416: Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'. diff --git a/tests/baselines/reference/elaboratedErrors.errors.txt b/tests/baselines/reference/elaboratedErrors.errors.txt index 9a05bdc1d1b..a9060282404 100644 --- a/tests/baselines/reference/elaboratedErrors.errors.txt +++ b/tests/baselines/reference/elaboratedErrors.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/elaboratedErrors.ts(11,3): error TS2416: Property 'read' in type 'WorkerFS' is not assignable to the same property in base type 'number'. +tests/cases/compiler/elaboratedErrors.ts(11,3): error TS2416: Property 'read' in type 'WorkerFS' is not assignable to the same property in base type 'FileSystem'. Type 'string' is not assignable to type 'number'. tests/cases/compiler/elaboratedErrors.ts(20,1): error TS2322: Type 'Beta' is not assignable to type 'Alpha'. Property 'x' is missing in type 'Beta'. @@ -21,7 +21,7 @@ tests/cases/compiler/elaboratedErrors.ts(25,1): error TS2322: Type 'Alpha' is no class WorkerFS implements FileSystem { read: string; ~~~~ -!!! error TS2416: Property 'read' in type 'WorkerFS' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'read' in type 'WorkerFS' is not assignable to the same property in base type 'FileSystem'. !!! error TS2416: Type 'string' is not assignable to type 'number'. } diff --git a/tests/baselines/reference/genericImplements.errors.txt b/tests/baselines/reference/genericImplements.errors.txt index 04ae8d0f0cb..fff51884f10 100644 --- a/tests/baselines/reference/genericImplements.errors.txt +++ b/tests/baselines/reference/genericImplements.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/genericImplements.ts(9,5): error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type '() => T'. +tests/cases/compiler/genericImplements.ts(9,5): error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type 'I'. Type '() => T' is not assignable to type '() => T'. Type 'B' is not assignable to type 'T'. @@ -14,7 +14,7 @@ tests/cases/compiler/genericImplements.ts(9,5): error TS2416: Property 'f' in ty class X implements I { f(): T { return undefined; } ~ -!!! error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type '() => T'. +!!! error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type 'I'. !!! error TS2416: Type '() => T' is not assignable to type '() => T'. !!! error TS2416: Type 'B' is not assignable to type 'T'. } // { f: () => { b; } } diff --git a/tests/baselines/reference/genericSpecializations1.errors.txt b/tests/baselines/reference/genericSpecializations1.errors.txt index b56cc0d7865..83015cef259 100644 --- a/tests/baselines/reference/genericSpecializations1.errors.txt +++ b/tests/baselines/reference/genericSpecializations1.errors.txt @@ -1,8 +1,8 @@ -tests/cases/compiler/genericSpecializations1.ts(6,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/genericSpecializations1.ts(6,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => string' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. -tests/cases/compiler/genericSpecializations1.ts(10,5): error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/genericSpecializations1.ts(10,5): error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => string' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. @@ -16,7 +16,7 @@ tests/cases/compiler/genericSpecializations1.ts(10,5): error TS2416: Property 'f class IntFooBad implements IFoo { foo(x: string): string { return null; } ~~~ -!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. @@ -25,7 +25,7 @@ tests/cases/compiler/genericSpecializations1.ts(10,5): error TS2416: Property 'f class StringFoo2 implements IFoo { foo(x: string): string { return null; } ~~~ -!!! error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. diff --git a/tests/baselines/reference/genericSpecializations2.errors.txt b/tests/baselines/reference/genericSpecializations2.errors.txt index dc59c200d4f..1088d7b8956 100644 --- a/tests/baselines/reference/genericSpecializations2.errors.txt +++ b/tests/baselines/reference/genericSpecializations2.errors.txt @@ -1,9 +1,9 @@ -tests/cases/compiler/genericSpecializations2.ts(8,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/genericSpecializations2.ts(8,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => string' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. tests/cases/compiler/genericSpecializations2.ts(8,9): error TS2368: Type parameter name cannot be 'string'. -tests/cases/compiler/genericSpecializations2.ts(12,5): error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/genericSpecializations2.ts(12,5): error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => string' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. @@ -20,7 +20,7 @@ tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parame class IntFooBad implements IFoo { foo(x: string): string { return null; } ~~~ -!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. @@ -31,7 +31,7 @@ tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parame class StringFoo2 implements IFoo { foo(x: string): string { return null; } ~~~ -!!! error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. diff --git a/tests/baselines/reference/genericSpecializations3.errors.txt b/tests/baselines/reference/genericSpecializations3.errors.txt index f99872539a9..eaa7f094bdb 100644 --- a/tests/baselines/reference/genericSpecializations3.errors.txt +++ b/tests/baselines/reference/genericSpecializations3.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/genericSpecializations3.ts(9,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: number) => number'. +tests/cases/compiler/genericSpecializations3.ts(9,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => string' is not assignable to type '(x: number) => number'. Types of parameters 'x' and 'x' are incompatible. Type 'number' is not assignable to type 'string'. @@ -25,7 +25,7 @@ tests/cases/compiler/genericSpecializations3.ts(29,1): error TS2322: Type 'IntFo class IntFooBad implements IFoo { // error foo(x: string): string { return null; } ~~~ -!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: number) => number'. +!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: number) => number'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'number' is not assignable to type 'string'. diff --git a/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt b/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt index d91eb2b864e..a7a96c2abd8 100644 --- a/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt +++ b/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(5,2): error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type '(a: { a: number; }) => void'. +tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(5,2): error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type 'I'. Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. Types of parameters 'a' and 'a' are incompatible. Type '{ a: number; }' is not assignable to type 'T'. @@ -18,7 +18,7 @@ tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(8,5): error TS2322 class X implements I { f(a: T): void { } ~ -!!! error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type '(a: { a: number; }) => void'. +!!! error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type 'I'. !!! error TS2416: Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. !!! error TS2416: Types of parameters 'a' and 'a' are incompatible. !!! error TS2416: Type '{ a: number; }' is not assignable to type 'T'. diff --git a/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt b/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt index 994174eb84c..576013f43c5 100644 --- a/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt +++ b/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt @@ -1,8 +1,8 @@ -tests/cases/compiler/implementGenericWithMismatchedTypes.ts(8,5): error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/implementGenericWithMismatchedTypes.ts(8,5): error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => number' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. -tests/cases/compiler/implementGenericWithMismatchedTypes.ts(17,5): error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/implementGenericWithMismatchedTypes.ts(17,5): error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type 'IFoo2'. Type '(x: Tstring) => number' is not assignable to type '(x: T) => T'. Type 'number' is not assignable to type 'T'. @@ -17,7 +17,7 @@ tests/cases/compiler/implementGenericWithMismatchedTypes.ts(17,5): error TS2416: class C implements IFoo { // error foo(x: string): number { ~~~ -!!! error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => number' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. @@ -31,7 +31,7 @@ tests/cases/compiler/implementGenericWithMismatchedTypes.ts(17,5): error TS2416: class C2 implements IFoo2 { // error foo(x: Tstring): number { ~~~ -!!! error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type 'IFoo2'. !!! error TS2416: Type '(x: Tstring) => number' is not assignable to type '(x: T) => T'. !!! error TS2416: Type 'number' is not assignable to type 'T'. return null; diff --git a/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt b/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt index 7b717545e77..f56da547126 100644 --- a/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt +++ b/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/implementsIncorrectlyNoAssertion.ts(9,5): error TS2416: Property 'x' in type 'Baz' is not assignable to the same property in base type 'string'. +tests/cases/compiler/implementsIncorrectlyNoAssertion.ts(9,5): error TS2416: Property 'x' in type 'Baz' is not assignable to the same property in base type 'Foo & Bar'. Type 'number' is not assignable to type 'string'. @@ -13,7 +13,7 @@ tests/cases/compiler/implementsIncorrectlyNoAssertion.ts(9,5): error TS2416: Pro class Baz implements Wrapper { x: number; ~ -!!! error TS2416: Property 'x' in type 'Baz' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'x' in type 'Baz' is not assignable to the same property in base type 'Foo & Bar'. !!! error TS2416: Type 'number' is not assignable to type 'string'. y: string; } diff --git a/tests/baselines/reference/incompatibleTypes.errors.txt b/tests/baselines/reference/incompatibleTypes.errors.txt index 1feed1a3fb6..1951e363eec 100644 --- a/tests/baselines/reference/incompatibleTypes.errors.txt +++ b/tests/baselines/reference/incompatibleTypes.errors.txt @@ -1,13 +1,13 @@ -tests/cases/compiler/incompatibleTypes.ts(6,12): error TS2416: Property 'p1' in type 'C1' is not assignable to the same property in base type '() => number'. +tests/cases/compiler/incompatibleTypes.ts(6,12): error TS2416: Property 'p1' in type 'C1' is not assignable to the same property in base type 'IFoo1'. Type '() => string' is not assignable to type '() => number'. Type 'string' is not assignable to type 'number'. -tests/cases/compiler/incompatibleTypes.ts(16,12): error TS2416: Property 'p1' in type 'C2' is not assignable to the same property in base type '(s: string) => number'. +tests/cases/compiler/incompatibleTypes.ts(16,12): error TS2416: Property 'p1' in type 'C2' is not assignable to the same property in base type 'IFoo2'. Type '(n: number) => number' is not assignable to type '(s: string) => number'. Types of parameters 'n' and 's' are incompatible. Type 'string' is not assignable to type 'number'. -tests/cases/compiler/incompatibleTypes.ts(26,12): error TS2416: Property 'p1' in type 'C3' is not assignable to the same property in base type 'string'. +tests/cases/compiler/incompatibleTypes.ts(26,12): error TS2416: Property 'p1' in type 'C3' is not assignable to the same property in base type 'IFoo3'. Type 'number' is not assignable to type 'string'. -tests/cases/compiler/incompatibleTypes.ts(34,12): error TS2416: Property 'p1' in type 'C4' is not assignable to the same property in base type '{ a: { a: string; }; b: string; }'. +tests/cases/compiler/incompatibleTypes.ts(34,12): error TS2416: Property 'p1' in type 'C4' is not assignable to the same property in base type 'IFoo4'. Type '{ c: { b: string; }; d: string; }' is not assignable to type '{ a: { a: string; }; b: string; }'. Property 'a' is missing in type '{ c: { b: string; }; d: string; }'. tests/cases/compiler/incompatibleTypes.ts(42,5): error TS2345: Argument of type 'C1' is not assignable to parameter of type 'IFoo2'. @@ -30,7 +30,7 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => class C1 implements IFoo1 { // incompatible on the return type public p1() { ~~ -!!! error TS2416: Property 'p1' in type 'C1' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Property 'p1' in type 'C1' is not assignable to the same property in base type 'IFoo1'. !!! error TS2416: Type '() => string' is not assignable to type '() => number'. !!! error TS2416: Type 'string' is not assignable to type 'number'. return "s"; @@ -44,7 +44,7 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => class C2 implements IFoo2 { // incompatible on the param type public p1(n:number) { ~~ -!!! error TS2416: Property 'p1' in type 'C2' is not assignable to the same property in base type '(s: string) => number'. +!!! error TS2416: Property 'p1' in type 'C2' is not assignable to the same property in base type 'IFoo2'. !!! error TS2416: Type '(n: number) => number' is not assignable to type '(s: string) => number'. !!! error TS2416: Types of parameters 'n' and 's' are incompatible. !!! error TS2416: Type 'string' is not assignable to type 'number'. @@ -59,7 +59,7 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => class C3 implements IFoo3 { // incompatible on the property type public p1: number; ~~ -!!! error TS2416: Property 'p1' in type 'C3' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'p1' in type 'C3' is not assignable to the same property in base type 'IFoo3'. !!! error TS2416: Type 'number' is not assignable to type 'string'. } @@ -70,7 +70,7 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => class C4 implements IFoo4 { // incompatible on the property type public p1: { c: { b: string; }; d: string; }; ~~ -!!! error TS2416: Property 'p1' in type 'C4' is not assignable to the same property in base type '{ a: { a: string; }; b: string; }'. +!!! error TS2416: Property 'p1' in type 'C4' is not assignable to the same property in base type 'IFoo4'. !!! error TS2416: Type '{ c: { b: string; }; d: string; }' is not assignable to type '{ a: { a: string; }; b: string; }'. !!! error TS2416: Property 'a' is missing in type '{ c: { b: string; }; d: string; }'. } diff --git a/tests/baselines/reference/inheritance.errors.txt b/tests/baselines/reference/inheritance.errors.txt index 429eb2674df..b476f1399b4 100644 --- a/tests/baselines/reference/inheritance.errors.txt +++ b/tests/baselines/reference/inheritance.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/inheritance.ts(31,12): error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. -tests/cases/compiler/inheritance.ts(32,12): error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type '() => number'. +tests/cases/compiler/inheritance.ts(32,12): error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type 'Good'. Type '(n: number) => number' is not assignable to type '() => number'. @@ -39,7 +39,7 @@ tests/cases/compiler/inheritance.ts(32,12): error TS2416: Property 'g' in type ' !!! error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. public g(n: number) { return 0; } ~ -!!! error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type 'Good'. !!! error TS2416: Type '(n: number) => number' is not assignable to type '() => number'. } \ No newline at end of file diff --git a/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt b/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt index a0c20277333..66d955324c8 100644 --- a/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt +++ b/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt @@ -1,9 +1,9 @@ tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type '() => string'. +tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. Type 'string' is not assignable to type '() => string'. tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS2423: Class 'a' defines instance member function 'x', but extended class 'b' defines it as instance member accessor. tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type '() => string'. +tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. Type 'string' is not assignable to type '() => string'. @@ -19,7 +19,7 @@ tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error T ~ !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. ~ -!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type '() => string'. +!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. !!! error TS2416: Type 'string' is not assignable to type '() => string'. ~ !!! error TS2423: Class 'a' defines instance member function 'x', but extended class 'b' defines it as instance member accessor. @@ -29,7 +29,7 @@ tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error T ~ !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. ~ -!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type '() => string'. +!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. !!! error TS2416: Type 'string' is not assignable to type '() => string'. } diff --git a/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt b/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt index b31d5d12ec6..38a390d5063 100644 --- a/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt +++ b/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(2,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(5,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'string'. +tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. Type '() => string' is not assignable to type 'string'. tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2426: Class 'a' defines instance member accessor 'x', but extended class 'b' defines it as instance member function. @@ -22,7 +22,7 @@ tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2 class b extends a { x() { ~ -!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. !!! error TS2416: Type '() => string' is not assignable to type 'string'. ~ !!! error TS2426: Class 'a' defines instance member accessor 'x', but extended class 'b' defines it as instance member function. diff --git a/tests/baselines/reference/instanceSubtypeCheck2.errors.txt b/tests/baselines/reference/instanceSubtypeCheck2.errors.txt index b1d0f33af08..84b454d7ea0 100644 --- a/tests/baselines/reference/instanceSubtypeCheck2.errors.txt +++ b/tests/baselines/reference/instanceSubtypeCheck2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/instanceSubtypeCheck2.ts(6,5): error TS2416: Property 'x' in type 'C2' is not assignable to the same property in base type 'C2'. +tests/cases/compiler/instanceSubtypeCheck2.ts(6,5): error TS2416: Property 'x' in type 'C2' is not assignable to the same property in base type 'C1'. Type 'string' is not assignable to type 'C2'. @@ -10,6 +10,6 @@ tests/cases/compiler/instanceSubtypeCheck2.ts(6,5): error TS2416: Property 'x' i class C2 extends C1 { x: string ~ -!!! error TS2416: Property 'x' in type 'C2' is not assignable to the same property in base type 'C2'. +!!! error TS2416: Property 'x' in type 'C2' is not assignable to the same property in base type 'C1'. !!! error TS2416: Type 'string' is not assignable to type 'C2'. } \ No newline at end of file diff --git a/tests/baselines/reference/interfaceDeclaration3.errors.txt b/tests/baselines/reference/interfaceDeclaration3.errors.txt index 2c29b6a86f2..2ea419aaa52 100644 --- a/tests/baselines/reference/interfaceDeclaration3.errors.txt +++ b/tests/baselines/reference/interfaceDeclaration3.errors.txt @@ -1,6 +1,6 @@ -tests/cases/compiler/interfaceDeclaration3.ts(7,16): error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'string'. +tests/cases/compiler/interfaceDeclaration3.ts(7,16): error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'I1'. Type 'number' is not assignable to type 'string'. -tests/cases/compiler/interfaceDeclaration3.ts(32,16): error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'string'. +tests/cases/compiler/interfaceDeclaration3.ts(32,16): error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'I1'. Type 'number' is not assignable to type 'string'. tests/cases/compiler/interfaceDeclaration3.ts(54,11): error TS2430: Interface 'I2' incorrectly extends interface 'I1'. Types of property 'item' are incompatible. @@ -16,7 +16,7 @@ tests/cases/compiler/interfaceDeclaration3.ts(54,11): error TS2430: Interface 'I class C1 implements I1 { public item:number; ~~~~ -!!! error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'I1'. !!! error TS2416: Type 'number' is not assignable to type 'string'. } class C2 implements I1 { @@ -44,7 +44,7 @@ tests/cases/compiler/interfaceDeclaration3.ts(54,11): error TS2430: Interface 'I class C1 implements I1 { public item:number; ~~~~ -!!! error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'I1'. !!! error TS2416: Type 'number' is not assignable to type 'string'. } class C2 implements I1 { diff --git a/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt b/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt index cac4ba6def7..d6af9ce44dd 100644 --- a/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt +++ b/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt @@ -2,11 +2,13 @@ tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(10,7): error TS2415: C Types have separate declarations of a private property 'x'. tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(10,7): error TS2420: Class 'D' incorrectly implements interface 'I'. Types have separate declarations of a private property 'x'. -tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(20,13): error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'number'. +tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(20,13): error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'C'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(20,13): error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'I'. Type 'string' is not assignable to type 'number'. -==== tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts (3 errors) ==== +==== tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts (4 errors) ==== class C { public foo(x: any) { return x; } private x = 1; @@ -34,7 +36,10 @@ tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(20,13): error TS2416: public foo(x: any) { return x; } private x = ""; ~ -!!! error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'C'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. + ~ +!!! error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'I'. !!! error TS2416: Type 'string' is not assignable to type 'number'. other(x: any) { return x; } bar() { } diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt index 6a53fc01c0d..87faadeb4a6 100644 --- a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt +++ b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt @@ -14,15 +14,15 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectI tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(11,11): error TS2430: Interface 'I5' incorrectly extends interface 'T5'. Types of property 'c' are incompatible. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(16,38): error TS2416: Property 'a' in type 'C1' is not assignable to the same property in base type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(16,38): error TS2416: Property 'a' in type 'C1' is not assignable to the same property in base type 'T1'. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(17,38): error TS2416: Property 'b' in type 'C2' is not assignable to the same property in base type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(17,38): error TS2416: Property 'b' in type 'C2' is not assignable to the same property in base type 'T2'. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(18,38): error TS2416: Property 'length' in type 'C3' is not assignable to the same property in base type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(18,38): error TS2416: Property 'length' in type 'C3' is not assignable to the same property in base type 'number[]'. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(19,38): error TS2416: Property '0' in type 'C4' is not assignable to the same property in base type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(19,38): error TS2416: Property '0' in type 'C4' is not assignable to the same property in base type '[string, number]'. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(20,38): error TS2416: Property 'c' in type 'C5' is not assignable to the same property in base type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(20,38): error TS2416: Property 'c' in type 'C5' is not assignable to the same property in base type 'T5'. Type 'number' is not assignable to type 'string'. tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(30,11): error TS2430: Interface 'I10' incorrectly extends interface 'typeof CX'. Types of property 'a' are incompatible. @@ -94,23 +94,23 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectI class C1 extends Constructor() { a: string } ~ -!!! error TS2416: Property 'a' in type 'C1' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'a' in type 'C1' is not assignable to the same property in base type 'T1'. !!! error TS2416: Type 'string' is not assignable to type 'number'. class C2 extends Constructor() { b: string } ~ -!!! error TS2416: Property 'b' in type 'C2' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'b' in type 'C2' is not assignable to the same property in base type 'T2'. !!! error TS2416: Type 'string' is not assignable to type 'number'. class C3 extends Constructor() { length: string } ~~~~~~ -!!! error TS2416: Property 'length' in type 'C3' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'length' in type 'C3' is not assignable to the same property in base type 'number[]'. !!! error TS2416: Type 'string' is not assignable to type 'number'. class C4 extends Constructor() { 0: number } ~ -!!! error TS2416: Property '0' in type 'C4' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property '0' in type 'C4' is not assignable to the same property in base type '[string, number]'. !!! error TS2416: Type 'number' is not assignable to type 'string'. class C5 extends Constructor() { c: number } ~ -!!! error TS2416: Property 'c' in type 'C5' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'c' in type 'C5' is not assignable to the same property in base type 'T5'. !!! error TS2416: Type 'number' is not assignable to type 'string'. declare class CX { static a: string } diff --git a/tests/baselines/reference/interfaceImplementation7.errors.txt b/tests/baselines/reference/interfaceImplementation7.errors.txt index de9bbdae835..a275090b199 100644 --- a/tests/baselines/reference/interfaceImplementation7.errors.txt +++ b/tests/baselines/reference/interfaceImplementation7.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/interfaceImplementation7.ts(4,11): error TS2320: Interface 'i3' cannot simultaneously extend types 'i1' and 'i2'. Named property 'name' of types 'i1' and 'i2' are not identical. -tests/cases/compiler/interfaceImplementation7.ts(8,12): error TS2416: Property 'name' in type 'C1' is not assignable to the same property in base type '() => { s: string; n: number; }'. +tests/cases/compiler/interfaceImplementation7.ts(8,12): error TS2416: Property 'name' in type 'C1' is not assignable to the same property in base type 'i4'. Type '() => string' is not assignable to type '() => { s: string; n: number; }'. Type 'string' is not assignable to type '{ s: string; n: number; }'. @@ -18,7 +18,7 @@ tests/cases/compiler/interfaceImplementation7.ts(8,12): error TS2416: Property ' class C1 implements i4 { public name(): string { return ""; } ~~~~ -!!! error TS2416: Property 'name' in type 'C1' is not assignable to the same property in base type '() => { s: string; n: number; }'. +!!! error TS2416: Property 'name' in type 'C1' is not assignable to the same property in base type 'i4'. !!! error TS2416: Type '() => string' is not assignable to type '() => { s: string; n: number; }'. !!! error TS2416: Type 'string' is not assignable to type '{ s: string; n: number; }'. } diff --git a/tests/baselines/reference/mismatchedGenericArguments1.errors.txt b/tests/baselines/reference/mismatchedGenericArguments1.errors.txt index 4b2d13986ce..8c95aa78fb7 100644 --- a/tests/baselines/reference/mismatchedGenericArguments1.errors.txt +++ b/tests/baselines/reference/mismatchedGenericArguments1.errors.txt @@ -1,8 +1,8 @@ -tests/cases/compiler/mismatchedGenericArguments1.ts(5,4): error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/mismatchedGenericArguments1.ts(5,4): error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => number' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. -tests/cases/compiler/mismatchedGenericArguments1.ts(11,4): error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/mismatchedGenericArguments1.ts(11,4): error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => number' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. @@ -15,7 +15,7 @@ tests/cases/compiler/mismatchedGenericArguments1.ts(11,4): error TS2416: Propert class C implements IFoo { foo(x: string): number { ~~~ -!!! error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => number' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. @@ -26,7 +26,7 @@ tests/cases/compiler/mismatchedGenericArguments1.ts(11,4): error TS2416: Propert class C2 implements IFoo { foo(x: string): number { ~~~ -!!! error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => number' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. diff --git a/tests/baselines/reference/multipleInheritance.errors.txt b/tests/baselines/reference/multipleInheritance.errors.txt index 72e44dc999c..c4a440d9a0e 100644 --- a/tests/baselines/reference/multipleInheritance.errors.txt +++ b/tests/baselines/reference/multipleInheritance.errors.txt @@ -1,7 +1,7 @@ tests/cases/compiler/multipleInheritance.ts(9,21): error TS1174: Classes can only extend a single class. tests/cases/compiler/multipleInheritance.ts(18,21): error TS1174: Classes can only extend a single class. tests/cases/compiler/multipleInheritance.ts(35,12): error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. -tests/cases/compiler/multipleInheritance.ts(36,12): error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type '() => number'. +tests/cases/compiler/multipleInheritance.ts(36,12): error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type 'Good'. Type '(n: number) => number' is not assignable to type '() => number'. @@ -49,7 +49,7 @@ tests/cases/compiler/multipleInheritance.ts(36,12): error TS2416: Property 'g' i !!! error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. public g(n:number) { return 0; } ~ -!!! error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type 'Good'. !!! error TS2416: Type '(n: number) => number' is not assignable to type '() => number'. } \ No newline at end of file diff --git a/tests/baselines/reference/requiredInitializedParameter2.errors.txt b/tests/baselines/reference/requiredInitializedParameter2.errors.txt index cdb659f251a..278d5c0f359 100644 --- a/tests/baselines/reference/requiredInitializedParameter2.errors.txt +++ b/tests/baselines/reference/requiredInitializedParameter2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/requiredInitializedParameter2.ts(6,5): error TS2416: Property 'method' in type 'C1' is not assignable to the same property in base type '() => any'. +tests/cases/compiler/requiredInitializedParameter2.ts(6,5): error TS2416: Property 'method' in type 'C1' is not assignable to the same property in base type 'I1'. Type '(a: number, b: any) => void' is not assignable to type '() => any'. @@ -10,6 +10,6 @@ tests/cases/compiler/requiredInitializedParameter2.ts(6,5): error TS2416: Proper class C1 implements I1 { method(a = 0, b) { } ~~~~~~ -!!! error TS2416: Property 'method' in type 'C1' is not assignable to the same property in base type '() => any'. +!!! error TS2416: Property 'method' in type 'C1' is not assignable to the same property in base type 'I1'. !!! error TS2416: Type '(a: number, b: any) => void' is not assignable to type '() => any'. } \ No newline at end of file diff --git a/tests/baselines/reference/subtypesOfTypeParameter.errors.txt b/tests/baselines/reference/subtypesOfTypeParameter.errors.txt index f0bed548c97..8983c26e153 100644 --- a/tests/baselines/reference/subtypesOfTypeParameter.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameter.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameter.ts(8,5): error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameter.ts(8,5): error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'C3'. Type 'U' is not assignable to type 'T'. @@ -12,7 +12,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf class D1 extends C3 { foo: U; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'U' is not assignable to type 'T'. } diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt index 7019967d204..cff11049787 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt @@ -1,36 +1,36 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(19,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(19,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'C3'. Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(19,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'C3'. Type 'U' is not assignable to type 'T'. Type 'V' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(67,5): error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(67,5): error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'C3'. Type 'V' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(67,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(72,5): error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(72,5): error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'C3'. Type 'V' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(72,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'C3'. Type 'U' is not assignable to type 'T'. Type 'V' is not assignable to type 'T'. Type 'Date' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'C3'. Type 'V' is not assignable to type 'T'. Type 'Date' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'C3'. Type 'V' is not assignable to type 'U'. Type 'Date' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'C3'. Type 'Date' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(161,5): error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(161,5): error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'C3'. Type 'Date' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(161,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(166,5): error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(166,5): error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'C3'. Type 'Date' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(166,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'V'. @@ -56,7 +56,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'U' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. @@ -92,7 +92,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'U' is not assignable to type 'T'. !!! error TS2416: Type 'V' is not assignable to type 'T'. ~~~~~~~ @@ -115,7 +115,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'V' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. @@ -125,7 +125,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'V' is not assignable to type 'U'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. @@ -170,7 +170,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'U' is not assignable to type 'T'. !!! error TS2416: Type 'V' is not assignable to type 'T'. !!! error TS2416: Type 'Date' is not assignable to type 'T'. @@ -199,7 +199,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'V' is not assignable to type 'T'. !!! error TS2416: Type 'Date' is not assignable to type 'T'. ~~~~~~~ @@ -210,7 +210,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'V' is not assignable to type 'U'. !!! error TS2416: Type 'Date' is not assignable to type 'U'. ~~~~~~~ @@ -233,7 +233,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: Date; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'Date' is not assignable to type 'T'. ~~~~~~~~~~ !!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'T'. @@ -243,7 +243,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: Date; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'Date' is not assignable to type 'U'. ~~~~~~~~~~ !!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'U'. @@ -253,7 +253,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: Date; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'V'. +!!! error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'Date' is not assignable to type 'V'. ~~~~~~~~~~ !!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'V'. diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt index 5b1cd0dffa3..ad85188fb4d 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt @@ -1,18 +1,18 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'B1'. Type 'V' is not assignable to type 'Foo'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'Foo'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'B1'. Type 'U' is not assignable to type 'T'. Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(62,5): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(62,5): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'B1'. Type 'V' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(62,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'B1'. Type 'T' is not assignable to type 'U'. Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(77,5): error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(77,5): error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'B1'. Type 'V' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(77,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. @@ -66,7 +66,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: Foo; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'V' is not assignable to type 'Foo'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'Foo'. @@ -81,7 +81,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'U' is not assignable to type 'T'. !!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~~ @@ -92,7 +92,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'V' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. @@ -102,7 +102,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: T; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'T' is not assignable to type 'U'. !!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~~ @@ -118,7 +118,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'V' is not assignable to type 'U'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt index 35c086e52a2..c5adf758728 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt @@ -1,58 +1,58 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(68,9): error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(68,9): error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'Base'. Type 'U' is not assignable to type 'T'. Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(68,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(73,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(73,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base'. Type 'V' is not assignable to type 'T'. Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(73,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(78,9): error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(78,9): error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'Base'. Type 'T' is not assignable to type 'U'. Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(78,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(88,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(88,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base'. Type 'V' is not assignable to type 'U'. Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(88,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(93,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(93,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base'. Type 'T' is not assignable to type 'V'. Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(93,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(98,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(98,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base'. Type 'U' is not assignable to type 'V'. Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(98,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(115,9): error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(115,9): error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'Base2'. Type 'T' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'U' is not assignable to type 'T'. Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(120,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(125,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(125,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base2'. Type 'V' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'V' is not assignable to type 'T'. Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(125,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(130,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(135,9): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(135,9): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'Base2'. Type 'U' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'T' is not assignable to type 'U'. Type 'Foo' is not assignable to type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(140,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(140,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base2'. Type 'V' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'V' is not assignable to type 'U'. Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(140,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(145,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(145,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base2'. Type 'T' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'U' is not assignable to type 'V'. Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(145,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(150,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(150,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base2'. Type 'U' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'T' is not assignable to type 'V'. @@ -130,7 +130,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U ~~~ -!!! error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'U' is not assignable to type 'T'. !!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~ @@ -141,7 +141,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V ~~~ -!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'V' is not assignable to type 'T'. !!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~ @@ -152,7 +152,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: T ~~~ -!!! error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'T' is not assignable to type 'U'. !!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~ @@ -168,7 +168,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V ~~~ -!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'V' is not assignable to type 'U'. !!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~ @@ -179,7 +179,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: T ~~~ -!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'V'. +!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'T' is not assignable to type 'V'. !!! error TS2416: Type 'Foo' is not assignable to type 'V'. ~~~~~~ @@ -190,7 +190,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: U ~~~ -!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'V'. +!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'U' is not assignable to type 'V'. !!! error TS2416: Type 'Foo' is not assignable to type 'V'. ~~~~~~ @@ -213,7 +213,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: T ~~~ -!!! error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'T' is not assignable to type 'Foo'. !!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. !!! error TS2416: Type 'U' is not assignable to type 'T'. @@ -231,7 +231,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V ~~~ -!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'V' is not assignable to type 'Foo'. !!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. !!! error TS2416: Type 'V' is not assignable to type 'T'. @@ -251,7 +251,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: U ~~~ -!!! error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'U' is not assignable to type 'Foo'. !!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. !!! error TS2416: Type 'T' is not assignable to type 'U'. @@ -262,7 +262,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V ~~~ -!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'V' is not assignable to type 'Foo'. !!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. !!! error TS2416: Type 'V' is not assignable to type 'U'. @@ -275,7 +275,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: T ~~~ -!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'T' is not assignable to type 'Foo'. !!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. !!! error TS2416: Type 'U' is not assignable to type 'V'. @@ -288,7 +288,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: U ~~~ -!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'U' is not assignable to type 'Foo'. !!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. !!! error TS2416: Type 'T' is not assignable to type 'V'. diff --git a/tests/baselines/reference/subtypingWithObjectMembers.errors.txt b/tests/baselines/reference/subtypingWithObjectMembers.errors.txt index 2be672f5c03..044e4ee0f2b 100644 --- a/tests/baselines/reference/subtypingWithObjectMembers.errors.txt +++ b/tests/baselines/reference/subtypingWithObjectMembers.errors.txt @@ -1,14 +1,14 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(14,5): error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(14,5): error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'A'. Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(24,5): error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(24,5): error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'A2'. Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(34,5): error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(34,5): error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'A3'. Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(45,9): error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(45,9): error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'A'. Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(55,9): error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(55,9): error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'A2'. Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(65,9): error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(65,9): error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'A3'. Type 'string' is not assignable to type 'Base'. @@ -28,7 +28,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW foo: Derived; // ok bar: string; // error ~~~ -!!! error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'A'. !!! error TS2416: Type 'string' is not assignable to type 'Base'. } @@ -41,7 +41,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW 1: Derived; // ok 2: string; // error ~ -!!! error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'A2'. !!! error TS2416: Type 'string' is not assignable to type 'Base'. } @@ -54,7 +54,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW '1': Derived; // ok '2.0': string; // error ~~~~~ -!!! error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'A3'. !!! error TS2416: Type 'string' is not assignable to type 'Base'. } @@ -68,7 +68,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW foo: Derived2; // ok bar: string; // error ~~~ -!!! error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'A'. !!! error TS2416: Type 'string' is not assignable to type 'Base'. } @@ -81,7 +81,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW 1: Derived2; // ok 2: string; // error ~ -!!! error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'A2'. !!! error TS2416: Type 'string' is not assignable to type 'Base'. } @@ -94,7 +94,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW '1': Derived2; // ok '2.0': string; // error ~~~~~ -!!! error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'A3'. !!! error TS2416: Type 'string' is not assignable to type 'Base'. } } \ No newline at end of file From 7a1deae6aa9a6b36c8364556aa9f8fc8225f01ed Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 10 Jan 2018 12:52:35 -0800 Subject: [PATCH 140/189] AsteriskToken should always have length 1 (#21126) --- 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 f0685b7372e..2797fe557c7 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6491,7 +6491,7 @@ namespace ts { if (state === JSDocState.BeginningOfLine) { // leading asterisks start recording on the *next* (non-whitespace) token state = JSDocState.SawAsterisk; - indent += scanner.getTokenText().length; + indent += 1; break; } // record the * as a comment From 71c92bf2f6ec864e3b794c3b919915fe2c15116c Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 10 Jan 2018 13:38:25 -0800 Subject: [PATCH 141/189] Fix lint error --- src/services/pathCompletions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 98b1737adf3..9ed612f0ef3 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -312,7 +312,7 @@ namespace ts.Completions.PathCompletions { function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] { // Check for typings specified in compiler options - let seen = createMap(); + const seen = createMap(); if (options.types) { for (const typesName of options.types) { const moduleName = getPackageNameFromAtTypesDirectoryWithoutPrefix(typesName); From 5d8598f2808b56bfce526defd45ea8fa0d9ec0cb Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 10 Jan 2018 13:38:32 -0800 Subject: [PATCH 142/189] Add regression test --- .../fourslash/completionListInImportClause05.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/cases/fourslash/completionListInImportClause05.ts diff --git a/tests/cases/fourslash/completionListInImportClause05.ts b/tests/cases/fourslash/completionListInImportClause05.ts new file mode 100644 index 00000000000..b98e91c4cbb --- /dev/null +++ b/tests/cases/fourslash/completionListInImportClause05.ts @@ -0,0 +1,17 @@ +/// + +// @Filename: app.ts +//// import * as A from "[|/*1*/|]"; + +// @Filename: /node_modules/@types/a__b/index.d.ts +////declare module "@e/f" { function fun(): string; } + +// @Filename: /node_modules/@types/c__d/index.d.ts +////export declare let x: number; + +const [replacementSpan] = test.ranges(); +verify.completionsAt("1", [ + { name: "@a/b", replacementSpan }, + { name: "@c/d", replacementSpan }, + { name: "@e/f", replacementSpan }, +]); From 8275bed33fd75dcc2f1c7ebcd1e7ba08b3cbb9f5 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 10 Jan 2018 13:57:06 -0800 Subject: [PATCH 143/189] Add comment explaining test-only workaround --- tests/cases/fourslash/completionListInImportClause05.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/cases/fourslash/completionListInImportClause05.ts b/tests/cases/fourslash/completionListInImportClause05.ts index b98e91c4cbb..e1401706ea1 100644 --- a/tests/cases/fourslash/completionListInImportClause05.ts +++ b/tests/cases/fourslash/completionListInImportClause05.ts @@ -9,6 +9,11 @@ // @Filename: /node_modules/@types/c__d/index.d.ts ////export declare let x: number; +// NOTE: When performing completion, the "current directory" appears to be "/", +// which is well above "." (i.e. the directory containing "app.ts"). This issue +// is specific to the virtual file system, so just work around it by putting the +// node modules folder in "/", rather than ".". + const [replacementSpan] = test.ranges(); verify.completionsAt("1", [ { name: "@a/b", replacementSpan }, From 0b23811a5635e41c8d4cf3bd156930617019760c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 10 Jan 2018 14:00:52 -0800 Subject: [PATCH 144/189] Handle indexed mapped types in transformIndexedAccessType Also rename transformIndexedAccessType to simplifyIndexedAccessType --- src/compiler/checker.ts | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d530ef8e334..a5e21ff6535 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6351,7 +6351,7 @@ namespace ts { return getObjectFlags(type) & ObjectFlags.Mapped && !!(type).declaration.questionToken; } - function isGenericMappedType(type: Type) { + function isGenericMappedType(type: Type): type is MappedType { return getObjectFlags(type) & ObjectFlags.Mapped && isGenericIndexType(getConstraintTypeFromMappedType(type)); } @@ -6463,14 +6463,12 @@ namespace ts { } function getConstraintOfIndexedAccess(type: IndexedAccessType) { - const transformed = getTransformedIndexedAccessType(type); + const transformed = simplifyIndexedAccessType(type); if (transformed) { return transformed; } const baseObjectType = getBaseConstraintOfType(type.objectType); - const keepTypeParameterForMappedType = baseObjectType && getObjectFlags(baseObjectType) & ObjectFlags.Mapped && - type.indexType.flags & TypeFlags.TypeParameter; - const baseIndexType = !keepTypeParameterForMappedType && getBaseConstraintOfType(type.indexType); + 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`. @@ -6546,7 +6544,7 @@ namespace ts { return stringType; } if (t.flags & TypeFlags.IndexedAccess) { - const transformed = getTransformedIndexedAccessType(t); + const transformed = simplifyIndexedAccessType(t); if (transformed) { return getBaseConstraint(transformed); } @@ -6555,6 +6553,9 @@ namespace ts { const baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined; } + if (isGenericMappedType(t)) { + return emptyObjectType; + } return t; } } @@ -8355,7 +8356,7 @@ namespace ts { // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return // undefined if no transformation is possible. - function getTransformedIndexedAccessType(type: IndexedAccessType): Type { + function simplifyIndexedAccessType(type: IndexedAccessType): Type { const objectType = type.objectType; // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a @@ -8381,14 +8382,24 @@ namespace ts { // that substitutes the index type for P. For example, for an index access { [P in K]: Box }[X], we // construct the type Box. if (isGenericMappedType(objectType)) { - const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [type.indexType]); - const objectTypeMapper = (objectType).mapper; - const templateMapper = objectTypeMapper ? combineTypeMappers(objectTypeMapper, mapper) : mapper; - return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper); + return substituteIndexedMappedType(objectType, type); + } + if (objectType.flags & TypeFlags.TypeParameter) { + const constraint = getConstraintFromTypeParameter(objectType as TypeParameter); + if (constraint && isGenericMappedType(constraint)) { + return substituteIndexedMappedType(constraint, type); + } } return undefined; } + function substituteIndexedMappedType(objectType: MappedType, type: IndexedAccessType) { + const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [type.indexType]); + const objectTypeMapper = (objectType).mapper; + const templateMapper = objectTypeMapper ? combineTypeMappers(objectTypeMapper, mapper) : mapper; + return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper); + } + function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode): Type { // If the index type is generic, or if the object type is generic and doesn't originate in an expression, // we are performing a higher-order index access where we cannot meaningfully access the properties of the From 8f45373e442034fb94aef20f9f7b65dc8d38ebb9 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 10 Jan 2018 14:43:55 -0800 Subject: [PATCH 145/189] Rename simplifyIndexedAccessType->getSimplifiedIndexedAccessType --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a5e21ff6535..8504074080a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6463,7 +6463,7 @@ namespace ts { } function getConstraintOfIndexedAccess(type: IndexedAccessType) { - const transformed = simplifyIndexedAccessType(type); + const transformed = getSimplifiedIndexedAccessType(type); if (transformed) { return transformed; } @@ -6544,7 +6544,7 @@ namespace ts { return stringType; } if (t.flags & TypeFlags.IndexedAccess) { - const transformed = simplifyIndexedAccessType(t); + const transformed = getSimplifiedIndexedAccessType(t); if (transformed) { return getBaseConstraint(transformed); } @@ -8356,7 +8356,7 @@ namespace ts { // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return // undefined if no transformation is possible. - function simplifyIndexedAccessType(type: IndexedAccessType): Type { + function getSimplifiedIndexedAccessType(type: IndexedAccessType): Type { const objectType = type.objectType; // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a From ff102da9d1a77bd148d7c713ad109e65edfcba65 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 10 Jan 2018 15:12:00 -0800 Subject: [PATCH 146/189] Refine explanatory comment --- tests/cases/fourslash/completionListInImportClause05.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/cases/fourslash/completionListInImportClause05.ts b/tests/cases/fourslash/completionListInImportClause05.ts index e1401706ea1..f7b5244d5a4 100644 --- a/tests/cases/fourslash/completionListInImportClause05.ts +++ b/tests/cases/fourslash/completionListInImportClause05.ts @@ -1,7 +1,7 @@ /// // @Filename: app.ts -//// import * as A from "[|/*1*/|]"; +////import * as A from "[|/*1*/|]"; // @Filename: /node_modules/@types/a__b/index.d.ts ////declare module "@e/f" { function fun(): string; } @@ -9,10 +9,8 @@ // @Filename: /node_modules/@types/c__d/index.d.ts ////export declare let x: number; -// NOTE: When performing completion, the "current directory" appears to be "/", -// which is well above "." (i.e. the directory containing "app.ts"). This issue -// is specific to the virtual file system, so just work around it by putting the -// node modules folder in "/", rather than ".". +// NOTE: The node_modules folder is in "/", rather than ".", because it requires +// less scaffolding to mock. In particular, "/" is where we look for type roots. const [replacementSpan] = test.ranges(); verify.completionsAt("1", [ From 211be0ae69f217db437ca13185ad76586aab5054 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 10 Jan 2018 15:12:10 -0800 Subject: [PATCH 147/189] Add regression test for de-dup'ing. --- .../fourslash/completionListInImportClause06.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/cases/fourslash/completionListInImportClause06.ts diff --git a/tests/cases/fourslash/completionListInImportClause06.ts b/tests/cases/fourslash/completionListInImportClause06.ts new file mode 100644 index 00000000000..f6cfefa437f --- /dev/null +++ b/tests/cases/fourslash/completionListInImportClause06.ts @@ -0,0 +1,17 @@ +/// + +// @typeRoots: T1,T2 + +// @Filename: app.ts +////import * as A from "[|/*1*/|]"; + +// @Filename: T1/a__b/index.d.ts +////export declare let x: number; + +// @Filename: T2/a__b/index.d.ts +////export declare let x: number; + +// Confirm that entries are de-dup'd. +verify.completionsAt("1", [ + { name: "@a/b", replacementSpan: test.ranges()[0] }, +]); From 9a4fe8eb7e3242cbca2aa430eb7200e0ad6d0001 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 10 Jan 2018 15:17:27 -0800 Subject: [PATCH 148/189] Rename getPackageNameFromAtTypesDirectoryWithoutPrefix to getUnmangledNameForScopedPackage --- src/compiler/moduleNameResolver.ts | 10 +++++----- src/services/pathCompletions.ts | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 532d076504b..018bddd420b 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -1097,16 +1097,16 @@ namespace ts { export function getPackageNameFromAtTypesDirectory(mangledName: string): string { const withoutAtTypePrefix = removePrefix(mangledName, "@types/"); if (withoutAtTypePrefix !== mangledName) { - return getPackageNameFromAtTypesDirectoryWithoutPrefix(withoutAtTypePrefix); + return getUnmangledNameForScopedPackage(withoutAtTypePrefix); } return mangledName; } /* @internal */ - export function getPackageNameFromAtTypesDirectoryWithoutPrefix(withoutAtTypePrefix: string): string { - return stringContains(withoutAtTypePrefix, mangledScopedPackageSeparator) ? - "@" + withoutAtTypePrefix.replace(mangledScopedPackageSeparator, ts.directorySeparator) : - withoutAtTypePrefix; + export function getUnmangledNameForScopedPackage(typesPackageName: string): string { + return stringContains(typesPackageName, mangledScopedPackageSeparator) ? + "@" + typesPackageName.replace(mangledScopedPackageSeparator, ts.directorySeparator) : + typesPackageName; } function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, traceEnabled: boolean, host: ModuleResolutionHost): SearchResult { diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 9ed612f0ef3..82f144ac377 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -315,7 +315,7 @@ namespace ts.Completions.PathCompletions { const seen = createMap(); if (options.types) { for (const typesName of options.types) { - const moduleName = getPackageNameFromAtTypesDirectoryWithoutPrefix(typesName); + const moduleName = getUnmangledNameForScopedPackage(typesName); pushResult(moduleName); } } @@ -349,7 +349,7 @@ namespace ts.Completions.PathCompletions { for (let typeDirectory of directories) { typeDirectory = normalizePath(typeDirectory); const directoryName = getBaseFileName(typeDirectory); - const moduleName = getPackageNameFromAtTypesDirectoryWithoutPrefix(directoryName); + const moduleName = getUnmangledNameForScopedPackage(directoryName); pushResult(moduleName); } } From f0ef9a08d86ae92815559e66c8ceb63a6c953830 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 10 Jan 2018 15:37:27 -0800 Subject: [PATCH 149/189] getConstraintOfTypeParameter:check circularity in base constraint --- src/compiler/checker.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fd6a033653a..f67f90a3d04 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6301,9 +6301,9 @@ namespace ts { (type.typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(type.declaration.typeParameter))); } - function getConstraintTypeFromMappedType(type: MappedType) { + function getConstraintTypeFromMappedType(type: MappedType, typeStack?: Type[]) { return type.constraintType || - (type.constraintType = instantiateType(getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)), type.mapper || identityMapper) || unknownType); + (type.constraintType = instantiateType(getConstraintOfTypeParameter(getTypeParameterFromMappedType(type), typeStack), type.mapper || identityMapper) || unknownType); } function getTemplateTypeFromMappedType(type: MappedType) { @@ -6351,8 +6351,8 @@ namespace ts { return getObjectFlags(type) & ObjectFlags.Mapped && !!(type).declaration.questionToken; } - function isGenericMappedType(type: Type) { - return getObjectFlags(type) & ObjectFlags.Mapped && isGenericIndexType(getConstraintTypeFromMappedType(type)); + function isGenericMappedType(type: Type, typeStack?: Type[]): type is MappedType { + return getObjectFlags(type) & ObjectFlags.Mapped && isGenericIndexType(getConstraintTypeFromMappedType(type, typeStack)); } function resolveStructuredTypeMembers(type: StructuredType): ResolvedType { @@ -6458,7 +6458,10 @@ namespace ts { getBaseConstraintOfType(type); } - function getConstraintOfTypeParameter(typeParameter: TypeParameter): Type { + function getConstraintOfTypeParameter(typeParameter: TypeParameter, typeStack?: Type[]): Type { + if (typeStack) { + return !contains(typeStack, typeParameter) && getConstraintFromTypeParameter(typeParameter); + } return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined; } @@ -6547,7 +6550,7 @@ namespace ts { const baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined; } - if (isGenericMappedType(t)) { + if (isGenericMappedType(t, typeStack)) { return emptyObjectType; } return t; From c0dd832e468aa60f18a538cd2d9fe8d8e7ec4bc7 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 10 Jan 2018 15:38:22 -0800 Subject: [PATCH 150/189] Test:incorrect mapped type doesn't infinitely recur --- ...ctRecursiveMappedTypeConstraint.errors.txt | 13 +++++++++++ .../incorrectRecursiveMappedTypeConstraint.js | 12 ++++++++++ ...rrectRecursiveMappedTypeConstraint.symbols | 21 +++++++++++++++++ ...correctRecursiveMappedTypeConstraint.types | 23 +++++++++++++++++++ .../incorrectRecursiveMappedTypeConstraint.ts | 4 ++++ .../TypeScript-Node-Starter | 2 +- 6 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.errors.txt create mode 100644 tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.js create mode 100644 tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.symbols create mode 100644 tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types create mode 100644 tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts diff --git a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.errors.txt b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.errors.txt new file mode 100644 index 00000000000..8773f92549f --- /dev/null +++ b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.errors.txt @@ -0,0 +1,13 @@ +tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts(2,32): error TS2322: Type 'T' is not assignable to type 'string'. + Type '{ [P in T]: number; }' is not assignable to type 'string'. + + +==== tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts (1 errors) ==== + // #17847 + function sum(n: number, v: T, k: K) { + ~ +!!! error TS2322: Type 'T' is not assignable to type 'string'. +!!! error TS2322: Type '{ [P in T]: number; }' is not assignable to type 'string'. + n += v[k]; + } + \ No newline at end of file diff --git a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.js b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.js new file mode 100644 index 00000000000..44954f5c7c2 --- /dev/null +++ b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.js @@ -0,0 +1,12 @@ +//// [incorrectRecursiveMappedTypeConstraint.ts] +// #17847 +function sum(n: number, v: T, k: K) { + n += v[k]; +} + + +//// [incorrectRecursiveMappedTypeConstraint.js] +// #17847 +function sum(n, v, k) { + n += v[k]; +} diff --git a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.symbols b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.symbols new file mode 100644 index 00000000000..42cc7b1f4fb --- /dev/null +++ b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.symbols @@ -0,0 +1,21 @@ +=== tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts === +// #17847 +function sum(n: number, v: T, k: K) { +>sum : Symbol(sum, Decl(incorrectRecursiveMappedTypeConstraint.ts, 0, 0)) +>T : Symbol(T, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 13)) +>P : Symbol(P, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 26)) +>T : Symbol(T, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 13)) +>K : Symbol(K, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 44)) +>T : Symbol(T, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 13)) +>n : Symbol(n, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 64)) +>v : Symbol(v, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 74)) +>T : Symbol(T, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 13)) +>k : Symbol(k, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 80)) +>K : Symbol(K, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 44)) + + n += v[k]; +>n : Symbol(n, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 64)) +>v : Symbol(v, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 74)) +>k : Symbol(k, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 80)) +} + diff --git a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types new file mode 100644 index 00000000000..9dee691eaf0 --- /dev/null +++ b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts === +// #17847 +function sum(n: number, v: T, k: K) { +>sum : (n: number, v: T, k: K) => void +>T : T +>P : P +>T : T +>K : K +>T : T +>n : number +>v : T +>T : T +>k : K +>K : K + + n += v[k]; +>n += v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K +} + diff --git a/tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts b/tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts new file mode 100644 index 00000000000..67e996c975b --- /dev/null +++ b/tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts @@ -0,0 +1,4 @@ +// #17847 +function sum(n: number, v: T, k: K) { + n += v[k]; +} diff --git a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter index 40bdb4eadab..ed149eb0c78 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 40bdb4eadabc9fbed7d83e3f26817a931c0763b6 +Subproject commit ed149eb0c787b1195a95b44105822c64bb6eb636 From e34a4101b5a17c861c0404d9e5383ac628814747 Mon Sep 17 00:00:00 2001 From: csigs Date: Thu, 11 Jan 2018 17:10:12 +0000 Subject: [PATCH 151/189] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 118 +++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index b01830dcac5..093c228c5a4 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -474,6 +474,15 @@ + + + + + + + + + @@ -876,6 +885,12 @@ + + + + + + @@ -1281,6 +1296,24 @@ + + + + + + + + + + + + + + + + + + @@ -1830,6 +1863,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2298,6 +2358,15 @@ + + + + + + + + + @@ -2895,6 +2964,15 @@ + + + + + + + + + @@ -4539,6 +4617,12 @@ + + + + + + @@ -5574,6 +5658,15 @@ + + + + + + + + + @@ -5931,6 +6024,15 @@ + + + + + + + + + @@ -7995,6 +8097,15 @@ + + + + + + + + + @@ -8498,10 +8609,13 @@ - + - + + + + From 16a80030117e00f4ab046db5a2d1ff009ddebccb Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 11 Jan 2018 10:07:59 -0800 Subject: [PATCH 152/189] push/popTypeResolution for circular base constraints Instead of a custom cache `typeStack`. --- src/compiler/checker.ts | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4b59cbc5d8a..d402f344d60 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -530,6 +530,7 @@ namespace ts { ResolvedBaseConstructorType, DeclaredType, ResolvedReturnType, + ResolvedBaseConstraint, } const enum CheckMode { @@ -4254,7 +4255,7 @@ namespace ts { return -1; } - function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): Type { + function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): Type | boolean { if (propertyName === TypeSystemPropertyName.Type) { return getSymbolLinks(target).type; } @@ -4267,6 +4268,10 @@ namespace ts { if (propertyName === TypeSystemPropertyName.ResolvedReturnType) { return (target).resolvedReturnType; } + if (propertyName === TypeSystemPropertyName.ResolvedBaseConstraint) { + const bc = (target).resolvedBaseConstraint; + return bc && bc !== circularConstraintType; + } Debug.fail("Unhandled TypeSystemPropertyName " + propertyName); } @@ -6301,9 +6306,9 @@ namespace ts { (type.typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(type.declaration.typeParameter))); } - function getConstraintTypeFromMappedType(type: MappedType, typeStack?: Type[]) { + function getConstraintTypeFromMappedType(type: MappedType) { return type.constraintType || - (type.constraintType = instantiateType(getConstraintOfTypeParameter(getTypeParameterFromMappedType(type), typeStack), type.mapper || identityMapper) || unknownType); + (type.constraintType = instantiateType(getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)), type.mapper || identityMapper) || unknownType); } function getTemplateTypeFromMappedType(type: MappedType) { @@ -6351,8 +6356,8 @@ namespace ts { return getObjectFlags(type) & ObjectFlags.Mapped && !!(type).declaration.questionToken; } - function isGenericMappedType(type: Type, typeStack?: Type[]): type is MappedType { - return getObjectFlags(type) & ObjectFlags.Mapped && isGenericIndexType(getConstraintTypeFromMappedType(type, typeStack)); + function isGenericMappedType(type: Type): type is MappedType { + return getObjectFlags(type) & ObjectFlags.Mapped && isGenericIndexType(getConstraintTypeFromMappedType(type)); } function resolveStructuredTypeMembers(type: StructuredType): ResolvedType { @@ -6458,10 +6463,7 @@ namespace ts { getBaseConstraintOfType(type); } - function getConstraintOfTypeParameter(typeParameter: TypeParameter, typeStack?: Type[]): Type { - if (typeStack) { - return !contains(typeStack, typeParameter) && getConstraintFromTypeParameter(typeParameter); - } + function getConstraintOfTypeParameter(typeParameter: TypeParameter): Type { return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined; } @@ -6503,23 +6505,23 @@ namespace ts { * circularly references the type variable. */ function getResolvedBaseConstraint(type: TypeVariable | UnionOrIntersectionType): Type { - let typeStack: Type[]; let circular: boolean; if (!type.resolvedBaseConstraint) { - typeStack = []; const constraint = getBaseConstraint(type); type.resolvedBaseConstraint = circular ? circularConstraintType : getTypeWithThisArgument(constraint || noConstraintType, type); } return type.resolvedBaseConstraint; function getBaseConstraint(t: Type): Type { - if (contains(typeStack, t)) { + if (!pushTypeResolution(t, TypeSystemPropertyName.ResolvedBaseConstraint)) { circular = true; return undefined; } - typeStack.push(t); const result = computeBaseConstraint(t); - typeStack.pop(); + if (!popTypeResolution()) { + circular = true; + return undefined; + } return result; } @@ -6556,7 +6558,7 @@ namespace ts { const baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined; } - if (isGenericMappedType(t, typeStack)) { + if (isGenericMappedType(t)) { return emptyObjectType; } return t; From 2b630e9ea5002b5a5bf7219d32e71e26e4e56a82 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 11 Jan 2018 10:08:49 -0800 Subject: [PATCH 153/189] Update baselines --- .../incorrectRecursiveMappedTypeConstraint.errors.txt | 6 ++---- .../incorrectRecursiveMappedTypeConstraint.types | 2 +- .../reference/recursiveMappedTypes.errors.txt | 11 ++++++++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.errors.txt b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.errors.txt index 8773f92549f..5300c97a576 100644 --- a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.errors.txt +++ b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.errors.txt @@ -1,13 +1,11 @@ -tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts(2,32): error TS2322: Type 'T' is not assignable to type 'string'. - Type '{ [P in T]: number; }' is not assignable to type 'string'. +tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts(2,32): error TS2313: Type parameter 'P' has a circular constraint. ==== tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts (1 errors) ==== // #17847 function sum(n: number, v: T, k: K) { ~ -!!! error TS2322: Type 'T' is not assignable to type 'string'. -!!! error TS2322: Type '{ [P in T]: number; }' is not assignable to type 'string'. +!!! error TS2313: Type parameter 'P' has a circular constraint. n += v[k]; } \ No newline at end of file diff --git a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types index 9dee691eaf0..b6589956216 100644 --- a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types +++ b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types @@ -1,7 +1,7 @@ === tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts === // #17847 function sum(n: number, v: T, k: K) { ->sum : (n: number, v: T, k: K) => void +>sum : (n: number, v: T, k: K) => void >T : T >P : P >T : T diff --git a/tests/baselines/reference/recursiveMappedTypes.errors.txt b/tests/baselines/reference/recursiveMappedTypes.errors.txt index 440825f5319..8279f4f60a6 100644 --- a/tests/baselines/reference/recursiveMappedTypes.errors.txt +++ b/tests/baselines/reference/recursiveMappedTypes.errors.txt @@ -1,25 +1,34 @@ tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(3,6): error TS2456: Type alias 'Recurse' circularly references itself. +tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(4,11): error TS2313: Type parameter 'K' has a circular constraint. tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(7,6): error TS2456: Type alias 'Recurse1' circularly references itself. +tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(8,11): error TS2313: Type parameter 'K' has a circular constraint. tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(11,6): error TS2456: Type alias 'Recurse2' circularly references itself. +tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(12,11): error TS2313: Type parameter 'K' has a circular constraint. -==== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts (3 errors) ==== +==== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts (6 errors) ==== // Recursive mapped types simply appear empty type Recurse = { ~~~~~~~ !!! error TS2456: Type alias 'Recurse' circularly references itself. [K in keyof Recurse]: Recurse[K] + ~~~~~~~~~~~~~ +!!! error TS2313: Type parameter 'K' has a circular constraint. } type Recurse1 = { ~~~~~~~~ !!! error TS2456: Type alias 'Recurse1' circularly references itself. [K in keyof Recurse2]: Recurse2[K] + ~~~~~~~~~~~~~~ +!!! error TS2313: Type parameter 'K' has a circular constraint. } type Recurse2 = { ~~~~~~~~ !!! error TS2456: Type alias 'Recurse2' circularly references itself. [K in keyof Recurse1]: Recurse1[K] + ~~~~~~~~~~~~~~ +!!! error TS2313: Type parameter 'K' has a circular constraint. } \ No newline at end of file From a77c6014b339e6310878821ee20b56fd7b3c41f1 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 11 Jan 2018 10:49:39 -0800 Subject: [PATCH 154/189] Parse comment on @property tag and use as documentation comment (#21119) * Parse comment on @property tag and use as documentation comment * Fix comment parsing bug -- back up after seeing `@` character * Add test for indent * Don't default comment to "" --- src/compiler/parser.ts | 46 +++++++++---------- src/compiler/utilities.ts | 17 ++----- src/services/jsDoc.ts | 36 ++++++++++----- ...ments.parsesCorrectly.leadingAsterisk.json | 3 +- ...nts.parsesCorrectly.noLeadingAsterisk.json | 3 +- ...Comments.parsesCorrectly.noReturnType.json | 3 +- ...cComments.parsesCorrectly.oneParamTag.json | 3 +- ...parsesCorrectly.paramTagNameThenType1.json | 3 +- ...ents.parsesCorrectly.paramWithoutType.json | 3 +- ...ocComments.parsesCorrectly.returnTag1.json | 3 +- ...cComments.parsesCorrectly.returnsTag1.json | 3 +- ...cComments.parsesCorrectly.templateTag.json | 3 +- ...Comments.parsesCorrectly.templateTag2.json | 3 +- ...Comments.parsesCorrectly.templateTag3.json | 3 +- ...Comments.parsesCorrectly.templateTag4.json | 3 +- ...Comments.parsesCorrectly.templateTag5.json | 3 +- ...Comments.parsesCorrectly.twoParamTag2.json | 6 +-- ...parsesCorrectly.twoParamTagOnSameLine.json | 6 +-- .../DocComments.parsesCorrectly.typeTag.json | 3 +- ...sCorrectly.typedefTagWithChildrenTags.json | 3 +- tests/baselines/reference/jsDocTags.baseline | 15 ++---- tests/baselines/reference/jsDocTypeTag1.js | 26 +++++------ tests/baselines/reference/jsDocTypeTag2.js | 24 +++++----- tests/baselines/reference/jsDocTypedef1.js | 2 +- .../reference/quickInfoJsDocTags.baseline | 4 +- tests/cases/fourslash/jsDocTags.ts | 2 +- tests/cases/fourslash/quickInfoPropertyTag.ts | 16 +++++++ 27 files changed, 122 insertions(+), 123 deletions(-) create mode 100644 tests/cases/fourslash/quickInfoPropertyTag.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 2797fe557c7..e3677014996 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6260,7 +6260,6 @@ namespace ts { scanner.scanRange(start + 3, length - 5, () => { // Initially we can parse out a tag. We also have seen a starting asterisk. // This is so that /** * @type */ doesn't parse. - let advanceToken = true; let state = JSDocState.SawAsterisk; let margin: number | undefined = undefined; // + 4 for leading '/** ' @@ -6292,7 +6291,6 @@ namespace ts { // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning // for malformed examples like `/** @param {string} x @returns {number} the length */` state = JSDocState.BeginningOfLine; - advanceToken = false; margin = undefined; indent++; } @@ -6344,13 +6342,7 @@ namespace ts { pushComment(scanner.getTokenText()); break; } - if (advanceToken) { - t = nextJSDocToken(); - } - else { - advanceToken = true; - t = currentToken as JsDocSyntaxKind; - } + t = nextJSDocToken(); } removeLeadingNewlines(comments); removeTrailingNewlines(comments); @@ -6446,10 +6438,11 @@ namespace ts { // a badly malformed tag should not be added to the list of tags return; } - addTag(tag, parseTagComments(indent + tag.end - tag.pos)); + tag.comment = parseTagComments(indent + tag.end - tag.pos); + addTag(tag); } - function parseTagComments(indent: number) { + function parseTagComments(indent: number): string | undefined { const comments: string[] = []; let state = JSDocState.BeginningOfLine; let margin: number | undefined; @@ -6471,6 +6464,8 @@ namespace ts { indent = 0; break; case SyntaxKind.AtToken: + scanner.setTextPos(scanner.getTextPos() - 1); + // falls through case SyntaxKind.EndOfFileToken: // Done break loop; @@ -6506,7 +6501,7 @@ namespace ts { removeLeadingNewlines(comments); removeTrailingNewlines(comments); - return comments; + return comments.length === 0 ? undefined : comments.join(""); } function parseUnknownTag(atToken: AtToken, tagName: Identifier) { @@ -6516,9 +6511,7 @@ namespace ts { return finishNode(result); } - function addTag(tag: JSDocTag, comments: string[]): void { - tag.comment = comments.join(""); - + function addTag(tag: JSDocTag): void { if (!tags) { tags = [tag]; tagsPos = tag.pos; @@ -6563,9 +6556,7 @@ namespace ts { } } - function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse.Parameter): JSDocParameterTag; - function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse.Property): JSDocPropertyTag; - function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse): JSDocPropertyLikeTag { + function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse): JSDocParameterTag | JSDocPropertyTag { let typeExpression = tryParseTypeExpression(); let isNameFirst = !typeExpression; skipWhitespace(); @@ -6577,7 +6568,7 @@ namespace ts { typeExpression = tryParseTypeExpression(); } - const result: JSDocPropertyLikeTag = target === PropertyLikeParse.Parameter ? + const result = target === PropertyLikeParse.Parameter ? createNode(SyntaxKind.JSDocParameterTag, atToken.pos) : createNode(SyntaxKind.JSDocPropertyTag, atToken.pos); const nestedTypeLiteral = parseNestedTypeLiteral(typeExpression, name); @@ -6592,7 +6583,6 @@ namespace ts { result.isNameFirst = isNameFirst; result.isBracketed = isBracketed; return finishNode(result); - } function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression, name: EntityName) { @@ -6815,18 +6805,28 @@ namespace ts { if (!tagName) { return false; } + let t: PropertyLikeParse; switch (tagName.escapedText) { case "type": return target === PropertyLikeParse.Property && parseTypeTag(atToken, tagName); case "prop": case "property": - return target === PropertyLikeParse.Property && parseParameterOrPropertyTag(atToken, tagName, target); + t = PropertyLikeParse.Property; + break; case "arg": case "argument": case "param": - return target === PropertyLikeParse.Parameter && parseParameterOrPropertyTag(atToken, tagName, target); + t = PropertyLikeParse.Parameter; + break; + default: + return false; } - return false; + if (target !== t) { + return false; + } + const tag = parseParameterOrPropertyTag(atToken, tagName, target); + tag.comment = parseTagComments(tag.end - tag.pos); + return tag; } function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag | undefined { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 37b62fd5d85..8304320b301 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1586,42 +1586,35 @@ namespace ts { ((node as JSDocFunctionType).parameters[0].name as Identifier).escapedText === "new"; } - export function getAllJSDocs(node: Node): (JSDoc | JSDocTag)[] { - if (isJSDocTypedefTag(node)) { - return [node.parent]; - } - return getJSDocCommentsAndTags(node); - } - - export function getSourceOfAssignment(node: Node): Node { + function getSourceOfAssignment(node: Node): Node { return isExpressionStatement(node) && node.expression && isBinaryExpression(node.expression) && node.expression.operatorToken.kind === SyntaxKind.EqualsToken && node.expression.right; } - export function getSingleInitializerOfVariableStatement(node: Node, child?: Node): Node { + function getSingleInitializerOfVariableStatement(node: Node, child?: Node): Node { return isVariableStatement(node) && node.declarationList.declarations.length > 0 && (!child || node.declarationList.declarations[0].initializer === child) && node.declarationList.declarations[0].initializer; } - export function getSingleVariableOfVariableStatement(node: Node, child?: Node): Node { + function getSingleVariableOfVariableStatement(node: Node, child?: Node): Node { return isVariableStatement(node) && node.declarationList.declarations.length > 0 && (!child || node.declarationList.declarations[0] === child) && node.declarationList.declarations[0]; } - export function getNestedModuleDeclaration(node: Node): Node { + function getNestedModuleDeclaration(node: Node): Node { return node.kind === SyntaxKind.ModuleDeclaration && (node as ModuleDeclaration).body && (node as ModuleDeclaration).body.kind === SyntaxKind.ModuleDeclaration && (node as ModuleDeclaration).body; } - export function getJSDocCommentsAndTags(node: Node): (JSDoc | JSDocTag)[] { + export function getJSDocCommentsAndTags(node: Node): ReadonlyArray { let result: (JSDoc | JSDocTag)[] | undefined; getJSDocCommentsAndTagsWorker(node); return result || emptyArray; diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 46f2458bba9..91774e2290c 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -52,20 +52,30 @@ namespace ts.JsDoc { // Eg. const a: Array | Array; a.length // The property length will have two declarations of property length coming // from Array - Array and Array - const documentationComment = []; + const documentationComment: SymbolDisplayPart[] = []; forEachUnique(declarations, declaration => { - forEach(getAllJSDocs(declaration), doc => { - if (doc.comment) { - if (documentationComment.length) { - documentationComment.push(lineBreakPart()); - } - documentationComment.push(textPart(doc.comment)); + for (const { comment } of getCommentHavingNodes(declaration)) { + if (comment === undefined) continue; + if (documentationComment.length) { + documentationComment.push(lineBreakPart()); } - }); + documentationComment.push(textPart(comment)); + } }); return documentationComment; } + function getCommentHavingNodes(declaration: Declaration): ReadonlyArray { + switch (declaration.kind) { + case SyntaxKind.JSDocPropertyTag: + return [declaration as JSDocPropertyTag]; + case SyntaxKind.JSDocTypedefTag: + return [(declaration as JSDocTypedefTag).parent]; + default: + return getJSDocCommentsAndTags(declaration); + } + } + export function getJsDocTagsFromDeclarations(declarations?: Declaration[]): JSDocTagInfo[] { // Only collect doc comments from duplicate declarations once. const tags: JSDocTagInfo[] = []; @@ -77,7 +87,7 @@ namespace ts.JsDoc { return tags; } - function getCommentText(tag: JSDocTag): string { + function getCommentText(tag: JSDocTag): string | undefined { const { comment } = tag; switch (tag.kind) { case SyntaxKind.JSDocAugmentsTag: @@ -96,11 +106,15 @@ namespace ts.JsDoc { } function withNode(node: Node) { - return `${node.getText()} ${comment}`; + return addComment(node.getText()); } function withList(list: NodeArray): string { - return `${list.map(x => x.getText())} ${comment}`; + return addComment(list.map(x => x.getText()).join(", ")); + } + + function addComment(s: string) { + return comment === undefined ? s : `${s} ${comment}`; } } diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.leadingAsterisk.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.leadingAsterisk.json index 934de3d8faf..a21f9f81c44 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.leadingAsterisk.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.leadingAsterisk.json @@ -27,8 +27,7 @@ "pos": 15, "end": 21 } - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noLeadingAsterisk.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noLeadingAsterisk.json index 934de3d8faf..a21f9f81c44 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noLeadingAsterisk.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noLeadingAsterisk.json @@ -27,8 +27,7 @@ "pos": 15, "end": 21 } - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json index 62228eac4af..079d09c6eeb 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json @@ -17,8 +17,7 @@ "pos": 9, "end": 15, "escapedText": "return" - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json index 15e8b4a5cfb..4940bcf325e 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json @@ -35,8 +35,7 @@ "escapedText": "name1" }, "isNameFirst": false, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json index 93f47686e8f..7a1c85b25d6 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json @@ -35,8 +35,7 @@ "escapedText": "name1" }, "isNameFirst": true, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json index 926344175d7..3d511525c64 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json @@ -25,8 +25,7 @@ "escapedText": "foo" }, "isNameFirst": true, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag1.json index 0668e7d6324..e02a0a38bb4 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag1.json @@ -27,8 +27,7 @@ "pos": 17, "end": 23 } - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnsTag1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnsTag1.json index e108287c52a..70497ee8c1b 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnsTag1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnsTag1.json @@ -27,8 +27,7 @@ "pos": 18, "end": 24 } - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json index b39b16497e6..8a146e3cfaf 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json @@ -33,8 +33,7 @@ "length": 1, "pos": 18, "end": 20 - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json index 5eeb97af119..5bb1df30665 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json @@ -44,8 +44,7 @@ "length": 2, "pos": 18, "end": 22 - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json index 96645551c5c..295b2122daa 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json @@ -44,8 +44,7 @@ "length": 2, "pos": 18, "end": 23 - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json index 0b2719f59ba..4aa29db3092 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json @@ -44,8 +44,7 @@ "length": 2, "pos": 18, "end": 23 - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json index 8b6118e9b19..5e707f6f03b 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json @@ -44,8 +44,7 @@ "length": 2, "pos": 18, "end": 24 - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json index 391ee1aac2f..c73009315bc 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json @@ -35,8 +35,7 @@ "escapedText": "name1" }, "isNameFirst": false, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "1": { "kind": "JSDocParameterTag", @@ -70,8 +69,7 @@ "escapedText": "name2" }, "isNameFirst": false, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "length": 2, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json index 628d54d162d..e1ef0adb926 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json @@ -35,8 +35,7 @@ "escapedText": "name1" }, "isNameFirst": false, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "1": { "kind": "JSDocParameterTag", @@ -70,8 +69,7 @@ "escapedText": "name2" }, "isNameFirst": false, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "length": 2, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typeTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typeTag.json index 934de3d8faf..a21f9f81c44 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typeTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typeTag.json @@ -27,8 +27,7 @@ "pos": 15, "end": 21 } - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json index 08d270286b9..a4a69fc48a6 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json @@ -104,8 +104,7 @@ "isBracketed": false } ] - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/jsDocTags.baseline b/tests/baselines/reference/jsDocTags.baseline index 7f9e9fdce98..f316a9c4245 100644 --- a/tests/baselines/reference/jsDocTags.baseline +++ b/tests/baselines/reference/jsDocTags.baseline @@ -268,8 +268,7 @@ "documentation": [], "tags": [ { - "name": "mytag", - "text": "" + "name": "mytag" } ] } @@ -446,8 +445,7 @@ "text": "Another value" }, { - "name": "mytag", - "text": "" + "name": "mytag" } ] } @@ -580,12 +578,10 @@ "text": "here all the comments are on a new line" }, { - "name": "mytag3", - "text": "" + "name": "mytag3" }, { - "name": "mytag", - "text": "" + "name": "mytag" } ] } @@ -655,8 +651,7 @@ "documentation": [], "tags": [ { - "name": "mytag", - "text": "" + "name": "mytag" } ] } diff --git a/tests/baselines/reference/jsDocTypeTag1.js b/tests/baselines/reference/jsDocTypeTag1.js index 75333c69364..657ff5031a2 100644 --- a/tests/baselines/reference/jsDocTypeTag1.js +++ b/tests/baselines/reference/jsDocTypeTag1.js @@ -41,7 +41,7 @@ "tags": [ { "name": "type", - "text": "{String} " + "text": "{String}" } ] } @@ -88,7 +88,7 @@ "tags": [ { "name": "type", - "text": "{Number} " + "text": "{Number}" } ] } @@ -135,7 +135,7 @@ "tags": [ { "name": "type", - "text": "{Boolean} " + "text": "{Boolean}" } ] } @@ -182,7 +182,7 @@ "tags": [ { "name": "type", - "text": "{Void} " + "text": "{Void}" } ] } @@ -229,7 +229,7 @@ "tags": [ { "name": "type", - "text": "{Undefined} " + "text": "{Undefined}" } ] } @@ -276,7 +276,7 @@ "tags": [ { "name": "type", - "text": "{Null} " + "text": "{Null}" } ] } @@ -331,7 +331,7 @@ "tags": [ { "name": "type", - "text": "{Array} " + "text": "{Array}" } ] } @@ -390,7 +390,7 @@ "tags": [ { "name": "type", - "text": "{Promise} " + "text": "{Promise}" } ] } @@ -437,7 +437,7 @@ "tags": [ { "name": "type", - "text": "{Object} " + "text": "{Object}" } ] } @@ -484,7 +484,7 @@ "tags": [ { "name": "type", - "text": "{Function} " + "text": "{Function}" } ] } @@ -531,7 +531,7 @@ "tags": [ { "name": "type", - "text": "{*} " + "text": "{*}" } ] } @@ -578,7 +578,7 @@ "tags": [ { "name": "type", - "text": "{?} " + "text": "{?}" } ] } @@ -641,7 +641,7 @@ "tags": [ { "name": "type", - "text": "{String|Number} " + "text": "{String|Number}" } ] } diff --git a/tests/baselines/reference/jsDocTypeTag2.js b/tests/baselines/reference/jsDocTypeTag2.js index 01032a5cc09..9933360b009 100644 --- a/tests/baselines/reference/jsDocTypeTag2.js +++ b/tests/baselines/reference/jsDocTypeTag2.js @@ -41,7 +41,7 @@ "tags": [ { "name": "type", - "text": "{string} " + "text": "{string}" } ] } @@ -88,7 +88,7 @@ "tags": [ { "name": "type", - "text": "{number} " + "text": "{number}" } ] } @@ -135,7 +135,7 @@ "tags": [ { "name": "type", - "text": "{boolean} " + "text": "{boolean}" } ] } @@ -182,7 +182,7 @@ "tags": [ { "name": "type", - "text": "{void} " + "text": "{void}" } ] } @@ -229,7 +229,7 @@ "tags": [ { "name": "type", - "text": "{undefined} " + "text": "{undefined}" } ] } @@ -276,7 +276,7 @@ "tags": [ { "name": "type", - "text": "{null} " + "text": "{null}" } ] } @@ -331,7 +331,7 @@ "tags": [ { "name": "type", - "text": "{array} " + "text": "{array}" } ] } @@ -390,7 +390,7 @@ "tags": [ { "name": "type", - "text": "{promise} " + "text": "{promise}" } ] } @@ -437,7 +437,7 @@ "tags": [ { "name": "type", - "text": "{?number} " + "text": "{?number}" } ] } @@ -484,7 +484,7 @@ "tags": [ { "name": "type", - "text": "{function} " + "text": "{function}" } ] } @@ -567,7 +567,7 @@ "tags": [ { "name": "type", - "text": "{function (number): number} " + "text": "{function (number): number}" } ] } @@ -630,7 +630,7 @@ "tags": [ { "name": "type", - "text": "{string | number} " + "text": "{string | number}" } ] } diff --git a/tests/baselines/reference/jsDocTypedef1.js b/tests/baselines/reference/jsDocTypedef1.js index 96a86a4f7a8..e1b34f14c2b 100644 --- a/tests/baselines/reference/jsDocTypedef1.js +++ b/tests/baselines/reference/jsDocTypedef1.js @@ -181,7 +181,7 @@ "tags": [ { "name": "param", - "text": "opts " + "text": "opts" } ] } diff --git a/tests/baselines/reference/quickInfoJsDocTags.baseline b/tests/baselines/reference/quickInfoJsDocTags.baseline index ba225209760..56f190b4446 100644 --- a/tests/baselines/reference/quickInfoJsDocTags.baseline +++ b/tests/baselines/reference/quickInfoJsDocTags.baseline @@ -63,7 +63,7 @@ ], "documentation": [ { - "text": "Doc{T} A template", + "text": "DocT} A template", "kind": "text" } ], @@ -82,7 +82,7 @@ }, { "name": "typedef", - "text": "NumOrStr " + "text": "NumOrStr" }, { "name": "property", diff --git a/tests/cases/fourslash/jsDocTags.ts b/tests/cases/fourslash/jsDocTags.ts index 368939ecbfc..14ac14e6331 100644 --- a/tests/cases/fourslash/jsDocTags.ts +++ b/tests/cases/fourslash/jsDocTags.ts @@ -67,7 +67,7 @@ verify.currentSignatureHelpTagsAre([{name: "myjsdoctag", text:"this is a comment goTo.marker("11"); verify.currentSignatureHelpTagsAre([{name: "mytag", text:"comment1 comment2"}]) goTo.marker("12"); -verify.currentSignatureHelpTagsAre([{name: "mytag", text:""}]) +verify.currentSignatureHelpTagsAre([{name: "mytag"}]) goTo.marker("13"); verify.currentSignatureHelpTagsAre([{ name: "returns", text: "a value" }]) diff --git a/tests/cases/fourslash/quickInfoPropertyTag.ts b/tests/cases/fourslash/quickInfoPropertyTag.ts new file mode 100644 index 00000000000..b413a7610e1 --- /dev/null +++ b/tests/cases/fourslash/quickInfoPropertyTag.ts @@ -0,0 +1,16 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////** +//// * @typedef I +//// * @property {number} x Doc +//// * More doc +//// */ +//// +/////** @type {I} */ +////const obj = { /**/x: 10 }; + +// TODO: GH#21123 There shouldn't be a " " before "More doc" +verify.quickInfoAt("", "(property) x: number", "Doc\n More doc"); From c5ed8646e18e22c4323c474cb690bc42dee9c39c Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 11 Jan 2018 12:33:38 -0800 Subject: [PATCH 155/189] Add test where emit of the file results in invalidating resolution and hence invoking recompile --- src/compiler/watch.ts | 4 ++++ src/harness/unittests/tscWatchMode.ts | 33 ++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index b4ed1c1ac1b..ccbf169c3a2 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -20,6 +20,9 @@ namespace ts { // Callbacks to do custom action before creating program and after creating program beforeCompile(compilerOptions: CompilerOptions): void; afterCompile(host: DirectoryStructureHost, program: Program, builder: Builder): void; + + // Only for testing + maxNumberOfFilesToIterateForInvalidation?: number; } const defaultFormatDiagnosticsHost: FormatDiagnosticsHost = sys ? { @@ -301,6 +304,7 @@ namespace ts { hasChangedAutomaticTypeDirectiveNames = true; scheduleProgramUpdate(); }, + maxNumberOfFilesToIterateForInvalidation: watchingHost.maxNumberOfFilesToIterateForInvalidation, writeLog }; // Cache for the module resolution diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index 758a55b8f95..096778300e1 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -30,8 +30,9 @@ namespace ts.tscWatch { return ts.parseConfigFile(configFileName, {}, watchingSystemHost.system, watchingSystemHost.reportDiagnostic, watchingSystemHost.reportWatchDiagnostic); } - function createWatchModeWithConfigFile(configFilePath: string, host: WatchedSystem) { + function createWatchModeWithConfigFile(configFilePath: string, host: WatchedSystem, maxNumberOfFilesToIterateForInvalidation?: number) { const watchingSystemHost = createWatchingSystemHost(host); + watchingSystemHost.maxNumberOfFilesToIterateForInvalidation = maxNumberOfFilesToIterateForInvalidation; const configFileResult = parseConfigFile(configFilePath, watchingSystemHost); return ts.createWatchModeWithConfigFile(configFileResult, {}, watchingSystemHost); } @@ -1067,6 +1068,36 @@ namespace ts.tscWatch { assert.equal(nowErrors[0].start, intialErrors[0].start - configFileContentComment.length); assert.equal(nowErrors[1].start, intialErrors[1].start - configFileContentComment.length); }); + + it("should not trigger recompilation because of program emit", () => { + const proj = "/user/username/projects/myproject"; + const file1: FileOrFolder = { + path: `${proj}/file1.ts`, + content: "export const c = 30;" + }; + const file2: FileOrFolder = { + path: `${proj}/src/file2.ts`, + content: `import {c} from "file1"; export const d = 30;` + }; + const tsconfig: FileOrFolder = { + path: `${proj}/tsconfig.json`, + content: JSON.stringify({ + compilerOptions: { + module: "amd", + outDir: "build" + } + }) + }; + const host = createWatchedSystem([file1, file2, libFile, tsconfig], { currentDirectory: proj }); + const watch = createWatchModeWithConfigFile(tsconfig.path, host, /*maxNumberOfFilesToIterateForInvalidation*/1); + checkProgramActualFiles(watch(), [file1.path, file2.path, libFile.path]); + + assert.isTrue(host.fileExists("build/file1.js")); + assert.isTrue(host.fileExists("build/src/file2.js")); + + // This should be 0 + host.checkTimeoutQueueLengthAndRun(1); + }); }); describe("tsc-watch emit with outFile or out setting", () => { From 69bb5ea8f06348c8068b65b81679633d7a0ee297 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 11 Jan 2018 11:52:46 -0800 Subject: [PATCH 156/189] Do not trigger the failed lookup location invalidation for creation of program emit files Handles #20934 --- src/compiler/emitter.ts | 14 ++++++++++---- src/compiler/program.ts | 17 ++++++++++++++++- src/compiler/resolutionCache.ts | 6 ++++++ src/compiler/types.ts | 2 ++ src/compiler/watch.ts | 7 ++++++- src/compiler/watchUtilities.ts | 8 ++++++++ src/harness/unittests/tscWatchMode.ts | 2 +- src/server/project.ts | 5 ++++- 8 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 909dd0feede..aee8c98db0d 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -18,8 +18,8 @@ namespace ts { * If an array, the full list of source files to emit. * Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit. */ - export function forEachEmittedFile( - host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => void, + export function forEachEmittedFile( + host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => T, sourceFilesOrTargetSourceFile?: SourceFile[] | SourceFile, emitOnlyDtsFiles?: boolean) { @@ -30,7 +30,10 @@ namespace ts { const jsFilePath = options.outFile || options.out; const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + Extension.Dts : ""; - action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles); + const result = action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles); + if (result) { + return result; + } } } else { @@ -38,7 +41,10 @@ namespace ts { const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options)); const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined; - action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles); + const result = action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles); + if (result) { + return result; + } } } } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 88a2f5ee8f1..0d1bbf233a3 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -667,7 +667,8 @@ namespace ts { dropDiagnosticsProducingTypeChecker, getSourceFileFromReference, sourceFileToPackageName, - redirectTargetsSet + redirectTargetsSet, + isEmittedFile }; verifyCompilerOptions(); @@ -2343,6 +2344,20 @@ namespace ts { hasEmitBlockingDiagnostics.set(toPath(emitFileName), true); programDiagnostics.add(diag); } + + function isEmittedFile(file: string) { + if (options.noEmit) { + return false; + } + + return forEachEmittedFile(getEmitHost(), ({ jsFilePath, declarationFilePath }) => + isSameFile(jsFilePath, file) || + (declarationFilePath && isSameFile(declarationFilePath, file))); + } + + function isSameFile(file1: string, file2: string) { + return comparePaths(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === Comparison.EqualTo; + } } /* @internal */ diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index e21e81a2e88..aac25c5d596 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -52,6 +52,7 @@ namespace ts { getGlobalCache?(): string | undefined; writeLog(s: string): void; maxNumberOfFilesToIterateForInvalidation?: number; + getCurrentProgram(): Program; } interface DirectoryWatchesOfFailedLookup { @@ -472,6 +473,11 @@ namespace ts { resolutionHost.getCachedDirectoryStructureHost().addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath); } + // Ignore emits from the program + if (isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectory)) { + return; + } + // If the files are added to project root or node_modules directory, always run through the invalidation process // Otherwise run through invalidation only if adding to the immediate directory if (!allFilesHaveInvalidatedResolution && diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 23798635671..e4ada136730 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2659,6 +2659,8 @@ namespace ts { /* @internal */ sourceFileToPackageName: Map; /** Set of all source files that some other source file redirects to. */ /* @internal */ redirectTargetsSet: Map; + /** Is the file emitted file */ + /* @internal */ isEmittedFile(file: string): boolean; } /* @internal */ diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index ccbf169c3a2..79e26f5986c 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -305,6 +305,7 @@ namespace ts { scheduleProgramUpdate(); }, maxNumberOfFilesToIterateForInvalidation: watchingHost.maxNumberOfFilesToIterateForInvalidation, + getCurrentProgram, writeLog }; // Cache for the module resolution @@ -322,7 +323,11 @@ namespace ts { // Update the wild card directory watch watchConfigFileWildCardDirectories(); - return () => program; + return getCurrentProgram; + + function getCurrentProgram() { + return program; + } function synchronizeProgram() { writeLog(`Synchronizing program`); diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index 0cf38f372d9..0bc6920479b 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -82,6 +82,14 @@ namespace ts { } } + export function isEmittedFileOfProgram(program: Program | undefined, file: string) { + if (!program) { + return false; + } + + return program.isEmittedFile(file); + } + export function addFileWatcher(host: System, file: string, cb: FileWatcherCallback): FileWatcher { return host.watchFile(file, cb); } diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index 096778300e1..9e01021155c 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -1096,7 +1096,7 @@ namespace ts.tscWatch { assert.isTrue(host.fileExists("build/src/file2.js")); // This should be 0 - host.checkTimeoutQueueLengthAndRun(1); + host.checkTimeoutQueueLengthAndRun(0); }); }); diff --git a/src/server/project.ts b/src/server/project.ts index ebc93ae3e1e..a25e6870bda 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -830,7 +830,10 @@ namespace ts.server { return !hasChanges; } - + /* @internal */ + getCurrentProgram() { + return this.program; + } protected removeExistingTypings(include: string[]): string[] { const existing = ts.getAutomaticTypeDirectiveNames(this.getCompilerOptions(), this.directoryStructureHost); From 269867f5e83004b0ef1e7a54290dfc1bc1c75d5d Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 11 Jan 2018 13:42:08 -0800 Subject: [PATCH 157/189] Fix bug: get merged symbol of symbol.parent before checking against module symbol (#21147) --- src/services/completions.ts | 2 +- ...port_named_exportEqualsNamespace_merged.ts | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/completionsImport_named_exportEqualsNamespace_merged.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index bdd5e4a86a2..ac1eb8f6a46 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1200,7 +1200,7 @@ namespace ts.Completions { // Don't add a completion for a re-export, only for the original. // If `symbol.parent !== ...`, this comes from an `export * from "foo"` re-export. Those don't create new symbols. // If `some(...)`, this comes from an `export { foo } from "foo"` re-export, which creates a new symbol (thus isn't caught by the first check). - if (symbol.parent !== typeChecker.resolveExternalModuleSymbol(moduleSymbol) + if (typeChecker.getMergedSymbol(symbol.parent) !== typeChecker.resolveExternalModuleSymbol(moduleSymbol) || some(symbol.declarations, d => isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier)) { continue; } diff --git a/tests/cases/fourslash/completionsImport_named_exportEqualsNamespace_merged.ts b/tests/cases/fourslash/completionsImport_named_exportEqualsNamespace_merged.ts new file mode 100644 index 00000000000..55b33c22114 --- /dev/null +++ b/tests/cases/fourslash/completionsImport_named_exportEqualsNamespace_merged.ts @@ -0,0 +1,21 @@ +/// + +// @Filename: /b.d.ts +////declare namespace N { +//// export const foo: number; +////} +////declare module "n" { +//// export = N; +////} + +// @Filename: /c.d.ts +////declare namespace N {} + +// @Filename: /a.ts +////fo/**/ + +goTo.marker(""); +verify.completionListContains({ name: "foo", source: "n" }, "const N.foo: number", "", "const", undefined, /*hasAction*/ true, { + includeExternalModuleExports: true, + sourceDisplay: "n", +}); From c75f328697f9a7357c7993d75481c8a1b8db38e1 Mon Sep 17 00:00:00 2001 From: csigs Date: Thu, 11 Jan 2018 23:10:17 +0000 Subject: [PATCH 158/189] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 118 +++++++++++++++++- .../diagnosticMessages.generated.json.lcl | 118 +++++++++++++++++- 2 files changed, 232 insertions(+), 4 deletions(-) diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 30850814f26..66702cf999d 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -483,6 +483,15 @@ + + + + + + + + + @@ -885,6 +894,12 @@ + + + + + + @@ -1290,6 +1305,24 @@ + + + + + + + + + + + + + + + + + + @@ -1839,6 +1872,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2307,6 +2367,15 @@ + + + + + + + + + @@ -2904,6 +2973,15 @@ + + + + + + + + + @@ -4548,6 +4626,12 @@ + + + + + + @@ -5583,6 +5667,15 @@ + + + + + + + + + @@ -5940,6 +6033,15 @@ + + + + + + + + + @@ -8004,6 +8106,15 @@ + + + + + + + + + @@ -8507,10 +8618,13 @@ - + - + + + + diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 76488c39e76..2ac1ab23150 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -474,6 +474,15 @@ + + + + + + + + + @@ -876,6 +885,12 @@ + + + + + + @@ -1281,6 +1296,24 @@ + + + + + + + + + + + + + + + + + + @@ -1830,6 +1863,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2298,6 +2358,15 @@ + + + + + + + + + @@ -2895,6 +2964,15 @@ + + + + + + + + + @@ -4539,6 +4617,12 @@ + + + + + + @@ -5574,6 +5658,15 @@ + + + + + + + + + @@ -5931,6 +6024,15 @@ + + + + + + + + + @@ -7995,6 +8097,15 @@ + + + + + + + + + @@ -8498,10 +8609,13 @@ - + - + + + + From 1ae0b461f88e9a68c2b2ad51519611a2cc292fec Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 11 Jan 2018 16:14:19 -0800 Subject: [PATCH 159/189] Use contra-variant inferences when co-variant inferences yield 'never' --- src/compiler/checker.ts | 50 ++++++++++++++++++++++++++--------------- src/compiler/types.ts | 21 +++++++++-------- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fd6a033653a..665b61be66b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11344,6 +11344,7 @@ namespace ts { return { typeParameter, candidates: undefined, + contraCandidates: undefined, inferredType: undefined, priority: undefined, topLevel: true, @@ -11355,6 +11356,7 @@ namespace ts { return { typeParameter: inference.typeParameter, candidates: inference.candidates && inference.candidates.slice(), + contraCandidates: inference.contraCandidates && inference.contraCandidates.slice(), inferredType: inference.inferredType, priority: inference.priority, topLevel: inference.topLevel, @@ -11468,6 +11470,7 @@ namespace ts { function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) { let symbolStack: Symbol[]; let visited: Map; + let contravariant = false; inferFromTypes(originalSource, originalTarget); function inferFromTypes(source: Type, target: Type) { @@ -11535,18 +11538,20 @@ namespace ts { const inference = getInferenceInfoForType(target); if (inference) { if (!inference.isFixed) { - // We give lowest priority to inferences of implicitNeverType (which is used as the - // element type for empty array literals). Thus, inferences from empty array literals - // only matter when no other inferences are made. - const p = priority | (source === implicitNeverType ? InferencePriority.NeverType : 0); - if (!inference.candidates || p < inference.priority) { - inference.candidates = [source]; - inference.priority = p; + if (inference.priority === undefined || priority < inference.priority) { + inference.candidates = undefined; + inference.contraCandidates = undefined; + inference.priority = priority; } - else if (p === inference.priority) { - inference.candidates.push(source); + if (priority === inference.priority) { + if (contravariant) { + inference.contraCandidates = append(inference.contraCandidates, source); + } + else { + inference.candidates = append(inference.candidates, source); + } } - if (!(p & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, target)) { + if (!(priority & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, target)) { inference.topLevel = false; } } @@ -11569,15 +11574,15 @@ namespace ts { } } else if (source.flags & TypeFlags.Index && target.flags & TypeFlags.Index) { - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; inferFromTypes((source).type, (target).type); - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; } else if ((isLiteralType(source) || source.flags & TypeFlags.String) && target.flags & TypeFlags.Index) { const empty = createEmptyObjectTypeFromStringLiteral(source); - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; inferFromTypes(empty, (target as IndexType).type); - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; } else if (source.flags & TypeFlags.IndexedAccess && target.flags & TypeFlags.IndexedAccess) { inferFromTypes((source).objectType, (target).objectType); @@ -11646,9 +11651,9 @@ namespace ts { function inferFromContravariantTypes(source: Type, target: Type) { if (strictFunctionTypes) { - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; inferFromTypes(source, target); - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; } else { inferFromTypes(source, target); @@ -11827,10 +11832,19 @@ namespace ts { // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if // union types were requested or if all inferences were made from the return type position, infer a // union type. Otherwise, infer a common supertype. - const unwidenedType = inference.priority & InferencePriority.Contravariant ? getCommonSubtype(baseCandidates) : - context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ? getUnionType(baseCandidates, UnionReduction.Subtype) : + const unwidenedType = context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ? + getUnionType(baseCandidates, UnionReduction.Subtype) : getCommonSupertype(baseCandidates); inferredType = getWidenedType(unwidenedType); + // If we have inferred 'never' but have contravariant candidates. To get a more specific type we + // infer from the contravariant candidates instead. + if (inferredType.flags & TypeFlags.Never && inference.contraCandidates) { + inferredType = getCommonSubtype(inference.contraCandidates); + } + } + else if (inference.contraCandidates) { + // We only have contravariant inferences, infer the best common subtype of those + inferredType = getCommonSubtype(inference.contraCandidates); } else if (context.flags & InferenceFlags.NoDefault) { // We use silentNeverType as the wildcard that signals no inferences. diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 23798635671..7c9a7da69e6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3772,20 +3772,19 @@ namespace ts { export type TypeMapper = (t: TypeParameter) => Type; export const enum InferencePriority { - Contravariant = 1 << 0, // Inference from contravariant position - NakedTypeVariable = 1 << 1, // Naked type variable in union or intersection type - MappedType = 1 << 2, // Reverse inference for mapped type - ReturnType = 1 << 3, // Inference made from return type of generic function - NeverType = 1 << 4, // Inference made from the never type + NakedTypeVariable = 1 << 0, // Naked type variable in union or intersection type + MappedType = 1 << 1, // Reverse inference for mapped type + ReturnType = 1 << 2, // Inference made from return type of generic function } export interface InferenceInfo { - typeParameter: TypeParameter; - candidates: Type[]; - inferredType: Type; - priority: InferencePriority; - topLevel: boolean; - isFixed: boolean; + typeParameter: TypeParameter; // Type parameter for which inferences are being made + candidates: Type[]; // Candidates in covariant positions (or undefined) + contraCandidates: Type[]; // Candidates in contravariant positions (or undefined) + inferredType: Type; // Cache for resolved inferred type + priority: InferencePriority; // Priority of current inference set + topLevel: boolean; // True if all inferences are to top level occurrences + isFixed: boolean; // True if inferences are fixed } export const enum InferenceFlags { From 6b882c7b39c061bbd2e250508f0b58320c699244 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 11 Jan 2018 16:14:45 -0800 Subject: [PATCH 160/189] Accept new baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 9 ++++----- tests/baselines/reference/api/typescript.d.ts | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 3eabea4435a..1aac7c893c5 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2149,15 +2149,14 @@ declare namespace ts { declaration?: SignatureDeclaration; } enum InferencePriority { - Contravariant = 1, - NakedTypeVariable = 2, - MappedType = 4, - ReturnType = 8, - NeverType = 16, + NakedTypeVariable = 1, + MappedType = 2, + ReturnType = 4, } interface InferenceInfo { typeParameter: TypeParameter; candidates: Type[]; + contraCandidates: Type[]; inferredType: Type; priority: InferencePriority; topLevel: boolean; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 630b7a08a28..3bf033798f9 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2149,15 +2149,14 @@ declare namespace ts { declaration?: SignatureDeclaration; } enum InferencePriority { - Contravariant = 1, - NakedTypeVariable = 2, - MappedType = 4, - ReturnType = 8, - NeverType = 16, + NakedTypeVariable = 1, + MappedType = 2, + ReturnType = 4, } interface InferenceInfo { typeParameter: TypeParameter; candidates: Type[]; + contraCandidates: Type[]; inferredType: Type; priority: InferencePriority; topLevel: boolean; From 12b80f3183cd97aacf448c29d609aa4b56be260c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 11 Jan 2018 16:26:38 -0800 Subject: [PATCH 161/189] Keep string index from intersections in base constraint of index type --- src/compiler/checker.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d402f344d60..a32104c0535 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6468,7 +6468,7 @@ namespace ts { } function getConstraintOfIndexedAccess(type: IndexedAccessType) { - const transformed = getSimplifiedIndexedAccessType(type); + const transformed = getSubstitutedIndexedMappedType(type); if (transformed) { return transformed; } @@ -8383,6 +8383,11 @@ namespace ts { getIntersectionType(stringIndexTypes) ]); } + return getSubstitutedIndexedMappedType(type); + } + + function getSubstitutedIndexedMappedType(type: IndexedAccessType): Type { + const objectType = type.objectType; // 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. From baf31ec52e500bd646090f62fcb4b6112bb09645 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 11 Jan 2018 16:30:05 -0800 Subject: [PATCH 162/189] Test Diff and Omit --- .../indexedAccessRetainsIndexSignature.js | 10 ++++++ ...indexedAccessRetainsIndexSignature.symbols | 33 +++++++++++++++++++ .../indexedAccessRetainsIndexSignature.types | 33 +++++++++++++++++++ .../indexedAccessRetainsIndexSignature.ts | 6 ++++ 4 files changed, 82 insertions(+) create mode 100644 tests/baselines/reference/indexedAccessRetainsIndexSignature.js create mode 100644 tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols create mode 100644 tests/baselines/reference/indexedAccessRetainsIndexSignature.types create mode 100644 tests/cases/compiler/indexedAccessRetainsIndexSignature.ts diff --git a/tests/baselines/reference/indexedAccessRetainsIndexSignature.js b/tests/baselines/reference/indexedAccessRetainsIndexSignature.js new file mode 100644 index 00000000000..6c33317f156 --- /dev/null +++ b/tests/baselines/reference/indexedAccessRetainsIndexSignature.js @@ -0,0 +1,10 @@ +//// [indexedAccessRetainsIndexSignature.ts] +type Diff = + ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T] +type Omit = Pick> + + +type O = Omit<{ a: number, b: string }, 'a'> + + +//// [indexedAccessRetainsIndexSignature.js] diff --git a/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols b/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols new file mode 100644 index 00000000000..908d74c9452 --- /dev/null +++ b/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols @@ -0,0 +1,33 @@ +=== tests/cases/compiler/indexedAccessRetainsIndexSignature.ts === +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)) + + ({ [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)) +>x : Symbol(x, Decl(indexedAccessRetainsIndexSignature.ts, 1, 48)) +>T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 0, 10)) + +type Omit = Pick> +>Omit : Symbol(Omit, Decl(indexedAccessRetainsIndexSignature.ts, 1, 71)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 2, 10)) +>K : Symbol(K, Decl(indexedAccessRetainsIndexSignature.ts, 2, 12)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 2, 10)) +>Pick : Symbol(Pick, Decl(lib.d.ts, --, --)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 2, 10)) +>Diff : Symbol(Diff, Decl(indexedAccessRetainsIndexSignature.ts, 0, 0)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 2, 10)) +>K : Symbol(K, Decl(indexedAccessRetainsIndexSignature.ts, 2, 12)) + + +type O = Omit<{ a: number, b: string }, 'a'> +>O : Symbol(O, Decl(indexedAccessRetainsIndexSignature.ts, 2, 59)) +>Omit : Symbol(Omit, Decl(indexedAccessRetainsIndexSignature.ts, 1, 71)) +>a : Symbol(a, Decl(indexedAccessRetainsIndexSignature.ts, 5, 15)) +>b : Symbol(b, Decl(indexedAccessRetainsIndexSignature.ts, 5, 26)) + diff --git a/tests/baselines/reference/indexedAccessRetainsIndexSignature.types b/tests/baselines/reference/indexedAccessRetainsIndexSignature.types new file mode 100644 index 00000000000..8ef6cb62559 --- /dev/null +++ b/tests/baselines/reference/indexedAccessRetainsIndexSignature.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/indexedAccessRetainsIndexSignature.ts === +type Diff = +>Diff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T] +>T : T +>U : U + + ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T] +>P : P +>T : T +>P : P +>P : P +>U : U +>x : string +>T : T + +type Omit = Pick> +>Omit : Pick +>U : U +>K : K +>U : U +>Pick : Pick +>U : U +>Diff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T] +>U : U +>K : K + + +type O = Omit<{ a: number, b: string }, 'a'> +>O : Pick<{ a: number; b: string; }, "b"> +>Omit : Pick +>a : number +>b : string + diff --git a/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts b/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts new file mode 100644 index 00000000000..ff38b2d9090 --- /dev/null +++ b/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts @@ -0,0 +1,6 @@ +type Diff = + ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T] +type Omit = Pick> + + +type O = Omit<{ a: number, b: string }, 'a'> From 13bf022ef67cb0f5a6a73d2a9a3aa2867305c7f7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 11 Jan 2018 16:45:44 -0800 Subject: [PATCH 163/189] Add regression tests --- tests/cases/compiler/strictFunctionTypes1.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/cases/compiler/strictFunctionTypes1.ts b/tests/cases/compiler/strictFunctionTypes1.ts index 6c07bc51ffe..ad8836fcf05 100644 --- a/tests/cases/compiler/strictFunctionTypes1.ts +++ b/tests/cases/compiler/strictFunctionTypes1.ts @@ -17,3 +17,13 @@ const x1 = f1(fo, fs); // (x: string) => void const x2 = f2("abc", fo, fs); // "abc" const x3 = f3("abc", fo, fx); // "abc" | "def" const x4 = f4(fo, fs); // Func + +declare const never: never; + +const x10 = f2(never, fo, fs); // string +const x11 = f3(never, fo, fx); // "def" + +// Repro from #21112 + +declare function foo(a: ReadonlyArray): T; +let x = foo([]); // never From b6b936f2df617872e2ef9ee9f7346ef88e8f5792 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 11 Jan 2018 16:45:54 -0800 Subject: [PATCH 164/189] Accept new baselines --- .../reference/strictFunctionTypes1.js | 18 ++++++++++ .../reference/strictFunctionTypes1.symbols | 31 ++++++++++++++++ .../reference/strictFunctionTypes1.types | 35 +++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/tests/baselines/reference/strictFunctionTypes1.js b/tests/baselines/reference/strictFunctionTypes1.js index e802c443561..94ee06f88f8 100644 --- a/tests/baselines/reference/strictFunctionTypes1.js +++ b/tests/baselines/reference/strictFunctionTypes1.js @@ -15,6 +15,16 @@ const x1 = f1(fo, fs); // (x: string) => void const x2 = f2("abc", fo, fs); // "abc" const x3 = f3("abc", fo, fx); // "abc" | "def" const x4 = f4(fo, fs); // Func + +declare const never: never; + +const x10 = f2(never, fo, fs); // string +const x11 = f3(never, fo, fx); // "def" + +// Repro from #21112 + +declare function foo(a: ReadonlyArray): T; +let x = foo([]); // never //// [strictFunctionTypes1.js] @@ -23,6 +33,9 @@ var x1 = f1(fo, fs); // (x: string) => void var x2 = f2("abc", fo, fs); // "abc" var x3 = f3("abc", fo, fx); // "abc" | "def" var x4 = f4(fo, fs); // Func +var x10 = f2(never, fo, fs); // string +var x11 = f3(never, fo, fx); // "def" +var x = foo([]); // never //// [strictFunctionTypes1.d.ts] @@ -40,3 +53,8 @@ declare const x1: (x: string) => void; declare const x2 = "abc"; declare const x3: string; declare const x4: Func; +declare const never: never; +declare const x10: string; +declare const x11: "def"; +declare function foo(a: ReadonlyArray): T; +declare let x: never; diff --git a/tests/baselines/reference/strictFunctionTypes1.symbols b/tests/baselines/reference/strictFunctionTypes1.symbols index 70253411201..715ea287734 100644 --- a/tests/baselines/reference/strictFunctionTypes1.symbols +++ b/tests/baselines/reference/strictFunctionTypes1.symbols @@ -94,3 +94,34 @@ const x4 = f4(fo, fs); // Func >fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) >fs : Symbol(fs, Decl(strictFunctionTypes1.ts, 8, 37)) +declare const never: never; +>never : Symbol(never, Decl(strictFunctionTypes1.ts, 17, 13)) + +const x10 = f2(never, fo, fs); // string +>x10 : Symbol(x10, Decl(strictFunctionTypes1.ts, 19, 5)) +>f2 : Symbol(f2, Decl(strictFunctionTypes1.ts, 0, 79)) +>never : Symbol(never, Decl(strictFunctionTypes1.ts, 17, 13)) +>fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) +>fs : Symbol(fs, Decl(strictFunctionTypes1.ts, 8, 37)) + +const x11 = f3(never, fo, fx); // "def" +>x11 : Symbol(x11, Decl(strictFunctionTypes1.ts, 20, 5)) +>f3 : Symbol(f3, Decl(strictFunctionTypes1.ts, 1, 74)) +>never : Symbol(never, Decl(strictFunctionTypes1.ts, 17, 13)) +>fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) +>fx : Symbol(fx, Decl(strictFunctionTypes1.ts, 9, 37)) + +// Repro from #21112 + +declare function foo(a: ReadonlyArray): T; +>foo : Symbol(foo, Decl(strictFunctionTypes1.ts, 20, 30)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 24, 21)) +>a : Symbol(a, Decl(strictFunctionTypes1.ts, 24, 24)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 24, 21)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 24, 21)) + +let x = foo([]); // never +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 25, 3)) +>foo : Symbol(foo, Decl(strictFunctionTypes1.ts, 20, 30)) + diff --git a/tests/baselines/reference/strictFunctionTypes1.types b/tests/baselines/reference/strictFunctionTypes1.types index 9701d78cff0..b915e0b5f6b 100644 --- a/tests/baselines/reference/strictFunctionTypes1.types +++ b/tests/baselines/reference/strictFunctionTypes1.types @@ -100,3 +100,38 @@ const x4 = f4(fo, fs); // Func >fo : (x: Object) => void >fs : (x: string) => void +declare const never: never; +>never : never + +const x10 = f2(never, fo, fs); // string +>x10 : string +>f2(never, fo, fs) : string +>f2 : (obj: T, f1: (x: T) => void, f2: (x: T) => void) => T +>never : never +>fo : (x: Object) => void +>fs : (x: string) => void + +const x11 = f3(never, fo, fx); // "def" +>x11 : "def" +>f3(never, fo, fx) : "def" +>f3 : (obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void) => T +>never : never +>fo : (x: Object) => void +>fx : (f: (x: "def") => void) => void + +// Repro from #21112 + +declare function foo(a: ReadonlyArray): T; +>foo : (a: ReadonlyArray) => T +>T : T +>a : ReadonlyArray +>ReadonlyArray : ReadonlyArray +>T : T +>T : T + +let x = foo([]); // never +>x : never +>foo([]) : never +>foo : (a: ReadonlyArray) => T +>[] : never[] + From d2fd137d882b66a1f1dd73be5fd3570c4654fa85 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 12 Jan 2018 10:44:39 -0800 Subject: [PATCH 165/189] Add a `getFullText()` helper method to `IScriptSnapshot` (#21155) * Add a `getFullText()` helper method to `IScriptSnapshot` * Use a function instead of a method --- src/harness/fourslash.ts | 6 +---- src/harness/harnessLanguageService.ts | 23 +++++-------------- src/harness/unittests/hostNewLineSupport.ts | 23 +++---------------- src/harness/unittests/incrementalParser.ts | 6 ++--- .../unittests/tsserverProjectSystem.ts | 11 ++++----- src/harness/unittests/versionCache.ts | 4 +--- src/server/client.ts | 3 +-- src/server/scriptInfo.ts | 3 +-- src/server/scriptVersionCache.ts | 2 +- src/server/session.ts | 4 +--- src/services/services.ts | 5 ++-- src/services/shims.ts | 6 ++--- src/services/utilities.ts | 4 ++++ 13 files changed, 31 insertions(+), 69 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 8c5570f730c..2e98a95831f 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -170,11 +170,7 @@ namespace FourSlash { // This function creates IScriptSnapshot object for testing getPreProcessedFileInfo // Return object may lack some functionalities for other purposes. function createScriptSnapShot(sourceText: string): ts.IScriptSnapshot { - return { - getText: (start: number, end: number) => sourceText.substr(start, end - start), - getLength: () => sourceText.length, - getChangeRange: () => undefined - }; + return ts.ScriptSnapshot.fromString(sourceText); } export class TestState { diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index d51517c159b..0e142debedc 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -84,7 +84,7 @@ namespace Harness.LanguageService { } class ScriptSnapshotProxy implements ts.ScriptSnapshotShim { - constructor(public scriptSnapshot: ts.IScriptSnapshot) { + constructor(private readonly scriptSnapshot: ts.IScriptSnapshot) { } public getText(start: number, end: number): string { @@ -96,14 +96,8 @@ namespace Harness.LanguageService { } public getChangeRange(oldScript: ts.ScriptSnapshotShim): string { - const oldShim = oldScript; - - const range = this.scriptSnapshot.getChangeRange(oldShim.scriptSnapshot); - if (range === undefined) { - return undefined; - } - - return JSON.stringify({ span: { start: range.span.start, length: range.span.length }, newLength: range.newLength }); + const range = this.scriptSnapshot.getChangeRange((oldScript as ScriptSnapshotProxy).scriptSnapshot); + return range && JSON.stringify(range); } } @@ -236,12 +230,7 @@ namespace Harness.LanguageService { } readFile(path: string): string | undefined { const target = this.symlinks.get(path); - if (target !== undefined) { - return this.readFile(target); - } - - const snapshot = this.getScriptSnapshot(path); - return snapshot.getText(0, snapshot.getLength()); + return target !== undefined ? this.readFile(target) : ts.getSnapshotText(this.getScriptSnapshot(path)); } addSymlink(from: string, target: string) { this.symlinks.set(from, target); } realpath(path: string): string { @@ -350,7 +339,7 @@ namespace Harness.LanguageService { fileExists(fileName: string) { return this.getScriptInfo(fileName) !== undefined; } readFile(fileName: string) { const snapshot = this.nativeHost.getScriptSnapshot(fileName); - return snapshot && snapshot.getText(0, snapshot.getLength()); + return snapshot && ts.getSnapshotText(snapshot); } log(s: string): void { this.nativeHost.log(s); } trace(s: string): void { this.nativeHost.trace(s); } @@ -654,7 +643,7 @@ namespace Harness.LanguageService { } const snapshot = this.host.getScriptSnapshot(fileName); - return snapshot && snapshot.getText(0, snapshot.getLength()); + return snapshot && ts.getSnapshotText(snapshot); } writeFile = ts.noop; diff --git a/src/harness/unittests/hostNewLineSupport.ts b/src/harness/unittests/hostNewLineSupport.ts index 95a05f101f7..e7e5c11e33e 100644 --- a/src/harness/unittests/hostNewLineSupport.ts +++ b/src/harness/unittests/hostNewLineSupport.ts @@ -4,27 +4,10 @@ namespace ts { function testLSWithFiles(settings: CompilerOptions, files: Harness.Compiler.TestFile[]) { function snapFor(path: string): IScriptSnapshot { if (path === "lib.d.ts") { - return { - dispose: noop, - getChangeRange() { return undefined; }, - getLength() { return 0; }, - getText() { - return ""; - } - }; + return ScriptSnapshot.fromString(""); } - const result = forEach(files, f => f.unitName === path ? f : undefined); - if (result) { - return { - dispose: noop, - getChangeRange() { return undefined; }, - getLength() { return result.content.length; }, - getText(start, end) { - return result.content.substring(start, end); - } - }; - } - return undefined; + const result = find(files, f => f.unitName === path); + return result && ScriptSnapshot.fromString(result.content); } const lshost: LanguageServiceHost = { getCompilationSettings: () => settings, diff --git a/src/harness/unittests/incrementalParser.ts b/src/harness/unittests/incrementalParser.ts index c71b89d3da6..cdccce418bc 100644 --- a/src/harness/unittests/incrementalParser.ts +++ b/src/harness/unittests/incrementalParser.ts @@ -5,7 +5,7 @@ namespace ts { ts.disableIncrementalParsing = false; function withChange(text: IScriptSnapshot, start: number, length: number, newText: string): { text: IScriptSnapshot; textChangeRange: TextChangeRange; } { - const contents = text.getText(0, text.getLength()); + const contents = getSnapshotText(text); const newContents = contents.substr(0, start) + newText + contents.substring(start + length); return { text: ScriptSnapshot.fromString(newContents), textChangeRange: createTextChangeRange(createTextSpan(start, length), newText.length) }; @@ -105,7 +105,7 @@ namespace ts { const newTextAndChange = withDelete(oldText, index, 1); const newTree = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1, oldTree).incrementalNewTree; - source = newTextAndChange.text.getText(0, newTextAndChange.text.getLength()); + source = getSnapshotText(newTextAndChange.text); oldTree = newTree; } } @@ -118,7 +118,7 @@ namespace ts { const newTextAndChange = withInsert(oldText, index + i, toInsert.charAt(i)); const newTree = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1, oldTree).incrementalNewTree; - source = newTextAndChange.text.getText(0, newTextAndChange.text.getLength()); + source = getSnapshotText(newTextAndChange.text); oldTree = newTree; } } diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index fe7a2095b86..565c20ac9cd 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -2116,7 +2116,7 @@ namespace ts.projectSystem { const scriptInfo = project.getScriptInfo(file1.path); const snap = scriptInfo.getSnapshot(); - const actualText = snap.getText(0, snap.getLength()); + const actualText = getSnapshotText(snap); assert.equal(actualText, "", `expected content to be empty string, got "${actualText}"`); projectService.openClientFile(file1.path, `var x = 1;`); @@ -2128,8 +2128,7 @@ namespace ts.projectSystem { projectService.closeClientFile(file1.path); const scriptInfo2 = project.getScriptInfo(file1.path); - const snap2 = scriptInfo2.getSnapshot(); - const actualText2 = snap2.getText(0, snap.getLength()); + const actualText2 = getSnapshotText(scriptInfo2.getSnapshot()); assert.equal(actualText2, "", `expected content to be empty string, got "${actualText2}"`); }); @@ -4178,7 +4177,7 @@ namespace ts.projectSystem { // verify content const projectServiice = session.getProjectService(); const snap1 = projectServiice.getScriptInfo(f1.path).getSnapshot(); - assert.equal(snap1.getText(0, snap1.getLength()), tmp.content, "content should be equal to the content of temp file"); + assert.equal(getSnapshotText(snap1), tmp.content, "content should be equal to the content of temp file"); // reload from original file file session.executeCommand({ @@ -4190,7 +4189,7 @@ namespace ts.projectSystem { // verify content const snap2 = projectServiice.getScriptInfo(f1.path).getSnapshot(); - assert.equal(snap2.getText(0, snap2.getLength()), f1.content, "content should be equal to the content of original file"); + assert.equal(getSnapshotText(snap2), f1.content, "content should be equal to the content of original file"); }); @@ -4280,7 +4279,7 @@ namespace ts.projectSystem { function checkScriptInfoContents(contentsOfInfo: string, captionForContents: string) { const snap = info.getSnapshot(); - assert.equal(snap.getText(0, snap.getLength()), contentsOfInfo, "content should be equal to " + captionForContents); + assert.equal(getSnapshotText(snap), contentsOfInfo, "content should be equal to " + captionForContents); } }); }); diff --git a/src/harness/unittests/versionCache.ts b/src/harness/unittests/versionCache.ts index bbd23f25dac..3062a55170c 100644 --- a/src/harness/unittests/versionCache.ts +++ b/src/harness/unittests/versionCache.ts @@ -284,9 +284,7 @@ and grew 1cm per day`; svc.edit(ersa[i], elas[i], insertString); checkText = editFlat(ersa[i], elas[i], insertString, checkText); if (0 === (i % 4)) { - const snap = svc.getSnapshot(); - const snapText = snap.getText(0, checkText.length); - assert.equal(checkText, snapText); + assert.equal(checkText, getSnapshotText(svc.getSnapshot())); } } }); diff --git a/src/server/client.ts b/src/server/client.ts index f34516ac4fd..7a64d9b528c 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -52,8 +52,7 @@ namespace ts.server { private getLineMap(fileName: string): number[] { let lineMap = this.lineMaps.get(fileName); if (!lineMap) { - const scriptSnapshot = this.host.getScriptSnapshot(fileName); - lineMap = computeLineStarts(scriptSnapshot.getText(0, scriptSnapshot.getLength())); + lineMap = computeLineStarts(getSnapshotText(this.host.getScriptSnapshot(fileName))); this.lineMaps.set(fileName, lineMap); } return lineMap; diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index f800a1117d0..6a722b5c3e0 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -370,8 +370,7 @@ namespace ts.server { } saveTo(fileName: string) { - const snap = this.textStorage.getSnapshot(); - this.host.writeFile(fileName, snap.getText(0, snap.getLength())); + this.host.writeFile(fileName, getSnapshotText(this.textStorage.getSnapshot())); } /*@internal*/ diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts index 9650130634e..dccf4d3267b 100644 --- a/src/server/scriptVersionCache.ts +++ b/src/server/scriptVersionCache.ts @@ -371,7 +371,7 @@ namespace ts.server { } getLength() { - return this.index.root.charCount(); + return this.index.getLength(); } getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange { diff --git a/src/server/session.ts b/src/server/session.ts index 693d1651c91..b66bd83c19f 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1534,9 +1534,7 @@ namespace ts.server { let mappedRenameLocation: protocol.Location | undefined; if (renameFilename !== undefined && renameLocation !== undefined) { const renameScriptInfo = project.getScriptInfoForNormalizedPath(toNormalizedPath(renameFilename)); - const snapshot = renameScriptInfo.getSnapshot(); - const oldText = snapshot.getText(0, snapshot.getLength()); - mappedRenameLocation = getLocationInNewDocument(oldText, renameFilename, renameLocation, edits); + mappedRenameLocation = getLocationInNewDocument(getSnapshotText(renameScriptInfo.getSnapshot()), renameFilename, renameLocation, edits); } return { renameLocation: mappedRenameLocation, renameFilename, edits: this.mapTextChangesToCodeEdits(project, edits) }; } diff --git a/src/services/services.ts b/src/services/services.ts index eb5e3ae5743..90e9b64a1df 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1065,8 +1065,7 @@ namespace ts { } export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean, scriptKind?: ScriptKind): SourceFile { - const text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); - const sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents, scriptKind); + const sourceFile = createSourceFile(fileName, getSnapshotText(scriptSnapshot), scriptTarget, setNodeParents, scriptKind); setSourceFileFields(sourceFile, scriptSnapshot, version); return sourceFile; } @@ -1265,7 +1264,7 @@ namespace ts { const path = toPath(fileName, currentDirectory, getCanonicalFileName); const entry = hostCache.getEntryByPath(path); if (entry) { - return isString(entry) ? undefined : entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength()); + return isString(entry) ? undefined : getSnapshotText(entry.scriptSnapshot); } return host.readFile && host.readFile(fileName); }, diff --git a/src/services/shims.ts b/src/services/shims.ts index fda698785b3..30a836a113f 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -1083,7 +1083,7 @@ namespace ts { `getPreProcessedFileInfo('${fileName}')`, () => { // for now treat files as JavaScript - const result = preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()), /* readImportFiles */ true, /* detectJavaScriptImports */ true); + const result = preProcessFile(getSnapshotText(sourceTextSnapshot), /* readImportFiles */ true, /* detectJavaScriptImports */ true); return { referencedFiles: this.convertFileReferences(result.referencedFiles), importedFiles: this.convertFileReferences(result.importedFiles), @@ -1123,9 +1123,7 @@ namespace ts { return this.forwardJSONCall( `getTSConfigFileInfo('${fileName}')`, () => { - const text = sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()); - - const result = parseJsonText(fileName, text); + const result = parseJsonText(fileName, getSnapshotText(sourceTextSnapshot)); const normalizedFileName = normalizeSlashes(fileName); const configFile = parseJsonSourceFileConfigFileContent(result, this.host, getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName); diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 8fe12d29313..9562def31f5 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1107,6 +1107,10 @@ namespace ts { seen.set(key, true); return true; } + + export function getSnapshotText(snap: IScriptSnapshot): string { + return snap.getText(0, snap.getLength()); + } } // Display-part writer helpers From b8acf8d0c461677a96aabe19ea5bd7614c5e9bb3 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 12 Jan 2018 14:25:33 -0800 Subject: [PATCH 166/189] Handle jsconfig.json in fourslash tests (#16484) --- src/harness/fourslash.ts | 24 ++++++++++-------------- src/harness/harness.ts | 7 ++++++- tests/cases/fourslash/jsconfig.ts | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 15 deletions(-) create mode 100644 tests/cases/fourslash/jsconfig.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 2e98a95831f..4c0c72a200f 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -258,13 +258,13 @@ namespace FourSlash { let startResolveFileRef: FourSlashFile; let configFileName: string; - ts.forEach(testData.files, file => { + for (const file of testData.files) { // Create map between fileName and its content for easily looking up when resolveReference flag is specified this.inputFiles.set(file.fileName, file.content); - if (isTsconfig(file)) { + if (isConfig(file)) { const configJson = ts.parseConfigFileTextToJson(file.fileName, file.content); if (configJson.config === undefined) { - throw new Error(`Failed to parse test tsconfig.json: ${configJson.error.messageText}`); + throw new Error(`Failed to parse test ${file.fileName}: ${configJson.error.messageText}`); } // Extend our existing compiler options so that we can also support tsconfig only options @@ -286,7 +286,7 @@ namespace FourSlash { // If entry point for resolving file references is already specified, report duplication error throw new Error("There exists a Fourslash file which has resolveReference flag specified; remove duplicated resolveReference flag"); } - }); + } if (configFileName) { const baseDir = ts.normalizePath(ts.getDirectoryPath(configFileName)); @@ -295,12 +295,7 @@ namespace FourSlash { const configJsonObj = ts.parseConfigFileTextToJson(configFileName, this.inputFiles.get(configFileName)); assert.isTrue(configJsonObj.config !== undefined); - const { options, errors } = ts.parseJsonConfigFileContent(configJsonObj.config, host, baseDir); - - // Extend our existing compiler options so that we can also support tsconfig only options - if (!errors || errors.length === 0) { - compilationOptions = ts.extend(compilationOptions, options); - } + compilationOptions = ts.parseJsonConfigFileContent(configJsonObj.config, host, baseDir, compilationOptions, configFileName).options; } @@ -3401,13 +3396,14 @@ ${code} } // @Filename is the only directive that can be used in a test that contains tsconfig.json file. - if (files.some(isTsconfig)) { + const config = ts.find(files, isConfig); + if (config) { let directive = getNonFileNameOptionInFileList(files); if (!directive) { directive = getNonFileNameOptionInObject(globalOptions); } if (directive) { - throw Error("It is not allowed to use tsconfig.json along with directive '" + directive + "'"); + throw Error(`It is not allowed to use ${config.fileName} along with directive '${directive}'`); } } @@ -3420,8 +3416,8 @@ ${code} }; } - function isTsconfig(file: FourSlashFile): boolean { - return ts.getBaseFileName(file.fileName).toLowerCase() === "tsconfig.json"; + function isConfig(file: FourSlashFile): boolean { + return Harness.getConfigNameFromFileName(file.fileName) !== undefined; } function getNonFileNameOptionInFileList(files: FourSlashFile[]): string { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 612224cb312..f2f8587d834 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1961,7 +1961,7 @@ namespace Harness { let tsConfigFileUnitData: TestUnitData; for (let i = 0; i < testUnitData.length; i++) { const data = testUnitData[i]; - if (ts.getBaseFileName(data.name).toLowerCase() === "tsconfig.json") { + if (getConfigNameFromFileName(data.name)) { const configJson = ts.parseJsonText(data.name, data.content); assert.isTrue(configJson.endOfFileToken !== undefined); let baseDir = ts.normalizePath(ts.getDirectoryPath(data.name)); @@ -2172,5 +2172,10 @@ namespace Harness { return { unitName: libFile, content: io.readFile(libFile) }; } + export function getConfigNameFromFileName(filename: string): "tsconfig.json" | "jsconfig.json" | undefined { + const flc = ts.getBaseFileName(filename).toLowerCase(); + return ts.find(["tsconfig.json" as "tsconfig.json", "jsconfig.json" as "jsconfig.json"], x => x === flc); + } + if (Error) (Error).stackTraceLimit = 100; } diff --git a/tests/cases/fourslash/jsconfig.ts b/tests/cases/fourslash/jsconfig.ts new file mode 100644 index 00000000000..ce09c46b857 --- /dev/null +++ b/tests/cases/fourslash/jsconfig.ts @@ -0,0 +1,16 @@ +/// + +// @Filename: /a.js +////function f(/**/x) { +////} + +// @Filename: /jsconfig.json +////{ +//// "compilerOptions": { +//// "checkJs": true, +//// "noImplicitAny": true +//// } +////} + +goTo.file("/a.js"); +verify.errorExistsAfterMarker(""); From d74820d51997d6a84edd9acfe2916e0090240f5b Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 12 Jan 2018 14:43:31 -0800 Subject: [PATCH 167/189] Remove mapped types to never from intersections when transforming an indexed access type in order to get its constraint. --- src/compiler/checker.ts | 25 ++++++++++--- .../indexedAccessRetainsIndexSignature.js | 5 +++ ...indexedAccessRetainsIndexSignature.symbols | 35 +++++++++++++++++-- .../indexedAccessRetainsIndexSignature.types | 31 ++++++++++++++++ .../indexedAccessRetainsIndexSignature.ts | 4 +++ 5 files changed, 92 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a32104c0535..1a5cc357c78 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6468,7 +6468,7 @@ namespace ts { } function getConstraintOfIndexedAccess(type: IndexedAccessType) { - const transformed = getSubstitutedIndexedMappedType(type); + const transformed = getSimplifiedIndexedAccessType(type); if (transformed) { return transformed; } @@ -8359,6 +8359,10 @@ namespace ts { return false; } + function isMappedTypeToNever(type: Type) { + return getObjectFlags(type) & ObjectFlags.Mapped && getTemplateTypeFromMappedType(type as MappedType) === neverType; + } + // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return // undefined if no transformation is possible. function getSimplifiedIndexedAccessType(type: IndexedAccessType): Type { @@ -8383,11 +8387,22 @@ namespace ts { getIntersectionType(stringIndexTypes) ]); } - return getSubstitutedIndexedMappedType(type); - } + // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or + // more mapped types with a template type `never`, '(U & V & { [P in T]: never })[K]', return a + // transformed type that removes the never-mapped type: '(U & V)[K]'. This mirrors what would happen + // eventually anyway, but it easier to reason about. + if (objectType.flags & TypeFlags.Intersection && isGenericObjectType(objectType) && some((objectType).types, isMappedTypeToNever)) { + let nonNeverTypes: Type[]; + for (const t of (objectType).types) { + if (!isMappedTypeToNever(t)) { + (nonNeverTypes || (nonNeverTypes = [])).push(t); + } + } + if (nonNeverTypes) { + return getIndexedAccessType(getIntersectionType(nonNeverTypes), type.indexType); + } + } - function getSubstitutedIndexedMappedType(type: IndexedAccessType): Type { - const objectType = type.objectType; // 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. diff --git a/tests/baselines/reference/indexedAccessRetainsIndexSignature.js b/tests/baselines/reference/indexedAccessRetainsIndexSignature.js index 6c33317f156..1b77b95527b 100644 --- a/tests/baselines/reference/indexedAccessRetainsIndexSignature.js +++ b/tests/baselines/reference/indexedAccessRetainsIndexSignature.js @@ -2,9 +2,14 @@ type Diff = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T] type Omit = Pick> +type Omit1 = Pick>; +// is in fact an equivalent of +type Omit2 = {[P in Diff]: T[P]}; type O = Omit<{ a: number, b: string }, 'a'> +const o: O = { b: '' } //// [indexedAccessRetainsIndexSignature.js] +var o = { b: '' }; diff --git a/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols b/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols index 908d74c9452..9858f6fc162 100644 --- a/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols +++ b/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols @@ -24,10 +24,39 @@ type Omit = Pick> >U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 2, 10)) >K : Symbol(K, Decl(indexedAccessRetainsIndexSignature.ts, 2, 12)) +type Omit1 = Pick>; +>Omit1 : Symbol(Omit1, Decl(indexedAccessRetainsIndexSignature.ts, 2, 59)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 3, 11)) +>K : Symbol(K, Decl(indexedAccessRetainsIndexSignature.ts, 3, 13)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 3, 11)) +>Pick : Symbol(Pick, Decl(lib.d.ts, --, --)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 3, 11)) +>Diff : Symbol(Diff, Decl(indexedAccessRetainsIndexSignature.ts, 0, 0)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 3, 11)) +>K : Symbol(K, Decl(indexedAccessRetainsIndexSignature.ts, 3, 13)) + +// is in fact an equivalent of + +type Omit2 = {[P in Diff]: T[P]}; +>Omit2 : Symbol(Omit2, Decl(indexedAccessRetainsIndexSignature.ts, 3, 61)) +>T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 6, 11)) +>K : Symbol(K, Decl(indexedAccessRetainsIndexSignature.ts, 6, 13)) +>T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 6, 11)) +>P : Symbol(P, Decl(indexedAccessRetainsIndexSignature.ts, 6, 37)) +>Diff : Symbol(Diff, Decl(indexedAccessRetainsIndexSignature.ts, 0, 0)) +>T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 6, 11)) +>K : Symbol(K, Decl(indexedAccessRetainsIndexSignature.ts, 6, 13)) +>T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 6, 11)) +>P : Symbol(P, Decl(indexedAccessRetainsIndexSignature.ts, 6, 37)) type O = Omit<{ a: number, b: string }, 'a'> ->O : Symbol(O, Decl(indexedAccessRetainsIndexSignature.ts, 2, 59)) +>O : Symbol(O, Decl(indexedAccessRetainsIndexSignature.ts, 6, 67)) >Omit : Symbol(Omit, Decl(indexedAccessRetainsIndexSignature.ts, 1, 71)) ->a : Symbol(a, Decl(indexedAccessRetainsIndexSignature.ts, 5, 15)) ->b : Symbol(b, Decl(indexedAccessRetainsIndexSignature.ts, 5, 26)) +>a : Symbol(a, Decl(indexedAccessRetainsIndexSignature.ts, 8, 15)) +>b : Symbol(b, Decl(indexedAccessRetainsIndexSignature.ts, 8, 26)) + +const o: O = { b: '' } +>o : Symbol(o, Decl(indexedAccessRetainsIndexSignature.ts, 9, 5)) +>O : Symbol(O, Decl(indexedAccessRetainsIndexSignature.ts, 6, 67)) +>b : Symbol(b, Decl(indexedAccessRetainsIndexSignature.ts, 9, 14)) diff --git a/tests/baselines/reference/indexedAccessRetainsIndexSignature.types b/tests/baselines/reference/indexedAccessRetainsIndexSignature.types index 8ef6cb62559..3e3f52f7ca6 100644 --- a/tests/baselines/reference/indexedAccessRetainsIndexSignature.types +++ b/tests/baselines/reference/indexedAccessRetainsIndexSignature.types @@ -24,6 +24,30 @@ type Omit = Pick> >U : U >K : K +type Omit1 = Pick>; +>Omit1 : Pick +>U : U +>K : K +>U : U +>Pick : Pick +>U : U +>Diff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T] +>U : U +>K : K + +// is in fact an equivalent of + +type Omit2 = {[P in Diff]: T[P]}; +>Omit2 : Omit2 +>T : T +>K : K +>T : T +>P : P +>Diff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T] +>T : T +>K : K +>T : T +>P : P type O = Omit<{ a: number, b: string }, 'a'> >O : Pick<{ a: number; b: string; }, "b"> @@ -31,3 +55,10 @@ type O = Omit<{ a: number, b: string }, 'a'> >a : number >b : string +const o: O = { b: '' } +>o : Pick<{ a: number; b: string; }, "b"> +>O : Pick<{ a: number; b: string; }, "b"> +>{ b: '' } : { b: string; } +>b : string +>'' : "" + diff --git a/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts b/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts index ff38b2d9090..d23cbe87ddf 100644 --- a/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts +++ b/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts @@ -1,6 +1,10 @@ type Diff = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T] type Omit = Pick> +type Omit1 = Pick>; +// is in fact an equivalent of +type Omit2 = {[P in Diff]: T[P]}; type O = Omit<{ a: number, b: string }, 'a'> +const o: O = { b: '' } From f1622f0dc6b75a727ce8f0c2e2ef05a33dd31bbd Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 12 Jan 2018 14:56:50 -0800 Subject: [PATCH 168/189] Use filter instead of unnecessary laziness --- src/compiler/checker.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1a5cc357c78..811fe868f96 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8389,18 +8389,11 @@ namespace ts { } // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or // more mapped types with a template type `never`, '(U & V & { [P in T]: never })[K]', return a - // transformed type that removes the never-mapped type: '(U & V)[K]'. This mirrors what would happen + // transformed type that removes the never-mapped type: '(U & V)[K]'. This mirrors what would happen // eventually anyway, but it easier to reason about. if (objectType.flags & TypeFlags.Intersection && isGenericObjectType(objectType) && some((objectType).types, isMappedTypeToNever)) { - let nonNeverTypes: Type[]; - for (const t of (objectType).types) { - if (!isMappedTypeToNever(t)) { - (nonNeverTypes || (nonNeverTypes = [])).push(t); - } - } - if (nonNeverTypes) { - return getIndexedAccessType(getIntersectionType(nonNeverTypes), type.indexType); - } + const nonNeverTypes = filter((objectType).types, t => !isMappedTypeToNever(t)); + return 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 From fd1bb9bde21f79bc90325990129f45dc3b0185a0 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 12 Jan 2018 15:07:46 -0800 Subject: [PATCH 169/189] Group intersection code in getSimplifiedIndexedAccessType --- src/compiler/checker.ts | 52 +++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 811fe868f96..5e26b37b61a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8367,33 +8367,35 @@ namespace ts { // undefined if no transformation is possible. function getSimplifiedIndexedAccessType(type: IndexedAccessType): Type { const objectType = type.objectType; - // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or - // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a - // transformed type of the form '(U & V)[K] | D'. This allows us to properly reason about higher order indexed - // access types with default property values as expressed by D. - if (objectType.flags & TypeFlags.Intersection && isGenericObjectType(objectType) && some((objectType).types, isStringIndexOnlyType)) { - const regularTypes: Type[] = []; - const stringIndexTypes: Type[] = []; - for (const t of (objectType).types) { - if (isStringIndexOnlyType(t)) { - stringIndexTypes.push(getIndexTypeOfType(t, IndexKind.String)); - } - else { - regularTypes.push(t); + if (objectType.flags & TypeFlags.Intersection && isGenericObjectType(objectType)) { + // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or + // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a + // transformed type of the form '(U & V)[K] | D'. This allows us to properly reason about higher order indexed + // access types with default property values as expressed by D. + if (some((objectType).types, isStringIndexOnlyType)) { + const regularTypes: Type[] = []; + const stringIndexTypes: Type[] = []; + for (const t of (objectType).types) { + if (isStringIndexOnlyType(t)) { + stringIndexTypes.push(getIndexTypeOfType(t, IndexKind.String)); + } + else { + regularTypes.push(t); + } } + return getUnionType([ + getIndexedAccessType(getIntersectionType(regularTypes), type.indexType), + getIntersectionType(stringIndexTypes) + ]); + } + // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or + // more mapped types with a template type `never`, '(U & V & { [P in T]: never })[K]', return a + // transformed type that removes the never-mapped type: '(U & V)[K]'. This mirrors what would happen + // 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 getUnionType([ - getIndexedAccessType(getIntersectionType(regularTypes), type.indexType), - getIntersectionType(stringIndexTypes) - ]); - } - // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or - // more mapped types with a template type `never`, '(U & V & { [P in T]: never })[K]', return a - // transformed type that removes the never-mapped type: '(U & V)[K]'. This mirrors what would happen - // eventually anyway, but it easier to reason about. - if (objectType.flags & TypeFlags.Intersection && isGenericObjectType(objectType) && some((objectType).types, isMappedTypeToNever)) { - const nonNeverTypes = filter((objectType).types, t => !isMappedTypeToNever(t)); - return 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 From 64305edbcecf2e084e5fcc1534a8b1ee54f49a38 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 12 Jan 2018 18:24:02 -0800 Subject: [PATCH 170/189] Skip outer expressions when checking for super keyword in binder (#20164) * Skip outter expressions when checking for super keyword in binder * use TransformFlags to optimize and correct super call transforms * Lint --- src/compiler/binder.ts | 74 +++++++---- src/compiler/types.ts | 6 +- .../reference/decoratorOnClassMethod12.js | 1 - tests/baselines/reference/superAccess2.js | 1 - .../reference/superAccessCastedCall.js | 54 ++++++++ .../reference/superAccessCastedCall.symbols | 50 ++++++++ .../reference/superAccessCastedCall.types | 59 +++++++++ .../reference/superElementAccess.errors.txt | 44 +++++++ .../baselines/reference/superElementAccess.js | 84 +++++++++++++ .../reference/superElementAccess.symbols | 91 ++++++++++++++ .../reference/superElementAccess.types | 115 ++++++++++++++++++ tests/baselines/reference/superErrors.js | 12 +- tests/baselines/reference/superInLambdas.js | 2 - .../reference/superPropertyAccess.js | 5 +- ...opertyElementNoUnusedLexicalThisCapture.js | 53 ++++++++ ...yElementNoUnusedLexicalThisCapture.symbols | 33 +++++ ...rtyElementNoUnusedLexicalThisCapture.types | 39 ++++++ tests/cases/compiler/superAccessCastedCall.ts | 20 +++ tests/cases/compiler/superElementAccess.ts | 36 ++++++ ...opertyElementNoUnusedLexicalThisCapture.ts | 17 +++ 20 files changed, 753 insertions(+), 43 deletions(-) create mode 100644 tests/baselines/reference/superAccessCastedCall.js create mode 100644 tests/baselines/reference/superAccessCastedCall.symbols create mode 100644 tests/baselines/reference/superAccessCastedCall.types create mode 100644 tests/baselines/reference/superElementAccess.errors.txt create mode 100644 tests/baselines/reference/superElementAccess.js create mode 100644 tests/baselines/reference/superElementAccess.symbols create mode 100644 tests/baselines/reference/superElementAccess.types create mode 100644 tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.js create mode 100644 tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.symbols create mode 100644 tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.types create mode 100644 tests/cases/compiler/superAccessCastedCall.ts create mode 100644 tests/cases/compiler/superElementAccess.ts create mode 100644 tests/cases/compiler/superPropertyElementNoUnusedLexicalThisCapture.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 4e4b4f12705..d366ff3dfe5 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2740,6 +2740,9 @@ namespace ts { case SyntaxKind.PropertyAccessExpression: return computePropertyAccess(node, subtreeFlags); + case SyntaxKind.ElementAccessExpression: + return computeElementAccess(node, subtreeFlags); + default: return computeOther(node, kind, subtreeFlags); } @@ -2748,17 +2751,21 @@ namespace ts { function computeCallExpression(node: CallExpression, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; const expression = node.expression; - const expressionKind = expression.kind; if (node.typeArguments) { transformFlags |= TransformFlags.AssertTypeScript; } if (subtreeFlags & TransformFlags.ContainsSpread - || isSuperOrSuperProperty(expression, expressionKind)) { + || (expression.transformFlags & (TransformFlags.Super | TransformFlags.ContainsSuper))) { // If the this node contains a SpreadExpression, or is a super call, then it is an ES6 // node. transformFlags |= TransformFlags.AssertES2015; + // super property or element accesses could be inside lambdas, etc, and need a captured `this`, + // while super keyword for super calls (indicated by TransformFlags.Super) does not (since it can only be top-level in a constructor) + if (expression.transformFlags & TransformFlags.ContainsSuper) { + transformFlags |= TransformFlags.ContainsLexicalThis; + } } if (expression.kind === SyntaxKind.ImportKeyword) { @@ -2775,21 +2782,6 @@ namespace ts { return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes; } - function isSuperOrSuperProperty(node: Node, kind: SyntaxKind) { - switch (kind) { - case SyntaxKind.SuperKeyword: - return true; - - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - const expression = (node).expression; - const expressionKind = expression.kind; - return expressionKind === SyntaxKind.SuperKeyword; - } - - return false; - } - function computeNewExpression(node: NewExpression, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; if (node.typeArguments) { @@ -2884,7 +2876,7 @@ namespace ts { } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; + return transformFlags & ~TransformFlags.OuterExpressionExcludes; } function computeClassDeclaration(node: ClassDeclaration, subtreeFlags: TransformFlags) { @@ -3203,17 +3195,32 @@ namespace ts { function computePropertyAccess(node: PropertyAccessExpression, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; - const expression = node.expression; - const expressionKind = expression.kind; // If a PropertyAccessExpression starts with a super keyword, then it is // ES6 syntax, and requires a lexical `this` binding. - if (expressionKind === SyntaxKind.SuperKeyword) { - transformFlags |= TransformFlags.ContainsLexicalThis; + if (transformFlags & TransformFlags.Super) { + transformFlags ^= TransformFlags.Super; + transformFlags |= TransformFlags.ContainsSuper; } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; + return transformFlags & ~TransformFlags.PropertyAccessExcludes; + } + + function computeElementAccess(node: ElementAccessExpression, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + const expression = node.expression; + const expressionFlags = expression.transformFlags; // We do not want to aggregate flags from the argument expression for super/this capturing + + // If an ElementAccessExpression starts with a super keyword, then it is + // ES6 syntax, and requires a lexical `this` binding. + if (expressionFlags & TransformFlags.Super) { + transformFlags &= ~TransformFlags.Super; + transformFlags |= TransformFlags.ContainsSuper; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.PropertyAccessExcludes; } function computeVariableDeclaration(node: VariableDeclaration, subtreeFlags: TransformFlags) { @@ -3333,6 +3340,13 @@ namespace ts { transformFlags |= TransformFlags.AssertESNext | TransformFlags.AssertES2017; break; + case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.AsExpression: + case SyntaxKind.PartiallyEmittedExpression: + // These nodes are TypeScript syntax. + transformFlags |= TransformFlags.AssertTypeScript; + excludeFlags = TransformFlags.OuterExpressionExcludes; + break; case SyntaxKind.PublicKeyword: case SyntaxKind.PrivateKeyword: case SyntaxKind.ProtectedKeyword: @@ -3341,8 +3355,6 @@ namespace ts { case SyntaxKind.ConstKeyword: case SyntaxKind.EnumDeclaration: case SyntaxKind.EnumMember: - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: case SyntaxKind.NonNullExpression: case SyntaxKind.ReadonlyKeyword: // These nodes are TypeScript syntax. @@ -3470,7 +3482,8 @@ namespace ts { case SyntaxKind.SuperKeyword: // This node is ES6 syntax. - transformFlags |= TransformFlags.AssertES2015; + transformFlags |= TransformFlags.AssertES2015 | TransformFlags.Super; + excludeFlags = TransformFlags.OuterExpressionExcludes; // must be set to persist `Super` break; case SyntaxKind.ThisKeyword: @@ -3627,6 +3640,15 @@ namespace ts { case SyntaxKind.ObjectBindingPattern: case SyntaxKind.ArrayBindingPattern: return TransformFlags.BindingPatternExcludes; + case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.AsExpression: + case SyntaxKind.PartiallyEmittedExpression: + case SyntaxKind.ParenthesizedExpression: + case SyntaxKind.SuperKeyword: + return TransformFlags.OuterExpressionExcludes; + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.ElementAccessExpression: + return TransformFlags.PropertyAccessExcludes; default: return TransformFlags.NodeExcludes; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e4ada136730..c51208c4f79 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4456,6 +4456,8 @@ namespace ts { ContainsYield = 1 << 24, ContainsHoistedDeclarationOrCompletion = 1 << 25, ContainsDynamicImport = 1 << 26, + Super = 1 << 27, + ContainsSuper = 1 << 28, // Please leave this as 1 << 29. // It is the maximum bit we can set before we outgrow the size of a v8 small integer (SMI) on an x86 system. @@ -4476,7 +4478,9 @@ namespace ts { // Scope Exclusions // - Bitmasks that exclude flags from propagating out of a specific context // into the subtree flags of their container. - NodeExcludes = TypeScript | ES2015 | DestructuringAssignment | Generator | HasComputedFlags, + OuterExpressionExcludes = TypeScript | ES2015 | DestructuringAssignment | Generator | HasComputedFlags, + PropertyAccessExcludes = OuterExpressionExcludes | Super, + NodeExcludes = PropertyAccessExcludes | ContainsSuper, ArrowFunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest, FunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest, ConstructorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest, diff --git a/tests/baselines/reference/decoratorOnClassMethod12.js b/tests/baselines/reference/decoratorOnClassMethod12.js index 0063e0225bc..494cb083a20 100644 --- a/tests/baselines/reference/decoratorOnClassMethod12.js +++ b/tests/baselines/reference/decoratorOnClassMethod12.js @@ -28,7 +28,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, }; var M; (function (M) { - var _this = this; var S = /** @class */ (function () { function S() { } diff --git a/tests/baselines/reference/superAccess2.js b/tests/baselines/reference/superAccess2.js index d3aac217e22..de755361a16 100644 --- a/tests/baselines/reference/superAccess2.js +++ b/tests/baselines/reference/superAccess2.js @@ -35,7 +35,6 @@ var __extends = (this && this.__extends) || (function () { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); -var _this = this; var P = /** @class */ (function () { function P() { } diff --git a/tests/baselines/reference/superAccessCastedCall.js b/tests/baselines/reference/superAccessCastedCall.js new file mode 100644 index 00000000000..a4583b3e710 --- /dev/null +++ b/tests/baselines/reference/superAccessCastedCall.js @@ -0,0 +1,54 @@ +//// [superAccessCastedCall.ts] +class Foo { + bar(): void {} +} + +class Bar extends Foo { + x: Number; + + constructor() { + super(); + this.x = 2; + } + + bar() { + super.bar(); + (super.bar as any)(); + } +} + +let b = new Bar(); +b.bar() + +//// [superAccessCastedCall.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 Foo = /** @class */ (function () { + function Foo() { + } + Foo.prototype.bar = function () { }; + return Foo; +}()); +var Bar = /** @class */ (function (_super) { + __extends(Bar, _super); + function Bar() { + var _this = _super.call(this) || this; + _this.x = 2; + return _this; + } + Bar.prototype.bar = function () { + _super.prototype.bar.call(this); + _super.prototype.bar.call(this); + }; + return Bar; +}(Foo)); +var b = new Bar(); +b.bar(); diff --git a/tests/baselines/reference/superAccessCastedCall.symbols b/tests/baselines/reference/superAccessCastedCall.symbols new file mode 100644 index 00000000000..83b9447c3f7 --- /dev/null +++ b/tests/baselines/reference/superAccessCastedCall.symbols @@ -0,0 +1,50 @@ +=== tests/cases/compiler/superAccessCastedCall.ts === +class Foo { +>Foo : Symbol(Foo, Decl(superAccessCastedCall.ts, 0, 0)) + + bar(): void {} +>bar : Symbol(Foo.bar, Decl(superAccessCastedCall.ts, 0, 11)) +} + +class Bar extends Foo { +>Bar : Symbol(Bar, Decl(superAccessCastedCall.ts, 2, 1)) +>Foo : Symbol(Foo, Decl(superAccessCastedCall.ts, 0, 0)) + + x: Number; +>x : Symbol(Bar.x, Decl(superAccessCastedCall.ts, 4, 23)) +>Number : Symbol(Number, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + constructor() { + super(); +>super : Symbol(Foo, Decl(superAccessCastedCall.ts, 0, 0)) + + this.x = 2; +>this.x : Symbol(Bar.x, Decl(superAccessCastedCall.ts, 4, 23)) +>this : Symbol(Bar, Decl(superAccessCastedCall.ts, 2, 1)) +>x : Symbol(Bar.x, Decl(superAccessCastedCall.ts, 4, 23)) + } + + bar() { +>bar : Symbol(Bar.bar, Decl(superAccessCastedCall.ts, 10, 5)) + + super.bar(); +>super.bar : Symbol(Foo.bar, Decl(superAccessCastedCall.ts, 0, 11)) +>super : Symbol(Foo, Decl(superAccessCastedCall.ts, 0, 0)) +>bar : Symbol(Foo.bar, Decl(superAccessCastedCall.ts, 0, 11)) + + (super.bar as any)(); +>super.bar : Symbol(Foo.bar, Decl(superAccessCastedCall.ts, 0, 11)) +>super : Symbol(Foo, Decl(superAccessCastedCall.ts, 0, 0)) +>bar : Symbol(Foo.bar, Decl(superAccessCastedCall.ts, 0, 11)) + } +} + +let b = new Bar(); +>b : Symbol(b, Decl(superAccessCastedCall.ts, 18, 3)) +>Bar : Symbol(Bar, Decl(superAccessCastedCall.ts, 2, 1)) + +b.bar() +>b.bar : Symbol(Bar.bar, Decl(superAccessCastedCall.ts, 10, 5)) +>b : Symbol(b, Decl(superAccessCastedCall.ts, 18, 3)) +>bar : Symbol(Bar.bar, Decl(superAccessCastedCall.ts, 10, 5)) + diff --git a/tests/baselines/reference/superAccessCastedCall.types b/tests/baselines/reference/superAccessCastedCall.types new file mode 100644 index 00000000000..72ee3c05a7e --- /dev/null +++ b/tests/baselines/reference/superAccessCastedCall.types @@ -0,0 +1,59 @@ +=== tests/cases/compiler/superAccessCastedCall.ts === +class Foo { +>Foo : Foo + + bar(): void {} +>bar : () => void +} + +class Bar extends Foo { +>Bar : Bar +>Foo : Foo + + x: Number; +>x : Number +>Number : Number + + constructor() { + super(); +>super() : void +>super : typeof Foo + + this.x = 2; +>this.x = 2 : 2 +>this.x : Number +>this : this +>x : Number +>2 : 2 + } + + bar() { +>bar : () => void + + super.bar(); +>super.bar() : void +>super.bar : () => void +>super : Foo +>bar : () => void + + (super.bar as any)(); +>(super.bar as any)() : any +>(super.bar as any) : any +>super.bar as any : any +>super.bar : () => void +>super : Foo +>bar : () => void + } +} + +let b = new Bar(); +>b : Bar +>new Bar() : Bar +>Bar : typeof Bar + +b.bar() +>b.bar() : void +>b.bar : () => void +>b : Bar +>bar : () => void + diff --git a/tests/baselines/reference/superElementAccess.errors.txt b/tests/baselines/reference/superElementAccess.errors.txt new file mode 100644 index 00000000000..e5d8c3ea5ad --- /dev/null +++ b/tests/baselines/reference/superElementAccess.errors.txt @@ -0,0 +1,44 @@ +tests/cases/compiler/superElementAccess.ts(7,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. +tests/cases/compiler/superElementAccess.ts(8,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + + +==== tests/cases/compiler/superElementAccess.ts (2 errors) ==== + class MyBase { + m1(a: string) { return a; } + private p1() { } + m2: () => void = function () { } + d1: number = 42; + private d2: number = 42; + get value() {return 0 } + ~~~~~ +!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + set value(v: number) { } + ~~~~~ +!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + } + + + class MyDerived extends MyBase { + + foo() { + super["m1"]("hi"); // Should be allowed, method on base prototype + + var l2 = super["m1"].bind(this); // Should be allowed, can access properties as well as invoke + + var x: (a: string) => string = super["m1"]; // Should be allowed, can assign to var with compatible signature + + super["m2"].bind(this); // Should error, instance property, not a public instance member function + + super["p1"](); // Should error, private not public instance member function + + var l1 = super["d1"]; // Should error, instance data property not a public instance member function + + var l1 = super["d2"]; // Should error, instance data property not a public instance member function + + super["m1"] = function (a: string) { return ""; }; // Should be allowed, we will not restrict assignment + + super["value"] = 0; // Should error, instance data property not a public instance member function + + var z = super["value"]; // Should error, instance data property not a public instance member function + } + } \ No newline at end of file diff --git a/tests/baselines/reference/superElementAccess.js b/tests/baselines/reference/superElementAccess.js new file mode 100644 index 00000000000..422b80109bb --- /dev/null +++ b/tests/baselines/reference/superElementAccess.js @@ -0,0 +1,84 @@ +//// [superElementAccess.ts] +class MyBase { + m1(a: string) { return a; } + private p1() { } + m2: () => void = function () { } + d1: number = 42; + private d2: number = 42; + get value() {return 0 } + set value(v: number) { } +} + + +class MyDerived extends MyBase { + + foo() { + super["m1"]("hi"); // Should be allowed, method on base prototype + + var l2 = super["m1"].bind(this); // Should be allowed, can access properties as well as invoke + + var x: (a: string) => string = super["m1"]; // Should be allowed, can assign to var with compatible signature + + super["m2"].bind(this); // Should error, instance property, not a public instance member function + + super["p1"](); // Should error, private not public instance member function + + var l1 = super["d1"]; // Should error, instance data property not a public instance member function + + var l1 = super["d2"]; // Should error, instance data property not a public instance member function + + super["m1"] = function (a: string) { return ""; }; // Should be allowed, we will not restrict assignment + + super["value"] = 0; // Should error, instance data property not a public instance member function + + var z = super["value"]; // Should error, instance data property not a public instance member function + } +} + +//// [superElementAccess.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 MyBase = /** @class */ (function () { + function MyBase() { + this.m2 = function () { }; + this.d1 = 42; + this.d2 = 42; + } + MyBase.prototype.m1 = function (a) { return a; }; + MyBase.prototype.p1 = function () { }; + Object.defineProperty(MyBase.prototype, "value", { + get: function () { return 0; }, + set: function (v) { }, + enumerable: true, + configurable: true + }); + return MyBase; +}()); +var MyDerived = /** @class */ (function (_super) { + __extends(MyDerived, _super); + function MyDerived() { + return _super !== null && _super.apply(this, arguments) || this; + } + MyDerived.prototype.foo = function () { + _super.prototype["m1"].call(this, "hi"); // Should be allowed, method on base prototype + var l2 = (_a = _super.prototype["m1"]).bind.call(_a, this); // Should be allowed, can access properties as well as invoke + var x = _super.prototype["m1"]; // Should be allowed, can assign to var with compatible signature + (_b = _super.prototype["m2"]).bind.call(_b, this); // Should error, instance property, not a public instance member function + _super.prototype["p1"].call(this); // Should error, private not public instance member function + var l1 = _super.prototype["d1"]; // Should error, instance data property not a public instance member function + var l1 = _super.prototype["d2"]; // Should error, instance data property not a public instance member function + _super.prototype["m1"] = function (a) { return ""; }; // Should be allowed, we will not restrict assignment + _super.prototype["value"] = 0; // Should error, instance data property not a public instance member function + var z = _super.prototype["value"]; // Should error, instance data property not a public instance member function + var _a, _b; + }; + return MyDerived; +}(MyBase)); diff --git a/tests/baselines/reference/superElementAccess.symbols b/tests/baselines/reference/superElementAccess.symbols new file mode 100644 index 00000000000..5da1450212b --- /dev/null +++ b/tests/baselines/reference/superElementAccess.symbols @@ -0,0 +1,91 @@ +=== tests/cases/compiler/superElementAccess.ts === +class MyBase { +>MyBase : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) + + m1(a: string) { return a; } +>m1 : Symbol(MyBase.m1, Decl(superElementAccess.ts, 0, 14)) +>a : Symbol(a, Decl(superElementAccess.ts, 1, 7)) +>a : Symbol(a, Decl(superElementAccess.ts, 1, 7)) + + private p1() { } +>p1 : Symbol(MyBase.p1, Decl(superElementAccess.ts, 1, 31)) + + m2: () => void = function () { } +>m2 : Symbol(MyBase.m2, Decl(superElementAccess.ts, 2, 20)) + + d1: number = 42; +>d1 : Symbol(MyBase.d1, Decl(superElementAccess.ts, 3, 36)) + + private d2: number = 42; +>d2 : Symbol(MyBase.d2, Decl(superElementAccess.ts, 4, 20)) + + get value() {return 0 } +>value : Symbol(MyBase.value, Decl(superElementAccess.ts, 5, 28), Decl(superElementAccess.ts, 6, 27)) + + set value(v: number) { } +>value : Symbol(MyBase.value, Decl(superElementAccess.ts, 5, 28), Decl(superElementAccess.ts, 6, 27)) +>v : Symbol(v, Decl(superElementAccess.ts, 7, 14)) +} + + +class MyDerived extends MyBase { +>MyDerived : Symbol(MyDerived, Decl(superElementAccess.ts, 8, 1)) +>MyBase : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) + + foo() { +>foo : Symbol(MyDerived.foo, Decl(superElementAccess.ts, 11, 32)) + + super["m1"]("hi"); // Should be allowed, method on base prototype +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"m1" : Symbol(MyBase.m1, Decl(superElementAccess.ts, 0, 14)) + + var l2 = super["m1"].bind(this); // Should be allowed, can access properties as well as invoke +>l2 : Symbol(l2, Decl(superElementAccess.ts, 16, 11)) +>super["m1"].bind : Symbol(Function.bind, Decl(lib.d.ts, --, --)) +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"m1" : Symbol(MyBase.m1, Decl(superElementAccess.ts, 0, 14)) +>bind : Symbol(Function.bind, Decl(lib.d.ts, --, --)) +>this : Symbol(MyDerived, Decl(superElementAccess.ts, 8, 1)) + + var x: (a: string) => string = super["m1"]; // Should be allowed, can assign to var with compatible signature +>x : Symbol(x, Decl(superElementAccess.ts, 18, 11)) +>a : Symbol(a, Decl(superElementAccess.ts, 18, 16)) +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"m1" : Symbol(MyBase.m1, Decl(superElementAccess.ts, 0, 14)) + + super["m2"].bind(this); // Should error, instance property, not a public instance member function +>super["m2"].bind : Symbol(Function.bind, Decl(lib.d.ts, --, --)) +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"m2" : Symbol(MyBase.m2, Decl(superElementAccess.ts, 2, 20)) +>bind : Symbol(Function.bind, Decl(lib.d.ts, --, --)) +>this : Symbol(MyDerived, Decl(superElementAccess.ts, 8, 1)) + + super["p1"](); // Should error, private not public instance member function +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"p1" : Symbol(MyBase.p1, Decl(superElementAccess.ts, 1, 31)) + + var l1 = super["d1"]; // Should error, instance data property not a public instance member function +>l1 : Symbol(l1, Decl(superElementAccess.ts, 24, 11), Decl(superElementAccess.ts, 26, 11)) +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"d1" : Symbol(MyBase.d1, Decl(superElementAccess.ts, 3, 36)) + + var l1 = super["d2"]; // Should error, instance data property not a public instance member function +>l1 : Symbol(l1, Decl(superElementAccess.ts, 24, 11), Decl(superElementAccess.ts, 26, 11)) +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"d2" : Symbol(MyBase.d2, Decl(superElementAccess.ts, 4, 20)) + + super["m1"] = function (a: string) { return ""; }; // Should be allowed, we will not restrict assignment +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"m1" : Symbol(MyBase.m1, Decl(superElementAccess.ts, 0, 14)) +>a : Symbol(a, Decl(superElementAccess.ts, 28, 32)) + + super["value"] = 0; // Should error, instance data property not a public instance member function +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"value" : Symbol(MyBase.value, Decl(superElementAccess.ts, 5, 28), Decl(superElementAccess.ts, 6, 27)) + + var z = super["value"]; // Should error, instance data property not a public instance member function +>z : Symbol(z, Decl(superElementAccess.ts, 32, 11)) +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"value" : Symbol(MyBase.value, Decl(superElementAccess.ts, 5, 28), Decl(superElementAccess.ts, 6, 27)) + } +} diff --git a/tests/baselines/reference/superElementAccess.types b/tests/baselines/reference/superElementAccess.types new file mode 100644 index 00000000000..9fa75ec6bc4 --- /dev/null +++ b/tests/baselines/reference/superElementAccess.types @@ -0,0 +1,115 @@ +=== tests/cases/compiler/superElementAccess.ts === +class MyBase { +>MyBase : MyBase + + m1(a: string) { return a; } +>m1 : (a: string) => string +>a : string +>a : string + + private p1() { } +>p1 : () => void + + m2: () => void = function () { } +>m2 : () => void +>function () { } : () => void + + d1: number = 42; +>d1 : number +>42 : 42 + + private d2: number = 42; +>d2 : number +>42 : 42 + + get value() {return 0 } +>value : number +>0 : 0 + + set value(v: number) { } +>value : number +>v : number +} + + +class MyDerived extends MyBase { +>MyDerived : MyDerived +>MyBase : MyBase + + foo() { +>foo : () => void + + super["m1"]("hi"); // Should be allowed, method on base prototype +>super["m1"]("hi") : string +>super["m1"] : (a: string) => string +>super : MyBase +>"m1" : "m1" +>"hi" : "hi" + + var l2 = super["m1"].bind(this); // Should be allowed, can access properties as well as invoke +>l2 : any +>super["m1"].bind(this) : any +>super["m1"].bind : (this: Function, thisArg: any, ...argArray: any[]) => any +>super["m1"] : (a: string) => string +>super : MyBase +>"m1" : "m1" +>bind : (this: Function, thisArg: any, ...argArray: any[]) => any +>this : this + + var x: (a: string) => string = super["m1"]; // Should be allowed, can assign to var with compatible signature +>x : (a: string) => string +>a : string +>super["m1"] : (a: string) => string +>super : MyBase +>"m1" : "m1" + + super["m2"].bind(this); // Should error, instance property, not a public instance member function +>super["m2"].bind(this) : any +>super["m2"].bind : (this: Function, thisArg: any, ...argArray: any[]) => any +>super["m2"] : () => void +>super : MyBase +>"m2" : "m2" +>bind : (this: Function, thisArg: any, ...argArray: any[]) => any +>this : this + + super["p1"](); // Should error, private not public instance member function +>super["p1"]() : void +>super["p1"] : () => void +>super : MyBase +>"p1" : "p1" + + var l1 = super["d1"]; // Should error, instance data property not a public instance member function +>l1 : number +>super["d1"] : number +>super : MyBase +>"d1" : "d1" + + var l1 = super["d2"]; // Should error, instance data property not a public instance member function +>l1 : number +>super["d2"] : number +>super : MyBase +>"d2" : "d2" + + super["m1"] = function (a: string) { return ""; }; // Should be allowed, we will not restrict assignment +>super["m1"] = function (a: string) { return ""; } : (a: string) => string +>super["m1"] : (a: string) => string +>super : MyBase +>"m1" : "m1" +>function (a: string) { return ""; } : (a: string) => string +>a : string +>"" : "" + + super["value"] = 0; // Should error, instance data property not a public instance member function +>super["value"] = 0 : 0 +>super["value"] : number +>super : MyBase +>"value" : "value" +>0 : 0 + + var z = super["value"]; // Should error, instance data property not a public instance member function +>z : number +>super["value"] : number +>super : MyBase +>"value" : "value" + } +} diff --git a/tests/baselines/reference/superErrors.js b/tests/baselines/reference/superErrors.js index 87d4e3bb85a..952cb03fd80 100644 --- a/tests/baselines/reference/superErrors.js +++ b/tests/baselines/reference/superErrors.js @@ -63,7 +63,6 @@ var __extends = (this && this.__extends) || (function () { }; })(); function foo() { - var _this = this; // super in a non class context var x = _super.; var y = function () { return _super.; }; @@ -93,10 +92,7 @@ var RegisteredUser = /** @class */ (function (_super) { var x = function () { return _super.sayHello.call(_this); }; } // super call in a lambda in a function expression in a constructor - (function () { - var _this = this; - return function () { return _super.; }; - })(); + (function () { return function () { return _super.; }; })(); return _this; } RegisteredUser.prototype.sayHello = function () { @@ -108,13 +104,9 @@ var RegisteredUser = /** @class */ (function (_super) { var x = function () { return _super.sayHello.call(_this); }; } // super call in a lambda in a function expression in a constructor - (function () { - var _this = this; - return function () { return _super.; }; - })(); + (function () { return function () { return _super.; }; })(); }; RegisteredUser.staticFunction = function () { - var _this = this; // super in static functions var s = _super.; var x = function () { return _super.; }; diff --git a/tests/baselines/reference/superInLambdas.js b/tests/baselines/reference/superInLambdas.js index 653d3ae84c1..9bb1a87e0ea 100644 --- a/tests/baselines/reference/superInLambdas.js +++ b/tests/baselines/reference/superInLambdas.js @@ -133,7 +133,6 @@ var RegisteredUser3 = /** @class */ (function (_super) { return _this; } RegisteredUser3.prototype.sayHello = function () { - var _this = this; // super property in a nested lambda in a method var superName = function () { return function () { return function () { return _super.prototype.name; }; }; }; }; @@ -149,7 +148,6 @@ var RegisteredUser4 = /** @class */ (function (_super) { return _this; } RegisteredUser4.prototype.sayHello = function () { - var _this = this; // super in a nested lambda in a method var x = function () { return function () { return _super.prototype.; }; }; }; diff --git a/tests/baselines/reference/superPropertyAccess.js b/tests/baselines/reference/superPropertyAccess.js index cc9758a1617..8fa0984745c 100644 --- a/tests/baselines/reference/superPropertyAccess.js +++ b/tests/baselines/reference/superPropertyAccess.js @@ -69,15 +69,16 @@ var MyDerived = /** @class */ (function (_super) { } MyDerived.prototype.foo = function () { _super.prototype.m1.call(this, "hi"); // Should be allowed, method on base prototype - var l2 = _super.prototype.m1.bind(this); // Should be allowed, can access properties as well as invoke + var l2 = (_a = _super.prototype.m1).bind.call(_a, this); // Should be allowed, can access properties as well as invoke var x = _super.prototype.m1; // Should be allowed, can assign to var with compatible signature - _super.prototype.m2.bind(this); // Should error, instance property, not a public instance member function + (_b = _super.prototype.m2).bind.call(_b, this); // Should error, instance property, not a public instance member function _super.prototype.p1.call(this); // Should error, private not public instance member function var l1 = _super.prototype.d1; // Should error, instance data property not a public instance member function var l1 = _super.prototype.d2; // Should error, instance data property not a public instance member function _super.prototype.m1 = function (a) { return ""; }; // Should be allowed, we will not restrict assignment _super.prototype.value = 0; // Should error, instance data property not a public instance member function var z = _super.prototype.value; // Should error, instance data property not a public instance member function + var _a, _b; }; return MyDerived; }(MyBase)); diff --git a/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.js b/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.js new file mode 100644 index 00000000000..126c123b40d --- /dev/null +++ b/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.js @@ -0,0 +1,53 @@ +//// [superPropertyElementNoUnusedLexicalThisCapture.ts] +class A { x() {} } + +class B extends A { + constructor() { + super(); + } + foo() { + return () => { + super.x; + } + } + bar() { + return () => { + super["x"]; + } + } +} + +//// [superPropertyElementNoUnusedLexicalThisCapture.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 A = /** @class */ (function () { + function A() { + } + A.prototype.x = function () { }; + return A; +}()); +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super.call(this) || this; + } + B.prototype.foo = function () { + return function () { + _super.prototype.x; + }; + }; + B.prototype.bar = function () { + return function () { + _super.prototype["x"]; + }; + }; + return B; +}(A)); diff --git a/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.symbols b/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.symbols new file mode 100644 index 00000000000..080268a0744 --- /dev/null +++ b/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.symbols @@ -0,0 +1,33 @@ +=== tests/cases/compiler/superPropertyElementNoUnusedLexicalThisCapture.ts === +class A { x() {} } +>A : Symbol(A, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 0)) +>x : Symbol(A.x, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 9)) + +class B extends A { +>B : Symbol(B, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 18)) +>A : Symbol(A, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 0)) + + constructor() { + super(); +>super : Symbol(A, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 0)) + } + foo() { +>foo : Symbol(B.foo, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 5, 5)) + + return () => { + super.x; +>super.x : Symbol(A.x, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 9)) +>super : Symbol(A, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 0)) +>x : Symbol(A.x, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 9)) + } + } + bar() { +>bar : Symbol(B.bar, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 10, 5)) + + return () => { + super["x"]; +>super : Symbol(A, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 0)) +>"x" : Symbol(A.x, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 9)) + } + } +} diff --git a/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.types b/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.types new file mode 100644 index 00000000000..37048f2f1d5 --- /dev/null +++ b/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.types @@ -0,0 +1,39 @@ +=== tests/cases/compiler/superPropertyElementNoUnusedLexicalThisCapture.ts === +class A { x() {} } +>A : A +>x : () => void + +class B extends A { +>B : B +>A : A + + constructor() { + super(); +>super() : void +>super : typeof A + } + foo() { +>foo : () => () => void + + return () => { +>() => { super.x; } : () => void + + super.x; +>super.x : () => void +>super : A +>x : () => void + } + } + bar() { +>bar : () => () => void + + return () => { +>() => { super["x"]; } : () => void + + super["x"]; +>super["x"] : () => void +>super : A +>"x" : "x" + } + } +} diff --git a/tests/cases/compiler/superAccessCastedCall.ts b/tests/cases/compiler/superAccessCastedCall.ts new file mode 100644 index 00000000000..98f154834e1 --- /dev/null +++ b/tests/cases/compiler/superAccessCastedCall.ts @@ -0,0 +1,20 @@ +class Foo { + bar(): void {} +} + +class Bar extends Foo { + x: Number; + + constructor() { + super(); + this.x = 2; + } + + bar() { + super.bar(); + (super.bar as any)(); + } +} + +let b = new Bar(); +b.bar() \ No newline at end of file diff --git a/tests/cases/compiler/superElementAccess.ts b/tests/cases/compiler/superElementAccess.ts new file mode 100644 index 00000000000..1b7e3f45683 --- /dev/null +++ b/tests/cases/compiler/superElementAccess.ts @@ -0,0 +1,36 @@ + +class MyBase { + m1(a: string) { return a; } + private p1() { } + m2: () => void = function () { } + d1: number = 42; + private d2: number = 42; + get value() {return 0 } + set value(v: number) { } +} + + +class MyDerived extends MyBase { + + foo() { + super["m1"]("hi"); // Should be allowed, method on base prototype + + var l2 = super["m1"].bind(this); // Should be allowed, can access properties as well as invoke + + var x: (a: string) => string = super["m1"]; // Should be allowed, can assign to var with compatible signature + + super["m2"].bind(this); // Should error, instance property, not a public instance member function + + super["p1"](); // Should error, private not public instance member function + + var l1 = super["d1"]; // Should error, instance data property not a public instance member function + + var l1 = super["d2"]; // Should error, instance data property not a public instance member function + + super["m1"] = function (a: string) { return ""; }; // Should be allowed, we will not restrict assignment + + super["value"] = 0; // Should error, instance data property not a public instance member function + + var z = super["value"]; // Should error, instance data property not a public instance member function + } +} \ No newline at end of file diff --git a/tests/cases/compiler/superPropertyElementNoUnusedLexicalThisCapture.ts b/tests/cases/compiler/superPropertyElementNoUnusedLexicalThisCapture.ts new file mode 100644 index 00000000000..b5e40b7ceff --- /dev/null +++ b/tests/cases/compiler/superPropertyElementNoUnusedLexicalThisCapture.ts @@ -0,0 +1,17 @@ +class A { x() {} } + +class B extends A { + constructor() { + super(); + } + foo() { + return () => { + super.x; + } + } + bar() { + return () => { + super["x"]; + } + } +} \ No newline at end of file From 2e1738bffaa9af5feaf343830f892c84abd82ced Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 12 Jan 2018 18:24:41 -0800 Subject: [PATCH 171/189] Enable substitution for object literal shorthand property assignments in the system transform (#21106) --- src/compiler/transformers/module/system.ts | 55 +++++++++++++++++++ .../reference/systemObjectShorthandRename.js | 44 +++++++++++++++ .../systemObjectShorthandRename.symbols | 24 ++++++++ .../systemObjectShorthandRename.types | 28 ++++++++++ .../compiler/systemObjectShorthandRename.ts | 12 ++++ 5 files changed, 163 insertions(+) create mode 100644 tests/baselines/reference/systemObjectShorthandRename.js create mode 100644 tests/baselines/reference/systemObjectShorthandRename.symbols create mode 100644 tests/baselines/reference/systemObjectShorthandRename.types create mode 100644 tests/cases/compiler/systemObjectShorthandRename.ts diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index e5d638cf04d..2e6f6d84b51 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -24,6 +24,7 @@ namespace ts { context.onSubstituteNode = onSubstituteNode; context.onEmitNode = onEmitNode; context.enableSubstitution(SyntaxKind.Identifier); // Substitutes expression identifiers for imported symbols. + context.enableSubstitution(SyntaxKind.ShorthandPropertyAssignment); // Substitutes expression identifiers for imported symbols context.enableSubstitution(SyntaxKind.BinaryExpression); // Substitutes assignments to exported symbols. context.enableSubstitution(SyntaxKind.PrefixUnaryExpression); // Substitutes updates to exported symbols. context.enableSubstitution(SyntaxKind.PostfixUnaryExpression); // Substitutes updates to exported symbols. @@ -1625,10 +1626,64 @@ namespace ts { if (hint === EmitHint.Expression) { return substituteExpression(node); } + else if (hint === EmitHint.Unspecified) { + return substituteUnspecified(node); + } return node; } + /** + * Substitute the node, if necessary. + * + * @param node The node to substitute. + */ + function substituteUnspecified(node: Node) { + switch (node.kind) { + case SyntaxKind.ShorthandPropertyAssignment: + return substituteShorthandPropertyAssignment(node); + } + return node; + } + /** + * Substitution for a ShorthandPropertyAssignment whose name that may contain an imported or exported symbol. + * + * @param node The node to substitute. + */ + function substituteShorthandPropertyAssignment(node: ShorthandPropertyAssignment) { + const name = node.name; + if (!isGeneratedIdentifier(name) && !isLocalName(name)) { + const importDeclaration = resolver.getReferencedImportDeclaration(name); + if (importDeclaration) { + if (isImportClause(importDeclaration)) { + return setTextRange( + createPropertyAssignment( + getSynthesizedClone(name), + createPropertyAccess( + getGeneratedNameForNode(importDeclaration.parent), + createIdentifier("default") + ) + ), + /*location*/ node + ); + } + else if (isImportSpecifier(importDeclaration)) { + return setTextRange( + createPropertyAssignment( + getSynthesizedClone(name), + createPropertyAccess( + getGeneratedNameForNode(importDeclaration.parent.parent.parent), + getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name) + ), + ), + /*location*/ node + ); + } + } + } + return node; + } + /** * Substitute the expression, if necessary. * diff --git a/tests/baselines/reference/systemObjectShorthandRename.js b/tests/baselines/reference/systemObjectShorthandRename.js new file mode 100644 index 00000000000..a7ac63968cd --- /dev/null +++ b/tests/baselines/reference/systemObjectShorthandRename.js @@ -0,0 +1,44 @@ +//// [tests/cases/compiler/systemObjectShorthandRename.ts] //// + +//// [x.ts] +export const x = 'X' +//// [index.ts] +import {x} from './x.js' + +const x2 = {x} +const a = {x2} + +const x3 = x +const b = {x3} + +//// [x.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + var x; + return { + setters: [], + execute: function () { + exports_1("x", x = 'X'); + } + }; +}); +//// [index.js] +System.register(["./x.js"], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + var x_js_1, x2, a, x3, b; + return { + setters: [ + function (x_js_1_1) { + x_js_1 = x_js_1_1; + } + ], + execute: function () { + x2 = { x: x_js_1.x }; + a = { x2 }; + x3 = x_js_1.x; + b = { x3 }; + } + }; +}); diff --git a/tests/baselines/reference/systemObjectShorthandRename.symbols b/tests/baselines/reference/systemObjectShorthandRename.symbols new file mode 100644 index 00000000000..3321d047ea1 --- /dev/null +++ b/tests/baselines/reference/systemObjectShorthandRename.symbols @@ -0,0 +1,24 @@ +=== tests/cases/compiler/x.ts === +export const x = 'X' +>x : Symbol(x, Decl(x.ts, 0, 12)) + +=== tests/cases/compiler/index.ts === +import {x} from './x.js' +>x : Symbol(x, Decl(index.ts, 0, 8)) + +const x2 = {x} +>x2 : Symbol(x2, Decl(index.ts, 2, 5)) +>x : Symbol(x, Decl(index.ts, 2, 12)) + +const a = {x2} +>a : Symbol(a, Decl(index.ts, 3, 5)) +>x2 : Symbol(x2, Decl(index.ts, 3, 11)) + +const x3 = x +>x3 : Symbol(x3, Decl(index.ts, 5, 5)) +>x : Symbol(x, Decl(index.ts, 0, 8)) + +const b = {x3} +>b : Symbol(b, Decl(index.ts, 6, 5)) +>x3 : Symbol(x3, Decl(index.ts, 6, 11)) + diff --git a/tests/baselines/reference/systemObjectShorthandRename.types b/tests/baselines/reference/systemObjectShorthandRename.types new file mode 100644 index 00000000000..23f3d74c951 --- /dev/null +++ b/tests/baselines/reference/systemObjectShorthandRename.types @@ -0,0 +1,28 @@ +=== tests/cases/compiler/x.ts === +export const x = 'X' +>x : "X" +>'X' : "X" + +=== tests/cases/compiler/index.ts === +import {x} from './x.js' +>x : "X" + +const x2 = {x} +>x2 : { x: string; } +>{x} : { x: string; } +>x : string + +const a = {x2} +>a : { x2: { x: string; }; } +>{x2} : { x2: { x: string; }; } +>x2 : { x: string; } + +const x3 = x +>x3 : "X" +>x : "X" + +const b = {x3} +>b : { x3: string; } +>{x3} : { x3: string; } +>x3 : string + diff --git a/tests/cases/compiler/systemObjectShorthandRename.ts b/tests/cases/compiler/systemObjectShorthandRename.ts new file mode 100644 index 00000000000..7bc6ce56649 --- /dev/null +++ b/tests/cases/compiler/systemObjectShorthandRename.ts @@ -0,0 +1,12 @@ +// @module: system +// @target: es2015 +// @filename: x.ts +export const x = 'X' +// @filename: index.ts +import {x} from './x.js' + +const x2 = {x} +const a = {x2} + +const x3 = x +const b = {x3} \ No newline at end of file From da18a247caa852a0bc34ead3ab5175c8b6d994e3 Mon Sep 17 00:00:00 2001 From: csigs Date: Sat, 13 Jan 2018 05:10:05 +0000 Subject: [PATCH 172/189] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 118 +++++++++++++++++- .../diagnosticMessages.generated.json.lcl | 116 ++++++++++++++++- .../diagnosticMessages.generated.json.lcl | 118 +++++++++++++++++- .../diagnosticMessages.generated.json.lcl | 118 +++++++++++++++++- .../diagnosticMessages.generated.json.lcl | 118 +++++++++++++++++- .../diagnosticMessages.generated.json.lcl | 118 +++++++++++++++++- .../diagnosticMessages.generated.json.lcl | 118 +++++++++++++++++- .../diagnosticMessages.generated.json.lcl | 118 +++++++++++++++++- .../diagnosticMessages.generated.json.lcl | 118 +++++++++++++++++- 9 files changed, 1043 insertions(+), 17 deletions(-) diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index 921ca600aa6..f6a140a47f7 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -474,6 +474,15 @@ + + + + + + + + + @@ -876,6 +885,12 @@ + + + + + + @@ -1281,6 +1296,24 @@ + + + + + + + + + + + + + + + + + + @@ -1830,6 +1863,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2298,6 +2358,15 @@ + + + + + + + + + @@ -2895,6 +2964,15 @@ + + + + + + + + + @@ -4539,6 +4617,12 @@ + + + + + + @@ -5574,6 +5658,15 @@ + + + + + + + + + @@ -5931,6 +6024,15 @@ + + + + + + + + + @@ -7995,6 +8097,15 @@ + + + + + + + + + @@ -8498,10 +8609,13 @@ - + - + + + + diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index 922edbca2de..00fd63f90f9 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -474,6 +474,15 @@ + + + + + + + + + @@ -873,6 +882,12 @@ + + + + + + @@ -1278,6 +1293,24 @@ + + + + + + + + + + + + + + + + + + @@ -1827,6 +1860,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2295,6 +2355,15 @@ + + + + + + + + + @@ -2892,6 +2961,15 @@ + + + + + + + + + @@ -4536,6 +4614,12 @@ + + + + + + @@ -5568,6 +5652,15 @@ + + + + + + + + + @@ -5925,6 +6018,15 @@ + + + + + + + + + @@ -7986,6 +8088,15 @@ + + + + + + + + + @@ -8489,10 +8600,13 @@ - + + + + diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index efd7b273f5d..d6048a235f5 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -483,6 +483,15 @@ + + + + + + + + + @@ -885,6 +894,12 @@ + + + + + + @@ -1290,6 +1305,24 @@ + + + + + + + + + + + + + + + + + + @@ -1839,6 +1872,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2307,6 +2367,15 @@ + + + + + + + + + @@ -2904,6 +2973,15 @@ + + + + + + + + + @@ -4548,6 +4626,12 @@ + + + + + + @@ -5583,6 +5667,15 @@ + + + + + + + + + @@ -5940,6 +6033,15 @@ + + + + + + + + + @@ -8004,6 +8106,15 @@ + + + + + + + + + @@ -8507,10 +8618,13 @@ - + - + + + + diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index 8f52506d6b9..4d76091f527 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -474,6 +474,15 @@ + + + + + + + + + @@ -876,6 +885,12 @@ + + + + + + @@ -1281,6 +1296,24 @@ + + + + + + + + + + + + + + + + + + @@ -1830,6 +1863,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2298,6 +2358,15 @@ + + + + + + + + + @@ -2895,6 +2964,15 @@ + + + + + + + + + @@ -4539,6 +4617,12 @@ + + + + + + @@ -5574,6 +5658,15 @@ + + + + + + + + + @@ -5931,6 +6024,15 @@ + + + + + + + + + @@ -7995,6 +8097,15 @@ + + + + + + + + + @@ -8498,10 +8609,13 @@ - + - + + + + diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index 2418583bb98..dcd9d3695fc 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -474,6 +474,15 @@ + + + + + + + + + @@ -876,6 +885,12 @@ + + + + + + @@ -1281,6 +1296,24 @@ + + + + + + + + + + + + + + + + + + @@ -1830,6 +1863,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2298,6 +2358,15 @@ + + + + + + + + + @@ -2895,6 +2964,15 @@ + + + + + + + + + @@ -4539,6 +4617,12 @@ + + + + + + @@ -5574,6 +5658,15 @@ + + + + + + + + + @@ -5931,6 +6024,15 @@ + + + + + + + + + @@ -7995,6 +8097,15 @@ + + + + + + + + + @@ -8498,10 +8609,13 @@ - + - + + + + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 42685f7a45e..a36010b60e3 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -467,6 +467,15 @@ + + + + + + + + + @@ -866,6 +875,12 @@ + + + + + + @@ -1271,6 +1286,24 @@ + + + + + + + + + + + + + + + + + + @@ -1820,6 +1853,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2288,6 +2348,15 @@ + + + + + + + + + @@ -2885,6 +2954,15 @@ + + + + + + + + + @@ -4529,6 +4607,12 @@ + + + + + + @@ -5561,6 +5645,15 @@ + + + + + + + + + @@ -5918,6 +6011,15 @@ + + + + + + + + + @@ -7979,6 +8081,15 @@ + + + + + + + + + @@ -8482,10 +8593,13 @@ - + - + + + + diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index bcace1bd162..8eed7be8b99 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -467,6 +467,15 @@ + + + + + + + + + @@ -866,6 +875,12 @@ + + + + + + @@ -1271,6 +1286,24 @@ + + + + + + + + + + + + + + + + + + @@ -1820,6 +1853,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2288,6 +2348,15 @@ + + + + + + + + + @@ -2885,6 +2954,15 @@ + + + + + + + + + @@ -4529,6 +4607,12 @@ + + + + + + @@ -5561,6 +5645,15 @@ + + + + + + + + + @@ -5918,6 +6011,15 @@ + + + + + + + + + @@ -7979,6 +8081,15 @@ + + + + + + + + + @@ -8482,10 +8593,13 @@ - + - + + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index ca1dcf2d4cb..a8529c74fd0 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -473,6 +473,15 @@ + + + + + + + + + @@ -875,6 +884,12 @@ + + + + + + @@ -1280,6 +1295,24 @@ + + + + + + + + + + + + + + + + + + @@ -1829,6 +1862,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2297,6 +2357,15 @@ + + + + + + + + + @@ -2894,6 +2963,15 @@ + + + + + + + + + @@ -4538,6 +4616,12 @@ + + + + + + @@ -5573,6 +5657,15 @@ + + + + + + + + + @@ -5930,6 +6023,15 @@ + + + + + + + + + @@ -7994,6 +8096,15 @@ + + + + + + + + + @@ -8497,10 +8608,13 @@ - + - + + + + diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 34cf0f01ff6..c8c49d28117 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -467,6 +467,15 @@ + + + + + + + + + @@ -869,6 +878,12 @@ + + + + + + @@ -1274,6 +1289,24 @@ + + + + + + + + + + + + + + + + + + @@ -1823,6 +1856,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2291,6 +2351,15 @@ + + + + + + + + + @@ -2888,6 +2957,15 @@ + + + + + + + + + @@ -4532,6 +4610,12 @@ + + + + + + @@ -5567,6 +5651,15 @@ + + + + + + + + + @@ -5924,6 +6017,15 @@ + + + + + + + + + @@ -7988,6 +8090,15 @@ + + + + + + + + + @@ -8491,10 +8602,13 @@ - + - + + + + From f4cfc9db731997a9b4b2393bc21a4e1b17183b2f Mon Sep 17 00:00:00 2001 From: csigs Date: Mon, 15 Jan 2018 11:10:12 +0000 Subject: [PATCH 173/189] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 118 +++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index c2febd1ee9b..93c54090734 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -483,6 +483,15 @@ + + + + + + + + + @@ -885,6 +894,12 @@ + + + + + + @@ -1290,6 +1305,24 @@ + + + + + + + + + + + + + + + + + + @@ -1839,6 +1872,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2307,6 +2367,15 @@ + + + + + + + + + @@ -2904,6 +2973,15 @@ + + + + + + + + + @@ -4548,6 +4626,12 @@ + + + + + + @@ -5583,6 +5667,15 @@ + + + + + + + + + @@ -5940,6 +6033,15 @@ + + + + + + + + + @@ -8004,6 +8106,15 @@ + + + + + + + + + @@ -8507,10 +8618,13 @@ - + - + + + + From bcb9fd7825d39774eb9657fd3ddedefb77bfd412 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 16 Jan 2018 17:53:43 +0100 Subject: [PATCH 174/189] fix: formatting for chaining methods (#21027) Closes: #20996 --- src/services/formatting/formatting.ts | 10 ++++- .../fourslash/formattingChainingMethods.ts | 37 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/formattingChainingMethods.ts diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 31f29e9ebbe..49fb1420db8 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -484,7 +484,13 @@ namespace ts.formatting { delta = Math.min(options.indentSize, parentDynamicIndentation.getDelta(node) + delta); } else if (indentation === Constants.Unknown) { - if (SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) { + if (node.kind === SyntaxKind.OpenParenToken && startLine === lastIndentedLine) { + // the is used for chaining methods formatting + // - we need to get the indentation on last line and the delta of parent + indentation = indentationOnLastIndentedLine; + delta = parentDynamicIndentation.getDelta(node); + } + else if (SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) { indentation = parentDynamicIndentation.getIndentation(); } else { @@ -622,7 +628,7 @@ namespace ts.formatting { let childContextNode = contextNode; // if there are any tokens that logically belong to node and interleave child nodes - // such tokens will be consumed in processChildNode for for the child that follows them + // such tokens will be consumed in processChildNode for the child that follows them forEachChild( node, child => { diff --git a/tests/cases/fourslash/formattingChainingMethods.ts b/tests/cases/fourslash/formattingChainingMethods.ts new file mode 100644 index 00000000000..8e8cafb14cd --- /dev/null +++ b/tests/cases/fourslash/formattingChainingMethods.ts @@ -0,0 +1,37 @@ +/// + +//// z$ = this.store.select(this.fake()) +//// .ofType( +//// 'ACTION', +//// 'ACTION-2' +//// ) +//// .pipe( +//// filter(x => !!x), +//// switchMap(() => +//// this.store.select(this.menuSelector.getAll('x')) +//// .pipe( +//// tap(x => { +//// this.x = !x; +//// }) +//// ) +//// ) +//// ); + +format.document(); +verify.currentFileContentIs(`z$ = this.store.select(this.fake()) + .ofType( + 'ACTION', + 'ACTION-2' + ) + .pipe( + filter(x => !!x), + switchMap(() => + this.store.select(this.menuSelector.getAll('x')) + .pipe( + tap(x => { + this.x = !x; + }) + ) + ) + );` +); From 76d95248660d1c7bc7f7a64d5113383f4a015712 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 16 Jan 2018 09:53:42 -0800 Subject: [PATCH 175/189] Fully deprecate the symbol display builder, reimplement in terms of node builder (#18860) * Remove SymbolWriter, give methods to EmitTextWriter * Unification of writers is done-ish * Make node builder support more flags * Write out mixins like we used to * Accept prototype-free baselines * Use instantiated constraint when building mapped type nodes * Accept better mapped type baselines * Report inaccessible this in node builder * Turns out there was a bug in our codefix, too * Symbol display builder usage falling * Replace signatureToString with a nodeBuilder solution * Replace the last internal usages of the symbol writer * Accept semicolon additions * Accept updated symbol baseline output * Start using node builder for some LS operations * Remove those pesky trailing semicolons on signatures * Get signature printing much closer to old output * Parameter lists should not be indented by default, especially when single-line * Signatures up to snuff * Type quickinfo emit is up to snuff * Start of symbol writer replacement, needs a bit more for full compat * Slightly mor accurate to old behavior * Replicate qualified name type argument output correctly * Bring back the old symbol baselines * Mostly identical to old symbol emit now * Perfectly matches old behavior thus far * Replace another usage of the symbol builder * Another usage removed * Another usage removed * Remove final uses of symbol display builder * Remove implementation and types for unused symbol display builder * Cleanup in the checker * monomorphize new emitter code * Replace emitWithSuffix * Push space character to interface with writer * List emit * Fix lack of usage of emitExpression * writeList, not printList * Remove listy writes and replace with new printer calls * Move ListFormat into types.ts * Remove most new XToString functions in favor of node builder functions * Accept API breaks * Add getSymbolDisplayBuilder polyfill * Accept updated API baseline * Move definition to make diff easier to read * Reinternalize some things * Remove trailign whitespace * Reorder for zero diff * Remove newline * Make shim mor eperfectly imitate old behavior * Style feedback * Rename reset to clear to maintain backcompat with SymbolWriter * Fix quickfix * Keep EmitTextWriter internal * Remove EmitTextWriter from public API * Mimic default name declaration emit fix * Fix tests broken by merge * use isFunctionLike * Cleanup, sync TypeFormat and NodeBuilder flags * Reorder Node initialization so pos and end are first, so a TextRange hidden class is made first to reduce future polymorphism * Use variable instead of ternary * Write helper for emitNodeWithWriter * Emitter cleanup * Cleanup whitespace, comment * Reuse printer * Raise error if display parts writer uses rawWrite * Hide writer parameter through different function instead of overload, rename function in emitter * Make less printer * fix lint --- src/compiler/checker.ts | 1334 ++++++----------- src/compiler/core.ts | 8 +- src/compiler/declarationEmitter.ts | 10 +- src/compiler/emitter.ts | 891 ++++++----- src/compiler/factory.ts | 15 +- src/compiler/sourcemap.ts | 8 +- src/compiler/types.ts | 309 +++- src/compiler/utilities.ts | 37 +- src/compiler/visitor.ts | 4 +- src/services/codefixes/inferFromUsage.ts | 17 +- src/services/services.ts | 3 +- src/services/signatureHelp.ts | 42 +- src/services/symbolDisplay.ts | 18 +- src/services/textChanges.ts | 36 +- src/services/utilities.ts | 20 +- .../reference/api/tsserverlibrary.d.ts | 208 ++- tests/baselines/reference/api/typescript.d.ts | 208 ++- .../reference/commentOnParameter1.js | 12 +- .../reference/commentOnParameter2.js | 10 +- tests/baselines/reference/commentsFunction.js | 6 +- .../reference/declFileConstructors.js | 8 +- .../baselines/reference/declFileFunctions.js | 12 +- tests/baselines/reference/declFileMethods.js | 32 +- .../declarationEmitBindingPatterns.js | 2 +- .../declarationEmitDestructuring2.js | 28 +- .../declarationEmitIndexTypeArray.js | 2 +- ...declarationEmitTypeofDefaultExport.symbols | 4 +- .../reference/deferredLookupTypeResolution.js | 4 +- .../deferredLookupTypeResolution.types | 16 +- .../deferredLookupTypeResolution2.errors.txt | 8 +- .../deferredLookupTypeResolution2.types | 28 +- .../isomorphicMappedTypeInference.js | 4 +- ...ngNamedPropertyOfIllegalCharacters.symbols | 4 +- ...nfoDisplayPartsLiteralLikeNames01.baseline | 6 +- .../reference/recursiveTypeRelations.types | 2 +- .../typeGuardFunctionOfFormThisErrors.js | 2 +- ...odeFixClassImplementInterfaceMappedType.ts | 2 +- 37 files changed, 1750 insertions(+), 1610 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5e26b37b61a..7ab50f7be60 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -128,6 +128,11 @@ namespace ts { typeToTypeNode: nodeBuilder.typeToTypeNode, indexInfoToIndexSignatureDeclaration: nodeBuilder.indexInfoToIndexSignatureDeclaration, signatureToSignatureDeclaration: nodeBuilder.signatureToSignatureDeclaration, + symbolToEntityName: nodeBuilder.symbolToEntityName, + symbolToExpression: nodeBuilder.symbolToExpression, + symbolToTypeParameterDeclarations: nodeBuilder.symbolToTypeParameterDeclarations, + symbolToParameterDeclaration: nodeBuilder.symbolToParameterDeclaration, + typeParameterToDeclaration: nodeBuilder.typeParameterToDeclaration, getSymbolsInScope: (location, meaning) => { location = getParseTreeNode(location); return location ? getSymbolsInScope(location, meaning) : []; @@ -155,16 +160,31 @@ namespace ts { location = getParseTreeNode(location, isIdentifier); return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined; }, - signatureToString: (signature, enclosingDeclaration?, flags?, kind?) => { + signatureToString: (signature, enclosingDeclaration, flags, kind) => { return signatureToString(signature, getParseTreeNode(enclosingDeclaration), flags, kind); }, - typeToString: (type, enclosingDeclaration?, flags?) => { + typeToString: (type, enclosingDeclaration, flags) => { return typeToString(type, getParseTreeNode(enclosingDeclaration), flags); }, - getSymbolDisplayBuilder, - symbolToString: (symbol, enclosingDeclaration?, meaning?) => { - return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning); + symbolToString: (symbol, enclosingDeclaration, meaning, flags) => { + return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning, flags); }, + typePredicateToString: (predicate, enclosingDeclaration, flags) => { + return typePredicateToString(predicate, getParseTreeNode(enclosingDeclaration), flags); + }, + writeSignature: (signature, enclosingDeclaration, flags, kind, writer) => { + return signatureToString(signature, getParseTreeNode(enclosingDeclaration), flags, kind, writer); + }, + writeType: (type, enclosingDeclaration, flags, writer) => { + return typeToString(type, getParseTreeNode(enclosingDeclaration), flags, writer); + }, + writeSymbol: (symbol, enclosingDeclaration, meaning, flags, writer) => { + return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning, flags, writer); + }, + writeTypePredicate: (predicate, enclosingDeclaration, flags, writer) => { + return typePredicateToString(predicate, getParseTreeNode(enclosingDeclaration), flags, writer); + }, + getSymbolDisplayBuilder, // TODO (weswigham): Remove once deprecation process is complete getAugmentedPropertiesOfType, getRootSymbols, getContextualType: node => { @@ -273,6 +293,7 @@ namespace ts { }, getJsxNamespace: () => unescapeLeadingUnderscores(getJsxNamespace()), getAccessibleSymbolChain, + getTypePredicateOfSignature, resolveExternalModuleSymbol, }; @@ -520,9 +541,6 @@ namespace ts { const identityRelation = createMap(); const enumRelation = createMap(); - // This is for caching the result of getSymbolDisplayBuilder. Do not access directly. - let _displayBuilder: SymbolDisplayBuilder; - type TypeSystemEntity = Symbol | Type | Signature; const enum TypeSystemPropertyName { @@ -572,6 +590,145 @@ namespace ts { return checker; + /** + * @deprecated + */ + function getSymbolDisplayBuilder(): SymbolDisplayBuilder { + return { + buildTypeDisplay(type, writer, enclosingDeclaration?, flags?) { + typeToString(type, enclosingDeclaration, flags, emitTextWriterWrapper(writer)); + }, + buildSymbolDisplay(symbol, writer, enclosingDeclaration?, meaning?, flags?) { + symbolToString(symbol, enclosingDeclaration, meaning, flags | SymbolFormatFlags.AllowAnyNodeKind, emitTextWriterWrapper(writer)); + }, + buildSignatureDisplay(signature, writer, enclosing?, flags?, kind?) { + signatureToString(signature, enclosing, flags, kind, emitTextWriterWrapper(writer)); + }, + buildIndexSignatureDisplay(info, writer, kind, enclosing?, flags?) { + const sig = nodeBuilder.indexInfoToIndexSignatureDeclaration(info, kind, enclosing, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors, writer); + const printer = createPrinter({ removeComments: true }); + printer.writeNode(EmitHint.Unspecified, sig, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + }, + buildParameterDisplay(symbol, writer, enclosing?, flags?) { + const node = nodeBuilder.symbolToParameterDeclaration(symbol, enclosing, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors, writer); + const printer = createPrinter({ removeComments: true }); + printer.writeNode(EmitHint.Unspecified, node, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + }, + buildTypeParameterDisplay(tp, writer, enclosing?, flags?) { + const node = nodeBuilder.typeParameterToDeclaration(tp, enclosing, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.OmitParameterModifiers, writer); + const printer = createPrinter({ removeComments: true }); + printer.writeNode(EmitHint.Unspecified, node, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + }, + buildTypePredicateDisplay(predicate, writer, enclosing?, flags?) { + typePredicateToString(predicate, enclosing, flags, emitTextWriterWrapper(writer)); + }, + buildTypeParameterDisplayFromSymbol(symbol, writer, enclosing?, flags?) { + const nodes = nodeBuilder.symbolToTypeParameterDeclarations(symbol, enclosing, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors, writer); + const printer = createPrinter({ removeComments: true }); + printer.writeList(ListFormat.TypeParameters, nodes, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + }, + buildDisplayForParametersAndDelimiters(thisParameter, parameters, writer, enclosing?, originalFlags?) { + const printer = createPrinter({ removeComments: true }); + const flags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors | toNodeBuilderFlags(originalFlags); + const thisParameterArray = thisParameter ? [nodeBuilder.symbolToParameterDeclaration(thisParameter, enclosing, flags)] : []; + const params = createNodeArray([...thisParameterArray, ...map(parameters, param => nodeBuilder.symbolToParameterDeclaration(param, enclosing, flags))]); + printer.writeList(ListFormat.CallExpressionArguments, params, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + }, + buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosing?, flags?) { + const printer = createPrinter({ removeComments: true }); + const args = createNodeArray(map(typeParameters, p => nodeBuilder.typeParameterToDeclaration(p, enclosing, toNodeBuilderFlags(flags)))); + printer.writeList(ListFormat.TypeParameters, args, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + }, + buildReturnTypeDisplay(signature, writer, enclosing?, flags?) { + writer.writePunctuation(":"); + writer.writeSpace(" "); + const predicate = getTypePredicateOfSignature(signature); + if (predicate) { + return typePredicateToString(predicate, enclosing, flags, emitTextWriterWrapper(writer)); + } + const node = nodeBuilder.typeToTypeNode(getReturnTypeOfSignature(signature), enclosing, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors, writer); + const printer = createPrinter({ removeComments: true }); + printer.writeNode(EmitHint.Unspecified, node, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + } + }; + + function emitTextWriterWrapper(underlying: SymbolWriter): EmitTextWriter { + return { + write: ts.noop, + writeTextOfNode: ts.noop, + writeLine: ts.noop, + increaseIndent() { + return underlying.increaseIndent(); + }, + decreaseIndent() { + return underlying.decreaseIndent(); + }, + getText() { + return ""; + }, + rawWrite: ts.noop, + writeLiteral(s) { + return underlying.writeStringLiteral(s); + }, + getTextPos() { + return 0; + }, + getLine() { + return 0; + }, + getColumn() { + return 0; + }, + getIndent() { + return 0; + }, + isAtStartOfLine() { + return false; + }, + clear() { + return underlying.clear(); + }, + + writeKeyword(text) { + return underlying.writeKeyword(text); + }, + writeOperator(text) { + return underlying.writeOperator(text); + }, + writePunctuation(text) { + return underlying.writePunctuation(text); + }, + writeSpace(text) { + return underlying.writeSpace(text); + }, + writeStringLiteral(text) { + return underlying.writeStringLiteral(text); + }, + writeParameter(text) { + return underlying.writeParameter(text); + }, + writeProperty(text) { + return underlying.writeProperty(text); + }, + writeSymbol(text, symbol) { + return underlying.writeSymbol(text, symbol); + }, + trackSymbol(symbol, enclosing?, meaning?) { + return underlying.trackSymbol && underlying.trackSymbol(symbol, enclosing, meaning); + }, + reportInaccessibleThisError() { + return underlying.reportInaccessibleThisError && underlying.reportInaccessibleThisError(); + }, + reportPrivateInBaseOfClassExpression(name) { + return underlying.reportPrivateInBaseOfClassExpression && underlying.reportPrivateInBaseOfClassExpression(name); + }, + reportInaccessibleUniqueSymbolError() { + return underlying.reportInaccessibleUniqueSymbolError && underlying.reportInaccessibleUniqueSymbolError(); + } + }; + } + } + function getJsxNamespace(): __String { if (!_jsxNamespace) { _jsxNamespace = "React" as __String; @@ -2516,100 +2673,130 @@ namespace ts { }; } - function writeKeyword(writer: SymbolWriter, kind: SyntaxKind) { - writer.writeKeyword(tokenToString(kind)); + function symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags: SymbolFormatFlags = SymbolFormatFlags.AllowAnyNodeKind, writer?: EmitTextWriter): string { + let nodeFlags = NodeBuilderFlags.IgnoreErrors; + if (flags & SymbolFormatFlags.UseOnlyExternalAliasing) { + nodeFlags |= NodeBuilderFlags.UseOnlyExternalAliasing; + } + if (flags & SymbolFormatFlags.WriteTypeParametersOrArguments) { + nodeFlags |= NodeBuilderFlags.WriteTypeParametersInQualifiedName; + } + const builder = flags & SymbolFormatFlags.AllowAnyNodeKind ? nodeBuilder.symbolToExpression : nodeBuilder.symbolToEntityName; + return writer ? symbolToStringWorker(writer).getText() : usingSingleLineStringWriter(symbolToStringWorker); + + function symbolToStringWorker(writer: EmitTextWriter) { + const entity = builder(symbol, meaning, enclosingDeclaration, nodeFlags); + const printer = createPrinter({ removeComments: true }); + const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); + printer.writeNode(EmitHint.Unspecified, entity, /*sourceFile*/ sourceFile, writer); + return writer; + } } - function writePunctuation(writer: SymbolWriter, kind: SyntaxKind) { - writer.writePunctuation(tokenToString(kind)); + function signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind, writer?: EmitTextWriter): string { + return writer ? signatureToStringWorker(writer).getText() : usingSingleLineStringWriter(signatureToStringWorker); + + function signatureToStringWorker(writer: EmitTextWriter) { + let sigOutput: SyntaxKind; + if (flags & TypeFormatFlags.WriteArrowStyleSignature) { + sigOutput = kind === SignatureKind.Construct ? SyntaxKind.ConstructorType : SyntaxKind.FunctionType; + } + else { + sigOutput = kind === SignatureKind.Construct ? SyntaxKind.ConstructSignature : SyntaxKind.CallSignature; + } + const sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName); + const printer = createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); + printer.writeNode(EmitHint.Unspecified, sig, /*sourceFile*/ sourceFile, writer); + return writer; + } } - function writeSpace(writer: SymbolWriter) { - writer.writeSpace(" "); - } - - function symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string { - return usingSingleLineStringWriter(writer => { - getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning); - }); - } - - function signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string { - return usingSingleLineStringWriter(writer => { - getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags, kind); - }); - } - - function typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string { - const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName); + function typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags, writer: EmitTextWriter = createTextWriter("")): string { + const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors, writer); Debug.assert(typeNode !== undefined, "should always get typenode"); const options = { removeComments: true }; - const writer = createTextWriter(""); const printer = createPrinter(options); const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); printer.writeNode(EmitHint.Unspecified, typeNode, /*sourceFile*/ sourceFile, writer); const result = writer.getText(); const maxLength = compilerOptions.noErrorTruncation || flags & TypeFormatFlags.NoTruncation ? undefined : 100; - if (maxLength && result.length >= maxLength) { + if (maxLength && result && result.length >= maxLength) { return result.substr(0, maxLength - "...".length) + "..."; } return result; + } - function toNodeBuilderFlags(flags?: TypeFormatFlags): NodeBuilderFlags { - let result = NodeBuilderFlags.None; - if (!flags) { - return result; - } - if (flags & TypeFormatFlags.NoTruncation) { - result |= NodeBuilderFlags.NoTruncation; - } - if (flags & TypeFormatFlags.UseFullyQualifiedType) { - result |= NodeBuilderFlags.UseFullyQualifiedType; - } - if (flags & TypeFormatFlags.SuppressAnyReturnType) { - result |= NodeBuilderFlags.SuppressAnyReturnType; - } - if (flags & TypeFormatFlags.WriteArrayAsGenericType) { - result |= NodeBuilderFlags.WriteArrayAsGenericType; - } - if (flags & TypeFormatFlags.WriteTypeArgumentsOfSignature) { - result |= NodeBuilderFlags.WriteTypeArgumentsOfSignature; - } - - return result; - } + function toNodeBuilderFlags(flags?: TypeFormatFlags): NodeBuilderFlags { + return flags & TypeFormatFlags.NodeBuilderFlagsMask; } function createNodeBuilder() { return { - typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { + typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); - const context = createNodeBuilderContext(enclosingDeclaration, flags); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); const resultingNode = typeToTypeNodeHelper(type, context); const result = context.encounteredError ? undefined : resultingNode; return result; }, - indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { + indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); - const context = createNodeBuilderContext(enclosingDeclaration, flags); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); const resultingNode = indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context); const result = context.encounteredError ? undefined : resultingNode; return result; }, - signatureToSignatureDeclaration: (signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { + signatureToSignatureDeclaration: (signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); - const context = createNodeBuilderContext(enclosingDeclaration, flags); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); const resultingNode = signatureToSignatureDeclarationHelper(signature, kind, context); const result = context.encounteredError ? undefined : resultingNode; return result; - } + }, + symbolToEntityName: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { + Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); + const resultingNode = symbolToName(symbol, context, meaning, /*expectsIdentifier*/ false); + const result = context.encounteredError ? undefined : resultingNode; + return result; + }, + symbolToExpression: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { + Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); + const resultingNode = symbolToExpression(symbol, context, meaning); + const result = context.encounteredError ? undefined : resultingNode; + return result; + }, + symbolToTypeParameterDeclarations: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { + Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); + const resultingNode = typeParametersToTypeParameterDeclarations(symbol, context); + const result = context.encounteredError ? undefined : resultingNode; + return result; + }, + symbolToParameterDeclaration: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { + Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); + const resultingNode = symbolToParameterDeclaration(symbol, context); + const result = context.encounteredError ? undefined : resultingNode; + return result; + }, + typeParameterToDeclaration: (parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { + Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); + const resultingNode = typeParameterToDeclaration(parameter, context); + const result = context.encounteredError ? undefined : resultingNode; + return result; + }, }; - function createNodeBuilderContext(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): NodeBuilderContext { + function createNodeBuilderContext(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker: SymbolTracker | undefined): NodeBuilderContext { return { enclosingDeclaration, flags, + tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: noop }, encounteredError: false, symbolStack: undefined }; @@ -2656,6 +2843,11 @@ namespace ts { return (type).intrinsicName === "true" ? createTrue() : createFalse(); } if (type.flags & TypeFlags.UniqueESSymbol) { + if (!(context.flags & NodeBuilderFlags.AllowUniqueESSymbolType)) { + if (context.tracker.reportInaccessibleUniqueSymbolError) { + context.tracker.reportInaccessibleUniqueSymbolError(); + } + } return createTypeOperatorNode(SyntaxKind.UniqueKeyword, createKeywordTypeNode(SyntaxKind.SymbolKeyword)); } if (type.flags & TypeFlags.Void) { @@ -2681,6 +2873,9 @@ namespace ts { if (!context.encounteredError && !(context.flags & NodeBuilderFlags.AllowThisInObjectLiteral)) { context.encounteredError = true; } + if (context.tracker.reportInaccessibleThisError) { + context.tracker.reportInaccessibleThisError(); + } } return createThis(); } @@ -2696,7 +2891,7 @@ namespace ts { // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return createTypeReferenceNode(name, /*typeArguments*/ undefined); } - if (!inTypeAlias && type.aliasSymbol && isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration)) { + if (!inTypeAlias && type.aliasSymbol && (context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope || isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration))) { const name = symbolToTypeReferenceName(type.aliasSymbol); const typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context); return createTypeReferenceNode(name, typeArgumentNodes); @@ -2737,7 +2932,7 @@ namespace ts { Debug.assert(!!(type.flags & TypeFlags.Object)); const readonlyToken = type.declaration && type.declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; const questionToken = type.declaration && type.declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; - const typeParameterNode = typeParameterToDeclaration(getTypeParameterFromMappedType(type), context); + const typeParameterNode = typeParameterToDeclaration(getTypeParameterFromMappedType(type), context, getConstraintTypeFromMappedType(type)); const templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context); const mappedTypeNode = createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); @@ -2748,7 +2943,7 @@ namespace ts { const symbol = type.symbol; if (symbol) { // Always use 'typeof T' for type of class, enum, and module objects - if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || + if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) && !(symbol.valueDeclaration.kind === SyntaxKind.ClassExpression && context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) || symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || shouldWriteTypeOfFunctionSymbol()) { return createTypeQueryNodeFromSymbol(symbol, SymbolFlags.Value); @@ -2771,10 +2966,17 @@ namespace ts { if (!context.symbolStack) { context.symbolStack = []; } - context.symbolStack.push(symbol); - const result = createTypeNodeFromObjectType(type); - context.symbolStack.pop(); - return result; + + const isConstructorObject = getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & SymbolFlags.Class; + if (isConstructorObject) { + return createTypeNodeFromObjectType(type); + } + else { + context.symbolStack.push(symbol); + const result = createTypeNodeFromObjectType(type); + context.symbolStack.pop(); + return result; + } } } else { @@ -2791,7 +2993,7 @@ namespace ts { declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { // typeof is allowed only for static/non local functions - return contains(context.symbolStack, symbol); // it is type of the symbol uses itself recursively + return !!(context.flags & NodeBuilderFlags.UseTypeOfFunction) || contains(context.symbolStack, symbol); // it is type of the symbol uses itself recursively } } } @@ -2826,7 +3028,7 @@ namespace ts { const members = createTypeNodesFromResolvedType(resolved); context.flags = savedFlags; const typeLiteralNode = createTypeLiteralNode(members); - return setEmitFlags(typeLiteralNode, EmitFlags.SingleLine); + return setEmitFlags(typeLiteralNode, (context.flags & NodeBuilderFlags.MultilineObjectLiterals) ? 0 : EmitFlags.SingleLine); } function createTypeQueryNodeFromSymbol(symbol: Symbol, symbolFlags: SymbolFlags) { @@ -2864,6 +3066,11 @@ namespace ts { context.encounteredError = true; return undefined; } + else if (context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral && + type.symbol.valueDeclaration && + type.symbol.valueDeclaration.kind === SyntaxKind.ClassExpression) { + return createAnonymousTypeNode(type); + } else { const outerTypeParameters = type.target.outerTypeParameters; let i = 0; @@ -2965,9 +3172,24 @@ namespace ts { } for (const propertySymbol of properties) { + if (context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) { + if (propertySymbol.flags & SymbolFlags.Prototype) { + continue; + } + if (getDeclarationModifierFlagsFromSymbol(propertySymbol) & (ModifierFlags.Private | ModifierFlags.Protected) && context.tracker.reportPrivateInBaseOfClassExpression) { + context.tracker.reportPrivateInBaseOfClassExpression(unescapeLeadingUnderscores(propertySymbol.escapedName)); + } + } const propertyType = getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped ? anyType : getTypeOfSymbol(propertySymbol); const saveEnclosingDeclaration = context.enclosingDeclaration; context.enclosingDeclaration = undefined; + if (getCheckFlags(propertySymbol) & CheckFlags.Late) { + const decl = firstOrUndefined(propertySymbol.declarations); + const name = hasLateBindableName(decl) && resolveEntityName(decl.name.expression, SymbolFlags.Value); + if (name && context.tracker.trackSymbol) { + context.tracker.trackSymbol(name, saveEnclosingDeclaration, SymbolFlags.Value); + } + } const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true); context.enclosingDeclaration = saveEnclosingDeclaration; const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined; @@ -3023,7 +3245,10 @@ namespace ts { /*questionToken*/ undefined, indexerTypeNode, /*initializer*/ undefined); - const typeNode = typeToTypeNodeHelper(indexInfo.type, context); + const typeNode = indexInfo.type ? typeToTypeNodeHelper(indexInfo.type, context) : typeToTypeNodeHelper(anyType, context); + if (!indexInfo.type && !(context.flags & NodeBuilderFlags.AllowEmptyIndexInfoType)) { + context.encounteredError = true; + } return createIndexSignature( /*decorators*/ undefined, indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined, @@ -3032,7 +3257,14 @@ namespace ts { } function signatureToSignatureDeclarationHelper(signature: Signature, kind: SyntaxKind, context: NodeBuilderContext): SignatureDeclaration { - const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, context)); + let typeParameters: TypeParameterDeclaration[]; + let typeArguments: TypeNode[]; + if (context.flags & NodeBuilderFlags.WriteTypeArgumentsOfSignature && signature.target && signature.mapper && signature.target.typeParameters) { + typeArguments = signature.target.typeParameters.map(parameter => typeToTypeNodeHelper(instantiateType(parameter, signature.mapper), context)); + } + else { + typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, context)); + } const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter, context)); if (signature.thisParameter) { const thisParameter = symbolToParameterDeclaration(signature.thisParameter, context); @@ -3059,15 +3291,17 @@ namespace ts { else if (!returnTypeNode) { returnTypeNode = createKeywordTypeNode(SyntaxKind.AnyKeyword); } - return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode); + return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode, typeArguments); } - function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext): TypeParameterDeclaration { + function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintFromTypeParameter(type)): TypeParameterDeclaration { + const savedContextFlags = context.flags; + context.flags &= ~NodeBuilderFlags.WriteTypeParametersInQualifiedName; // Avoids potential infinite loop when building for a claimspace with a generic const name = symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ true); - const constraint = getConstraintFromTypeParameter(type); const constraintNode = constraint && typeToTypeNodeHelper(constraint, context); const defaultParameter = getDefaultFromTypeParameter(type); const defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, context); + context.flags = savedContextFlags; return createTypeParameterDeclaration(name, constraintNode, defaultParameterNode); } @@ -3081,7 +3315,7 @@ namespace ts { } const parameterTypeNode = typeToTypeNodeHelper(parameterType, context); - const modifiers = parameterDeclaration && parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedClone); + const modifiers = !(context.flags & NodeBuilderFlags.OmitParameterModifiers) && parameterDeclaration && parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedClone); const dotDotDotToken = !parameterDeclaration || isRestParameter(parameterDeclaration) ? createToken(SyntaxKind.DotDotDotToken) : undefined; const name = parameterDeclaration ? parameterDeclaration.name ? @@ -3114,10 +3348,8 @@ namespace ts { } } - function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: true): Identifier; - function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: false): EntityName; - function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: boolean): EntityName { - + function lookupSymbolChain(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags) { + context.tracker.trackSymbol(symbol, context.enclosingDeclaration, meaning); // Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration. let chain: Symbol[]; const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; @@ -3128,42 +3360,11 @@ namespace ts { else { chain = [symbol]; } - - if (expectsIdentifier && chain.length !== 1 - && !context.encounteredError - && !(context.flags & NodeBuilderFlags.AllowQualifedNameInPlaceOfIdentifier)) { - context.encounteredError = true; - } - return createEntityNameFromSymbolChain(chain, chain.length - 1); - - function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { - Debug.assert(chain && 0 <= index && index < chain.length); - const symbol = chain[index]; - let typeParameterNodes: ReadonlyArray | undefined; - if (context.flags & NodeBuilderFlags.WriteTypeParametersInQualifiedName && index > 0) { - const parentSymbol = chain[index - 1]; - let typeParameters: TypeParameter[]; - if (getCheckFlags(symbol) & CheckFlags.Instantiated) { - typeParameters = getTypeParametersOfClassOrInterface(parentSymbol); - } - else { - const targetSymbol = getTargetSymbol(parentSymbol); - if (targetSymbol.flags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeAlias)) { - typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); - } - } - - typeParameterNodes = mapToTypeNodes(typeParameters, context); - } - - const identifier = setEmitFlags(createIdentifier(getNameOfSymbolAsWritten(symbol, context), typeParameterNodes), EmitFlags.NoAsciiEscaping); - - return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; - } + return chain; /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined { - let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/ false); + let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & NodeBuilderFlags.UseOnlyExternalAliasing)); let parentSymbol: Symbol; if (!accessibleSymbolChain || @@ -3195,12 +3396,113 @@ namespace ts { } } } + + function typeParametersToTypeParameterDeclarations(symbol: Symbol, context: NodeBuilderContext) { + let typeParameterNodes: NodeArray | undefined; + const targetSymbol = getTargetSymbol(symbol); + if (targetSymbol.flags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeAlias)) { + typeParameterNodes = createNodeArray(map(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), tp => typeParameterToDeclaration(tp, context))); + } + return typeParameterNodes; + } + + function lookupTypeParameterNodes(chain: Symbol[], index: number, context: NodeBuilderContext) { + Debug.assert(chain && 0 <= index && index < chain.length); + const symbol = chain[index]; + let typeParameterNodes: ReadonlyArray | ReadonlyArray | undefined; + if (context.flags & NodeBuilderFlags.WriteTypeParametersInQualifiedName && index < (chain.length - 1)) { + const parentSymbol = symbol; + const nextSymbol = chain[index + 1]; + if (getCheckFlags(nextSymbol) & CheckFlags.Instantiated) { + const params = getTypeParametersOfClassOrInterface( + parentSymbol.flags & SymbolFlags.Alias ? resolveAlias(parentSymbol) : parentSymbol + ); + typeParameterNodes = mapToTypeNodes(map(params, (nextSymbol as TransientSymbol).mapper), context); + } + else { + typeParameterNodes = typeParametersToTypeParameterDeclarations(symbol, context); + } + } + return typeParameterNodes; + } + + function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: true): Identifier; + function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: false): EntityName; + function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: boolean): EntityName { + const chain = lookupSymbolChain(symbol, context, meaning); + + if (expectsIdentifier && chain.length !== 1 + && !context.encounteredError + && !(context.flags & NodeBuilderFlags.AllowQualifedNameInPlaceOfIdentifier)) { + context.encounteredError = true; + } + return createEntityNameFromSymbolChain(chain, chain.length - 1); + + function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { + const typeParameterNodes = lookupTypeParameterNodes(chain, index, context); + const symbol = chain[index]; + const symbolName = getNameOfSymbolAsWritten(symbol, context); + const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + identifier.symbol = symbol; + + return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; + } + } + + function symbolToExpression(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags) { + const chain = lookupSymbolChain(symbol, context, meaning); + + return createExpressionFromSymbolChain(chain, chain.length - 1); + + function createExpressionFromSymbolChain(chain: Symbol[], index: number): Expression { + const typeParameterNodes = lookupTypeParameterNodes(chain, index, context); + const symbol = chain[index]; + + let symbolName = getNameOfSymbolAsWritten(symbol, context); + let firstChar = symbolName.charCodeAt(0); + const canUsePropertyAccess = isIdentifierStart(firstChar, languageVersion); + if (index === 0 || canUsePropertyAccess) { + const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + identifier.symbol = symbol; + + return index > 0 ? createPropertyAccess(createExpressionFromSymbolChain(chain, index - 1), identifier) : identifier; + } + else { + if (firstChar === CharacterCodes.openBracket) { + symbolName = symbolName.substring(1, symbolName.length - 1); + firstChar = symbolName.charCodeAt(0); + } + let expression: Expression; + if (isSingleOrDoubleQuote(firstChar)) { + expression = createLiteral(symbolName.substring(1, symbolName.length - 1).replace(/\\./g, s => s.substring(1))); + (expression as StringLiteral).singleQuote = firstChar === CharacterCodes.singleQuote; + } + else if (("" + +symbolName) === symbolName) { + expression = createLiteral(+symbolName); + } + if (!expression) { + expression = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + expression.symbol = symbol; + } + return createElementAccess(createExpressionFromSymbolChain(chain, index - 1), expression); + } + } + } } - function typePredicateToString(typePredicate: TypePredicate, enclosingDeclaration?: Declaration, flags?: TypeFormatFlags): string { - return usingSingleLineStringWriter(writer => { - getSymbolDisplayBuilder().buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags); - }); + function typePredicateToString(typePredicate: TypePredicate, enclosingDeclaration?: Node, flags?: TypeFormatFlags, writer?: EmitTextWriter): string { + return writer ? typePredicateToStringWorker(writer).getText() : usingSingleLineStringWriter(typePredicateToStringWorker); + + function typePredicateToStringWorker(writer: EmitTextWriter) { + const predicate = createTypePredicateNode( + typePredicate.kind === TypePredicateKind.Identifier ? createIdentifier(typePredicate.parameterName) : createThisTypeNode(), + nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName) + ); + const printer = createPrinter({ removeComments: true }); + const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); + printer.writeNode(EmitHint.Unspecified, predicate, /*sourceFile*/ sourceFile, writer); + return writer; + } } function formatUnionTypes(types: Type[]): Type[] { @@ -3262,6 +3564,7 @@ namespace ts { interface NodeBuilderContext { enclosingDeclaration: Node | undefined; flags: NodeBuilderFlags | undefined; + tracker: SymbolTracker | undefined; // State encounteredError: boolean; @@ -3276,6 +3579,9 @@ namespace ts { * It will also use a representation of a number as written instead of a decimal form, e.g. `0o11` instead of `9`. */ function getNameOfSymbolAsWritten(symbol: Symbol, context?: NodeBuilderContext): string { + if (context && context.flags & NodeBuilderFlags.WriteDefaultSymbolWithoutName && symbol.escapedName === InternalSymbolName.Default) { + return "default"; + } if (symbol.declarations && symbol.declarations.length) { const declaration = symbol.declarations[0]; const name = getNameOfDeclaration(declaration); @@ -3305,781 +3611,6 @@ namespace ts { return symbolName(symbol); } - function getSymbolDisplayBuilder(): SymbolDisplayBuilder { - - /** - * Writes only the name of the symbol out to the writer. Uses the original source text - * for the name of the symbol if it is available to match how the user wrote the name. - */ - function appendSymbolNameOnly(symbol: Symbol, writer: SymbolWriter): void { - writer.writeSymbol(getNameOfSymbolAsWritten(symbol), symbol); - } - - /** - * Writes a property access or element access with the name of the symbol out to the writer. - * Uses the original source text for the name of the symbol if it is available to match how the user wrote the name, - * ensuring that any names written with literals use element accesses. - */ - function appendPropertyOrElementAccessForSymbol(symbol: Symbol, writer: SymbolWriter): void { - const symbolName = symbol.escapedName === InternalSymbolName.Default ? InternalSymbolName.Default : getNameOfSymbolAsWritten(symbol); - const firstChar = symbolName.charCodeAt(0); - const needsElementAccess = !isIdentifierStart(firstChar, languageVersion); - - if (needsElementAccess) { - if (firstChar !== CharacterCodes.openBracket) { - writePunctuation(writer, SyntaxKind.OpenBracketToken); - } - if (isSingleOrDoubleQuote(firstChar)) { - writer.writeStringLiteral(symbolName); - } - else { - writer.writeSymbol(symbolName, symbol); - } - if (firstChar !== CharacterCodes.openBracket) { - writePunctuation(writer, SyntaxKind.CloseBracketToken); - } - } - else { - writePunctuation(writer, SyntaxKind.DotToken); - writer.writeSymbol(symbolName, symbol); - } - } - - /** - * Enclosing declaration is optional when we don't want to get qualified name in the enclosing declaration scope - * Meaning needs to be specified if the enclosing declaration is given - */ - function buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags, typeFlags?: TypeFormatFlags): void { - let parentSymbol: Symbol; - function appendParentTypeArgumentsAndSymbolName(symbol: Symbol): void { - if (parentSymbol) { - // Write type arguments of instantiated class/interface here - if (flags & SymbolFormatFlags.WriteTypeParametersOrArguments) { - if (getCheckFlags(symbol) & CheckFlags.Instantiated) { - const params = getTypeParametersOfClassOrInterface(parentSymbol.flags & SymbolFlags.Alias ? resolveAlias(parentSymbol) : parentSymbol); - buildDisplayForTypeArgumentsAndDelimiters(params, (symbol).mapper, writer, enclosingDeclaration); - } - else { - buildTypeParameterDisplayFromSymbol(parentSymbol, writer, enclosingDeclaration); - } - } - appendPropertyOrElementAccessForSymbol(symbol, writer); - } - else { - appendSymbolNameOnly(symbol, writer); - } - parentSymbol = symbol; - } - - // Let the writer know we just wrote out a symbol. The declaration emitter writer uses - // this to determine if an import it has previously seen (and not written out) needs - // to be written to the file once the walk of the tree is complete. - // - // NOTE(cyrusn): This approach feels somewhat unfortunate. A simple pass over the tree - // up front (for example, during checking) could determine if we need to emit the imports - // and we could then access that data during declaration emit. - writer.trackSymbol(symbol, enclosingDeclaration, meaning); - /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ - function walkSymbol(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): void { - const accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, !!(flags & SymbolFormatFlags.UseOnlyExternalAliasing)); - - if (!accessibleSymbolChain || - needsQualification(accessibleSymbolChain[0], enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) { - - // Go up and add our parent. - const parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol); - if (parent) { - walkSymbol(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false); - } - } - - if (accessibleSymbolChain) { - for (const accessibleSymbol of accessibleSymbolChain) { - appendParentTypeArgumentsAndSymbolName(accessibleSymbol); - } - } - else if ( - // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols. - endOfChain || - // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.) - !(!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) && - // If a parent symbol is an anonymous type, don't write it. - !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral))) { - - appendParentTypeArgumentsAndSymbolName(symbol); - } - } - - // Get qualified name if the symbol is not a type parameter - // and there is an enclosing declaration or we specifically - // asked for it - const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; - const typeFormatFlag = TypeFormatFlags.UseFullyQualifiedType & typeFlags; - if (!isTypeParameter && (enclosingDeclaration || typeFormatFlag)) { - walkSymbol(symbol, meaning, /*endOfChain*/ true); - } - else { - appendParentTypeArgumentsAndSymbolName(symbol); - } - } - - function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) { - const globalFlagsToPass = globalFlags & (TypeFormatFlags.WriteOwnNameForAnyLike | TypeFormatFlags.WriteClassExpressionAsTypeLiteral); - let inObjectTypeLiteral = false; - return writeType(type, globalFlags); - - function writeType(type: Type, flags: TypeFormatFlags) { - const nextFlags = flags & ~TypeFormatFlags.InTypeAlias; - // Write undefined/null type as any - if (type.flags & TypeFlags.Intrinsic) { - // Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving - writer.writeKeyword(!(globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike) && isTypeAny(type) - ? "any" - : (type).intrinsicName); - } - else if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { - if (inObjectTypeLiteral) { - writer.reportInaccessibleThisError(); - } - writer.writeKeyword("this"); - } - else if (getObjectFlags(type) & ObjectFlags.Reference) { - writeTypeReference(type, nextFlags); - } - else if (type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union)) { - const parent = getParentOfSymbol(type.symbol); - buildSymbolDisplay(parent, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags); - // In a literal enum type with a single member E { A }, E and E.A denote the - // same type. We always display this type simply as E. - if (getDeclaredTypeOfSymbol(parent) !== type) { - writePunctuation(writer, SyntaxKind.DotToken); - appendSymbolNameOnly(type.symbol, writer); - } - } - else if (getObjectFlags(type) & ObjectFlags.ClassOrInterface || type.flags & (TypeFlags.EnumLike | TypeFlags.TypeParameter)) { - // The specified symbol flags need to be reinterpreted as type flags - buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags); - } - else if (!(flags & TypeFormatFlags.InTypeAlias) && type.aliasSymbol && - ((flags & TypeFormatFlags.UseAliasDefinedOutsideCurrentScope) || isTypeSymbolAccessible(type.aliasSymbol, enclosingDeclaration))) { - const typeArguments = type.aliasTypeArguments; - writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, length(typeArguments), nextFlags); - } - else if (type.flags & TypeFlags.UnionOrIntersection) { - writeUnionOrIntersectionType(type, nextFlags); - } - else if (getObjectFlags(type) & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { - writeAnonymousType(type, nextFlags); - } - else if (type.flags & TypeFlags.UniqueESSymbol) { - if (flags & TypeFormatFlags.AllowUniqueESSymbolType) { - writeKeyword(writer, SyntaxKind.UniqueKeyword); - writeSpace(writer); - } - else { - writer.reportInaccessibleUniqueSymbolError(); - } - writeKeyword(writer, SyntaxKind.SymbolKeyword); - } - else if (type.flags & TypeFlags.StringOrNumberLiteral) { - writer.writeStringLiteral(literalTypeToString(type)); - } - else if (type.flags & TypeFlags.Index) { - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - } - writer.writeKeyword("keyof"); - writeSpace(writer); - writeType((type).type, TypeFormatFlags.InElementType); - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - } - else if (type.flags & TypeFlags.IndexedAccess) { - writeType((type).objectType, TypeFormatFlags.InElementType); - writePunctuation(writer, SyntaxKind.OpenBracketToken); - writeType((type).indexType, TypeFormatFlags.None); - writePunctuation(writer, SyntaxKind.CloseBracketToken); - } - else { - // Should never get here - // { ... } - writePunctuation(writer, SyntaxKind.OpenBraceToken); - writeSpace(writer); - writePunctuation(writer, SyntaxKind.DotDotDotToken); - writeSpace(writer); - writePunctuation(writer, SyntaxKind.CloseBraceToken); - } - } - - - function writeTypeList(types: Type[], delimiter: SyntaxKind) { - for (let i = 0; i < types.length; i++) { - if (i > 0) { - if (delimiter !== SyntaxKind.CommaToken) { - writeSpace(writer); - } - writePunctuation(writer, delimiter); - writeSpace(writer); - } - writeType(types[i], delimiter === SyntaxKind.CommaToken ? TypeFormatFlags.None : TypeFormatFlags.InElementType); - } - } - - function writeSymbolTypeReference(symbol: Symbol, typeArguments: Type[], pos: number, end: number, flags: TypeFormatFlags) { - // Unnamed function expressions and arrow functions have reserved names that we don't want to display - if (symbol.flags & SymbolFlags.Class || !isReservedMemberName(symbol.escapedName)) { - buildSymbolDisplay(symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags); - } - if (pos < end) { - writePunctuation(writer, SyntaxKind.LessThanToken); - writeType(typeArguments[pos], TypeFormatFlags.InFirstTypeArgument); - pos++; - while (pos < end) { - writePunctuation(writer, SyntaxKind.CommaToken); - writeSpace(writer); - writeType(typeArguments[pos], TypeFormatFlags.None); - pos++; - } - writePunctuation(writer, SyntaxKind.GreaterThanToken); - } - } - - function writeTypeReference(type: TypeReference, flags: TypeFormatFlags) { - const typeArguments = type.typeArguments || emptyArray; - if (type.target === globalArrayType && !(flags & TypeFormatFlags.WriteArrayAsGenericType)) { - writeType(typeArguments[0], TypeFormatFlags.InElementType | TypeFormatFlags.InArrayType); - writePunctuation(writer, SyntaxKind.OpenBracketToken); - writePunctuation(writer, SyntaxKind.CloseBracketToken); - } - else if (type.target.objectFlags & ObjectFlags.Tuple) { - writePunctuation(writer, SyntaxKind.OpenBracketToken); - writeTypeList(type.typeArguments.slice(0, getTypeReferenceArity(type)), SyntaxKind.CommaToken); - writePunctuation(writer, SyntaxKind.CloseBracketToken); - } - else if (flags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral && - type.symbol.valueDeclaration && - type.symbol.valueDeclaration.kind === SyntaxKind.ClassExpression) { - writeAnonymousType(type, flags); - } - else { - // Write the type reference in the format f.g.C where A and B are type arguments - // for outer type parameters, and f and g are the respective declaring containers of those - // type parameters. - const outerTypeParameters = type.target.outerTypeParameters; - let i = 0; - if (outerTypeParameters) { - const length = outerTypeParameters.length; - while (i < length) { - // Find group of type arguments for type parameters with the same declaring container. - const start = i; - const parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]); - do { - i++; - } while (i < length && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent); - // When type parameters are their own type arguments for the whole group (i.e. we have - // the default outer type arguments), we don't show the group. - if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { - writeSymbolTypeReference(parent, typeArguments, start, i, flags); - writePunctuation(writer, SyntaxKind.DotToken); - } - } - } - const typeParameterCount = (type.target.typeParameters || emptyArray).length; - writeSymbolTypeReference(type.symbol, typeArguments, i, typeParameterCount, flags); - } - } - - function writeUnionOrIntersectionType(type: UnionOrIntersectionType, flags: TypeFormatFlags) { - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - } - if (type.flags & TypeFlags.Union) { - writeTypeList(formatUnionTypes(type.types), SyntaxKind.BarToken); - } - else { - writeTypeList(type.types, SyntaxKind.AmpersandToken); - } - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - } - - function writeAnonymousType(type: ObjectType, flags: TypeFormatFlags) { - const symbol = type.symbol; - if (symbol) { - // Always use 'typeof T' for type of class, enum, and module objects - if (symbol.flags & SymbolFlags.Class && - !getBaseTypeVariableOfClass(symbol) && - !(symbol.valueDeclaration.kind === SyntaxKind.ClassExpression && flags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral) || - symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule)) { - writeTypeOfSymbol(type.symbol, flags); - } - else if (shouldWriteTypeOfFunctionSymbol()) { - writeTypeOfSymbol(type.symbol, flags); - } - else if (contains(symbolStack, symbol)) { - // If type is an anonymous type literal in a type alias declaration, use type alias name - const typeAlias = getTypeAliasForTypeLiteral(type); - if (typeAlias) { - // The specified symbol flags need to be reinterpreted as type flags - buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags); - } - else { - // Recursive usage, use any - writeKeyword(writer, SyntaxKind.AnyKeyword); - } - } - else { - // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead - // of types allows us to catch circular references to instantiations of the same anonymous type - // However, in case of class expressions, we want to write both the static side and the instance side. - // We skip adding the static side so that the instance side has a chance to be written - // before checking for circular references. - if (!symbolStack) { - symbolStack = []; - } - const isConstructorObject = type.objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & SymbolFlags.Class; - if (isConstructorObject) { - writeLiteralType(type, flags); - } - else { - symbolStack.push(symbol); - writeLiteralType(type, flags); - symbolStack.pop(); - } - } - } - else { - // Anonymous types with no symbol are never circular - writeLiteralType(type, flags); - } - - function shouldWriteTypeOfFunctionSymbol() { - const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method) && // typeof static method - some(symbol.declarations, declaration => hasModifier(declaration, ModifierFlags.Static)); - const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && - (symbol.parent || // is exported function symbol - some(symbol.declarations, declaration => - declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); - if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { - // typeof is allowed only for static/non local functions - return !!(flags & TypeFormatFlags.UseTypeOfFunction) || // use typeof if format flags specify it - contains(symbolStack, symbol); // it is type of the symbol uses itself recursively - } - } - } - - function writeTypeOfSymbol(symbol: Symbol, typeFormatFlags?: TypeFormatFlags) { - if (typeFormatFlags & TypeFormatFlags.InArrayType) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - } - writeKeyword(writer, SyntaxKind.TypeOfKeyword); - writeSpace(writer); - buildSymbolDisplay(symbol, writer, enclosingDeclaration, SymbolFlags.Value, SymbolFormatFlags.None, typeFormatFlags); - if (typeFormatFlags & TypeFormatFlags.InArrayType) { - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - } - - function writePropertyWithModifiers(prop: Symbol) { - if (isReadonlySymbol(prop)) { - writeKeyword(writer, SyntaxKind.ReadonlyKeyword); - writeSpace(writer); - } - if (getCheckFlags(prop) & CheckFlags.Late) { - const decl = firstOrUndefined(prop.declarations); - const name = hasLateBindableName(decl) && resolveEntityName(decl.name.expression, SymbolFlags.Value); - if (name) { - writer.trackSymbol(name, enclosingDeclaration, SymbolFlags.Value); - } - } - buildSymbolDisplay(prop, writer); - if (prop.flags & SymbolFlags.Optional) { - writePunctuation(writer, SyntaxKind.QuestionToken); - } - } - - function shouldAddParenthesisAroundFunctionType(callSignature: Signature, flags: TypeFormatFlags) { - if (flags & TypeFormatFlags.InElementType) { - return true; - } - else if (flags & TypeFormatFlags.InFirstTypeArgument) { - // Add parenthesis around function type for the first type argument to avoid ambiguity - const typeParameters = callSignature.target && (flags & TypeFormatFlags.WriteTypeArgumentsOfSignature) ? - callSignature.target.typeParameters : callSignature.typeParameters; - return typeParameters && typeParameters.length !== 0; - } - return false; - } - - function writeLiteralType(type: ObjectType, flags: TypeFormatFlags) { - if (isGenericMappedType(type)) { - writeMappedType(type); - return; - } - - const resolved = resolveStructuredTypeMembers(type); - if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { - if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { - writePunctuation(writer, SyntaxKind.OpenBraceToken); - writePunctuation(writer, SyntaxKind.CloseBraceToken); - return; - } - - if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { - const parenthesizeSignature = shouldAddParenthesisAroundFunctionType(resolved.callSignatures[0], flags); - if (parenthesizeSignature) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - } - buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, /*kind*/ undefined, symbolStack); - if (parenthesizeSignature) { - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - return; - } - if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - } - writeKeyword(writer, SyntaxKind.NewKeyword); - writeSpace(writer); - buildSignatureDisplay(resolved.constructSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, /*kind*/ undefined, symbolStack); - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - return; - } - } - - const saveInObjectTypeLiteral = inObjectTypeLiteral; - inObjectTypeLiteral = true; - writePunctuation(writer, SyntaxKind.OpenBraceToken); - writer.writeLine(); - writer.increaseIndent(); - writeObjectLiteralType(resolved); - writer.decreaseIndent(); - writePunctuation(writer, SyntaxKind.CloseBraceToken); - inObjectTypeLiteral = saveInObjectTypeLiteral; - } - - function writeObjectLiteralType(resolved: ResolvedType) { - for (const signature of resolved.callSignatures) { - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - for (const signature of resolved.constructSignatures) { - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, SignatureKind.Construct, symbolStack); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - const stringIndexInfo = resolved.objectFlags & ObjectFlags.ReverseMapped && resolved.stringIndexInfo ? - createIndexInfo(anyType, resolved.stringIndexInfo.isReadonly, resolved.stringIndexInfo.declaration) : - resolved.stringIndexInfo; - buildIndexSignatureDisplay(stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack); - buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, IndexKind.Number, enclosingDeclaration, globalFlags, symbolStack); - for (const p of resolved.properties) { - if (globalFlags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral) { - if (p.flags & SymbolFlags.Prototype) { - continue; - } - if (getDeclarationModifierFlagsFromSymbol(p) & (ModifierFlags.Private | ModifierFlags.Protected)) { - writer.reportPrivateInBaseOfClassExpression(symbolName(p)); - } - } - const t = getCheckFlags(p) & CheckFlags.ReverseMapped ? anyType : getTypeOfSymbol(p); - if (p.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) { - const signatures = getSignaturesOfType(t, SignatureKind.Call); - for (const signature of signatures) { - writePropertyWithModifiers(p); - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - } - else { - writePropertyWithModifiers(p); - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - writeType(t, globalFlags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - } - } - - function writeMappedType(type: MappedType) { - writePunctuation(writer, SyntaxKind.OpenBraceToken); - writer.writeLine(); - writer.increaseIndent(); - if (type.declaration.readonlyToken) { - writeKeyword(writer, SyntaxKind.ReadonlyKeyword); - writeSpace(writer); - } - writePunctuation(writer, SyntaxKind.OpenBracketToken); - appendSymbolNameOnly(getTypeParameterFromMappedType(type).symbol, writer); - writeSpace(writer); - writeKeyword(writer, SyntaxKind.InKeyword); - writeSpace(writer); - writeType(getConstraintTypeFromMappedType(type), TypeFormatFlags.None); - writePunctuation(writer, SyntaxKind.CloseBracketToken); - if (type.declaration.questionToken) { - writePunctuation(writer, SyntaxKind.QuestionToken); - } - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - writeType(getTemplateTypeFromMappedType(type), TypeFormatFlags.None); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - writer.decreaseIndent(); - writePunctuation(writer, SyntaxKind.CloseBraceToken); - } - } - - function buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags) { - const targetSymbol = getTargetSymbol(symbol); - if (targetSymbol.flags & SymbolFlags.Class || targetSymbol.flags & SymbolFlags.Interface || targetSymbol.flags & SymbolFlags.TypeAlias) { - buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaration, flags); - } - } - - function buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - appendSymbolNameOnly(tp.symbol, writer); - const constraint = getConstraintOfTypeParameter(tp); - if (constraint) { - writeSpace(writer); - writeKeyword(writer, SyntaxKind.ExtendsKeyword); - writeSpace(writer); - buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, symbolStack); - } - const defaultType = getDefaultFromTypeParameter(tp); - if (defaultType) { - writeSpace(writer); - writePunctuation(writer, SyntaxKind.EqualsToken); - writeSpace(writer); - buildTypeDisplay(defaultType, writer, enclosingDeclaration, flags, symbolStack); - } - } - - function buildParameterDisplay(p: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - const parameterNode = p.valueDeclaration; - - if (parameterNode ? isRestParameter(parameterNode) : isTransientSymbol(p) && p.isRestParameter) { - writePunctuation(writer, SyntaxKind.DotDotDotToken); - } - if (parameterNode && isBindingPattern(parameterNode.name)) { - buildBindingPatternDisplay(parameterNode.name, writer, enclosingDeclaration, flags, symbolStack); - } - else { - appendSymbolNameOnly(p, writer); - } - if (parameterNode && isOptionalParameter(parameterNode)) { - writePunctuation(writer, SyntaxKind.QuestionToken); - } - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - - let type = getTypeOfSymbol(p); - if (parameterNode && isRequiredInitializedParameter(parameterNode)) { - type = getOptionalType(type); - } - buildTypeDisplay(type, writer, enclosingDeclaration, flags, symbolStack); - } - - function buildBindingPatternDisplay(bindingPattern: BindingPattern, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - // We have to explicitly emit square bracket and bracket because these tokens are not stored inside the node. - if (bindingPattern.kind === SyntaxKind.ObjectBindingPattern) { - writePunctuation(writer, SyntaxKind.OpenBraceToken); - buildDisplayForCommaSeparatedList(bindingPattern.elements, writer, e => buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack)); - writePunctuation(writer, SyntaxKind.CloseBraceToken); - } - else if (bindingPattern.kind === SyntaxKind.ArrayBindingPattern) { - writePunctuation(writer, SyntaxKind.OpenBracketToken); - const elements = bindingPattern.elements; - buildDisplayForCommaSeparatedList(elements, writer, e => buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack)); - if (elements && elements.hasTrailingComma) { - writePunctuation(writer, SyntaxKind.CommaToken); - } - writePunctuation(writer, SyntaxKind.CloseBracketToken); - } - } - - function buildBindingElementDisplay(bindingElement: ArrayBindingElement, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - if (isOmittedExpression(bindingElement)) { - return; - } - Debug.assert(bindingElement.kind === SyntaxKind.BindingElement); - if (bindingElement.propertyName) { - writer.writeProperty(getTextOfNode(bindingElement.propertyName)); - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - } - if (isBindingPattern(bindingElement.name)) { - buildBindingPatternDisplay(bindingElement.name, writer, enclosingDeclaration, flags, symbolStack); - } - else { - if (bindingElement.dotDotDotToken) { - writePunctuation(writer, SyntaxKind.DotDotDotToken); - } - appendSymbolNameOnly(bindingElement.symbol, writer); - } - } - - function buildDisplayForTypeParametersAndDelimiters(typeParameters: ReadonlyArray, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - if (typeParameters && typeParameters.length) { - writePunctuation(writer, SyntaxKind.LessThanToken); - buildDisplayForCommaSeparatedList(typeParameters, writer, p => buildTypeParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack)); - writePunctuation(writer, SyntaxKind.GreaterThanToken); - } - } - - function buildDisplayForCommaSeparatedList(list: ReadonlyArray, writer: SymbolWriter, action: (item: T) => void) { - for (let i = 0; i < list.length; i++) { - if (i > 0) { - writePunctuation(writer, SyntaxKind.CommaToken); - writeSpace(writer); - } - action(list[i]); - } - } - - function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: ReadonlyArray, mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node) { - if (typeParameters && typeParameters.length) { - writePunctuation(writer, SyntaxKind.LessThanToken); - let flags = TypeFormatFlags.InFirstTypeArgument; - for (let i = 0; i < typeParameters.length; i++) { - if (i > 0) { - writePunctuation(writer, SyntaxKind.CommaToken); - writeSpace(writer); - flags = TypeFormatFlags.None; - } - buildTypeDisplay(mapper(typeParameters[i]), writer, enclosingDeclaration, flags); - } - writePunctuation(writer, SyntaxKind.GreaterThanToken); - } - } - - function buildDisplayForParametersAndDelimiters(thisParameter: Symbol | undefined, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - if (thisParameter) { - buildParameterDisplay(thisParameter, writer, enclosingDeclaration, flags, symbolStack); - } - for (let i = 0; i < parameters.length; i++) { - if (i > 0 || thisParameter) { - writePunctuation(writer, SyntaxKind.CommaToken); - writeSpace(writer); - } - buildParameterDisplay(parameters[i], writer, enclosingDeclaration, flags, symbolStack); - } - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - - function buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]): void { - if (isIdentifierTypePredicate(predicate)) { - writer.writeParameter(predicate.parameterName); - } - else { - writeKeyword(writer, SyntaxKind.ThisKeyword); - } - writeSpace(writer); - writeKeyword(writer, SyntaxKind.IsKeyword); - writeSpace(writer); - buildTypeDisplay(predicate.type, writer, enclosingDeclaration, flags, symbolStack); - } - - function buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - const returnType = getReturnTypeOfSignature(signature); - if (flags & TypeFormatFlags.SuppressAnyReturnType && isTypeAny(returnType)) { - return; - } - - if (flags & TypeFormatFlags.WriteArrowStyleSignature) { - writeSpace(writer); - writePunctuation(writer, SyntaxKind.EqualsGreaterThanToken); - } - else { - writePunctuation(writer, SyntaxKind.ColonToken); - } - writeSpace(writer); - - const typePredicate = getTypePredicateOfSignature(signature); - if (typePredicate) { - buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags, symbolStack); - } - else { - buildTypeDisplay(returnType, writer, enclosingDeclaration, flags, symbolStack); - } - } - - function buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind, symbolStack?: Symbol[]) { - if (kind === SignatureKind.Construct) { - writeKeyword(writer, SyntaxKind.NewKeyword); - writeSpace(writer); - } - - if (signature.target && (flags & TypeFormatFlags.WriteTypeArgumentsOfSignature)) { - // Instantiated signature, write type arguments instead - // This is achieved by passing in the mapper separately - buildDisplayForTypeArgumentsAndDelimiters(signature.target.typeParameters, signature.mapper, writer, enclosingDeclaration); - } - else { - buildDisplayForTypeParametersAndDelimiters(signature.typeParameters, writer, enclosingDeclaration, flags, symbolStack); - } - - buildDisplayForParametersAndDelimiters(signature.thisParameter, signature.parameters, writer, enclosingDeclaration, flags, symbolStack); - - buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack); - } - - function buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) { - if (info) { - if (info.isReadonly) { - writeKeyword(writer, SyntaxKind.ReadonlyKeyword); - writeSpace(writer); - } - writePunctuation(writer, SyntaxKind.OpenBracketToken); - writer.writeParameter(info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : "x"); - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - switch (kind) { - case IndexKind.Number: - writeKeyword(writer, SyntaxKind.NumberKeyword); - break; - case IndexKind.String: - writeKeyword(writer, SyntaxKind.StringKeyword); - break; - } - - writePunctuation(writer, SyntaxKind.CloseBracketToken); - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - if (info.type) { - buildTypeDisplay(info.type, writer, enclosingDeclaration, globalFlags, symbolStack); - } - else { - writeKeyword(writer, SyntaxKind.AnyKeyword); - } - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - } - - return _displayBuilder || (_displayBuilder = { - buildSymbolDisplay, - buildTypeDisplay, - buildTypeParameterDisplay, - buildTypePredicateDisplay, - buildParameterDisplay, - buildDisplayForParametersAndDelimiters, - buildDisplayForTypeParametersAndDelimiters, - buildTypeParameterDisplayFromSymbol, - buildSignatureDisplay, - buildIndexSignatureDisplay, - buildReturnTypeDisplay - }); - } - function isDeclarationVisible(node: Declaration): boolean { if (node) { const links = getNodeLinks(node); @@ -25348,7 +24879,7 @@ namespace ts { } } - function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) { + function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: EmitTextWriter) { // Get type of the symbol if this is the valid symbol otherwise get type at location const symbol = getSymbolOfNode(declaration); let type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature)) @@ -25361,18 +24892,17 @@ namespace ts { if (flags & TypeFormatFlags.AddUndefined) { type = getOptionalType(type); } - - getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags); + typeToString(type, enclosingDeclaration, flags | TypeFormatFlags.MultilineObjectLiterals, writer); } - function writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) { + function writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: EmitTextWriter) { const signature = getSignatureFromDeclaration(signatureDeclaration); - getSymbolDisplayBuilder().buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags); + typeToString(getReturnTypeOfSignature(signature), enclosingDeclaration, flags | TypeFormatFlags.MultilineObjectLiterals, writer); } - function writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) { + function writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: EmitTextWriter) { const type = getWidenedType(getRegularTypeOfExpression(expr)); - getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags); + typeToString(type, enclosingDeclaration, flags | TypeFormatFlags.MultilineObjectLiterals, writer); } function hasGlobalName(name: string): boolean { @@ -25420,7 +24950,7 @@ namespace ts { return false; } - function writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: SymbolWriter) { + function writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: EmitTextWriter) { const type = getTypeOfSymbol(getSymbolOfNode(node)); writer.writeStringLiteral(literalTypeToString(type)); } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 24c2153c582..0faabbda2a0 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2771,10 +2771,10 @@ namespace ts { function Signature() {} // tslint:disable-line no-empty function Node(this: Node, kind: SyntaxKind, pos: number, end: number) { - this.id = 0; - this.kind = kind; this.pos = pos; this.end = end; + this.kind = kind; + this.id = 0; this.flags = NodeFlags.None; this.modifierFlagsCache = ModifierFlags.None; this.transformFlags = TransformFlags.None; @@ -3046,6 +3046,10 @@ namespace ts { return (arg: T) => f(arg) && g(arg); } + export function or(f: (arg: T) => boolean, g: (arg: T) => boolean) { + return (arg: T) => f(arg) || g(arg); + } + export function assertTypeIsNever(_: never): void { } // tslint:disable-line no-empty export interface FileAndDirectoryExistence { diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index b85c79e775c..f37ae497f84 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -20,14 +20,14 @@ namespace ts { type GetSymbolAccessibilityDiagnostic = (symbolAccessibilityResult: SymbolAccessibilityResult) => SymbolAccessibilityDiagnostic; - interface EmitTextWriterWithSymbolWriter extends EmitTextWriter, SymbolWriter { + interface EmitTextWriterWithSymbolWriter extends EmitTextWriter { getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic; } interface SymbolAccessibilityDiagnostic { errorNode: Node; diagnosticMessage: DiagnosticMessage; - typeName?: DeclarationName; + typeName?: DeclarationName | QualifiedName; } export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[] { @@ -358,7 +358,7 @@ namespace ts { } else { errorNameNode = declaration.name; - const format = TypeFormatFlags.UseTypeOfFunction | + const format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.WriteDefaultSymbolWithoutName | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | (shouldUseResolverType ? TypeFormatFlags.AddUndefined : 0); resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, format, writer); @@ -378,7 +378,7 @@ namespace ts { resolver.writeReturnTypeOfSignatureDeclaration( signature, enclosingDeclaration, - TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.WriteClassExpressionAsTypeLiteral, + TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, writer); errorNameNode = undefined; } @@ -643,7 +643,7 @@ namespace ts { resolver.writeTypeOfExpression( expr, enclosingDeclaration, - TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.WriteClassExpressionAsTypeLiteral, + TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, writer); write(";"); writeLine(); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index aee8c98db0d..8a1de17826c 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -5,7 +5,6 @@ /// namespace ts { - const delimiters = createDelimiterMap(); const brackets = createBracketsMap(); /*@internal*/ @@ -200,7 +199,7 @@ namespace ts { // Reset state sourceMap.reset(); - writer.reset(); + writer.clear(); currentSourceFile = undefined; bundledHelpers = undefined; @@ -292,16 +291,27 @@ namespace ts { let tempFlags: TempFlags; // TempFlags for the current name generation scope. let writer: EmitTextWriter; let ownWriter: EmitTextWriter; + let write = writeBase; + let commitPendingSemicolon: typeof commitPendingSemicolonInternal = noop; + let writeSemicolon: typeof writeSemicolonInternal = writeSemicolonInternal; + let pendingSemicolon = false; + if (printerOptions.omitTrailingSemicolon) { + commitPendingSemicolon = commitPendingSemicolonInternal; + writeSemicolon = deferWriteSemicolon; + } + const syntheticParent: TextRange = { pos: -1, end: -1 }; reset(); return { // public API printNode, + printList, printFile, printBundle, // internal API writeNode, + writeList, writeFile, writeBundle }; @@ -326,6 +336,11 @@ namespace ts { return endPrint(); } + function printList(format: ListFormat, nodes: NodeArray, sourceFile: SourceFile) { + writeList(format, nodes, sourceFile, beginPrint()); + return endPrint(); + } + function printBundle(bundle: Bundle): string { writeBundle(bundle, beginPrint()); return endPrint(); @@ -349,6 +364,17 @@ namespace ts { writer = previousWriter; } + function writeList(format: ListFormat, nodes: NodeArray, sourceFile: SourceFile | undefined, output: EmitTextWriter) { + const previousWriter = writer; + setWriter(output); + if (sourceFile) { + setSourceFile(sourceFile); + } + emitList(syntheticParent, nodes, format); + reset(); + writer = previousWriter; + } + function writeBundle(bundle: Bundle, output: EmitTextWriter) { const previousWriter = writer; setWriter(output); @@ -378,7 +404,7 @@ namespace ts { function endPrint() { const text = ownWriter.getText(); - ownWriter.reset(); + ownWriter.clear(); return text; } @@ -482,7 +508,9 @@ namespace ts { function emitMappedTypeParameter(node: TypeParameterDeclaration): void { emit(node.name); - write(" in "); + writeSpace(); + writeKeyword("in"); + writeSpace(); emit(node.constraint); } @@ -493,7 +521,7 @@ namespace ts { // Strict mode reserved words // Contextual keywords if (isKeyword(kind)) { - writeTokenNode(node); + writeTokenNode(node, writeKeyword); return; } @@ -752,7 +780,7 @@ namespace ts { } if (isToken(node)) { - writeTokenNode(node); + writeTokenNode(node, writePunctuation); return; } } @@ -780,7 +808,7 @@ namespace ts { case SyntaxKind.TrueKeyword: case SyntaxKind.ThisKeyword: case SyntaxKind.ImportKeyword: - writeTokenNode(node); + writeTokenNode(node, writeKeyword); return; // Expressions @@ -885,10 +913,11 @@ namespace ts { const text = getLiteralTextOfNode(node); if ((printerOptions.sourceMap || printerOptions.inlineSourceMap) && (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) { - writer.writeLiteral(text); + writeLiteral(text); } else { - write(text); + // Quick info expects all literals to be called with writeStringLiteral, as there's no specific type for numberLiterals + writeStringLiteral(text); } } @@ -897,8 +926,9 @@ namespace ts { // function emitIdentifier(node: Identifier) { - write(getTextOfNode(node, /*includeTrivia*/ false)); - emitTypeArguments(node, node.typeArguments); + const writeText = node.symbol ? writeSymbol : write; + writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol); + emitList(node, node.typeArguments, ListFormat.TypeParameters); // Call emitList directly since it could be an array of TypeParameterDeclarations _or_ type arguments } // @@ -907,7 +937,7 @@ namespace ts { function emitQualifiedName(node: QualifiedName) { emitEntityName(node.left); - write("."); + writePunctuation("."); emit(node.right); } @@ -921,9 +951,9 @@ namespace ts { } function emitComputedPropertyName(node: ComputedPropertyName) { - write("["); + writePunctuation("["); emitExpression(node.expression); - write("]"); + writePunctuation("]"); } // @@ -932,8 +962,18 @@ namespace ts { function emitTypeParameter(node: TypeParameterDeclaration) { emit(node.name); - emitWithPrefix(" extends ", node.constraint); - emitWithPrefix(" = ", node.default); + if (node.constraint) { + writeSpace(); + writeKeyword("extends"); + writeSpace(); + emit(node.constraint); + } + if (node.default) { + writeSpace(); + writeOperator("="); + writeSpace(); + emit(node.default); + } } function emitParameter(node: ParameterDeclaration) { @@ -941,20 +981,20 @@ namespace ts { emitModifiers(node, node.modifiers); emitIfPresent(node.dotDotDotToken); if (node.name) { - emit(node.name); + emitNodeWithWriter(node.name, writeParameter); } emitIfPresent(node.questionToken); if (node.parent && node.parent.kind === SyntaxKind.JSDocFunctionType && !node.name) { emit(node.type); } else { - emitWithPrefix(": ", node.type); + emitTypeAnnotation(node.type); } - emitExpressionWithPrefix(" = ", node.initializer); + emitInitializer(node.initializer); } function emitDecorator(decorator: Decorator) { - write("@"); + writePunctuation("@"); emitExpression(decorator.expression); } @@ -965,10 +1005,10 @@ namespace ts { function emitPropertySignature(node: PropertySignature) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - emit(node.name); + emitNodeWithWriter(node.name, writeProperty); emitIfPresent(node.questionToken); - emitWithPrefix(": ", node.type); - write(";"); + emitTypeAnnotation(node.type); + writeSemicolon(); } function emitPropertyDeclaration(node: PropertyDeclaration) { @@ -976,9 +1016,9 @@ namespace ts { emitModifiers(node, node.modifiers); emit(node.name); emitIfPresent(node.questionToken); - emitWithPrefix(": ", node.type); - emitExpressionWithPrefix(" = ", node.initializer); - write(";"); + emitTypeAnnotation(node.type); + emitInitializer(node.initializer); + writeSemicolon(); } function emitMethodSignature(node: MethodSignature) { @@ -988,8 +1028,8 @@ namespace ts { emitIfPresent(node.questionToken); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); - emitWithPrefix(": ", node.type); - write(";"); + emitTypeAnnotation(node.type); + writeSemicolon(); } function emitMethodDeclaration(node: MethodDeclaration) { @@ -1003,14 +1043,15 @@ namespace ts { function emitConstructor(node: ConstructorDeclaration) { emitModifiers(node, node.modifiers); - write("constructor"); + writeKeyword("constructor"); emitSignatureAndBody(node, emitSignatureHead); } function emitAccessorDeclaration(node: AccessorDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write(node.kind === SyntaxKind.GetAccessor ? "get " : "set "); + writeKeyword(node.kind === SyntaxKind.GetAccessor ? "get" : "set"); + writeSpace(); emit(node.name); emitSignatureAndBody(node, emitSignatureHead); } @@ -1020,30 +1061,31 @@ namespace ts { emitModifiers(node, node.modifiers); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); - emitWithPrefix(": ", node.type); - write(";"); + emitTypeAnnotation(node.type); + writeSemicolon(); } function emitConstructSignature(node: ConstructSignatureDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write("new "); + writeKeyword("new"); + writeSpace(); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); - emitWithPrefix(": ", node.type); - write(";"); + emitTypeAnnotation(node.type); + writeSemicolon(); } function emitIndexSignature(node: IndexSignatureDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emitParametersForIndexSignature(node, node.parameters); - emitWithPrefix(": ", node.type); - write(";"); + emitTypeAnnotation(node.type); + writeSemicolon(); } function emitSemicolonClassElement() { - write(";"); + writeSemicolon(); } // @@ -1052,7 +1094,9 @@ namespace ts { function emitTypePredicate(node: TypePredicateNode) { emit(node.parameterName); - write(" is "); + writeSpace(); + writeKeyword("is"); + writeSpace(); emit(node.type); } @@ -1064,7 +1108,9 @@ namespace ts { function emitFunctionType(node: FunctionTypeNode) { emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); - write(" => "); + writeSpace(); + writePunctuation("=>"); + writeSpace(); emit(node.type); } @@ -1092,28 +1138,33 @@ namespace ts { } function emitConstructorType(node: ConstructorTypeNode) { - write("new "); + writeKeyword("new"); + writeSpace(); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); - write(" => "); + writeSpace(); + writePunctuation("=>"); + writeSpace(); emit(node.type); } function emitTypeQuery(node: TypeQueryNode) { - write("typeof "); + writeKeyword("typeof"); + writeSpace(); emit(node.exprName); } function emitTypeLiteral(node: TypeLiteralNode) { - write("{"); + writePunctuation("{"); const flags = getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers; emitList(node, node.members, flags | ListFormat.NoSpaceIfEmpty); - write("}"); + writePunctuation("}"); } function emitArrayType(node: ArrayTypeNode) { emit(node.elementType); - write("[]"); + writePunctuation("["); + writePunctuation("]"); } function emitJSDocVariadicType(node: JSDocVariadicType) { @@ -1122,9 +1173,9 @@ namespace ts { } function emitTupleType(node: TupleTypeNode) { - write("["); + writePunctuation("["); emitList(node, node.elementTypes, ListFormat.TupleTypeElements); - write("]"); + writePunctuation("]"); } function emitUnionType(node: UnionTypeNode) { @@ -1136,33 +1187,33 @@ namespace ts { } function emitParenthesizedType(node: ParenthesizedTypeNode) { - write("("); + writePunctuation("("); emit(node.type); - write(")"); + writePunctuation(")"); } function emitThisType() { - write("this"); + writeKeyword("this"); } function emitTypeOperator(node: TypeOperatorNode) { - writeTokenText(node.operator); - write(" "); + writeTokenText(node.operator, writeKeyword); + writeSpace(); emit(node.type); } function emitIndexedAccessType(node: IndexedAccessTypeNode) { emit(node.objectType); - write("["); + writePunctuation("["); emit(node.indexType); - write("]"); + writePunctuation("]"); } function emitMappedType(node: MappedTypeNode) { const emitFlags = getEmitFlags(node); - write("{"); + writePunctuation("{"); if (emitFlags & EmitFlags.SingleLine) { - write(" "); + writeSpace(); } else { writeLine(); @@ -1170,25 +1221,26 @@ namespace ts { } if (node.readonlyToken) { emit(node.readonlyToken); - write(" "); + writeSpace(); } - write("["); + writePunctuation("["); pipelineEmitWithNotification(EmitHint.MappedTypeParameter, node.typeParameter); - write("]"); + writePunctuation("]"); emitIfPresent(node.questionToken); - write(": "); + writePunctuation(":"); + writeSpace(); emit(node.type); - write(";"); + writeSemicolon(); if (emitFlags & EmitFlags.SingleLine) { - write(" "); + writeSpace(); } else { writeLine(); decreaseIndent(); } - write("}"); + writePunctuation("}"); } function emitLiteralType(node: LiteralTypeNode) { @@ -1200,22 +1252,26 @@ namespace ts { // function emitObjectBindingPattern(node: ObjectBindingPattern) { - write("{"); + writePunctuation("{"); emitList(node, node.elements, ListFormat.ObjectBindingPatternElements); - write("}"); + writePunctuation("}"); } function emitArrayBindingPattern(node: ArrayBindingPattern) { - write("["); + writePunctuation("["); emitList(node, node.elements, ListFormat.ArrayBindingPatternElements); - write("]"); + writePunctuation("]"); } function emitBindingElement(node: BindingElement) { - emitWithSuffix(node.propertyName, ": "); + if (node.propertyName) { + emit(node.propertyName); + writePunctuation(":"); + writeSpace(); + } emitIfPresent(node.dotDotDotToken); emit(node.name); - emitExpressionWithPrefix(" = ", node.initializer); + emitInitializer(node.initializer); } // @@ -1260,7 +1316,7 @@ namespace ts { increaseIndentIf(indentBeforeDot); const shouldEmitDotDot = !indentBeforeDot && needsDotDotForPropertyAccess(node.expression); - write(shouldEmitDotDot ? ".." : "."); + writePunctuation(shouldEmitDotDot ? ".." : "."); increaseIndentIf(indentAfterDot); emit(node.name); @@ -1289,9 +1345,9 @@ namespace ts { function emitElementAccessExpression(node: ElementAccessExpression) { emitExpression(node.expression); - write("["); + writePunctuation("["); emitExpression(node.argumentExpression); - write("]"); + writePunctuation("]"); } function emitCallExpression(node: CallExpression) { @@ -1301,7 +1357,8 @@ namespace ts { } function emitNewExpression(node: NewExpression) { - write("new "); + writeKeyword("new"); + writeSpace(); emitExpression(node.expression); emitTypeArguments(node, node.typeArguments); emitExpressionList(node, node.arguments, ListFormat.NewExpressionArguments); @@ -1309,21 +1366,21 @@ namespace ts { function emitTaggedTemplateExpression(node: TaggedTemplateExpression) { emitExpression(node.tag); - write(" "); + writeSpace(); emitExpression(node.template); } function emitTypeAssertionExpression(node: TypeAssertion) { - write("<"); + writePunctuation("<"); emit(node.type); - write(">"); + writePunctuation(">"); emitExpression(node.expression); } function emitParenthesizedExpression(node: ParenthesizedExpression) { - write("("); + writePunctuation("("); emitExpression(node.expression); - write(")"); + writePunctuation(")"); } function emitFunctionExpression(node: FunctionExpression) { @@ -1339,35 +1396,39 @@ namespace ts { function emitArrowFunctionHead(node: ArrowFunction) { emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); - emitWithPrefix(": ", node.type); - write(" "); + emitTypeAnnotation(node.type); + writeSpace(); emit(node.equalsGreaterThanToken); } function emitDeleteExpression(node: DeleteExpression) { - write("delete "); + writeKeyword("delete"); + writeSpace(); emitExpression(node.expression); } function emitTypeOfExpression(node: TypeOfExpression) { - write("typeof "); + writeKeyword("typeof"); + writeSpace(); emitExpression(node.expression); } function emitVoidExpression(node: VoidExpression) { - write("void "); + writeKeyword("void"); + writeSpace(); emitExpression(node.expression); } function emitAwaitExpression(node: AwaitExpression) { - write("await "); + writeKeyword("await"); + writeSpace(); emitExpression(node.expression); } function emitPrefixUnaryExpression(node: PrefixUnaryExpression) { - writeTokenText(node.operator); + writeTokenText(node.operator, writeOperator); if (shouldEmitWhitespaceBeforeOperand(node)) { - write(" "); + writeSpace(); } emitExpression(node.operand); } @@ -1393,7 +1454,7 @@ namespace ts { function emitPostfixUnaryExpression(node: PostfixUnaryExpression) { emitExpression(node.operand); - writeTokenText(node.operator); + writeTokenText(node.operator, writeOperator); } function emitBinaryExpression(node: BinaryExpression) { @@ -1404,7 +1465,7 @@ namespace ts { emitExpression(node.left); increaseIndentIf(indentBeforeOperator, isCommaOperator ? " " : undefined); emitLeadingCommentsOfPosition(node.operatorToken.pos); - writeTokenNode(node.operatorToken); + writeTokenNode(node.operatorToken, writeOperator); emitTrailingCommentsOfPosition(node.operatorToken.end, /*prefixSpace*/ true); // Binary operators should have a space before the comment starts increaseIndentIf(indentAfterOperator, " "); emitExpression(node.right); @@ -1437,13 +1498,13 @@ namespace ts { } function emitYieldExpression(node: YieldExpression) { - write("yield"); + writeKeyword("yield"); emit(node.asteriskToken); - emitExpressionWithPrefix(" ", node.expression); + emitExpressionWithLeadingSpace(node.expression); } function emitSpreadExpression(node: SpreadElement) { - write("..."); + writePunctuation("..."); emitExpression(node.expression); } @@ -1459,19 +1520,21 @@ namespace ts { function emitAsExpression(node: AsExpression) { emitExpression(node.expression); if (node.type) { - write(" as "); + writeSpace(); + writeKeyword("as"); + writeSpace(); emit(node.type); } } function emitNonNullExpression(node: NonNullExpression) { emitExpression(node.expression); - write("!"); + writeOperator("!"); } function emitMetaProperty(node: MetaProperty) { - writeToken(node.keywordToken, node.pos); - write("."); + writeToken(node.keywordToken, node.pos, writePunctuation); + writePunctuation("."); emit(node.name); } @@ -1489,13 +1552,13 @@ namespace ts { // function emitBlock(node: Block) { - writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node); + writeToken(SyntaxKind.OpenBraceToken, node.pos, writePunctuation, /*contextNode*/ node); emitBlockStatements(node, /*forceSingleLine*/ !node.multiLine && isEmptyBlock(node)); // We have to call emitLeadingComments explicitly here because otherwise leading comments of the close brace token will not be emitted increaseIndent(); emitLeadingCommentsOfPosition(node.statements.end); decreaseIndent(); - writeToken(SyntaxKind.CloseBraceToken, node.statements.end, /*contextNode*/ node); + writeToken(SyntaxKind.CloseBraceToken, node.statements.end, writePunctuation, /*contextNode*/ node); } function emitBlockStatements(node: BlockLike, forceSingleLine: boolean) { @@ -1506,30 +1569,30 @@ namespace ts { function emitVariableStatement(node: VariableStatement) { emitModifiers(node, node.modifiers); emit(node.declarationList); - write(";"); + writeSemicolon(); } function emitEmptyStatement() { - write(";"); + writeSemicolon(); } function emitExpressionStatement(node: ExpressionStatement) { emitExpression(node.expression); - write(";"); + writeSemicolon(); } function emitIfStatement(node: IfStatement) { - const openParenPos = writeToken(SyntaxKind.IfKeyword, node.pos, node); - write(" "); - writeToken(SyntaxKind.OpenParenToken, openParenPos, node); + const openParenPos = writeToken(SyntaxKind.IfKeyword, node.pos, writeKeyword, node); + writeSpace(); + writeToken(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); emitExpression(node.expression); - writeToken(SyntaxKind.CloseParenToken, node.expression.end, node); + writeToken(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); emitEmbeddedStatement(node, node.thenStatement); if (node.elseStatement) { writeLineOrSpace(node); - writeToken(SyntaxKind.ElseKeyword, node.thenStatement.end, node); + writeToken(SyntaxKind.ElseKeyword, node.thenStatement.end, writeKeyword, node); if (node.elseStatement.kind === SyntaxKind.IfStatement) { - write(" "); + writeSpace(); emit(node.elseStatement); } else { @@ -1539,60 +1602,68 @@ namespace ts { } function emitDoStatement(node: DoStatement) { - write("do"); + writeKeyword("do"); emitEmbeddedStatement(node, node.statement); if (isBlock(node.statement)) { - write(" "); + writeSpace(); } else { writeLineOrSpace(node); } - write("while ("); + writeKeyword("while"); + writeSpace(); + writePunctuation("("); emitExpression(node.expression); - write(");"); + writePunctuation(");"); } function emitWhileStatement(node: WhileStatement) { - write("while ("); + writeKeyword("while"); + writeSpace(); + writePunctuation("("); emitExpression(node.expression); - write(")"); + writePunctuation(")"); emitEmbeddedStatement(node, node.statement); } function emitForStatement(node: ForStatement) { - const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos); - write(" "); - writeToken(SyntaxKind.OpenParenToken, openParenPos, /*contextNode*/ node); + const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos, writeKeyword); + writeSpace(); + writeToken(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, /*contextNode*/ node); emitForBinding(node.initializer); - write(";"); - emitExpressionWithPrefix(" ", node.condition); - write(";"); - emitExpressionWithPrefix(" ", node.incrementor); - write(")"); + writeSemicolon(); + emitExpressionWithLeadingSpace(node.condition); + writeSemicolon(); + emitExpressionWithLeadingSpace(node.incrementor); + writePunctuation(")"); emitEmbeddedStatement(node, node.statement); } function emitForInStatement(node: ForInStatement) { - const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos); - write(" "); - writeToken(SyntaxKind.OpenParenToken, openParenPos); + const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos, writeKeyword); + writeSpace(); + writeToken(SyntaxKind.OpenParenToken, openParenPos, writePunctuation); emitForBinding(node.initializer); - write(" in "); + writeSpace(); + writeKeyword("in"); + writeSpace(); emitExpression(node.expression); - writeToken(SyntaxKind.CloseParenToken, node.expression.end); + writeToken(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation); emitEmbeddedStatement(node, node.statement); } function emitForOfStatement(node: ForOfStatement) { - const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos); - write(" "); - emitWithSuffix(node.awaitModifier, " "); - writeToken(SyntaxKind.OpenParenToken, openParenPos); + const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos, writeKeyword); + writeSpace(); + emitWithTrailingSpace(node.awaitModifier); + writeToken(SyntaxKind.OpenParenToken, openParenPos, writePunctuation); emitForBinding(node.initializer); - write(" of "); + writeSpace(); + writeKeyword("of"); + writeSpace(); emitExpression(node.expression); - writeToken(SyntaxKind.CloseParenToken, node.expression.end); + writeToken(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation); emitEmbeddedStatement(node, node.statement); } @@ -1608,23 +1679,23 @@ namespace ts { } function emitContinueStatement(node: ContinueStatement) { - writeToken(SyntaxKind.ContinueKeyword, node.pos); - emitWithPrefix(" ", node.label); - write(";"); + writeToken(SyntaxKind.ContinueKeyword, node.pos, writeKeyword); + emitWithLeadingSpace(node.label); + writeSemicolon(); } function emitBreakStatement(node: BreakStatement) { - writeToken(SyntaxKind.BreakKeyword, node.pos); - emitWithPrefix(" ", node.label); - write(";"); + writeToken(SyntaxKind.BreakKeyword, node.pos, writeKeyword); + emitWithLeadingSpace(node.label); + writeSemicolon(); } - function emitTokenWithComment(token: SyntaxKind, pos: number, contextNode?: Node) { + function emitTokenWithComment(token: SyntaxKind, pos: number, writer: (s: string) => void, contextNode?: Node) { const node = contextNode && getParseTreeNode(contextNode); if (node && node.kind === contextNode.kind) { pos = skipTrivia(currentSourceFile.text, pos); } - pos = writeToken(token, pos, /*contextNode*/ contextNode); + pos = writeToken(token, pos, writer, /*contextNode*/ contextNode); if (node && node.kind === contextNode.kind) { emitTrailingCommentsOfPosition(pos, /*prefixSpace*/ true); } @@ -1632,42 +1703,46 @@ namespace ts { } function emitReturnStatement(node: ReturnStatement) { - emitTokenWithComment(SyntaxKind.ReturnKeyword, node.pos, /*contextNode*/ node); - emitExpressionWithPrefix(" ", node.expression); - write(";"); + emitTokenWithComment(SyntaxKind.ReturnKeyword, node.pos, writeKeyword, /*contextNode*/ node); + emitExpressionWithLeadingSpace(node.expression); + writeSemicolon(); } function emitWithStatement(node: WithStatement) { - write("with ("); + writeKeyword("with"); + writeSpace(); + writePunctuation("("); emitExpression(node.expression); - write(")"); + writePunctuation(")"); emitEmbeddedStatement(node, node.statement); } function emitSwitchStatement(node: SwitchStatement) { - const openParenPos = writeToken(SyntaxKind.SwitchKeyword, node.pos); - write(" "); - writeToken(SyntaxKind.OpenParenToken, openParenPos); + const openParenPos = writeToken(SyntaxKind.SwitchKeyword, node.pos, writeKeyword); + writeSpace(); + writeToken(SyntaxKind.OpenParenToken, openParenPos, writePunctuation); emitExpression(node.expression); - writeToken(SyntaxKind.CloseParenToken, node.expression.end); - write(" "); + writeToken(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation); + writeSpace(); emit(node.caseBlock); } function emitLabeledStatement(node: LabeledStatement) { emit(node.label); - write(": "); + writePunctuation(":"); + writeSpace(); emit(node.statement); } function emitThrowStatement(node: ThrowStatement) { - write("throw"); - emitExpressionWithPrefix(" ", node.expression); - write(";"); + writeKeyword("throw"); + emitExpressionWithLeadingSpace(node.expression); + writeSemicolon(); } function emitTryStatement(node: TryStatement) { - write("try "); + writeKeyword("try"); + writeSpace(); emit(node.tryBlock); if (node.catchClause) { writeLineOrSpace(node); @@ -1675,14 +1750,15 @@ namespace ts { } if (node.finallyBlock) { writeLineOrSpace(node); - write("finally "); + writeKeyword("finally"); + writeSpace(); emit(node.finallyBlock); } } function emitDebuggerStatement(node: DebuggerStatement) { - writeToken(SyntaxKind.DebuggerKeyword, node.pos); - write(";"); + writeToken(SyntaxKind.DebuggerKeyword, node.pos, writeKeyword); + writeSemicolon(); } // @@ -1691,12 +1767,13 @@ namespace ts { function emitVariableDeclaration(node: VariableDeclaration) { emit(node.name); - emitWithPrefix(": ", node.type); - emitExpressionWithPrefix(" = ", node.initializer); + emitTypeAnnotation(node.type); + emitInitializer(node.initializer); } function emitVariableDeclarationList(node: VariableDeclarationList) { - write(isLet(node) ? "let " : isConst(node) ? "const " : "var "); + writeKeyword(isLet(node) ? "let" : isConst(node) ? "const" : "var"); + writeSpace(); emitList(node, node.declarations, ListFormat.VariableDeclarationList); } @@ -1707,9 +1784,9 @@ namespace ts { function emitFunctionDeclarationOrExpression(node: FunctionDeclaration | FunctionExpression) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write("function"); + writeKeyword("function"); emitIfPresent(node.asteriskToken); - write(" "); + writeSpace(); emitIdentifierName(node.name); emitSignatureAndBody(node, emitSignatureHead); } @@ -1743,13 +1820,13 @@ namespace ts { } else { emitSignatureHead(node); - write(" "); + writeSpace(); emitExpression(body); } } else { emitSignatureHead(node); - write(";"); + writeSemicolon(); } } @@ -1757,7 +1834,7 @@ namespace ts { function emitSignatureHead(node: FunctionDeclaration | FunctionExpression | MethodDeclaration | AccessorDeclaration | ConstructorDeclaration) { emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); - emitWithPrefix(": ", node.type); + emitTypeAnnotation(node.type); } function shouldEmitBlockFunctionBodyOnSingleLine(body: Block) { @@ -1799,7 +1876,8 @@ namespace ts { } function emitBlockFunctionBody(body: Block) { - write(" {"); + writeSpace(); + writePunctuation("{"); increaseIndent(); const emitBlockFunctionBody = shouldEmitBlockFunctionBodyOnSingleLine(body) @@ -1814,7 +1892,7 @@ namespace ts { } decreaseIndent(); - writeToken(SyntaxKind.CloseBraceToken, body.statements.end, body); + writeToken(SyntaxKind.CloseBraceToken, body.statements.end, writePunctuation, body); } function emitBlockFunctionBodyOnSingleLine(body: Block) { @@ -1843,8 +1921,11 @@ namespace ts { function emitClassDeclarationOrExpression(node: ClassDeclaration | ClassExpression) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write("class"); - emitNodeWithPrefix(" ", node.name, emitIdentifierName); + writeKeyword("class"); + if (node.name) { + writeSpace(); + emitIdentifierName(node.name); + } const indentedFlag = getEmitFlags(node) & EmitFlags.Indented; if (indentedFlag) { @@ -1854,9 +1935,10 @@ namespace ts { emitTypeParameters(node, node.typeParameters); emitList(node, node.heritageClauses, ListFormat.ClassHeritageClauses); - write(" {"); + writeSpace(); + writePunctuation("{"); emitList(node, node.members, ListFormat.ClassMembers); - write("}"); + writePunctuation("}"); if (indentedFlag) { decreaseIndent(); @@ -1866,74 +1948,86 @@ namespace ts { function emitInterfaceDeclaration(node: InterfaceDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write("interface "); + writeKeyword("interface"); + writeSpace(); emit(node.name); emitTypeParameters(node, node.typeParameters); emitList(node, node.heritageClauses, ListFormat.HeritageClauses); - write(" {"); + writeSpace(); + writePunctuation("{"); emitList(node, node.members, ListFormat.InterfaceMembers); - write("}"); + writePunctuation("}"); } function emitTypeAliasDeclaration(node: TypeAliasDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write("type "); + writeKeyword("type"); + writeSpace(); emit(node.name); emitTypeParameters(node, node.typeParameters); - write(" = "); + writeSpace(); + writePunctuation("="); + writeSpace(); emit(node.type); - write(";"); + writeSemicolon(); } function emitEnumDeclaration(node: EnumDeclaration) { emitModifiers(node, node.modifiers); - write("enum "); + writeKeyword("enum"); + writeSpace(); emit(node.name); - write(" {"); + + writeSpace(); + writePunctuation("{"); emitList(node, node.members, ListFormat.EnumMembers); - write("}"); + writePunctuation("}"); } function emitModuleDeclaration(node: ModuleDeclaration) { emitModifiers(node, node.modifiers); if (~node.flags & NodeFlags.GlobalAugmentation) { - write(node.flags & NodeFlags.Namespace ? "namespace " : "module "); + writeKeyword(node.flags & NodeFlags.Namespace ? "namespace" : "module"); + writeSpace(); } emit(node.name); let body = node.body; while (body.kind === SyntaxKind.ModuleDeclaration) { - write("."); + writePunctuation("."); emit((body).name); body = (body).body; } - write(" "); + writeSpace(); emit(body); } function emitModuleBlock(node: ModuleBlock) { pushNameGenerationScope(node); - write("{"); + writePunctuation("{"); emitBlockStatements(node, /*forceSingleLine*/ isEmptyBlock(node)); - write("}"); + writePunctuation("}"); popNameGenerationScope(node); } function emitCaseBlock(node: CaseBlock) { - writeToken(SyntaxKind.OpenBraceToken, node.pos); + writeToken(SyntaxKind.OpenBraceToken, node.pos, writePunctuation); emitList(node, node.clauses, ListFormat.CaseBlockClauses); - writeToken(SyntaxKind.CloseBraceToken, node.clauses.end); + writeToken(SyntaxKind.CloseBraceToken, node.clauses.end, writePunctuation); } function emitImportEqualsDeclaration(node: ImportEqualsDeclaration) { emitModifiers(node, node.modifiers); - write("import "); + writeKeyword("import"); + writeSpace(); emit(node.name); - write(" = "); + writeSpace(); + writePunctuation("="); + writeSpace(); emitModuleReference(node.moduleReference); - write(";"); + writeSemicolon(); } function emitModuleReference(node: ModuleReference) { @@ -1947,25 +2041,32 @@ namespace ts { function emitImportDeclaration(node: ImportDeclaration) { emitModifiers(node, node.modifiers); - write("import "); + writeKeyword("import"); + writeSpace(); if (node.importClause) { emit(node.importClause); - write(" from "); + writeSpace(); + writeKeyword("from"); + writeSpace(); } emitExpression(node.moduleSpecifier); - write(";"); + writeSemicolon(); } function emitImportClause(node: ImportClause) { emit(node.name); if (node.name && node.namedBindings) { - write(", "); + writePunctuation(","); + writeSpace(); } emit(node.namedBindings); } function emitNamespaceImport(node: NamespaceImport) { - write("* as "); + writePunctuation("*"); + writeSpace(); + writeKeyword("as"); + writeSpace(); emit(node.name); } @@ -1978,30 +2079,46 @@ namespace ts { } function emitExportAssignment(node: ExportAssignment) { - write(node.isExportEquals ? "export = " : "export default "); + writeKeyword("export"); + writeSpace(); + if (node.isExportEquals) { + writeOperator("="); + } + else { + writeKeyword("default"); + } + writeSpace(); emitExpression(node.expression); - write(";"); + writeSemicolon(); } function emitExportDeclaration(node: ExportDeclaration) { - write("export "); + writeKeyword("export"); + writeSpace(); if (node.exportClause) { emit(node.exportClause); } else { - write("*"); + writePunctuation("*"); } if (node.moduleSpecifier) { - write(" from "); + writeSpace(); + writeKeyword("from"); + writeSpace(); emitExpression(node.moduleSpecifier); } - write(";"); + writeSemicolon(); } function emitNamespaceExportDeclaration(node: NamespaceExportDeclaration) { - write("export as namespace "); + writeKeyword("export"); + writeSpace(); + writeKeyword("as"); + writeSpace(); + writeKeyword("namespace"); + writeSpace(); emit(node.name); - write(";"); + writeSemicolon(); } function emitNamedExports(node: NamedExports) { @@ -2013,15 +2130,17 @@ namespace ts { } function emitNamedImportsOrExports(node: NamedImportsOrExports) { - write("{"); + writePunctuation("{"); emitList(node, node.elements, ListFormat.NamedImportsOrExportsElements); - write("}"); + writePunctuation("}"); } function emitImportOrExportSpecifier(node: ImportOrExportSpecifier) { if (node.propertyName) { emit(node.propertyName); - write(" as "); + writeSpace(); + writeKeyword("as"); + writeSpace(); } emit(node.name); @@ -2032,9 +2151,10 @@ namespace ts { // function emitExternalModuleReference(node: ExternalModuleReference) { - write("require("); + writeKeyword("require"); + writePunctuation("("); emitExpression(node.expression); - write(")"); + writePunctuation(")"); } // @@ -2048,14 +2168,14 @@ namespace ts { } function emitJsxSelfClosingElement(node: JsxSelfClosingElement) { - write("<"); + writePunctuation("<"); emitJsxTagName(node.tagName); - write(" "); + writeSpace(); // We are checking here so we won't re-enter the emiting pipeline and emit extra sourcemap if (node.attributes.properties && node.attributes.properties.length > 0) { emit(node.attributes); } - write("/>"); + writePunctuation("/>"); } function emitJsxFragment(node: JsxFragment) { @@ -2065,30 +2185,31 @@ namespace ts { } function emitJsxOpeningElementOrFragment(node: JsxOpeningElement | JsxOpeningFragment) { - write("<"); + writePunctuation("<"); if (isJsxOpeningElement(node)) { emitJsxTagName(node.tagName); // We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap if (node.attributes.properties && node.attributes.properties.length > 0) { - write(" "); + writeSpace(); emit(node.attributes); } } - write(">"); + writePunctuation(">"); } function emitJsxText(node: JsxText) { + commitPendingSemicolon(); writer.writeLiteral(getTextOfNode(node, /*includeTrivia*/ true)); } function emitJsxClosingElementOrFragment(node: JsxClosingElement | JsxClosingFragment) { - write(""); + writePunctuation(">"); } function emitJsxAttributes(node: JsxAttributes) { @@ -2097,21 +2218,21 @@ namespace ts { function emitJsxAttribute(node: JsxAttribute) { emit(node.name); - emitWithPrefix("=", node.initializer); + emitNodeWithPrefix("=", writePunctuation, node.initializer, emit); } function emitJsxSpreadAttribute(node: JsxSpreadAttribute) { - write("{..."); + writePunctuation("{..."); emitExpression(node.expression); - write("}"); + writePunctuation("}"); } function emitJsxExpression(node: JsxExpression) { if (node.expression) { - write("{"); + writePunctuation("{"); emitIfPresent(node.dotDotDotToken); emitExpression(node.expression); - write("}"); + writePunctuation("}"); } } @@ -2129,15 +2250,17 @@ namespace ts { // function emitCaseClause(node: CaseClause) { - write("case "); + writeKeyword("case"); + writeSpace(); emitExpression(node.expression); - write(":"); + writePunctuation(":"); emitCaseOrDefaultClauseStatements(node, node.statements); } function emitDefaultClause(node: DefaultClause) { - write("default:"); + writeKeyword("default"); + writePunctuation(":"); emitCaseOrDefaultClauseStatements(node, node.statements); } @@ -2169,27 +2292,27 @@ namespace ts { let format = ListFormat.CaseOrDefaultClauseStatements; if (emitAsSingleStatement) { - write(" "); + writeSpace(); format &= ~(ListFormat.MultiLine | ListFormat.Indented); } emitList(parentNode, statements, format); } function emitHeritageClause(node: HeritageClause) { - write(" "); - writeTokenText(node.token); - write(" "); + writeSpace(); + writeTokenText(node.token, writeKeyword); + writeSpace(); emitList(node, node.types, ListFormat.HeritageClauseTypes); } function emitCatchClause(node: CatchClause) { - const openParenPos = writeToken(SyntaxKind.CatchKeyword, node.pos); - write(" "); + const openParenPos = writeToken(SyntaxKind.CatchKeyword, node.pos, writeKeyword); + writeSpace(); if (node.variableDeclaration) { - writeToken(SyntaxKind.OpenParenToken, openParenPos); + writeToken(SyntaxKind.OpenParenToken, openParenPos, writePunctuation); emit(node.variableDeclaration); - writeToken(SyntaxKind.CloseParenToken, node.variableDeclaration.end); - write(" "); + writeToken(SyntaxKind.CloseParenToken, node.variableDeclaration.end, writePunctuation); + writeSpace(); } emit(node.block); } @@ -2200,7 +2323,8 @@ namespace ts { function emitPropertyAssignment(node: PropertyAssignment) { emit(node.name); - write(": "); + writePunctuation(":"); + writeSpace(); // This is to ensure that we emit comment in the following case: // For example: // obj = { @@ -2219,14 +2343,16 @@ namespace ts { function emitShorthandPropertyAssignment(node: ShorthandPropertyAssignment) { emit(node.name); if (node.objectAssignmentInitializer) { - write(" = "); + writeSpace(); + writePunctuation("="); + writeSpace(); emitExpression(node.objectAssignmentInitializer); } } function emitSpreadAssignment(node: SpreadAssignment) { if (node.expression) { - write("..."); + writePunctuation("..."); emitExpression(node.expression); } } @@ -2237,7 +2363,7 @@ namespace ts { function emitEnumMember(node: EnumMember) { emit(node.name); - emitExpressionWithPrefix(" = ", node.initializer); + emitInitializer(node.initializer); } // @@ -2345,38 +2471,68 @@ namespace ts { // Helpers // + function emitNodeWithWriter(node: Node, writer: typeof write) { + const savedWrite = write; + write = writer; + emit(node); + write = savedWrite; + } + function emitModifiers(node: Node, modifiers: NodeArray) { if (modifiers && modifiers.length) { emitList(node, modifiers, ListFormat.Modifiers); - write(" "); + writeSpace(); } } - function emitWithPrefix(prefix: string, node: Node) { - emitNodeWithPrefix(prefix, node, emit); - } - - function emitExpressionWithPrefix(prefix: string, node: Node) { - emitNodeWithPrefix(prefix, node, emitExpression); - } - - function emitNodeWithPrefix(prefix: string, node: Node, emit: (node: Node) => void) { + function emitTypeAnnotation(node: TypeNode | undefined) { if (node) { - write(prefix); + writePunctuation(":"); + writeSpace(); emit(node); } } - function emitWithSuffix(node: Node, suffix: string) { + function emitInitializer(node: Expression | undefined) { + if (node) { + writeSpace(); + writeOperator("="); + writeSpace(); + emitExpression(node); + } + } + + function emitNodeWithPrefix(prefix: string, prefixWriter: (s: string) => void, node: Node, emit: (node: Node) => void) { + if (node) { + prefixWriter(prefix); + emit(node); + } + } + + function emitWithLeadingSpace(node: Node | undefined) { + if (node) { + writeSpace(); + emit(node); + } + } + + function emitExpressionWithLeadingSpace(node: Expression | undefined) { + if (node) { + writeSpace(); + emitExpression(node); + } + } + + function emitWithTrailingSpace(node: Node | undefined) { if (node) { emit(node); - write(suffix); + writeSpace(); } } function emitEmbeddedStatement(parent: Node, node: Statement) { if (isBlock(node) || getEmitFlags(parent) & EmitFlags.SingleLine) { - write(" "); + writeSpace(); emit(node); } else { @@ -2395,7 +2551,10 @@ namespace ts { emitList(parentNode, typeArguments, ListFormat.TypeArguments); } - function emitTypeParameters(parentNode: Node, typeParameters: NodeArray) { + function emitTypeParameters(parentNode: SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration | ClassDeclaration | ClassExpression, typeParameters: NodeArray) { + if (isFunctionLike(parentNode) && parentNode.typeArguments) { // Quick info uses type arguments in place of type parameters on instantiated signatures + return emitTypeArguments(parentNode, parentNode.typeArguments); + } emitList(parentNode, typeParameters, ListFormat.TypeParameters); } @@ -2433,15 +2592,33 @@ namespace ts { emitList(parentNode, parameters, ListFormat.IndexSignatureParameters); } - function emitList(parentNode: Node, children: NodeArray, format: ListFormat, start?: number, count?: number) { + function emitList(parentNode: TextRange, children: NodeArray, format: ListFormat, start?: number, count?: number) { emitNodeList(emit, parentNode, children, format, start, count); } - function emitExpressionList(parentNode: Node, children: NodeArray, format: ListFormat, start?: number, count?: number) { + function emitExpressionList(parentNode: TextRange, children: NodeArray, format: ListFormat, start?: number, count?: number) { emitNodeList(emitExpression, parentNode, children, format, start, count); } - function emitNodeList(emit: (node: Node) => void, parentNode: Node, children: NodeArray, format: ListFormat, start = 0, count = children ? children.length - start : 0) { + function writeDelimiter(format: ListFormat) { + switch (format & ListFormat.DelimitersMask) { + case ListFormat.None: + break; + case ListFormat.CommaDelimited: + writePunctuation(","); + break; + case ListFormat.BarDelimited: + writeSpace(); + writePunctuation("|"); + break; + case ListFormat.AmpersandDelimited: + writeSpace(); + writePunctuation("&"); + break; + } + } + + function emitNodeList(emit: (node: Node) => void, parentNode: TextRange, children: NodeArray, format: ListFormat, start = 0, count = children ? children.length - start : 0) { const isUndefined = children === undefined; if (isUndefined && format & ListFormat.OptionalIfUndefined) { return; @@ -2459,7 +2636,7 @@ namespace ts { } if (format & ListFormat.BracketsMask) { - write(getOpeningBracket(format)); + writePunctuation(getOpeningBracket(format)); } if (onBeforeEmitNodeArray) { @@ -2472,7 +2649,7 @@ namespace ts { writeLine(); } else if (format & ListFormat.SpaceBetweenBraces && !(format & ListFormat.NoSpaceIfEmpty)) { - write(" "); + writeSpace(); } } else { @@ -2484,7 +2661,7 @@ namespace ts { shouldEmitInterveningComments = false; } else if (format & ListFormat.SpaceBetweenBraces) { - write(" "); + writeSpace(); } // Increase the indent, if requested. @@ -2495,7 +2672,6 @@ namespace ts { // Emit each child. let previousSibling: Node; let shouldDecreaseIndentAfterEmit: boolean; - const delimiter = getDelimiter(format); for (let i = 0; i < count; i++) { const child = children[start + i]; @@ -2507,10 +2683,10 @@ namespace ts { // a // /* End of parameter a */ -> this comment isn't considered to be trailing comment of parameter "a" due to newline // , - if (delimiter && previousSibling.end !== parentNode.end) { + if (format & ListFormat.DelimitersMask && previousSibling.end !== parentNode.end) { emitLeadingCommentsOfPosition(previousSibling.end); } - write(delimiter); + writeDelimiter(format); // Write either a line terminator or whitespace to separate the elements. if (shouldWriteSeparatingLineTerminator(previousSibling, child, format)) { @@ -2525,7 +2701,7 @@ namespace ts { shouldEmitInterveningComments = false; } else if (previousSibling && format & ListFormat.SpaceBetweenSiblings) { - write(" "); + writeSpace(); } } @@ -2553,7 +2729,7 @@ namespace ts { // Write a trailing comma, if requested. const hasTrailingComma = (format & ListFormat.AllowTrailingComma) && children.hasTrailingComma; if (format & ListFormat.CommaDelimited && hasTrailingComma) { - write(","); + writePunctuation(","); } @@ -2563,7 +2739,7 @@ namespace ts { // 2 // /* end of element 2 */ // ]; - if (previousSibling && delimiter && previousSibling.end !== parentNode.end && !(getEmitFlags(previousSibling) & EmitFlags.NoTrailingComments)) { + if (previousSibling && format & ListFormat.DelimitersMask && previousSibling.end !== parentNode.end && !(getEmitFlags(previousSibling) & EmitFlags.NoTrailingComments)) { emitLeadingCommentsOfPosition(previousSibling.end); } @@ -2577,7 +2753,7 @@ namespace ts { writeLine(); } else if (format & ListFormat.SpaceBetweenBraces) { - write(" "); + writeSpace(); } } @@ -2586,51 +2762,115 @@ namespace ts { } if (format & ListFormat.BracketsMask) { - write(getClosingBracket(format)); + writePunctuation(getClosingBracket(format)); } } - function write(s: string) { + function commitPendingSemicolonInternal() { + if (pendingSemicolon) { + writeSemicolonInternal(); + pendingSemicolon = false; + } + } + + function writeLiteral(s: string) { + commitPendingSemicolon(); + writer.writeLiteral(s); + } + + function writeStringLiteral(s: string) { + commitPendingSemicolon(); + writer.writeStringLiteral(s); + } + + function writeBase(s: string) { + commitPendingSemicolon(); writer.write(s); } + function writeSymbol(s: string, sym: Symbol) { + commitPendingSemicolon(); + writer.writeSymbol(s, sym); + } + + function writePunctuation(s: string) { + commitPendingSemicolon(); + writer.writePunctuation(s); + } + + function deferWriteSemicolon() { + pendingSemicolon = true; + } + + function writeSemicolonInternal() { + writer.writePunctuation(";"); + } + + function writeKeyword(s: string) { + commitPendingSemicolon(); + writer.writeKeyword(s); + } + + function writeOperator(s: string) { + commitPendingSemicolon(); + writer.writeOperator(s); + } + + function writeParameter(s: string) { + commitPendingSemicolon(); + writer.writeParameter(s); + } + + function writeSpace() { + commitPendingSemicolon(); + writer.writeSpace(" "); + } + + function writeProperty(s: string) { + commitPendingSemicolon(); + writer.writeProperty(s); + } + function writeLine() { + commitPendingSemicolon(); writer.writeLine(); } function increaseIndent() { + commitPendingSemicolon(); writer.increaseIndent(); } function decreaseIndent() { + commitPendingSemicolon(); writer.decreaseIndent(); } - function writeToken(token: SyntaxKind, pos: number, contextNode?: Node) { + function writeToken(token: SyntaxKind, pos: number, writer: (s: string) => void, contextNode?: Node) { return onEmitSourceMapOfToken - ? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText) - : writeTokenText(token, pos); + ? onEmitSourceMapOfToken(contextNode, token, writer, pos, writeTokenText) + : writeTokenText(token, writer, pos); } - function writeTokenNode(node: Node) { + function writeTokenNode(node: Node, writer: (s: string) => void) { if (onBeforeEmitToken) { onBeforeEmitToken(node); } - write(tokenToString(node.kind)); + writer(tokenToString(node.kind)); if (onAfterEmitToken) { onAfterEmitToken(node); } } - function writeTokenText(token: SyntaxKind, pos?: number) { + function writeTokenText(token: SyntaxKind, writer: (s: string) => void, pos?: number) { const tokenString = tokenToString(token); - write(tokenString); + writer(tokenString); return pos < 0 ? pos : pos + tokenString.length; } function writeLineOrSpace(node: Node) { if (getEmitFlags(node) & EmitFlags.SingleLine) { - write(" "); + writeSpace(); } else { writeLine(); @@ -2688,7 +2928,7 @@ namespace ts { } } - function shouldWriteLeadingLineTerminator(parentNode: Node, children: NodeArray, format: ListFormat) { + function shouldWriteLeadingLineTerminator(parentNode: TextRange, children: NodeArray, format: ListFormat) { if (format & ListFormat.MultiLine) { return true; } @@ -2734,7 +2974,7 @@ namespace ts { } } - function shouldWriteClosingLineTerminator(parentNode: Node, children: NodeArray, format: ListFormat) { + function shouldWriteClosingLineTerminator(parentNode: TextRange, children: NodeArray, format: ListFormat) { if (format & ListFormat.MultiLine) { return (format & ListFormat.NoTrailingNewLine) === 0; } @@ -3073,19 +3313,6 @@ namespace ts { } } - function createDelimiterMap() { - const delimiters: string[] = []; - delimiters[ListFormat.None] = ""; - delimiters[ListFormat.CommaDelimited] = ","; - delimiters[ListFormat.BarDelimited] = " |"; - delimiters[ListFormat.AmpersandDelimited] = " &"; - return delimiters; - } - - function getDelimiter(format: ListFormat) { - return delimiters[format & ListFormat.DelimitersMask]; - } - function createBracketsMap() { const brackets: string[][] = []; brackets[ListFormat.Braces] = ["{", "}"]; @@ -3109,86 +3336,4 @@ namespace ts { CountMask = 0x0FFFFFFF, // Temp variable counter _i = 0x10000000, // Use/preference flag for '_i' } - - const enum ListFormat { - None = 0, - - // Line separators - SingleLine = 0, // Prints the list on a single line (default). - MultiLine = 1 << 0, // Prints the list on multiple lines. - PreserveLines = 1 << 1, // Prints the list using line preservation if possible. - LinesMask = SingleLine | MultiLine | PreserveLines, - - // Delimiters - NotDelimited = 0, // There is no delimiter between list items (default). - BarDelimited = 1 << 2, // Each list item is space-and-bar (" |") delimited. - AmpersandDelimited = 1 << 3, // Each list item is space-and-ampersand (" &") delimited. - CommaDelimited = 1 << 4, // Each list item is comma (",") delimited. - DelimitersMask = BarDelimited | AmpersandDelimited | CommaDelimited, - - AllowTrailingComma = 1 << 5, // Write a trailing comma (",") if present. - - // Whitespace - Indented = 1 << 6, // The list should be indented. - SpaceBetweenBraces = 1 << 7, // Inserts a space after the opening brace and before the closing brace. - SpaceBetweenSiblings = 1 << 8, // Inserts a space between each sibling node. - - // Brackets/Braces - Braces = 1 << 9, // The list is surrounded by "{" and "}". - Parenthesis = 1 << 10, // The list is surrounded by "(" and ")". - AngleBrackets = 1 << 11, // The list is surrounded by "<" and ">". - SquareBrackets = 1 << 12, // The list is surrounded by "[" and "]". - BracketsMask = Braces | Parenthesis | AngleBrackets | SquareBrackets, - - OptionalIfUndefined = 1 << 13, // Do not emit brackets if the list is undefined. - OptionalIfEmpty = 1 << 14, // Do not emit brackets if the list is empty. - Optional = OptionalIfUndefined | OptionalIfEmpty, - - // Other - PreferNewLine = 1 << 15, // Prefer adding a LineTerminator between synthesized nodes. - NoTrailingNewLine = 1 << 16, // Do not emit a trailing NewLine for a MultiLine list. - NoInterveningComments = 1 << 17, // Do not emit comments between each node - - NoSpaceIfEmpty = 1 << 18, // If the literal is empty, do not add spaces between braces. - SingleElement = 1 << 19, - - // Precomputed Formats - Modifiers = SingleLine | SpaceBetweenSiblings | NoInterveningComments, - HeritageClauses = SingleLine | SpaceBetweenSiblings, - SingleLineTypeLiteralMembers = SingleLine | SpaceBetweenBraces | SpaceBetweenSiblings | Indented, - MultiLineTypeLiteralMembers = MultiLine | Indented, - - TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented, - UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine, - IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine, - ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty, - ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty, - ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty, - ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets, - CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine, - CallExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis, - NewExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis | OptionalIfUndefined, - TemplateExpressionSpans = SingleLine | NoInterveningComments, - SingleLineBlockStatements = SpaceBetweenBraces | SpaceBetweenSiblings | SingleLine, - MultiLineBlockStatements = Indented | MultiLine, - VariableDeclarationList = CommaDelimited | SpaceBetweenSiblings | SingleLine, - SingleLineFunctionBodyStatements = SingleLine | SpaceBetweenSiblings | SpaceBetweenBraces, - MultiLineFunctionBodyStatements = MultiLine, - ClassHeritageClauses = SingleLine | SpaceBetweenSiblings, - ClassMembers = Indented | MultiLine, - InterfaceMembers = Indented | MultiLine, - EnumMembers = CommaDelimited | Indented | MultiLine, - CaseBlockClauses = Indented | MultiLine, - NamedImportsOrExportsElements = CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | SingleLine | SpaceBetweenBraces, - JsxElementOrFragmentChildren = SingleLine | NoInterveningComments, - JsxElementAttributes = SingleLine | SpaceBetweenSiblings | NoInterveningComments, - CaseOrDefaultClauseStatements = Indented | MultiLine | NoTrailingNewLine | OptionalIfEmpty, - HeritageClauseTypes = CommaDelimited | SpaceBetweenSiblings | SingleLine, - SourceFileStatements = MultiLine | NoTrailingNewLine, - Decorators = MultiLine | Optional, - TypeArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | AngleBrackets | Optional, - TypeParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | AngleBrackets | Optional, - Parameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | Parenthesis, - IndexSignatureParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | SquareBrackets, - } } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 7ddc8a0cd5f..14c8ad91eeb 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -112,21 +112,23 @@ namespace ts { export function createIdentifier(text: string): Identifier; /* @internal */ - // tslint:disable-next-line unified-signatures - export function createIdentifier(text: string, typeArguments: ReadonlyArray): Identifier; - export function createIdentifier(text: string, typeArguments?: ReadonlyArray): Identifier { + export function createIdentifier(text: string, typeArguments: ReadonlyArray): Identifier; // tslint:disable-line unified-signatures + export function createIdentifier(text: string, typeArguments?: ReadonlyArray): Identifier { const node = createSynthesizedNode(SyntaxKind.Identifier); node.escapedText = escapeLeadingUnderscores(text); node.originalKeywordKind = text ? stringToToken(text) : SyntaxKind.Unknown; node.autoGenerateKind = GeneratedIdentifierKind.None; node.autoGenerateId = 0; if (typeArguments) { - node.typeArguments = createNodeArray(typeArguments); + node.typeArguments = createNodeArray(typeArguments as ReadonlyArray); } return node; } - export function updateIdentifier(node: Identifier, typeArguments: NodeArray | undefined): Identifier { + export function updateIdentifier(node: Identifier): Identifier; + /* @internal */ + export function updateIdentifier(node: Identifier, typeArguments: NodeArray | undefined): Identifier; // tslint:disable-line unified-signatures + export function updateIdentifier(node: Identifier, typeArguments?: NodeArray | undefined): Identifier { return node.typeArguments !== typeArguments ? updateNode(createIdentifier(idText(node), typeArguments), node) : node; @@ -578,11 +580,12 @@ namespace ts { } /* @internal */ - export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined) { + export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, typeArguments?: TypeNode[] | undefined) { const node = createSynthesizedNode(kind) as SignatureDeclaration; node.typeParameters = asNodeArray(typeParameters); node.parameters = asNodeArray(parameters); node.type = type; + node.typeArguments = asNodeArray(typeArguments); return node; } diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index 828c5744bbd..2dabb97b08d 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -51,7 +51,7 @@ namespace ts { * @param tokenStartPos The start pos of the token. * @param emitCallback The callback used to emit the token. */ - emitTokenWithSourceMap(node: Node, token: SyntaxKind, tokenStartPos: number, emitCallback: (token: SyntaxKind, tokenStartPos: number) => number): number; + emitTokenWithSourceMap(node: Node, token: SyntaxKind, writer: (s: string) => void, tokenStartPos: number, emitCallback: (token: SyntaxKind, writer: (s: string) => void, tokenStartPos: number) => number): number; /** * Gets the text for the source map. @@ -372,9 +372,9 @@ namespace ts { * @param tokenStartPos The start pos of the token. * @param emitCallback The callback used to emit the token. */ - function emitTokenWithSourceMap(node: Node, token: SyntaxKind, tokenPos: number, emitCallback: (token: SyntaxKind, tokenStartPos: number) => number) { + function emitTokenWithSourceMap(node: Node, token: SyntaxKind, writer: (s: string) => void, tokenPos: number, emitCallback: (token: SyntaxKind, writer: (s: string) => void, tokenStartPos: number) => number) { if (disabled) { - return emitCallback(token, tokenPos); + return emitCallback(token, writer, tokenPos); } const emitNode = node && node.emitNode; @@ -386,7 +386,7 @@ namespace ts { emitPos(tokenPos); } - tokenPos = emitCallback(token, tokenPos); + tokenPos = emitCallback(token, writer, tokenPos); if (range) tokenPos = range.end; if ((emitFlags & EmitFlags.NoTokenTrailingSourceMaps) === 0 && tokenPos >= 0) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c51208c4f79..6622348e101 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -695,7 +695,7 @@ namespace ts { /*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier. /*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name. isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace - /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics. + /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics, quickinfo, and signature help. /*@internal*/ jsdocDotPos?: number; // Identifier occurs in JSDoc-style generic: Id. /*@internal*/ skipNameGenerationScope?: boolean; // Should skip a name generation scope when generating the name for this identifier } @@ -783,6 +783,7 @@ namespace ts { typeParameters?: NodeArray; parameters: NodeArray; type: TypeNode | undefined; + /* @internal */ typeArguments?: NodeArray; // Used for quick info, replaces typeParameters for instantiated signatures } export type SignatureDeclaration = @@ -966,7 +967,8 @@ namespace ts { | IndexSignatureDeclaration | MethodSignature | ConstructSignatureDeclaration - | CallSignatureDeclaration; + | CallSignatureDeclaration + | JSDocFunctionType; export interface FunctionDeclaration extends FunctionLikeDeclarationBase, DeclarationStatement { kind: SyntaxKind.FunctionDeclaration; @@ -2762,6 +2764,16 @@ namespace ts { signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration; /** Note that the resulting nodes cannot be checked. */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration; + /** Note that the resulting nodes cannot be checked. */ + symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): EntityName; + /** Note that the resulting nodes cannot be checked. */ + symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): Expression; + /** Note that the resulting nodes cannot be checked. */ + symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): NodeArray | undefined; + /** Note that the resulting nodes cannot be checked. */ + symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): ParameterDeclaration; + /** Note that the resulting nodes cannot be checked. */ + typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeParameterDeclaration; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol | undefined; @@ -2780,9 +2792,17 @@ namespace ts { getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined; getTypeAtLocation(node: Node): Type; getTypeFromTypeNode(node: TypeNode): Type; + signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; - symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; + symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): string; + typePredicateToString(predicate: TypePredicate, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; + + /* @internal */ writeSignature(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind, writer?: EmitTextWriter): string; + /* @internal */ writeType(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags, writer?: EmitTextWriter): string; + /* @internal */ writeSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags, writer?: EmitTextWriter): string; + /* @internal */ writeTypePredicate(predicate: TypePredicate, enclosingDeclaration?: Node, flags?: TypeFormatFlags, writer?: EmitTextWriter): string; + /** * @deprecated Use the createX factory functions or XToY typechecker methods and `createPrinter` or the `xToString` methods instead * This will be removed in a future version. @@ -2897,7 +2917,7 @@ namespace ts { * This should be called in a loop climbing parents of the symbol, so we'll get `N`. */ /* @internal */ getAccessibleSymbolChain(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, useOnlyExternalAliasing: boolean): Symbol[] | undefined; - + /* @internal */ getTypePredicateOfSignature(signature: Signature): TypePredicate; /* @internal */ resolveExternalModuleSymbol(symbol: Symbol): Symbol; } @@ -2908,30 +2928,98 @@ namespace ts { Subtype } - export enum NodeBuilderFlags { + export const enum NodeBuilderFlags { None = 0, // Options NoTruncation = 1 << 0, // Don't truncate result WriteArrayAsGenericType = 1 << 1, // Write Array instead T[] + WriteDefaultSymbolWithoutName = 1 << 2, // Write `default`-named symbols as `default` instead of how they were written + // empty space WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature UseFullyQualifiedType = 1 << 6, // Write out the fully qualified type name (eg. Module.Type, instead of Type) + UseOnlyExternalAliasing = 1 << 7, // Only use external aliases for a symbol SuppressAnyReturnType = 1 << 8, // If the return type is any-like, don't offer a return type. WriteTypeParametersInQualifiedName = 1 << 9, + MultilineObjectLiterals = 1 << 10, // Always write object literals across multiple lines + WriteClassExpressionAsTypeLiteral = 1 << 11, // Write class {} as { new(): {} } - used for mixin declaration emit + UseTypeOfFunction = 1 << 12, // Build using typeof instead of function type literal + OmitParameterModifiers = 1 << 13, // Omit modifiers on parameters + UseAliasDefinedOutsideCurrentScope = 1 << 14, // Allow non-visible aliases // Error handling - AllowThisInObjectLiteral = 1 << 10, - AllowQualifedNameInPlaceOfIdentifier = 1 << 11, - AllowAnonymousIdentifier = 1 << 13, - AllowEmptyUnionOrIntersection = 1 << 14, - AllowEmptyTuple = 1 << 15, + AllowThisInObjectLiteral = 1 << 15, + AllowQualifedNameInPlaceOfIdentifier = 1 << 16, + AllowAnonymousIdentifier = 1 << 17, + AllowEmptyUnionOrIntersection = 1 << 18, + AllowEmptyTuple = 1 << 19, + AllowUniqueESSymbolType = 1 << 20, + AllowEmptyIndexInfoType = 1 << 21, - IgnoreErrors = AllowThisInObjectLiteral | AllowQualifedNameInPlaceOfIdentifier | AllowAnonymousIdentifier | AllowEmptyUnionOrIntersection | AllowEmptyTuple, + IgnoreErrors = AllowThisInObjectLiteral | AllowQualifedNameInPlaceOfIdentifier | AllowAnonymousIdentifier | AllowEmptyUnionOrIntersection | AllowEmptyTuple | AllowEmptyIndexInfoType, // State - InObjectTypeLiteral = 1 << 20, + InObjectTypeLiteral = 1 << 22, InTypeAlias = 1 << 23, // Writing type in type alias declaration } + // Ensure the shared flags between this and `NodeBuilderFlags` stay in alignment + export const enum TypeFormatFlags { + None = 0, + NoTruncation = 1 << 0, // Don't truncate typeToString result + WriteArrayAsGenericType = 1 << 1, // Write Array instead T[] + WriteDefaultSymbolWithoutName = 1 << 2, // Write all `defaut`-named symbols as `default` instead of their written name + // hole because there's a hole in node builder flags + WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature + UseFullyQualifiedType = 1 << 6, // Write out the fully qualified type name (eg. Module.Type, instead of Type) + // hole because `UseOnlyExternalAliasing` is here in node builder flags, but functions which take old flags use `SymbolFormatFlags` instead + SuppressAnyReturnType = 1 << 8, // If the return type is any-like, don't offer a return type. + // hole because `WriteTypeParametersInQualifiedName` is here in node builder flags, but functions which take old flags use `SymbolFormatFlags` for this instead + MultilineObjectLiterals = 1 << 10, // Always print object literals across multiple lines (only used to map into node builder flags) + WriteClassExpressionAsTypeLiteral = 1 << 11, // Write a type literal instead of (Anonymous class) + UseTypeOfFunction = 1 << 12, // Write typeof instead of function type literal + OmitParameterModifiers = 1 << 13, // Omit modifiers on parameters + UseAliasDefinedOutsideCurrentScope = 1 << 14, // For a `type T = ... ` defined in a different file, write `T` instead of its value, + // even though `T` can't be accessed in the current scope. + + // Error Handling + AllowUniqueESSymbolType = 1 << 20, // This is bit 20 to align with the same bit in `NodeBuilderFlags` + + // TypeFormatFlags exclusive + AddUndefined = 1 << 17, // Add undefined to types of initialized, non-optional parameters + WriteArrowStyleSignature = 1 << 18, // Write arrow style signature + + // State + InArrayType = 1 << 19, // Writing an array element type + InElementType = 1 << 21, // Writing an array or union element type + InFirstTypeArgument = 1 << 22, // Writing first type argument of the instantiated type + InTypeAlias = 1 << 23, // Writing type in type alias declaration + + /** @deprecated */ WriteOwnNameForAnyLike = 0, // Does nothing + + NodeBuilderFlagsMask = + NoTruncation | WriteArrayAsGenericType | WriteDefaultSymbolWithoutName | WriteTypeArgumentsOfSignature | + UseFullyQualifiedType | SuppressAnyReturnType | MultilineObjectLiterals | WriteClassExpressionAsTypeLiteral | + UseTypeOfFunction | OmitParameterModifiers | UseAliasDefinedOutsideCurrentScope | AllowUniqueESSymbolType | InTypeAlias, + } + + export const enum SymbolFormatFlags { + None = 0x00000000, + + // Write symbols's type argument if it is instantiated symbol + // eg. class C { p: T } <-- Show p as C.p here + // var a: C; + // var p = a.p; <--- Here p is property of C so show it as C.p instead of just C.p + WriteTypeParametersOrArguments = 0x00000001, + + // Use only external alias information to get the symbol name in the given context + // eg. module m { export class c { } } import x = m.c; + // When this flag is specified m.c will be used to refer to the class instead of alias symbol x + UseOnlyExternalAliasing = 0x00000002, + + // Build symbol name using any nodes needed, instead of just components of an entity name + AllowAnyNodeKind = 0x00000004, + } + /* @internal */ export interface SymbolWalker { /** Note: Return values are not ordered. */ @@ -2940,21 +3028,27 @@ namespace ts { walkSymbol(root: Symbol): { visitedTypes: ReadonlyArray, visitedSymbols: ReadonlyArray }; } + /** + * @deprecated + */ export interface SymbolDisplayBuilder { - buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; - buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void; - buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void; - buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; + /** @deprecated */ buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void; + /** @deprecated */ buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void; + /** @deprecated */ buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; } - export interface SymbolWriter { + /** + * @deprecated Migrate to other methods of generating symbol names, ex symbolToEntityName + a printer or symbolToString + */ + export interface SymbolWriter extends SymbolTracker { writeKeyword(text: string): void; writeOperator(text: string): void; writePunctuation(text: string): void; @@ -2967,50 +3061,6 @@ namespace ts { increaseIndent(): void; decreaseIndent(): void; clear(): void; - - // Called when the symbol writer encounters a symbol to write. Currently only used by the - // declaration emitter to help determine if it should patch up the final declaration file - // with import statements it previously saw (but chose not to emit). - trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; - reportInaccessibleThisError(): void; - reportPrivateInBaseOfClassExpression(propertyName: string): void; - reportInaccessibleUniqueSymbolError(): void; - } - - export const enum TypeFormatFlags { - None = 0, - WriteArrayAsGenericType = 1 << 0, // Write Array instead T[] - UseTypeOfFunction = 1 << 2, // Write typeof instead of function type literal - NoTruncation = 1 << 3, // Don't truncate typeToString result - WriteArrowStyleSignature = 1 << 4, // Write arrow style signature - WriteOwnNameForAnyLike = 1 << 5, // Write symbol's own name instead of 'any' for any like types (eg. unknown, __resolving__ etc) - WriteTypeArgumentsOfSignature = 1 << 6, // Write the type arguments instead of type parameters of the signature - InElementType = 1 << 7, // Writing an array or union element type - UseFullyQualifiedType = 1 << 8, // Write out the fully qualified type name (eg. Module.Type, instead of Type) - InFirstTypeArgument = 1 << 9, // Writing first type argument of the instantiated type - InTypeAlias = 1 << 10, // Writing type in type alias declaration - SuppressAnyReturnType = 1 << 12, // If the return type is any-like, don't offer a return type. - AddUndefined = 1 << 13, // Add undefined to types of initialized, non-optional parameters - WriteClassExpressionAsTypeLiteral = 1 << 14, // Write a type literal instead of (Anonymous class) - InArrayType = 1 << 15, // Writing an array element type - UseAliasDefinedOutsideCurrentScope = 1 << 16, // For a `type T = ... ` defined in a different file, write `T` instead of its value, - // even though `T` can't be accessed in the current scope. - AllowUniqueESSymbolType = 1 << 17, - } - - export const enum SymbolFormatFlags { - None = 0x00000000, - - // Write symbols's type argument if it is instantiated symbol - // eg. class C { p: T } <-- Show p as C.p here - // var a: C; - // var p = a.p; <--- Here p is property of C so show it as C.p instead of just C.p - WriteTypeParametersOrArguments = 0x00000001, - - // Use only external alias information to get the symbol name in the given context - // eg. module m { export class c { } } import x = m.c; - // When this flag is specified m.c will be used to refer to the class instead of alias symbol x - UseOnlyExternalAliasing = 0x00000002, } /* @internal */ @@ -3102,9 +3152,9 @@ namespace ts { isImplementationOfOverload(node: FunctionLikeDeclaration): boolean | undefined; isRequiredInitializedParameter(node: ParameterDeclaration): boolean; isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean; - writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; - writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; - writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; + writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: EmitTextWriter): void; + writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: EmitTextWriter): void; + writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: EmitTextWriter): void; isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult; isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult; // Returns the constant value this property access resolves to, or 'undefined' for a non-constant @@ -3118,7 +3168,7 @@ namespace ts { getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): string[]; getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[]; isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean; - writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: SymbolWriter): void; + writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: EmitTextWriter): void; getJsxFactoryEntity(): EntityName; } @@ -4765,6 +4815,10 @@ namespace ts { * collisions. */ printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string; + /** + * Prints a list of nodes using the given format flags + */ + printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): string; /** * Prints a source file as-is, without any emit transformations. */ @@ -4774,6 +4828,7 @@ namespace ts { */ printBundle(bundle: Bundle): string; /*@internal*/ writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile | undefined, writer: EmitTextWriter): void; + /*@internal*/ writeList(format: ListFormat, list: NodeArray, sourceFile: SourceFile | undefined, writer: EmitTextWriter): void; /*@internal*/ writeFile(sourceFile: SourceFile, writer: EmitTextWriter): void; /*@internal*/ writeBundle(bundle: Bundle, writer: EmitTextWriter): void; } @@ -4821,7 +4876,7 @@ namespace ts { */ substituteNode?(hint: EmitHint, node: Node): Node; /*@internal*/ onEmitSourceMapOfNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void; - /*@internal*/ onEmitSourceMapOfToken?: (node: Node, token: SyntaxKind, pos: number, emitCallback: (token: SyntaxKind, pos: number) => number) => number; + /*@internal*/ onEmitSourceMapOfToken?: (node: Node, token: SyntaxKind, writer: (s: string) => void, pos: number, emitCallback: (token: SyntaxKind, writer: (s: string) => void, pos: number) => number) => number; /*@internal*/ onEmitSourceMapOfPosition?: (pos: number) => void; /*@internal*/ onEmitHelpers?: (node: Node, writeLines: (text: string) => void) => void; /*@internal*/ onSetSourceFile?: (node: SourceFile) => void; @@ -4834,13 +4889,14 @@ namespace ts { export interface PrinterOptions { removeComments?: boolean; newLine?: NewLineKind; + omitTrailingSemicolon?: boolean; /*@internal*/ sourceMap?: boolean; /*@internal*/ inlineSourceMap?: boolean; /*@internal*/ extendedDiagnostics?: boolean; } - /*@internal*/ - export interface EmitTextWriter { + /* @internal */ + export interface EmitTextWriter extends SymbolTracker, SymbolWriter { write(s: string): void; writeTextOfNode(text: string, node: Node): void; writeLine(): void; @@ -4854,7 +4910,26 @@ namespace ts { getColumn(): number; getIndent(): number; isAtStartOfLine(): boolean; - reset(): void; + clear(): void; + + writeKeyword(text: string): void; + writeOperator(text: string): void; + writePunctuation(text: string): void; + writeSpace(text: string): void; + writeStringLiteral(text: string): void; + writeParameter(text: string): void; + writeProperty(text: string): void; + writeSymbol(text: string, symbol: Symbol): void; + } + + export interface SymbolTracker { + // Called when the symbol writer encounters a symbol to write. Currently only used by the + // declaration emitter to help determine if it should patch up the final declaration file + // with import statements it previously saw (but chose not to emit). + trackSymbol?(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; + reportInaccessibleThisError?(): void; + reportPrivateInBaseOfClassExpression?(propertyName: string): void; + reportInaccessibleUniqueSymbolError?(): void; } export interface TextSpan { @@ -4893,4 +4968,86 @@ namespace ts { export interface SyntaxList extends Node { _children: Node[]; } + + export const enum ListFormat { + None = 0, + + // Line separators + SingleLine = 0, // Prints the list on a single line (default). + MultiLine = 1 << 0, // Prints the list on multiple lines. + PreserveLines = 1 << 1, // Prints the list using line preservation if possible. + LinesMask = SingleLine | MultiLine | PreserveLines, + + // Delimiters + NotDelimited = 0, // There is no delimiter between list items (default). + BarDelimited = 1 << 2, // Each list item is space-and-bar (" |") delimited. + AmpersandDelimited = 1 << 3, // Each list item is space-and-ampersand (" &") delimited. + CommaDelimited = 1 << 4, // Each list item is comma (",") delimited. + DelimitersMask = BarDelimited | AmpersandDelimited | CommaDelimited, + + AllowTrailingComma = 1 << 5, // Write a trailing comma (",") if present. + + // Whitespace + Indented = 1 << 6, // The list should be indented. + SpaceBetweenBraces = 1 << 7, // Inserts a space after the opening brace and before the closing brace. + SpaceBetweenSiblings = 1 << 8, // Inserts a space between each sibling node. + + // Brackets/Braces + Braces = 1 << 9, // The list is surrounded by "{" and "}". + Parenthesis = 1 << 10, // The list is surrounded by "(" and ")". + AngleBrackets = 1 << 11, // The list is surrounded by "<" and ">". + SquareBrackets = 1 << 12, // The list is surrounded by "[" and "]". + BracketsMask = Braces | Parenthesis | AngleBrackets | SquareBrackets, + + OptionalIfUndefined = 1 << 13, // Do not emit brackets if the list is undefined. + OptionalIfEmpty = 1 << 14, // Do not emit brackets if the list is empty. + Optional = OptionalIfUndefined | OptionalIfEmpty, + + // Other + PreferNewLine = 1 << 15, // Prefer adding a LineTerminator between synthesized nodes. + NoTrailingNewLine = 1 << 16, // Do not emit a trailing NewLine for a MultiLine list. + NoInterveningComments = 1 << 17, // Do not emit comments between each node + + NoSpaceIfEmpty = 1 << 18, // If the literal is empty, do not add spaces between braces. + SingleElement = 1 << 19, + + // Precomputed Formats + Modifiers = SingleLine | SpaceBetweenSiblings | NoInterveningComments, + HeritageClauses = SingleLine | SpaceBetweenSiblings, + SingleLineTypeLiteralMembers = SingleLine | SpaceBetweenBraces | SpaceBetweenSiblings | Indented, + MultiLineTypeLiteralMembers = MultiLine | Indented, + + TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented, + UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine, + IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine, + ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty, + ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty, + ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty, + ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets, + CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine, + CallExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis, + NewExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis | OptionalIfUndefined, + TemplateExpressionSpans = SingleLine | NoInterveningComments, + SingleLineBlockStatements = SpaceBetweenBraces | SpaceBetweenSiblings | SingleLine, + MultiLineBlockStatements = Indented | MultiLine, + VariableDeclarationList = CommaDelimited | SpaceBetweenSiblings | SingleLine, + SingleLineFunctionBodyStatements = SingleLine | SpaceBetweenSiblings | SpaceBetweenBraces, + MultiLineFunctionBodyStatements = MultiLine, + ClassHeritageClauses = SingleLine | SpaceBetweenSiblings, + ClassMembers = Indented | MultiLine, + InterfaceMembers = Indented | MultiLine, + EnumMembers = CommaDelimited | Indented | MultiLine, + CaseBlockClauses = Indented | MultiLine, + NamedImportsOrExportsElements = CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | SingleLine | SpaceBetweenBraces, + JsxElementOrFragmentChildren = SingleLine | NoInterveningComments, + JsxElementAttributes = SingleLine | SpaceBetweenSiblings | NoInterveningComments, + CaseOrDefaultClauseStatements = Indented | MultiLine | NoTrailingNewLine | OptionalIfEmpty, + HeritageClauseTypes = CommaDelimited | SpaceBetweenSiblings | SingleLine, + SourceFileStatements = MultiLine | NoTrailingNewLine, + Decorators = MultiLine | Optional, + TypeArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | AngleBrackets | Optional, + TypeParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | AngleBrackets | Optional, + Parameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis, + IndexSignatureParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | SquareBrackets, + } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8304320b301..796ed35a861 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -29,26 +29,31 @@ namespace ts { return undefined; } - export interface StringSymbolWriter extends SymbolWriter { - string(): string; - } - const stringWriter = createSingleLineStringWriter(); - function createSingleLineStringWriter(): StringSymbolWriter { + function createSingleLineStringWriter(): EmitTextWriter { let str = ""; const writeText: (text: string) => void = text => str += text; return { - string: () => str, + getText: () => str, + write: writeText, + rawWrite: writeText, + writeTextOfNode: writeText, writeKeyword: writeText, writeOperator: writeText, writePunctuation: writeText, writeSpace: writeText, writeStringLiteral: writeText, + writeLiteral: writeText, writeParameter: writeText, writeProperty: writeText, writeSymbol: writeText, + getTextPos: () => str.length, + getLine: () => 0, + getColumn: () => 0, + getIndent: () => 0, + isAtStartOfLine: () => false, // Completely ignore indentation for string writers. And map newlines to // a single space. @@ -63,11 +68,11 @@ namespace ts { }; } - export function usingSingleLineStringWriter(action: (writer: StringSymbolWriter) => void): string { - const oldString = stringWriter.string(); + export function usingSingleLineStringWriter(action: (writer: EmitTextWriter) => void): string { + const oldString = stringWriter.getText(); try { action(stringWriter); - return stringWriter.string(); + return stringWriter.getText(); } finally { stringWriter.clear(); @@ -2606,7 +2611,19 @@ namespace ts { getColumn: () => lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1, getText: () => output, isAtStartOfLine: () => lineStart, - reset + clear: reset, + reportInaccessibleThisError: noop, + reportPrivateInBaseOfClassExpression: noop, + reportInaccessibleUniqueSymbolError: noop, + trackSymbol: noop, + writeKeyword: write, + writeOperator: write, + writeParameter: write, + writeProperty: write, + writePunctuation: write, + writeSpace: write, + writeStringLiteral: write, + writeSymbol: write }; } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 2d678eb0eff..12b5d4f1b07 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -3,6 +3,8 @@ /// namespace ts { + const isTypeNodeOrTypeParameterDeclaration = or(isTypeNode, isTypeParameterDeclaration); + /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * @@ -222,7 +224,7 @@ namespace ts { // Names case SyntaxKind.Identifier: - return updateIdentifier(node, nodesVisitor((node).typeArguments, visitor, isTypeNode)); + return updateIdentifier(node, nodesVisitor((node).typeArguments, visitor, isTypeNodeOrTypeParameterDeclaration)); case SyntaxKind.QualifiedName: return updateQualifiedName(node, diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 95d85bc5aa0..6f6b2f3c61e 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -229,13 +229,13 @@ namespace ts.codefix { } } - function getTypeAccessiblityWriter(checker: TypeChecker): StringSymbolWriter { + function getTypeAccessiblityWriter(checker: TypeChecker): EmitTextWriter { let str = ""; let typeIsAccessible = true; const writeText: (text: string) => void = text => str += text; return { - string: () => typeIsAccessible ? str : undefined, + getText: () => typeIsAccessible ? str : undefined, writeKeyword: writeText, writeOperator: writeText, writePunctuation: writeText, @@ -244,6 +244,15 @@ namespace ts.codefix { writeParameter: writeText, writeProperty: writeText, writeSymbol: writeText, + write: writeText, + writeTextOfNode: writeText, + rawWrite: writeText, + writeLiteral: writeText, + getTextPos: () => 0, + getLine: () => 0, + getColumn: () => 0, + getIndent: () => 0, + isAtStartOfLine: () => false, writeLine: () => writeText(" "), increaseIndent: noop, decreaseIndent: noop, @@ -261,8 +270,8 @@ namespace ts.codefix { function typeToString(type: Type, enclosingDeclaration: Declaration, checker: TypeChecker): string { const writer = getTypeAccessiblityWriter(checker); - checker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration); - return writer.string(); + checker.writeType(type, enclosingDeclaration, /*flags*/ undefined, writer); + return writer.getText(); } namespace InferFromReference { diff --git a/src/services/services.ts b/src/services/services.ts index 90e9b64a1df..4236416fbb3 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -883,7 +883,8 @@ namespace ts { scriptKind: ScriptKind; } - export interface DisplayPartsSymbolWriter extends SymbolWriter { + /* @internal */ + export interface DisplayPartsSymbolWriter extends EmitTextWriter { displayParts(): SymbolDisplayPart[]; } diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index f5338db954b..734912b3ffc 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -360,6 +360,7 @@ namespace ts.SignatureHelp { const callTarget = getInvokedExpression(invocation); const callTargetSymbol = typeChecker.getSymbolAtLocation(callTarget); const callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined); + const printer = createPrinter({ removeComments: true }); const items: SignatureHelpItem[] = map(candidates, candidateSignature => { let signatureHelpParameters: SignatureHelpParameter[]; const prefixDisplayParts: SymbolDisplayPart[] = []; @@ -376,14 +377,22 @@ namespace ts.SignatureHelp { const typeParameters = (candidateSignature.target || candidateSignature).typeParameters; signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray; suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken)); - const parameterParts = mapToDisplayParts(writer => - typeChecker.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.thisParameter, candidateSignature.parameters, writer, invocation)); + const parameterParts = mapToDisplayParts(writer => { + const flags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors; + const thisParameter = candidateSignature.thisParameter ? [typeChecker.symbolToParameterDeclaration(candidateSignature.thisParameter, invocation, flags)] : []; + const params = createNodeArray([...thisParameter, ...map(candidateSignature.parameters, param => typeChecker.symbolToParameterDeclaration(param, invocation, flags))]); + printer.writeList(ListFormat.CallExpressionArguments, params, getSourceFileOfNode(getParseTreeNode(invocation)), writer); + }); addRange(suffixDisplayParts, parameterParts); } else { isVariadic = candidateSignature.hasRestParameter; - const typeParameterParts = mapToDisplayParts(writer => - typeChecker.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, invocation)); + const typeParameterParts = mapToDisplayParts(writer => { + if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) { + const args = createNodeArray(map(candidateSignature.typeParameters, p => typeChecker.typeParameterToDeclaration(p, invocation))); + printer.writeList(ListFormat.TypeParameters, args, getSourceFileOfNode(getParseTreeNode(invocation)), writer); + } + }); addRange(prefixDisplayParts, typeParameterParts); prefixDisplayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); @@ -391,8 +400,17 @@ namespace ts.SignatureHelp { suffixDisplayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } - const returnTypeParts = mapToDisplayParts(writer => - typeChecker.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, invocation)); + const returnTypeParts = mapToDisplayParts(writer => { + writer.writePunctuation(":"); + writer.writeSpace(" "); + const predicate = typeChecker.getTypePredicateOfSignature(candidateSignature); + if (predicate) { + typeChecker.writeTypePredicate(predicate, invocation, /*flags*/ undefined, writer); + } + else { + typeChecker.writeType(typeChecker.getReturnTypeOfSignature(candidateSignature), invocation, /*flags*/ undefined, writer); + } + }); addRange(suffixDisplayParts, returnTypeParts); return { @@ -416,8 +434,10 @@ namespace ts.SignatureHelp { return { items, applicableSpan, selectedItemIndex, argumentIndex, argumentCount }; function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter { - const displayParts = mapToDisplayParts(writer => - typeChecker.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation)); + const displayParts = mapToDisplayParts(writer => { + const param = typeChecker.symbolToParameterDeclaration(parameter, invocation, NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors); + printer.writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(invocation)), writer); + }); return { name: parameter.name, @@ -428,8 +448,10 @@ namespace ts.SignatureHelp { } function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter): SignatureHelpParameter { - const displayParts = mapToDisplayParts(writer => - typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, invocation)); + const displayParts = mapToDisplayParts(writer => { + const param = typeChecker.typeParameterToDeclaration(typeParameter, invocation); + printer.writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(invocation)), writer); + }); return { name: typeParameter.symbol.name, diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 6f979f1721b..9ec99f6ccaf 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -120,6 +120,7 @@ namespace ts.SymbolDisplay { let hasAddedSymbolInfo: boolean; const isThisExpression = location.kind === SyntaxKind.ThisKeyword && isExpression(location); let type: Type; + let printer: Printer; let documentationFromAlias: SymbolDisplayPart[]; // Class at constructor site need to be shown as constructor apart from property,method, vars @@ -198,7 +199,7 @@ namespace ts.SymbolDisplay { displayParts.push(punctuationPart(SyntaxKind.ColonToken)); displayParts.push(spacePart()); if (!(type.flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous) && type.symbol) { - addRange(displayParts, symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments)); + addRange(displayParts, symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, SymbolFormatFlags.AllowAnyNodeKind | SymbolFormatFlags.WriteTypeParametersOrArguments)); displayParts.push(lineBreakPart()); } if (useConstructSignatures) { @@ -450,7 +451,8 @@ namespace ts.SymbolDisplay { // If the type is type parameter, format it specially if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) { const typeParameterParts = mapToDisplayParts(writer => { - typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(type, writer, enclosingDeclaration); + const param = typeChecker.typeParameterToDeclaration(type as TypeParameter, enclosingDeclaration); + getPrinter().writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(enclosingDeclaration)), writer); }); addRange(displayParts, typeParameterParts); } @@ -510,6 +512,13 @@ namespace ts.SymbolDisplay { return { displayParts, documentation, symbolKind, tags }; + function getPrinter() { + if (!printer) { + printer = createPrinter({ removeComments: true }); + } + return printer; + } + function prefixNextMeaning() { if (displayParts.length) { displayParts.push(lineBreakPart()); @@ -535,7 +544,7 @@ namespace ts.SymbolDisplay { symbolToDisplay = alias; } const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined, - SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing); + SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing | SymbolFormatFlags.AllowAnyNodeKind); addRange(displayParts, fullSymbolDisplayParts); } @@ -584,7 +593,8 @@ namespace ts.SymbolDisplay { function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node) { const typeParameterParts = mapToDisplayParts(writer => { - typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration); + const params = typeChecker.symbolToTypeParameterDeclarations(symbol, enclosingDeclaration); + getPrinter().writeList(ListFormat.TypeParameters, params, getSourceFileOfNode(getParseTreeNode(enclosingDeclaration)), writer); }); addRange(displayParts, typeParameterParts); } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index b0efef44642..467ba6735ca 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -810,6 +810,38 @@ namespace ts.textChanges { this.writer.write(s); this.setLastNonTriviaPosition(s, /*force*/ false); } + writeKeyword(s: string): void { + this.writer.writeKeyword(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeOperator(s: string): void { + this.writer.writeOperator(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writePunctuation(s: string): void { + this.writer.writePunctuation(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeParameter(s: string): void { + this.writer.writeParameter(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeProperty(s: string): void { + this.writer.writeProperty(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeSpace(s: string): void { + this.writer.writeSpace(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeStringLiteral(s: string): void { + this.writer.writeStringLiteral(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeSymbol(s: string, sym: Symbol): void { + this.writer.writeSymbol(s, sym); + this.setLastNonTriviaPosition(s, /*force*/ false); + } writeTextOfNode(text: string, node: Node): void { this.writer.writeTextOfNode(text, node); } @@ -848,8 +880,8 @@ namespace ts.textChanges { isAtStartOfLine(): boolean { return this.writer.isAtStartOfLine(); } - reset(): void { - this.writer.reset(); + clear(): void { + this.writer.clear(); this.lastNonTriviaPosition = 0; } } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 9562def31f5..c5694625493 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1127,6 +1127,7 @@ namespace ts { let indent: number; resetWriter(); + const unknownWrite = (text: string) => writeKind(text, SymbolDisplayPartKind.text); return { displayParts: () => displayParts, writeKeyword: text => writeKind(text, SymbolDisplayPartKind.keyword), @@ -1136,8 +1137,18 @@ namespace ts { writeStringLiteral: text => writeKind(text, SymbolDisplayPartKind.stringLiteral), writeParameter: text => writeKind(text, SymbolDisplayPartKind.parameterName), writeProperty: text => writeKind(text, SymbolDisplayPartKind.propertyName), + writeLiteral: text => writeKind(text, SymbolDisplayPartKind.stringLiteral), writeSymbol, writeLine, + write: unknownWrite, + writeTextOfNode: unknownWrite, + getText: () => "", + getTextPos: () => 0, + getColumn: () => 0, + getLine: () => 0, + isAtStartOfLine: () => false, + rawWrite: notImplemented, + getIndent: () => indent, increaseIndent: () => { indent++; }, decreaseIndent: () => { indent--; }, clear: resetWriter, @@ -1249,6 +1260,7 @@ namespace ts { return displayPart("\n", SymbolDisplayPartKind.lineBreak); } + /* @internal */ export function mapToDisplayParts(writeDisplayParts: (writer: DisplayPartsSymbolWriter) => void): SymbolDisplayPart[] { try { writeDisplayParts(displayPartWriter); @@ -1261,20 +1273,20 @@ namespace ts { export function typeToDisplayParts(typechecker: TypeChecker, type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[] { return mapToDisplayParts(writer => { - typechecker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags); + typechecker.writeType(type, enclosingDeclaration, flags | TypeFormatFlags.MultilineObjectLiterals, writer); }); } export function symbolToDisplayParts(typeChecker: TypeChecker, symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): SymbolDisplayPart[] { return mapToDisplayParts(writer => { - typeChecker.getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning, flags); + typeChecker.writeSymbol(symbol, enclosingDeclaration, meaning, flags, writer); }); } export function signatureToDisplayParts(typechecker: TypeChecker, signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[] { - flags |= TypeFormatFlags.UseAliasDefinedOutsideCurrentScope; + flags |= TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | TypeFormatFlags.MultilineObjectLiterals | TypeFormatFlags.WriteTypeArgumentsOfSignature | TypeFormatFlags.OmitParameterModifiers; return mapToDisplayParts(writer => { - typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags); + typechecker.writeSignature(signature, enclosingDeclaration, flags, /*signatureKind*/ undefined, writer); }); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 3eabea4435a..bee3d4d2637 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -639,7 +639,7 @@ declare namespace ts { body?: Block | Expression; } type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction; - type FunctionLike = FunctionLikeDeclaration | FunctionTypeNode | ConstructorTypeNode | IndexSignatureDeclaration | MethodSignature | ConstructSignatureDeclaration | CallSignatureDeclaration; + type FunctionLike = FunctionLikeDeclaration | FunctionTypeNode | ConstructorTypeNode | IndexSignatureDeclaration | MethodSignature | ConstructSignatureDeclaration | CallSignatureDeclaration | JSDocFunctionType; interface FunctionDeclaration extends FunctionLikeDeclarationBase, DeclarationStatement { kind: SyntaxKind.FunctionDeclaration; name?: Identifier; @@ -1729,6 +1729,16 @@ declare namespace ts { signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration; /** Note that the resulting nodes cannot be checked. */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration; + /** Note that the resulting nodes cannot be checked. */ + symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): EntityName; + /** Note that the resulting nodes cannot be checked. */ + symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): Expression; + /** Note that the resulting nodes cannot be checked. */ + symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): NodeArray | undefined; + /** Note that the resulting nodes cannot be checked. */ + symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): ParameterDeclaration; + /** Note that the resulting nodes cannot be checked. */ + typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeParameterDeclaration; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol | undefined; getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[]; @@ -1748,7 +1758,8 @@ declare namespace ts { getTypeFromTypeNode(node: TypeNode): Type; signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; - symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; + symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): string; + typePredicateToString(predicate: TypePredicate, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; /** * @deprecated Use the createX factory functions or XToY typechecker methods and `createPrinter` or the `xToString` methods instead * This will be removed in a future version. @@ -1788,33 +1799,77 @@ declare namespace ts { None = 0, NoTruncation = 1, WriteArrayAsGenericType = 2, + WriteDefaultSymbolWithoutName = 4, + WriteTypeArgumentsOfSignature = 32, + UseFullyQualifiedType = 64, + UseOnlyExternalAliasing = 128, + SuppressAnyReturnType = 256, + WriteTypeParametersInQualifiedName = 512, + MultilineObjectLiterals = 1024, + WriteClassExpressionAsTypeLiteral = 2048, + UseTypeOfFunction = 4096, + OmitParameterModifiers = 8192, + UseAliasDefinedOutsideCurrentScope = 16384, + AllowThisInObjectLiteral = 32768, + AllowQualifedNameInPlaceOfIdentifier = 65536, + AllowAnonymousIdentifier = 131072, + AllowEmptyUnionOrIntersection = 262144, + AllowEmptyTuple = 524288, + AllowUniqueESSymbolType = 1048576, + AllowEmptyIndexInfoType = 2097152, + IgnoreErrors = 3112960, + InObjectTypeLiteral = 4194304, + InTypeAlias = 8388608, + } + enum TypeFormatFlags { + None = 0, + NoTruncation = 1, + WriteArrayAsGenericType = 2, + WriteDefaultSymbolWithoutName = 4, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, SuppressAnyReturnType = 256, - WriteTypeParametersInQualifiedName = 512, - AllowThisInObjectLiteral = 1024, - AllowQualifedNameInPlaceOfIdentifier = 2048, - AllowAnonymousIdentifier = 8192, - AllowEmptyUnionOrIntersection = 16384, - AllowEmptyTuple = 32768, - IgnoreErrors = 60416, - InObjectTypeLiteral = 1048576, + MultilineObjectLiterals = 1024, + WriteClassExpressionAsTypeLiteral = 2048, + UseTypeOfFunction = 4096, + OmitParameterModifiers = 8192, + UseAliasDefinedOutsideCurrentScope = 16384, + AllowUniqueESSymbolType = 1048576, + AddUndefined = 131072, + WriteArrowStyleSignature = 262144, + InArrayType = 524288, + InElementType = 2097152, + InFirstTypeArgument = 4194304, InTypeAlias = 8388608, + /** @deprecated */ WriteOwnNameForAnyLike = 0, + NodeBuilderFlagsMask = 9469287, } + enum SymbolFormatFlags { + None = 0, + WriteTypeParametersOrArguments = 1, + UseOnlyExternalAliasing = 2, + AllowAnyNodeKind = 4, + } + /** + * @deprecated + */ interface SymbolDisplayBuilder { - buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; - buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void; - buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void; - buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; + /** @deprecated */ buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void; + /** @deprecated */ buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void; + /** @deprecated */ buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; } - interface SymbolWriter { + /** + * @deprecated Migrate to other methods of generating symbol names, ex symbolToEntityName + a printer or symbolToString + */ + interface SymbolWriter extends SymbolTracker { writeKeyword(text: string): void; writeOperator(text: string): void; writePunctuation(text: string): void; @@ -1827,34 +1882,6 @@ declare namespace ts { increaseIndent(): void; decreaseIndent(): void; clear(): void; - trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; - reportInaccessibleThisError(): void; - reportPrivateInBaseOfClassExpression(propertyName: string): void; - reportInaccessibleUniqueSymbolError(): void; - } - enum TypeFormatFlags { - None = 0, - WriteArrayAsGenericType = 1, - UseTypeOfFunction = 4, - NoTruncation = 8, - WriteArrowStyleSignature = 16, - WriteOwnNameForAnyLike = 32, - WriteTypeArgumentsOfSignature = 64, - InElementType = 128, - UseFullyQualifiedType = 256, - InFirstTypeArgument = 512, - InTypeAlias = 1024, - SuppressAnyReturnType = 4096, - AddUndefined = 8192, - WriteClassExpressionAsTypeLiteral = 16384, - InArrayType = 32768, - UseAliasDefinedOutsideCurrentScope = 65536, - AllowUniqueESSymbolType = 131072, - } - enum SymbolFormatFlags { - None = 0, - WriteTypeParametersOrArguments = 1, - UseOnlyExternalAliasing = 2, } enum TypePredicateKind { This = 0, @@ -2634,6 +2661,10 @@ declare namespace ts { * collisions. */ printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string; + /** + * Prints a list of nodes using the given format flags + */ + printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): string; /** * Prints a source file as-is, without any emit transformations. */ @@ -2689,6 +2720,13 @@ declare namespace ts { interface PrinterOptions { removeComments?: boolean; newLine?: NewLineKind; + omitTrailingSemicolon?: boolean; + } + interface SymbolTracker { + trackSymbol?(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; + reportInaccessibleThisError?(): void; + reportPrivateInBaseOfClassExpression?(propertyName: string): void; + reportInaccessibleUniqueSymbolError?(): void; } interface TextSpan { start: number; @@ -2701,6 +2739,71 @@ declare namespace ts { interface SyntaxList extends Node { _children: Node[]; } + enum ListFormat { + None = 0, + SingleLine = 0, + MultiLine = 1, + PreserveLines = 2, + LinesMask = 3, + NotDelimited = 0, + BarDelimited = 4, + AmpersandDelimited = 8, + CommaDelimited = 16, + DelimitersMask = 28, + AllowTrailingComma = 32, + Indented = 64, + SpaceBetweenBraces = 128, + SpaceBetweenSiblings = 256, + Braces = 512, + Parenthesis = 1024, + AngleBrackets = 2048, + SquareBrackets = 4096, + BracketsMask = 7680, + OptionalIfUndefined = 8192, + OptionalIfEmpty = 16384, + Optional = 24576, + PreferNewLine = 32768, + NoTrailingNewLine = 65536, + NoInterveningComments = 131072, + NoSpaceIfEmpty = 262144, + SingleElement = 524288, + Modifiers = 131328, + HeritageClauses = 256, + SingleLineTypeLiteralMembers = 448, + MultiLineTypeLiteralMembers = 65, + TupleTypeElements = 336, + UnionTypeConstituents = 260, + IntersectionTypeConstituents = 264, + ObjectBindingPatternElements = 262576, + ArrayBindingPatternElements = 262448, + ObjectLiteralExpressionProperties = 263122, + ArrayLiteralExpressionElements = 4466, + CommaListElements = 272, + CallExpressionArguments = 1296, + NewExpressionArguments = 9488, + TemplateExpressionSpans = 131072, + SingleLineBlockStatements = 384, + MultiLineBlockStatements = 65, + VariableDeclarationList = 272, + SingleLineFunctionBodyStatements = 384, + MultiLineFunctionBodyStatements = 1, + ClassHeritageClauses = 256, + ClassMembers = 65, + InterfaceMembers = 65, + EnumMembers = 81, + CaseBlockClauses = 65, + NamedImportsOrExportsElements = 432, + JsxElementOrFragmentChildren = 131072, + JsxElementAttributes = 131328, + CaseOrDefaultClauseStatements = 81985, + HeritageClauseTypes = 272, + SourceFileStatements = 65537, + Decorators = 24577, + TypeArguments = 26896, + TypeParameters = 26896, + Parameters = 1296, + IndexSignatureParameters = 4432, + } } declare namespace ts { const versionMajorMinor = "2.7"; @@ -3296,7 +3399,7 @@ declare namespace ts { function createLiteral(value: string | number | boolean): PrimaryExpression; function createNumericLiteral(value: string): NumericLiteral; function createIdentifier(text: string): Identifier; - function updateIdentifier(node: Identifier, typeArguments: NodeArray | undefined): Identifier; + function updateIdentifier(node: Identifier): Identifier; /** Create a unique temporary variable. */ function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier; /** Create a unique temporary variable for use in a loop. */ @@ -4661,9 +4764,6 @@ declare namespace ts { declare namespace ts { /** The version of the language service API */ const servicesVersion = "0.7"; - interface DisplayPartsSymbolWriter extends SymbolWriter { - displayParts(): SymbolDisplayPart[]; - } function toEditorSettings(options: EditorOptions | EditorSettings): EditorSettings; function displayPartsToString(displayParts: SymbolDisplayPart[]): string; function getDefaultCompilerOptions(): CompilerOptions; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 630b7a08a28..09db501300b 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -639,7 +639,7 @@ declare namespace ts { body?: Block | Expression; } type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction; - type FunctionLike = FunctionLikeDeclaration | FunctionTypeNode | ConstructorTypeNode | IndexSignatureDeclaration | MethodSignature | ConstructSignatureDeclaration | CallSignatureDeclaration; + type FunctionLike = FunctionLikeDeclaration | FunctionTypeNode | ConstructorTypeNode | IndexSignatureDeclaration | MethodSignature | ConstructSignatureDeclaration | CallSignatureDeclaration | JSDocFunctionType; interface FunctionDeclaration extends FunctionLikeDeclarationBase, DeclarationStatement { kind: SyntaxKind.FunctionDeclaration; name?: Identifier; @@ -1729,6 +1729,16 @@ declare namespace ts { signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration; /** Note that the resulting nodes cannot be checked. */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration; + /** Note that the resulting nodes cannot be checked. */ + symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): EntityName; + /** Note that the resulting nodes cannot be checked. */ + symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): Expression; + /** Note that the resulting nodes cannot be checked. */ + symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): NodeArray | undefined; + /** Note that the resulting nodes cannot be checked. */ + symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): ParameterDeclaration; + /** Note that the resulting nodes cannot be checked. */ + typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeParameterDeclaration; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol | undefined; getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[]; @@ -1748,7 +1758,8 @@ declare namespace ts { getTypeFromTypeNode(node: TypeNode): Type; signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; - symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; + symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): string; + typePredicateToString(predicate: TypePredicate, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; /** * @deprecated Use the createX factory functions or XToY typechecker methods and `createPrinter` or the `xToString` methods instead * This will be removed in a future version. @@ -1788,33 +1799,77 @@ declare namespace ts { None = 0, NoTruncation = 1, WriteArrayAsGenericType = 2, + WriteDefaultSymbolWithoutName = 4, + WriteTypeArgumentsOfSignature = 32, + UseFullyQualifiedType = 64, + UseOnlyExternalAliasing = 128, + SuppressAnyReturnType = 256, + WriteTypeParametersInQualifiedName = 512, + MultilineObjectLiterals = 1024, + WriteClassExpressionAsTypeLiteral = 2048, + UseTypeOfFunction = 4096, + OmitParameterModifiers = 8192, + UseAliasDefinedOutsideCurrentScope = 16384, + AllowThisInObjectLiteral = 32768, + AllowQualifedNameInPlaceOfIdentifier = 65536, + AllowAnonymousIdentifier = 131072, + AllowEmptyUnionOrIntersection = 262144, + AllowEmptyTuple = 524288, + AllowUniqueESSymbolType = 1048576, + AllowEmptyIndexInfoType = 2097152, + IgnoreErrors = 3112960, + InObjectTypeLiteral = 4194304, + InTypeAlias = 8388608, + } + enum TypeFormatFlags { + None = 0, + NoTruncation = 1, + WriteArrayAsGenericType = 2, + WriteDefaultSymbolWithoutName = 4, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, SuppressAnyReturnType = 256, - WriteTypeParametersInQualifiedName = 512, - AllowThisInObjectLiteral = 1024, - AllowQualifedNameInPlaceOfIdentifier = 2048, - AllowAnonymousIdentifier = 8192, - AllowEmptyUnionOrIntersection = 16384, - AllowEmptyTuple = 32768, - IgnoreErrors = 60416, - InObjectTypeLiteral = 1048576, + MultilineObjectLiterals = 1024, + WriteClassExpressionAsTypeLiteral = 2048, + UseTypeOfFunction = 4096, + OmitParameterModifiers = 8192, + UseAliasDefinedOutsideCurrentScope = 16384, + AllowUniqueESSymbolType = 1048576, + AddUndefined = 131072, + WriteArrowStyleSignature = 262144, + InArrayType = 524288, + InElementType = 2097152, + InFirstTypeArgument = 4194304, InTypeAlias = 8388608, + /** @deprecated */ WriteOwnNameForAnyLike = 0, + NodeBuilderFlagsMask = 9469287, } + enum SymbolFormatFlags { + None = 0, + WriteTypeParametersOrArguments = 1, + UseOnlyExternalAliasing = 2, + AllowAnyNodeKind = 4, + } + /** + * @deprecated + */ interface SymbolDisplayBuilder { - buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; - buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void; - buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void; - buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; + /** @deprecated */ buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void; + /** @deprecated */ buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void; + /** @deprecated */ buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; } - interface SymbolWriter { + /** + * @deprecated Migrate to other methods of generating symbol names, ex symbolToEntityName + a printer or symbolToString + */ + interface SymbolWriter extends SymbolTracker { writeKeyword(text: string): void; writeOperator(text: string): void; writePunctuation(text: string): void; @@ -1827,34 +1882,6 @@ declare namespace ts { increaseIndent(): void; decreaseIndent(): void; clear(): void; - trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; - reportInaccessibleThisError(): void; - reportPrivateInBaseOfClassExpression(propertyName: string): void; - reportInaccessibleUniqueSymbolError(): void; - } - enum TypeFormatFlags { - None = 0, - WriteArrayAsGenericType = 1, - UseTypeOfFunction = 4, - NoTruncation = 8, - WriteArrowStyleSignature = 16, - WriteOwnNameForAnyLike = 32, - WriteTypeArgumentsOfSignature = 64, - InElementType = 128, - UseFullyQualifiedType = 256, - InFirstTypeArgument = 512, - InTypeAlias = 1024, - SuppressAnyReturnType = 4096, - AddUndefined = 8192, - WriteClassExpressionAsTypeLiteral = 16384, - InArrayType = 32768, - UseAliasDefinedOutsideCurrentScope = 65536, - AllowUniqueESSymbolType = 131072, - } - enum SymbolFormatFlags { - None = 0, - WriteTypeParametersOrArguments = 1, - UseOnlyExternalAliasing = 2, } enum TypePredicateKind { This = 0, @@ -2634,6 +2661,10 @@ declare namespace ts { * collisions. */ printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string; + /** + * Prints a list of nodes using the given format flags + */ + printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): string; /** * Prints a source file as-is, without any emit transformations. */ @@ -2689,6 +2720,13 @@ declare namespace ts { interface PrinterOptions { removeComments?: boolean; newLine?: NewLineKind; + omitTrailingSemicolon?: boolean; + } + interface SymbolTracker { + trackSymbol?(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; + reportInaccessibleThisError?(): void; + reportPrivateInBaseOfClassExpression?(propertyName: string): void; + reportInaccessibleUniqueSymbolError?(): void; } interface TextSpan { start: number; @@ -2701,6 +2739,71 @@ declare namespace ts { interface SyntaxList extends Node { _children: Node[]; } + enum ListFormat { + None = 0, + SingleLine = 0, + MultiLine = 1, + PreserveLines = 2, + LinesMask = 3, + NotDelimited = 0, + BarDelimited = 4, + AmpersandDelimited = 8, + CommaDelimited = 16, + DelimitersMask = 28, + AllowTrailingComma = 32, + Indented = 64, + SpaceBetweenBraces = 128, + SpaceBetweenSiblings = 256, + Braces = 512, + Parenthesis = 1024, + AngleBrackets = 2048, + SquareBrackets = 4096, + BracketsMask = 7680, + OptionalIfUndefined = 8192, + OptionalIfEmpty = 16384, + Optional = 24576, + PreferNewLine = 32768, + NoTrailingNewLine = 65536, + NoInterveningComments = 131072, + NoSpaceIfEmpty = 262144, + SingleElement = 524288, + Modifiers = 131328, + HeritageClauses = 256, + SingleLineTypeLiteralMembers = 448, + MultiLineTypeLiteralMembers = 65, + TupleTypeElements = 336, + UnionTypeConstituents = 260, + IntersectionTypeConstituents = 264, + ObjectBindingPatternElements = 262576, + ArrayBindingPatternElements = 262448, + ObjectLiteralExpressionProperties = 263122, + ArrayLiteralExpressionElements = 4466, + CommaListElements = 272, + CallExpressionArguments = 1296, + NewExpressionArguments = 9488, + TemplateExpressionSpans = 131072, + SingleLineBlockStatements = 384, + MultiLineBlockStatements = 65, + VariableDeclarationList = 272, + SingleLineFunctionBodyStatements = 384, + MultiLineFunctionBodyStatements = 1, + ClassHeritageClauses = 256, + ClassMembers = 65, + InterfaceMembers = 65, + EnumMembers = 81, + CaseBlockClauses = 65, + NamedImportsOrExportsElements = 432, + JsxElementOrFragmentChildren = 131072, + JsxElementAttributes = 131328, + CaseOrDefaultClauseStatements = 81985, + HeritageClauseTypes = 272, + SourceFileStatements = 65537, + Decorators = 24577, + TypeArguments = 26896, + TypeParameters = 26896, + Parameters = 1296, + IndexSignatureParameters = 4432, + } } declare namespace ts { const versionMajorMinor = "2.7"; @@ -3243,7 +3346,7 @@ declare namespace ts { function createLiteral(value: string | number | boolean): PrimaryExpression; function createNumericLiteral(value: string): NumericLiteral; function createIdentifier(text: string): Identifier; - function updateIdentifier(node: Identifier, typeArguments: NodeArray | undefined): Identifier; + function updateIdentifier(node: Identifier): Identifier; /** Create a unique temporary variable. */ function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier; /** Create a unique temporary variable for use in a loop. */ @@ -4661,9 +4764,6 @@ declare namespace ts { declare namespace ts { /** The version of the language service API */ const servicesVersion = "0.7"; - interface DisplayPartsSymbolWriter extends SymbolWriter { - displayParts(): SymbolDisplayPart[]; - } function toEditorSettings(options: EditorOptions | EditorSettings): EditorSettings; function displayPartsToString(displayParts: SymbolDisplayPart[]): string; function getDefaultCompilerOptions(): CompilerOptions; diff --git a/tests/baselines/reference/commentOnParameter1.js b/tests/baselines/reference/commentOnParameter1.js index 10ae2af1264..3e7ba725017 100644 --- a/tests/baselines/reference/commentOnParameter1.js +++ b/tests/baselines/reference/commentOnParameter1.js @@ -11,10 +11,10 @@ b //// [commentOnParameter1.js] function commentedParameters( - /* Parameter a */ - a - /* End of parameter a */ - /* Parameter b */ - , b - /* End of parameter b */ +/* Parameter a */ +a +/* End of parameter a */ +/* Parameter b */ +, b +/* End of parameter b */ ) { } diff --git a/tests/baselines/reference/commentOnParameter2.js b/tests/baselines/reference/commentOnParameter2.js index d0c024a6b3b..236e660abdf 100644 --- a/tests/baselines/reference/commentOnParameter2.js +++ b/tests/baselines/reference/commentOnParameter2.js @@ -10,9 +10,9 @@ b //// [commentOnParameter2.js] function commentedParameters( - /* Parameter a */ - a /* End of parameter a */ - /* Parameter b */ - , b - /* End of parameter b */ +/* Parameter a */ +a /* End of parameter a */ +/* Parameter b */ +, b +/* End of parameter b */ ) { } diff --git a/tests/baselines/reference/commentsFunction.js b/tests/baselines/reference/commentsFunction.js index ad31aa47b91..5588a27f5ba 100644 --- a/tests/baselines/reference/commentsFunction.js +++ b/tests/baselines/reference/commentsFunction.js @@ -61,8 +61,8 @@ function foo() { foo(); /** This is comment for function signature*/ function fooWithParameters(/** this is comment about a*/ a, - /** this is comment for b*/ - b) { +/** this is comment for b*/ +b) { var d = a; } // trailing comment of function fooWithParameters("a", 10); @@ -78,7 +78,7 @@ var lambddaNoVarComment = function (/**param a*/ a, /**param b*/ b) { return a * lambdaFoo(10, 20); lambddaNoVarComment(10, 20); function blah(a /* multiline trailing comment - multiline */) { +multiline */) { } function blah2(a /* single line multiple trailing comments */ /* second */) { } diff --git a/tests/baselines/reference/declFileConstructors.js b/tests/baselines/reference/declFileConstructors.js index 9f5fc12e002..f40ae2d5382 100644 --- a/tests/baselines/reference/declFileConstructors.js +++ b/tests/baselines/reference/declFileConstructors.js @@ -109,8 +109,8 @@ exports.SimpleConstructor = SimpleConstructor; var ConstructorWithParameters = /** @class */ (function () { /** This is comment for function signature*/ function ConstructorWithParameters(/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; } return ConstructorWithParameters; @@ -172,8 +172,8 @@ var GlobalSimpleConstructor = /** @class */ (function () { var GlobalConstructorWithParameters = /** @class */ (function () { /** This is comment for function signature*/ function GlobalConstructorWithParameters(/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; } return GlobalConstructorWithParameters; diff --git a/tests/baselines/reference/declFileFunctions.js b/tests/baselines/reference/declFileFunctions.js index 68ac66200a6..3e5c8af32ec 100644 --- a/tests/baselines/reference/declFileFunctions.js +++ b/tests/baselines/reference/declFileFunctions.js @@ -85,8 +85,8 @@ function foo() { exports.foo = foo; /** This is comment for function signature*/ function fooWithParameters(/** this is comment about a*/ a, - /** this is comment for b*/ - b) { +/** this is comment for b*/ +b) { var d = a; } exports.fooWithParameters = fooWithParameters; @@ -131,8 +131,8 @@ function nonExportedFoo() { } /** This is comment for function signature*/ function nonExportedFooWithParameters(/** this is comment about a*/ a, - /** this is comment for b*/ - b) { +/** this is comment for b*/ +b) { var d = a; } function nonExportedFooWithRestParameters(a) { @@ -151,8 +151,8 @@ function globalfoo() { } /** This is comment for function signature*/ function globalfooWithParameters(/** this is comment about a*/ a, - /** this is comment for b*/ - b) { +/** this is comment for b*/ +b) { var d = a; } function globalfooWithRestParameters(a) { diff --git a/tests/baselines/reference/declFileMethods.js b/tests/baselines/reference/declFileMethods.js index 78af9adcd98..a70dde6c3ee 100644 --- a/tests/baselines/reference/declFileMethods.js +++ b/tests/baselines/reference/declFileMethods.js @@ -200,8 +200,8 @@ var c1 = /** @class */ (function () { }; /** This is comment for function signature*/ c1.prototype.fooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c1.prototype.fooWithRestParameters = function (a) { @@ -219,8 +219,8 @@ var c1 = /** @class */ (function () { }; /** This is comment for function signature*/ c1.prototype.privateFooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c1.prototype.privateFooWithRestParameters = function (a) { @@ -238,8 +238,8 @@ var c1 = /** @class */ (function () { }; /** This is comment for function signature*/ c1.staticFooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c1.staticFooWithRestParameters = function (a) { @@ -257,8 +257,8 @@ var c1 = /** @class */ (function () { }; /** This is comment for function signature*/ c1.privateStaticFooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c1.privateStaticFooWithRestParameters = function (a) { @@ -283,8 +283,8 @@ var c2 = /** @class */ (function () { }; /** This is comment for function signature*/ c2.prototype.fooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c2.prototype.fooWithRestParameters = function (a) { @@ -302,8 +302,8 @@ var c2 = /** @class */ (function () { }; /** This is comment for function signature*/ c2.prototype.privateFooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c2.prototype.privateFooWithRestParameters = function (a) { @@ -321,8 +321,8 @@ var c2 = /** @class */ (function () { }; /** This is comment for function signature*/ c2.staticFooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c2.staticFooWithRestParameters = function (a) { @@ -340,8 +340,8 @@ var c2 = /** @class */ (function () { }; /** This is comment for function signature*/ c2.privateStaticFooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c2.privateStaticFooWithRestParameters = function (a) { diff --git a/tests/baselines/reference/declarationEmitBindingPatterns.js b/tests/baselines/reference/declarationEmitBindingPatterns.js index 800e30032c6..70ac7f437d3 100644 --- a/tests/baselines/reference/declarationEmitBindingPatterns.js +++ b/tests/baselines/reference/declarationEmitBindingPatterns.js @@ -18,7 +18,7 @@ function f(_a, _b, _c) { //// [declarationEmitBindingPatterns.d.ts] -declare const k: ({x: z}: { +declare const k: ({ x: z }: { x?: string; }) => void; declare var a: any; diff --git a/tests/baselines/reference/declarationEmitDestructuring2.js b/tests/baselines/reference/declarationEmitDestructuring2.js index 09980c5c9dd..c979b654960 100644 --- a/tests/baselines/reference/declarationEmitDestructuring2.js +++ b/tests/baselines/reference/declarationEmitDestructuring2.js @@ -26,18 +26,18 @@ declare function f({x, y: [a, b, c, d]}?: { }): void; declare function g([a, b, c, d]?: [number, number, number, number]): void; declare function h([a, [b], [[c]], {x, y: [a, b, c], z: {a1, b1}}]: [any, [any], [[any]], { - x?: number; - y: [any, any, any]; - z: { - a1: any; - b1: any; - }; -}]): void; + x?: number; + y: [any, any, any]; + z: { + a1: any; + b1: any; + }; + }]): void; declare function h1([a, [b], [[c]], {x, y, z: {a1, b1}}]: [any, [any], [[any]], { - x?: number; - y?: number[]; - z: { - a1: any; - b1: any; - }; -}]): void; + x?: number; + y?: number[]; + z: { + a1: any; + b1: any; + }; + }]): void; diff --git a/tests/baselines/reference/declarationEmitIndexTypeArray.js b/tests/baselines/reference/declarationEmitIndexTypeArray.js index a84080fb5c4..9fe8878a8db 100644 --- a/tests/baselines/reference/declarationEmitIndexTypeArray.js +++ b/tests/baselines/reference/declarationEmitIndexTypeArray.js @@ -21,5 +21,5 @@ var utilityFunctions = { //// [declarationEmitIndexTypeArray.d.ts] declare function doSomethingWithKeys(...keys: (keyof T)[]): void; declare const utilityFunctions: { - doSomethingWithKeys: (...keys: (keyof T)[]) => void; + doSomethingWithKeys: typeof doSomethingWithKeys; }; diff --git a/tests/baselines/reference/declarationEmitTypeofDefaultExport.symbols b/tests/baselines/reference/declarationEmitTypeofDefaultExport.symbols index 195f10a78a1..898a9883781 100644 --- a/tests/baselines/reference/declarationEmitTypeofDefaultExport.symbols +++ b/tests/baselines/reference/declarationEmitTypeofDefaultExport.symbols @@ -7,7 +7,7 @@ import * as a from "./a"; >a : Symbol(a, Decl(b.ts, 0, 6)) export default a.default; ->a.default : Symbol(a.default, Decl(a.ts, 0, 0)) +>a.default : Symbol(a.C, Decl(a.ts, 0, 0)) >a : Symbol(a, Decl(b.ts, 0, 6)) ->default : Symbol(a.default, Decl(a.ts, 0, 0)) +>default : Symbol(a.C, Decl(a.ts, 0, 0)) diff --git a/tests/baselines/reference/deferredLookupTypeResolution.js b/tests/baselines/reference/deferredLookupTypeResolution.js index 5f8edd63e57..e5baa6891e8 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution.js +++ b/tests/baselines/reference/deferredLookupTypeResolution.js @@ -54,9 +54,7 @@ declare type T2 = ObjectHasKey<{ declare function f1(a: A, b: B): { [P in A | B]: any; }; -declare function f2(a: A): { - [P in A | "x"]: any; -}; +declare function f2(a: A): { [P in A | "x"]: any; }; declare function f3(x: 'a' | 'b'): { a: any; b: any; diff --git a/tests/baselines/reference/deferredLookupTypeResolution.types b/tests/baselines/reference/deferredLookupTypeResolution.types index d9486d30b07..cd123a6019e 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution.types +++ b/tests/baselines/reference/deferredLookupTypeResolution.types @@ -17,7 +17,7 @@ type StringContains = ( >L : L type ObjectHasKey = StringContains ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >O : O >L : L >StringContains : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] @@ -25,19 +25,19 @@ type ObjectHasKey = StringContains >L : L type First = ObjectHasKey; // Should be deferred ->First : ({ [K in S]: "true"; } & { [key: string]: "false"; })["0"] +>First : ({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["0"] >T : T ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >T : T type T1 = ObjectHasKey<{ a: string }, 'a'>; // 'true' >T1 : "true" ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >a : string type T2 = ObjectHasKey<{ a: string }, 'b'>; // 'false' >T2 : "false" ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >a : string // Verify that mapped type isn't eagerly resolved in type-to-string operation @@ -55,13 +55,13 @@ declare function f1(a: A, b: B): { [P in A | >B : B function f2(a: A) { ->f2 : (a: A) => { [P in A | B]: any; } +>f2 : (a: A) => { [P in A | "x"]: any; } >A : A >a : A >A : A return f1(a, 'x'); ->f1(a, 'x') : { [P in A | B]: any; } +>f1(a, 'x') : { [P in A | "x"]: any; } >f1 : (a: A, b: B) => { [P in A | B]: any; } >a : A >'x' : "x" @@ -73,7 +73,7 @@ function f3(x: 'a' | 'b') { return f2(x); >f2(x) : { a: any; b: any; x: any; } ->f2 : (a: A) => { [P in A | B]: any; } +>f2 : (a: A) => { [P in A | "x"]: any; } >x : "a" | "b" } diff --git a/tests/baselines/reference/deferredLookupTypeResolution2.errors.txt b/tests/baselines/reference/deferredLookupTypeResolution2.errors.txt index f6bbe72f1a6..6d1d579c0ad 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 S]: "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 S]: "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 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 (2 errors) ==== @@ -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 S]: "true"; } & { [key: string]: "false"; })["1"]' cannot be used to index type '{ true: "true"; }'. +!!! error TS2536: Type '({ [K in keyof T]: "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 S]: "true"; } & { [key: string]: "false"; })["1"]]' cannot be used to index type '{ true: "true"; }'. +!!! 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"; }'. type DeepOK = { true: 'true', otherwise: 'false' }[Juxtapose]; \ No newline at end of file diff --git a/tests/baselines/reference/deferredLookupTypeResolution2.types b/tests/baselines/reference/deferredLookupTypeResolution2.types index 25b3ceff934..76354731097 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution2.types +++ b/tests/baselines/reference/deferredLookupTypeResolution2.types @@ -11,7 +11,7 @@ type StringContains = ({ [K in S]: 'true' } >L : L type ObjectHasKey = StringContains; ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >O : O >L : L >StringContains : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] @@ -19,52 +19,52 @@ type ObjectHasKey = StringContains; >L : L type A = ObjectHasKey; ->A : ({ [K in S]: "true"; } & { [key: string]: "false"; })["0"] +>A : ({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["0"] >T : T ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >T : T type B = ObjectHasKey<[string, number], '1'>; // "true" >B : "true" ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] type C = ObjectHasKey<[string, number], '2'>; // "false" >C : "false" ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] type D = A<[string]>; // "true" >D : "true" ->A : ({ [K in S]: "true"; } & { [key: string]: "false"; })["0"] +>A : ({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["0"] // Error, "false" not handled type E = { true: 'true' }[ObjectHasKey]; ->E : { true: "true"; }[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]] +>E : { true: "true"; }[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]] >T : T >true : "true" ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >T : T type Juxtapose = ({ true: 'otherwise' } & { [k: string]: 'true' })[ObjectHasKey]; ->Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]] +>Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]] >T : T >true : "otherwise" >k : string ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "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 S]: "true"; } & { [key: string]: "false"; })["1"]]] +>DeepError : { true: "true"; }[({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]]] >T : T >true : "true" ->Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]] +>Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "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 S]: "true"; } & { [key: string]: "false"; })["1"]]] +>DeepOK : { true: "true"; otherwise: "false"; }[({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]]] >T : T >true : "true" >otherwise : "false" ->Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]] +>Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]] >T : T diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.js b/tests/baselines/reference/isomorphicMappedTypeInference.js index aa000bc2913..e7df29894f9 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.js +++ b/tests/baselines/reference/isomorphicMappedTypeInference.js @@ -275,9 +275,7 @@ declare function f3(): void; declare function f4(): void; declare function makeRecord(obj: { [P in K]: T; -}): { - [P in K]: T; -}; +}): { [P in K]: T; }; declare function f5(s: string): void; declare function makeDictionary(obj: { [x: string]: T; diff --git a/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.symbols b/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.symbols index 773fb3f5760..558ec029790 100644 --- a/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.symbols +++ b/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.symbols @@ -31,7 +31,7 @@ var r3 = c["a b"]; var r4 = c["~!@#$%^&*()_+{}|:'<>?\/.,`"]; >r4 : Symbol(r4, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 13, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 26, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 39, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 51, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 8, 3)) ->"~!@#$%^&*()_+{}|:'<>?\/.,`" : Symbol(C["~!@#$%^&*()_+{}|:'<>?\/.,`"], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 2, 20)) +>"~!@#$%^&*()_+{}|:'<>?\/.,`" : Symbol(C["~!@#$%^&*()_+{}|:'<>?/.,`"], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 2, 20)) interface I { >I : Symbol(I, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 13, 41)) @@ -63,7 +63,7 @@ var r3 = i["a b"]; var r4 = i["~!@#$%^&*()_+{}|:'<>?\/.,`"]; >r4 : Symbol(r4, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 13, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 26, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 39, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 51, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 21, 3)) ->"~!@#$%^&*()_+{}|:'<>?\/.,`" : Symbol(I["~!@#$%^&*()_+{}|:'<>?\/.,`"], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 17, 20)) +>"~!@#$%^&*()_+{}|:'<>?\/.,`" : Symbol(I["~!@#$%^&*()_+{}|:'<>?/.,`"], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 17, 20)) var a: { diff --git a/tests/baselines/reference/quickInfoDisplayPartsLiteralLikeNames01.baseline b/tests/baselines/reference/quickInfoDisplayPartsLiteralLikeNames01.baseline index 39ab90e8e09..1d2d8216808 100644 --- a/tests/baselines/reference/quickInfoDisplayPartsLiteralLikeNames01.baseline +++ b/tests/baselines/reference/quickInfoDisplayPartsLiteralLikeNames01.baseline @@ -38,7 +38,7 @@ }, { "text": "1", - "kind": "methodName" + "kind": "stringLiteral" }, { "text": "]", @@ -310,7 +310,7 @@ }, { "text": "1", - "kind": "methodName" + "kind": "stringLiteral" }, { "text": "]", @@ -380,7 +380,7 @@ }, { "text": "1", - "kind": "methodName" + "kind": "stringLiteral" }, { "text": "]", diff --git a/tests/baselines/reference/recursiveTypeRelations.types b/tests/baselines/reference/recursiveTypeRelations.types index 110ff8175c4..03008690d8d 100644 --- a/tests/baselines/reference/recursiveTypeRelations.types +++ b/tests/baselines/reference/recursiveTypeRelations.types @@ -17,7 +17,7 @@ class Query> { >A : A multiply>(x: B): Query; ->multiply : (x: B) => Query +>multiply : (x: B) => Query >B : B >Attributes : { [Key in Keys]: string; } >B : B diff --git a/tests/baselines/reference/typeGuardFunctionOfFormThisErrors.js b/tests/baselines/reference/typeGuardFunctionOfFormThisErrors.js index 84db5d4a4a9..5f8a850c589 100644 --- a/tests/baselines/reference/typeGuardFunctionOfFormThisErrors.js +++ b/tests/baselines/reference/typeGuardFunctionOfFormThisErrors.js @@ -152,6 +152,6 @@ declare let b: GuardInterface; declare function invalidGuard(c: any): this is number; declare let c: number | number[]; declare let holder: { - invalidGuard: (c: any) => this is number; + invalidGuard: typeof invalidGuard; }; declare let detached: () => this is FollowerGuard; diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMappedType.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMappedType.ts index b787d0c271e..5fff622f2db 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMappedType.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMappedType.ts @@ -13,6 +13,6 @@ verify.codeFix({ x: { readonly [K in keyof X]: X[K] }; } class C implements I {\r - x: { readonly [K in keyof X]: Y[K]; };\r + x: { readonly [K in keyof Y]: Y[K]; };\r }`, }); From 639b2781d7075492b9e6b5ef92e159f8d6cbc48f Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 16 Jan 2018 11:13:53 -0800 Subject: [PATCH 176/189] Accept corrected baseline (#21201) --- .../reference/indexedAccessRetainsIndexSignature.types | 6 +++--- .../user/TypeScript-Node-Starter/TypeScript-Node-Starter | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/indexedAccessRetainsIndexSignature.types b/tests/baselines/reference/indexedAccessRetainsIndexSignature.types index 3e3f52f7ca6..8dcbe9bf218 100644 --- a/tests/baselines/reference/indexedAccessRetainsIndexSignature.types +++ b/tests/baselines/reference/indexedAccessRetainsIndexSignature.types @@ -14,7 +14,7 @@ type Diff = >T : T type Omit = Pick> ->Omit : Pick +>Omit : Pick >U : U >K : K >U : U @@ -25,7 +25,7 @@ type Omit = Pick> >K : K type Omit1 = Pick>; ->Omit1 : Pick +>Omit1 : Pick >U : U >K : K >U : U @@ -51,7 +51,7 @@ type Omit2 = {[P in Diff]: T[P]}; type O = Omit<{ a: number, b: string }, 'a'> >O : Pick<{ a: number; b: string; }, "b"> ->Omit : Pick +>Omit : Pick >a : number >b : string diff --git a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter index ed149eb0c78..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 ed149eb0c787b1195a95b44105822c64bb6eb636 +Subproject commit 40bdb4eadabc9fbed7d83e3f26817a931c0763b6 From 7c7651d617efe89066a4efeb6cbb13ab766e03c5 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Tue, 16 Jan 2018 21:11:06 +0100 Subject: [PATCH 177/189] Add overloads for forEach{Leading,Trailing}CommentRange (#21190) Avoids runtime errors when passing callback with state parameter but not passing a state. --- src/compiler/scanner.ts | 4 ++++ tests/baselines/reference/api/tsserverlibrary.d.ts | 6 ++++-- tests/baselines/reference/api/typescript.d.ts | 6 ++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index c8bb2ec0a25..5001ea58336 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -725,10 +725,14 @@ namespace ts { return accumulator; } + export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state); } + export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index bee3d4d2637..0a1385e9553 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3254,8 +3254,10 @@ declare namespace ts { function isWhiteSpaceSingleLine(ch: number): boolean; function isLineBreak(ch: number): boolean; function couldStartTrivia(text: string, pos: number): boolean; - function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined; - function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined; + function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; + function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U; function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U; function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 09db501300b..82995f97bfa 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2915,8 +2915,10 @@ declare namespace ts { function isWhiteSpaceSingleLine(ch: number): boolean; function isLineBreak(ch: number): boolean; function couldStartTrivia(text: string, pos: number): boolean; - function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined; - function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined; + function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; + function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U; function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U; function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined; From 1785d87fdae732aaa02652d6f20d4b94d0278a56 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 16 Jan 2018 12:33:55 -0800 Subject: [PATCH 178/189] Fix temp variable emit for names used in nested classes --- src/compiler/emitter.ts | 42 +++++++++++---- src/compiler/factory.ts | 24 +++++---- src/compiler/transformers/ts.ts | 9 ++-- src/compiler/types.ts | 26 +++++----- src/compiler/utilities.ts | 2 +- .../reference/asyncAwaitNestedClasses_es5.js | 52 +++++++++++++++++++ .../asyncAwaitNestedClasses_es5.symbols | 43 +++++++++++++++ .../asyncAwaitNestedClasses_es5.types | 52 +++++++++++++++++++ .../async/es5/asyncAwaitNestedClasses_es5.ts | 18 +++++++ 9 files changed, 232 insertions(+), 36 deletions(-) create mode 100644 tests/baselines/reference/asyncAwaitNestedClasses_es5.js create mode 100644 tests/baselines/reference/asyncAwaitNestedClasses_es5.symbols create mode 100644 tests/baselines/reference/asyncAwaitNestedClasses_es5.types create mode 100644 tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8a1de17826c..705c0811cdc 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -289,6 +289,9 @@ namespace ts { let generatedNames: Map; // Set of names generated by the NameGenerator. let tempFlagsStack: TempFlags[]; // Stack of enclosing name generation scopes. let tempFlags: TempFlags; // TempFlags for the current name generation scope. + let reservedNamesStack: Map[]; // Stack of TempFlags reserved in enclosing name generation scopes. + let reservedNames: Map; // TempFlags to reserve in nested name generation scopes. + let writer: EmitTextWriter; let ownWriter: EmitTextWriter; let write = writeBase; @@ -434,6 +437,7 @@ namespace ts { generatedNames = createMap(); tempFlagsStack = []; tempFlags = TempFlags.Auto; + reservedNamesStack = []; comments.reset(); setWriter(/*output*/ undefined); } @@ -3083,6 +3087,7 @@ namespace ts { } tempFlagsStack.push(tempFlags); tempFlags = 0; + reservedNamesStack.push(reservedNames); } /** @@ -3093,16 +3098,24 @@ namespace ts { return; } tempFlags = tempFlagsStack.pop(); + reservedNames = reservedNamesStack.pop(); + } + + function reserveNameInNestedScopes(name: string) { + if (!reservedNames || reservedNames === lastOrUndefined(reservedNamesStack)) { + reservedNames = createMap(); + } + reservedNames.set(name, true); } /** * Generate the text for a generated identifier. */ function generateName(name: GeneratedIdentifier) { - if (name.autoGenerateKind === GeneratedIdentifierKind.Node) { + if ((name.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) === GeneratedIdentifierFlags.Node) { // Node names generate unique names based on their original node // and are cached based on that node's id. - if (name.skipNameGenerationScope) { + if (name.autoGenerateFlags & GeneratedIdentifierFlags.SkipNameGenerationScope) { const savedTempFlags = tempFlags; popNameGenerationScope(/*node*/ undefined); const result = generateNameCached(getNodeForGeneratedName(name)); @@ -3134,7 +3147,8 @@ namespace ts { function isUniqueName(name: string): boolean { return !(hasGlobalName && hasGlobalName(name)) && !currentSourceFile.identifiers.has(name) - && !generatedNames.has(name); + && !generatedNames.has(name) + && !(reservedNames && reservedNames.has(name)); } /** @@ -3158,11 +3172,14 @@ namespace ts { * TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name. * Note that names generated by makeTempVariableName and makeUniqueName will never conflict. */ - function makeTempVariableName(flags: TempFlags): string { + function makeTempVariableName(flags: TempFlags, reservedInNestedScopes?: boolean): string { if (flags && !(tempFlags & flags)) { const name = flags === TempFlags._i ? "_i" : "_n"; if (isUniqueName(name)) { tempFlags |= flags; + if (reservedInNestedScopes) { + reserveNameInNestedScopes(name); + } return name; } } @@ -3175,6 +3192,9 @@ namespace ts { ? "_" + String.fromCharCode(CharacterCodes.a + count) : "_" + (count - 26); if (isUniqueName(name)) { + if (reservedInNestedScopes) { + reserveNameInNestedScopes(name); + } return name; } } @@ -3275,12 +3295,12 @@ namespace ts { * Generates a unique identifier for a node. */ function makeName(name: GeneratedIdentifier) { - switch (name.autoGenerateKind) { - case GeneratedIdentifierKind.Auto: - return makeTempVariableName(TempFlags.Auto); - case GeneratedIdentifierKind.Loop: - return makeTempVariableName(TempFlags._i); - case GeneratedIdentifierKind.Unique: + switch (name.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) { + case GeneratedIdentifierFlags.Auto: + return makeTempVariableName(TempFlags.Auto, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes)); + case GeneratedIdentifierFlags.Loop: + return makeTempVariableName(TempFlags._i, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes)); + case GeneratedIdentifierFlags.Unique: return makeUniqueName(idText(name)); } @@ -3300,7 +3320,7 @@ namespace ts { // if "node" is a different generated name (having a different // "autoGenerateId"), use it and stop traversing. if (isIdentifier(node) - && node.autoGenerateKind === GeneratedIdentifierKind.Node + && node.autoGenerateFlags === GeneratedIdentifierFlags.Node && node.autoGenerateId !== autoGenerateId) { break; } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 14c8ad91eeb..0a006e1c73a 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -117,7 +117,7 @@ namespace ts { const node = createSynthesizedNode(SyntaxKind.Identifier); node.escapedText = escapeLeadingUnderscores(text); node.originalKeywordKind = text ? stringToToken(text) : SyntaxKind.Unknown; - node.autoGenerateKind = GeneratedIdentifierKind.None; + node.autoGenerateFlags = GeneratedIdentifierFlags.None; node.autoGenerateId = 0; if (typeArguments) { node.typeArguments = createNodeArray(typeArguments as ReadonlyArray); @@ -137,21 +137,26 @@ namespace ts { let nextAutoGenerateId = 0; /** Create a unique temporary variable. */ - export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier { + export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier; + /* @internal */ export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes: boolean): Identifier; // tslint:disable-line unified-signatures + export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes?: boolean): Identifier { const name = createIdentifier(""); - name.autoGenerateKind = GeneratedIdentifierKind.Auto; + name.autoGenerateFlags = GeneratedIdentifierFlags.Auto; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; if (recordTempVariable) { recordTempVariable(name); } + if (reservedInNestedScopes) { + name.autoGenerateFlags |= GeneratedIdentifierFlags.ReservedInNestedScopes; + } return name; } /** Create a unique temporary variable for use in a loop. */ export function createLoopVariable(): Identifier { const name = createIdentifier(""); - name.autoGenerateKind = GeneratedIdentifierKind.Loop; + name.autoGenerateFlags = GeneratedIdentifierFlags.Loop; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; return name; @@ -160,7 +165,7 @@ namespace ts { /** Create a unique name based on the supplied text. */ export function createUniqueName(text: string): Identifier { const name = createIdentifier(text); - name.autoGenerateKind = GeneratedIdentifierKind.Unique; + name.autoGenerateFlags = GeneratedIdentifierFlags.Unique; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; return name; @@ -168,14 +173,15 @@ namespace ts { /** Create a unique name generated for a node. */ export function getGeneratedNameForNode(node: Node): Identifier; - // tslint:disable-next-line unified-signatures - /*@internal*/ export function getGeneratedNameForNode(node: Node, shouldSkipNameGenerationScope?: boolean): Identifier; + /* @internal */ export function getGeneratedNameForNode(node: Node, shouldSkipNameGenerationScope?: boolean): Identifier; // tslint:disable-line unified-signatures export function getGeneratedNameForNode(node: Node, shouldSkipNameGenerationScope?: boolean): Identifier { const name = createIdentifier(""); - name.autoGenerateKind = GeneratedIdentifierKind.Node; + name.autoGenerateFlags = GeneratedIdentifierFlags.Node; name.autoGenerateId = nextAutoGenerateId; name.original = node; - name.skipNameGenerationScope = !!shouldSkipNameGenerationScope; + if (shouldSkipNameGenerationScope) { + name.autoGenerateFlags |= GeneratedIdentifierFlags.SkipNameGenerationScope; + } nextAutoGenerateId++; return name; } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index cdb0d0667ad..f6c5d145a90 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -893,11 +893,14 @@ namespace ts { if (some(staticProperties) || some(pendingExpressions)) { const expressions: Expression[] = []; - const temp = createTempVariable(hoistVariableDeclaration); - if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) { + const isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference; + const temp = createTempVariable(hoistVariableDeclaration, !!isClassWithConstructorReference); + if (isClassWithConstructorReference) { // record an alias as the class name is not in scope for statics. enableSubstitutionForClassAliases(); - classAliases[getOriginalNodeId(node)] = getSynthesizedClone(temp); + const alias = getSynthesizedClone(temp); + alias.autoGenerateFlags &= ~GeneratedIdentifierFlags.ReservedInNestedScopes; + classAliases[getOriginalNodeId(node)] = alias; } // To preserve the behavior of the old emitter, we explicitly indent diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6622348e101..478585adb01 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -676,12 +676,18 @@ namespace ts { export type ModifiersArray = NodeArray; /*@internal*/ - export const enum GeneratedIdentifierKind { - None, // Not automatically generated. - Auto, // Automatically generated identifier. - Loop, // Automatically generated identifier with a preference for '_i'. - Unique, // Unique name based on the 'text' property. - Node, // Unique name based on the node in the 'original' property. + export const enum GeneratedIdentifierFlags { + // Kinds + None = 0, // Not automatically generated. + Auto = 1, // Automatically generated identifier. + Loop = 2, // Automatically generated identifier with a preference for '_i'. + Unique = 3, // Unique name based on the 'text' property. + Node = 4, // Unique name based on the node in the 'original' property. + KindMask = 7, // Mask to extract the kind of identifier from its flags. + + // Flags + SkipNameGenerationScope = 1 << 3, // Should skip a name generation scope when generating the name for this identifier + ReservedInNestedScopes = 1 << 4, // Reserve the generated name in nested scopes } export interface Identifier extends PrimaryExpression, Declaration { @@ -692,12 +698,11 @@ namespace ts { */ escapedText: __String; originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later - /*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier. + /*@internal*/ autoGenerateFlags?: GeneratedIdentifierFlags; // Specifies whether to auto-generate the text for an identifier. /*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name. isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics, quickinfo, and signature help. /*@internal*/ jsdocDotPos?: number; // Identifier occurs in JSDoc-style generic: Id. - /*@internal*/ skipNameGenerationScope?: boolean; // Should skip a name generation scope when generating the name for this identifier } // Transient identifier node (marked by id === -1) @@ -707,10 +712,7 @@ namespace ts { /*@internal*/ export interface GeneratedIdentifier extends Identifier { - autoGenerateKind: GeneratedIdentifierKind.Auto - | GeneratedIdentifierKind.Loop - | GeneratedIdentifierKind.Unique - | GeneratedIdentifierKind.Node; + autoGenerateFlags: GeneratedIdentifierFlags; } export interface QualifiedName extends Node { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 796ed35a861..357e5179865 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5134,7 +5134,7 @@ namespace ts { /* @internal */ export function isGeneratedIdentifier(node: Node): node is GeneratedIdentifier { // Using `>` here catches both `GeneratedIdentifierKind.None` and `undefined`. - return isIdentifier(node) && node.autoGenerateKind > GeneratedIdentifierKind.None; + return isIdentifier(node) && (node.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) > GeneratedIdentifierFlags.None; } // Keywords diff --git a/tests/baselines/reference/asyncAwaitNestedClasses_es5.js b/tests/baselines/reference/asyncAwaitNestedClasses_es5.js new file mode 100644 index 00000000000..ff806b76ff1 --- /dev/null +++ b/tests/baselines/reference/asyncAwaitNestedClasses_es5.js @@ -0,0 +1,52 @@ +//// [asyncAwaitNestedClasses_es5.ts] +// https://github.com/Microsoft/TypeScript/issues/20744 +class A { + static B = class B { + static func2(): Promise { + return new Promise((resolve) => { resolve(null); }); + } + static C = class C { + static async func() { + await B.func2(); + } + } + } +} + +A.B.C.func(); + +//// [asyncAwaitNestedClasses_es5.js] +// https://github.com/Microsoft/TypeScript/issues/20744 +var A = /** @class */ (function () { + function A() { + } + A.B = (_a = /** @class */ (function () { + function B() { + } + B.func2 = function () { + return new Promise(function (resolve) { resolve(null); }); + }; + return B; + }()), + _a.C = /** @class */ (function () { + function C() { + } + C.func = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_b) { + switch (_b.label) { + case 0: return [4 /*yield*/, _a.func2()]; + case 1: + _b.sent(); + return [2 /*return*/]; + } + }); + }); + }; + return C; + }()), + _a); + return A; + var _a; +}()); +A.B.C.func(); diff --git a/tests/baselines/reference/asyncAwaitNestedClasses_es5.symbols b/tests/baselines/reference/asyncAwaitNestedClasses_es5.symbols new file mode 100644 index 00000000000..339b2617fbf --- /dev/null +++ b/tests/baselines/reference/asyncAwaitNestedClasses_es5.symbols @@ -0,0 +1,43 @@ +=== tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts === +// https://github.com/Microsoft/TypeScript/issues/20744 +class A { +>A : Symbol(A, Decl(asyncAwaitNestedClasses_es5.ts, 0, 0)) + + static B = class B { +>B : Symbol(A.B, Decl(asyncAwaitNestedClasses_es5.ts, 1, 9)) +>B : Symbol(B, Decl(asyncAwaitNestedClasses_es5.ts, 2, 14)) + + static func2(): Promise { +>func2 : Symbol(B.func2, Decl(asyncAwaitNestedClasses_es5.ts, 2, 24)) +>Promise : Symbol(Promise, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + return new Promise((resolve) => { resolve(null); }); +>Promise : Symbol(Promise, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>resolve : Symbol(resolve, Decl(asyncAwaitNestedClasses_es5.ts, 4, 32)) +>resolve : Symbol(resolve, Decl(asyncAwaitNestedClasses_es5.ts, 4, 32)) + } + static C = class C { +>C : Symbol(B.C, Decl(asyncAwaitNestedClasses_es5.ts, 5, 9)) +>C : Symbol(C, Decl(asyncAwaitNestedClasses_es5.ts, 6, 18)) + + static async func() { +>func : Symbol(C.func, Decl(asyncAwaitNestedClasses_es5.ts, 6, 28)) + + await B.func2(); +>B.func2 : Symbol(B.func2, Decl(asyncAwaitNestedClasses_es5.ts, 2, 24)) +>B : Symbol(B, Decl(asyncAwaitNestedClasses_es5.ts, 2, 14)) +>func2 : Symbol(B.func2, Decl(asyncAwaitNestedClasses_es5.ts, 2, 24)) + } + } + } +} + +A.B.C.func(); +>A.B.C.func : Symbol(C.func, Decl(asyncAwaitNestedClasses_es5.ts, 6, 28)) +>A.B.C : Symbol(B.C, Decl(asyncAwaitNestedClasses_es5.ts, 5, 9)) +>A.B : Symbol(A.B, Decl(asyncAwaitNestedClasses_es5.ts, 1, 9)) +>A : Symbol(A, Decl(asyncAwaitNestedClasses_es5.ts, 0, 0)) +>B : Symbol(A.B, Decl(asyncAwaitNestedClasses_es5.ts, 1, 9)) +>C : Symbol(B.C, Decl(asyncAwaitNestedClasses_es5.ts, 5, 9)) +>func : Symbol(C.func, Decl(asyncAwaitNestedClasses_es5.ts, 6, 28)) + diff --git a/tests/baselines/reference/asyncAwaitNestedClasses_es5.types b/tests/baselines/reference/asyncAwaitNestedClasses_es5.types new file mode 100644 index 00000000000..fd61951d5cc --- /dev/null +++ b/tests/baselines/reference/asyncAwaitNestedClasses_es5.types @@ -0,0 +1,52 @@ +=== tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts === +// https://github.com/Microsoft/TypeScript/issues/20744 +class A { +>A : A + + static B = class B { +>B : typeof B +>class B { static func2(): Promise { return new Promise((resolve) => { resolve(null); }); } static C = class C { static async func() { await B.func2(); } } } : typeof B +>B : typeof B + + static func2(): Promise { +>func2 : () => Promise +>Promise : Promise + + return new Promise((resolve) => { resolve(null); }); +>new Promise((resolve) => { resolve(null); }) : Promise +>Promise : PromiseConstructor +>(resolve) => { resolve(null); } : (resolve: (value?: void | PromiseLike) => void) => void +>resolve : (value?: void | PromiseLike) => void +>resolve(null) : void +>resolve : (value?: void | PromiseLike) => void +>null : null + } + static C = class C { +>C : typeof C +>class C { static async func() { await B.func2(); } } : typeof C +>C : typeof C + + static async func() { +>func : () => Promise + + await B.func2(); +>await B.func2() : void +>B.func2() : Promise +>B.func2 : () => Promise +>B : typeof B +>func2 : () => Promise + } + } + } +} + +A.B.C.func(); +>A.B.C.func() : Promise +>A.B.C.func : () => Promise +>A.B.C : typeof C +>A.B : typeof B +>A : typeof A +>B : typeof B +>C : typeof C +>func : () => Promise + diff --git a/tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts b/tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts new file mode 100644 index 00000000000..222718122ef --- /dev/null +++ b/tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts @@ -0,0 +1,18 @@ +// @target: ES5 +// @lib: es5,es2015.promise +// @noEmitHelpers: true +// https://github.com/Microsoft/TypeScript/issues/20744 +class A { + static B = class B { + static func2(): Promise { + return new Promise((resolve) => { resolve(null); }); + } + static C = class C { + static async func() { + await B.func2(); + } + } + } +} + +A.B.C.func(); \ No newline at end of file From 154c6141f1a8f41b94d44611248662dc070c7c18 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 16 Jan 2018 12:37:15 -0800 Subject: [PATCH 179/189] Allow functions to be printed structurally in declaration emit even when they have symbols (#21203) * Allow functions to be printed structurally in declaration emit even when they have symbols * Implement CR feedback and fix lint --- src/compiler/checker.ts | 8 +++++- src/compiler/declarationEmitter.ts | 6 ++--- src/compiler/types.ts | 4 ++- .../reference/api/tsserverlibrary.d.ts | 4 ++- tests/baselines/reference/api/typescript.d.ts | 4 ++- ...nFunctionTypeNonlocalShouldNotBeAnError.js | 26 +++++++++++++++++++ ...tionTypeNonlocalShouldNotBeAnError.symbols | 15 +++++++++++ ...nctionTypeNonlocalShouldNotBeAnError.types | 16 ++++++++++++ .../privacyCheckTypeOfFunction.errors.txt | 5 +--- ...nFunctionTypeNonlocalShouldNotBeAnError.ts | 8 ++++++ 10 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.js create mode 100644 tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.symbols create mode 100644 tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.types create mode 100644 tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7ab50f7be60..c0eda617e0c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2531,6 +2531,11 @@ namespace ts { return access.accessibility === SymbolAccessibility.Accessible; } + function isValueSymbolAccessible(typeSymbol: Symbol, enclosingDeclaration: Node): boolean { + const access = isSymbolAccessible(typeSymbol, enclosingDeclaration, SymbolFlags.Value, /*shouldComputeAliasesToMakeVisible*/ false); + return access.accessibility === SymbolAccessibility.Accessible; + } + /** * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested * @@ -2993,7 +2998,8 @@ namespace ts { declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { // typeof is allowed only for static/non local functions - return !!(context.flags & NodeBuilderFlags.UseTypeOfFunction) || contains(context.symbolStack, symbol); // it is type of the symbol uses itself recursively + return (!!(context.flags & NodeBuilderFlags.UseTypeOfFunction) || contains(context.symbolStack, symbol)) && // it is type of the symbol uses itself recursively + (!(context.flags & NodeBuilderFlags.UseStructuralFallback) || isValueSymbolAccessible(symbol, context.enclosingDeclaration)); // And the build is going to succeed without visibility error or there is no structural fallback allowed } } } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index f37ae497f84..aa1ec82a631 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -358,7 +358,7 @@ namespace ts { } else { errorNameNode = declaration.name; - const format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.WriteDefaultSymbolWithoutName | + const format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteDefaultSymbolWithoutName | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | (shouldUseResolverType ? TypeFormatFlags.AddUndefined : 0); resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, format, writer); @@ -378,7 +378,7 @@ namespace ts { resolver.writeReturnTypeOfSignatureDeclaration( signature, enclosingDeclaration, - TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, + TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, writer); errorNameNode = undefined; } @@ -643,7 +643,7 @@ namespace ts { resolver.writeTypeOfExpression( expr, enclosingDeclaration, - TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, + TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, writer); write(";"); writeLine(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6622348e101..ba5c913c4b0 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2934,6 +2934,7 @@ namespace ts { NoTruncation = 1 << 0, // Don't truncate result WriteArrayAsGenericType = 1 << 1, // Write Array instead T[] WriteDefaultSymbolWithoutName = 1 << 2, // Write `default`-named symbols as `default` instead of how they were written + UseStructuralFallback = 1 << 3, // When an alias cannot be named by its symbol, rather than report an error, fallback to a structural printout if possible // empty space WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature UseFullyQualifiedType = 1 << 6, // Write out the fully qualified type name (eg. Module.Type, instead of Type) @@ -2968,6 +2969,7 @@ namespace ts { NoTruncation = 1 << 0, // Don't truncate typeToString result WriteArrayAsGenericType = 1 << 1, // Write Array instead T[] WriteDefaultSymbolWithoutName = 1 << 2, // Write all `defaut`-named symbols as `default` instead of their written name + UseStructuralFallback = 1 << 3, // When an alias cannot be named by its symbol, rather than report an error, fallback to a structural printout if possible // hole because there's a hole in node builder flags WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature UseFullyQualifiedType = 1 << 6, // Write out the fully qualified type name (eg. Module.Type, instead of Type) @@ -2997,7 +2999,7 @@ namespace ts { /** @deprecated */ WriteOwnNameForAnyLike = 0, // Does nothing NodeBuilderFlagsMask = - NoTruncation | WriteArrayAsGenericType | WriteDefaultSymbolWithoutName | WriteTypeArgumentsOfSignature | + NoTruncation | WriteArrayAsGenericType | WriteDefaultSymbolWithoutName | UseStructuralFallback | WriteTypeArgumentsOfSignature | UseFullyQualifiedType | SuppressAnyReturnType | MultilineObjectLiterals | WriteClassExpressionAsTypeLiteral | UseTypeOfFunction | OmitParameterModifiers | UseAliasDefinedOutsideCurrentScope | AllowUniqueESSymbolType | InTypeAlias, } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 0a1385e9553..cc8459f8556 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1800,6 +1800,7 @@ declare namespace ts { NoTruncation = 1, WriteArrayAsGenericType = 2, WriteDefaultSymbolWithoutName = 4, + UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, UseOnlyExternalAliasing = 128, @@ -1826,6 +1827,7 @@ declare namespace ts { NoTruncation = 1, WriteArrayAsGenericType = 2, WriteDefaultSymbolWithoutName = 4, + UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, SuppressAnyReturnType = 256, @@ -1842,7 +1844,7 @@ declare namespace ts { InFirstTypeArgument = 4194304, InTypeAlias = 8388608, /** @deprecated */ WriteOwnNameForAnyLike = 0, - NodeBuilderFlagsMask = 9469287, + NodeBuilderFlagsMask = 9469295, } enum SymbolFormatFlags { None = 0, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 82995f97bfa..a9769934d20 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1800,6 +1800,7 @@ declare namespace ts { NoTruncation = 1, WriteArrayAsGenericType = 2, WriteDefaultSymbolWithoutName = 4, + UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, UseOnlyExternalAliasing = 128, @@ -1826,6 +1827,7 @@ declare namespace ts { NoTruncation = 1, WriteArrayAsGenericType = 2, WriteDefaultSymbolWithoutName = 4, + UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, SuppressAnyReturnType = 256, @@ -1842,7 +1844,7 @@ declare namespace ts { InFirstTypeArgument = 4194304, InTypeAlias = 8388608, /** @deprecated */ WriteOwnNameForAnyLike = 0, - NodeBuilderFlagsMask = 9469287, + NodeBuilderFlagsMask = 9469295, } enum SymbolFormatFlags { None = 0, diff --git a/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.js b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.js new file mode 100644 index 00000000000..6faa0bfca60 --- /dev/null +++ b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.js @@ -0,0 +1,26 @@ +//// [declarationFunctionTypeNonlocalShouldNotBeAnError.ts] +namespace foo { + function bar(): void {} + + export const obj = { + bar + } +} + + +//// [declarationFunctionTypeNonlocalShouldNotBeAnError.js] +var foo; +(function (foo) { + function bar() { } + foo.obj = { + bar: bar + }; +})(foo || (foo = {})); + + +//// [declarationFunctionTypeNonlocalShouldNotBeAnError.d.ts] +declare namespace foo { + const obj: { + bar: () => void; + }; +} diff --git a/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.symbols b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.symbols new file mode 100644 index 00000000000..74ce59284e0 --- /dev/null +++ b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.symbols @@ -0,0 +1,15 @@ +=== tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts === +namespace foo { +>foo : Symbol(foo, Decl(declarationFunctionTypeNonlocalShouldNotBeAnError.ts, 0, 0)) + + function bar(): void {} +>bar : Symbol(bar, Decl(declarationFunctionTypeNonlocalShouldNotBeAnError.ts, 0, 15)) + + export const obj = { +>obj : Symbol(obj, Decl(declarationFunctionTypeNonlocalShouldNotBeAnError.ts, 3, 16)) + + bar +>bar : Symbol(bar, Decl(declarationFunctionTypeNonlocalShouldNotBeAnError.ts, 3, 24)) + } +} + diff --git a/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.types b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.types new file mode 100644 index 00000000000..e86ead184c9 --- /dev/null +++ b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts === +namespace foo { +>foo : typeof foo + + function bar(): void {} +>bar : () => void + + export const obj = { +>obj : { bar: () => void; } +>{ bar } : { bar: () => void; } + + bar +>bar : () => void + } +} + diff --git a/tests/baselines/reference/privacyCheckTypeOfFunction.errors.txt b/tests/baselines/reference/privacyCheckTypeOfFunction.errors.txt index 88801e06dfd..f901d08b462 100644 --- a/tests/baselines/reference/privacyCheckTypeOfFunction.errors.txt +++ b/tests/baselines/reference/privacyCheckTypeOfFunction.errors.txt @@ -1,14 +1,11 @@ tests/cases/compiler/privacyCheckTypeOfFunction.ts(3,22): error TS4025: Exported variable 'x' has or is using private name 'foo'. -tests/cases/compiler/privacyCheckTypeOfFunction.ts(4,12): error TS4025: Exported variable 'b' has or is using private name 'foo'. -==== tests/cases/compiler/privacyCheckTypeOfFunction.ts (2 errors) ==== +==== tests/cases/compiler/privacyCheckTypeOfFunction.ts (1 errors) ==== function foo() { } export var x: typeof foo; ~~~ !!! error TS4025: Exported variable 'x' has or is using private name 'foo'. export var b = foo; - ~ -!!! error TS4025: Exported variable 'b' has or is using private name 'foo'. \ No newline at end of file diff --git a/tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts b/tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts new file mode 100644 index 00000000000..8d70a435e4d --- /dev/null +++ b/tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts @@ -0,0 +1,8 @@ +// @declaration: true +namespace foo { + function bar(): void {} + + export const obj = { + bar + } +} From 16b13fe4490c54b71e8af205c5e0c0c4191ff005 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 16 Jan 2018 15:17:04 -0800 Subject: [PATCH 180/189] Fix incorrect parenthesization logic for conditional expression branches --- src/compiler/factory.ts | 4 ++- ...rmParenthesizesConditionalSubexpression.js | 10 +++++++ ...enthesizesConditionalSubexpression.symbols | 14 +++++++++ ...arenthesizesConditionalSubexpression.types | 30 +++++++++++++++++++ ...rmParenthesizesConditionalSubexpression.ts | 4 +++ 5 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/transformParenthesizesConditionalSubexpression.js create mode 100644 tests/baselines/reference/transformParenthesizesConditionalSubexpression.symbols create mode 100644 tests/baselines/reference/transformParenthesizesConditionalSubexpression.types create mode 100644 tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 14c8ad91eeb..0b52480e165 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -3954,7 +3954,9 @@ namespace ts { // per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions // so in case when comma expression is introduced as a part of previous transformations // if should be wrapped in parens since comma operator has the lowest precedence - return e.kind === SyntaxKind.BinaryExpression && (e).operatorToken.kind === SyntaxKind.CommaToken + const emittedExpression = skipPartiallyEmittedExpressions(e); + return emittedExpression.kind === SyntaxKind.BinaryExpression && (emittedExpression).operatorToken.kind === SyntaxKind.CommaToken || + emittedExpression.kind === SyntaxKind.CommaListExpression ? createParen(e) : e; } diff --git a/tests/baselines/reference/transformParenthesizesConditionalSubexpression.js b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.js new file mode 100644 index 00000000000..4f102f14ed4 --- /dev/null +++ b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.js @@ -0,0 +1,10 @@ +//// [transformParenthesizesConditionalSubexpression.ts] +var K = 'k' +var a = { p : (true ? { [K] : 'v'} : null) } +var b = { p : (true ? { [K] : 'v'} as any : null) } + +//// [transformParenthesizesConditionalSubexpression.js] +var K = 'k'; +var a = { p: (true ? (_a = {}, _a[K] = 'v', _a) : null) }; +var b = { p: (true ? (_b = {}, _b[K] = 'v', _b) : null) }; +var _a, _b; diff --git a/tests/baselines/reference/transformParenthesizesConditionalSubexpression.symbols b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.symbols new file mode 100644 index 00000000000..d3ae64c40d5 --- /dev/null +++ b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts === +var K = 'k' +>K : Symbol(K, Decl(transformParenthesizesConditionalSubexpression.ts, 0, 3)) + +var a = { p : (true ? { [K] : 'v'} : null) } +>a : Symbol(a, Decl(transformParenthesizesConditionalSubexpression.ts, 1, 3)) +>p : Symbol(p, Decl(transformParenthesizesConditionalSubexpression.ts, 1, 9)) +>K : Symbol(K, Decl(transformParenthesizesConditionalSubexpression.ts, 0, 3)) + +var b = { p : (true ? { [K] : 'v'} as any : null) } +>b : Symbol(b, Decl(transformParenthesizesConditionalSubexpression.ts, 2, 3)) +>p : Symbol(p, Decl(transformParenthesizesConditionalSubexpression.ts, 2, 9)) +>K : Symbol(K, Decl(transformParenthesizesConditionalSubexpression.ts, 0, 3)) + diff --git a/tests/baselines/reference/transformParenthesizesConditionalSubexpression.types b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.types new file mode 100644 index 00000000000..0ba4268d80a --- /dev/null +++ b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.types @@ -0,0 +1,30 @@ +=== tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts === +var K = 'k' +>K : string +>'k' : "k" + +var a = { p : (true ? { [K] : 'v'} : null) } +>a : { p: { [x: string]: string; }; } +>{ p : (true ? { [K] : 'v'} : null) } : { p: { [x: string]: string; }; } +>p : { [x: string]: string; } +>(true ? { [K] : 'v'} : null) : { [x: string]: string; } +>true ? { [K] : 'v'} : null : { [x: string]: string; } +>true : true +>{ [K] : 'v'} : { [x: string]: string; } +>K : string +>'v' : "v" +>null : null + +var b = { p : (true ? { [K] : 'v'} as any : null) } +>b : { p: any; } +>{ p : (true ? { [K] : 'v'} as any : null) } : { p: any; } +>p : any +>(true ? { [K] : 'v'} as any : null) : any +>true ? { [K] : 'v'} as any : null : any +>true : true +>{ [K] : 'v'} as any : any +>{ [K] : 'v'} : { [x: string]: string; } +>K : string +>'v' : "v" +>null : null + diff --git a/tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts b/tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts new file mode 100644 index 00000000000..d844a910279 --- /dev/null +++ b/tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts @@ -0,0 +1,4 @@ +// @target: es5 +var K = 'k' +var a = { p : (true ? { [K] : 'v'} : null) } +var b = { p : (true ? { [K] : 'v'} as any : null) } \ No newline at end of file From 6c9827725c30f7c4bb2567192db5a69ca35b5490 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 16 Jan 2018 15:45:10 -0800 Subject: [PATCH 181/189] Fix symbol-named properties incorrectly requiring alignment with string indexer type --- src/compiler/checker.ts | 3 +- tests/baselines/reference/symbolProperty60.js | 25 ++++++++++ .../reference/symbolProperty60.symbols | 48 +++++++++++++++++++ .../reference/symbolProperty60.types | 48 +++++++++++++++++++ .../es6/Symbols/symbolProperty60.ts | 23 +++++++++ 5 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/symbolProperty60.js create mode 100644 tests/baselines/reference/symbolProperty60.symbols create mode 100644 tests/baselines/reference/symbolProperty60.types create mode 100644 tests/cases/conformance/es6/Symbols/symbolProperty60.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 18ba4f2f047..489fff16e2c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22298,7 +22298,8 @@ namespace ts { indexType: Type, indexKind: IndexKind): void { - if (!indexType) { + // ESSymbol properties apply to neither string nor numeric indexers. + if (!indexType || isKnownSymbol(prop)) { return; } diff --git a/tests/baselines/reference/symbolProperty60.js b/tests/baselines/reference/symbolProperty60.js new file mode 100644 index 00000000000..d2a1ac92dd8 --- /dev/null +++ b/tests/baselines/reference/symbolProperty60.js @@ -0,0 +1,25 @@ +//// [symbolProperty60.ts] +// https://github.com/Microsoft/TypeScript/issues/20146 +interface I1 { + [Symbol.toStringTag]: string; + [key: string]: number; +} + +interface I2 { + [Symbol.toStringTag]: string; + [key: number]: boolean; +} + +declare const mySymbol: unique symbol; + +interface I3 { + [mySymbol]: string; + [key: string]: number; +} + +interface I4 { + [mySymbol]: string; + [key: number]: boolean; +} + +//// [symbolProperty60.js] diff --git a/tests/baselines/reference/symbolProperty60.symbols b/tests/baselines/reference/symbolProperty60.symbols new file mode 100644 index 00000000000..fca43277e97 --- /dev/null +++ b/tests/baselines/reference/symbolProperty60.symbols @@ -0,0 +1,48 @@ +=== tests/cases/conformance/es6/Symbols/symbolProperty60.ts === +// https://github.com/Microsoft/TypeScript/issues/20146 +interface I1 { +>I1 : Symbol(I1, Decl(symbolProperty60.ts, 0, 0)) + + [Symbol.toStringTag]: string; +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, 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, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [key: string]: number; +>key : Symbol(key, Decl(symbolProperty60.ts, 3, 5)) +} + +interface I2 { +>I2 : Symbol(I2, Decl(symbolProperty60.ts, 4, 1)) + + [Symbol.toStringTag]: string; +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, 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, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [key: number]: boolean; +>key : Symbol(key, Decl(symbolProperty60.ts, 8, 5)) +} + +declare const mySymbol: unique symbol; +>mySymbol : Symbol(mySymbol, Decl(symbolProperty60.ts, 11, 13)) + +interface I3 { +>I3 : Symbol(I3, Decl(symbolProperty60.ts, 11, 38)) + + [mySymbol]: string; +>mySymbol : Symbol(mySymbol, Decl(symbolProperty60.ts, 11, 13)) + + [key: string]: number; +>key : Symbol(key, Decl(symbolProperty60.ts, 15, 5)) +} + +interface I4 { +>I4 : Symbol(I4, Decl(symbolProperty60.ts, 16, 1)) + + [mySymbol]: string; +>mySymbol : Symbol(mySymbol, Decl(symbolProperty60.ts, 11, 13)) + + [key: number]: boolean; +>key : Symbol(key, Decl(symbolProperty60.ts, 20, 5)) +} diff --git a/tests/baselines/reference/symbolProperty60.types b/tests/baselines/reference/symbolProperty60.types new file mode 100644 index 00000000000..c81c003bd35 --- /dev/null +++ b/tests/baselines/reference/symbolProperty60.types @@ -0,0 +1,48 @@ +=== tests/cases/conformance/es6/Symbols/symbolProperty60.ts === +// https://github.com/Microsoft/TypeScript/issues/20146 +interface I1 { +>I1 : I1 + + [Symbol.toStringTag]: string; +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + [key: string]: number; +>key : string +} + +interface I2 { +>I2 : I2 + + [Symbol.toStringTag]: string; +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + [key: number]: boolean; +>key : number +} + +declare const mySymbol: unique symbol; +>mySymbol : unique symbol + +interface I3 { +>I3 : I3 + + [mySymbol]: string; +>mySymbol : unique symbol + + [key: string]: number; +>key : string +} + +interface I4 { +>I4 : I4 + + [mySymbol]: string; +>mySymbol : unique symbol + + [key: number]: boolean; +>key : number +} diff --git a/tests/cases/conformance/es6/Symbols/symbolProperty60.ts b/tests/cases/conformance/es6/Symbols/symbolProperty60.ts new file mode 100644 index 00000000000..4086223f69c --- /dev/null +++ b/tests/cases/conformance/es6/Symbols/symbolProperty60.ts @@ -0,0 +1,23 @@ +// @target: es2015 +// https://github.com/Microsoft/TypeScript/issues/20146 +interface I1 { + [Symbol.toStringTag]: string; + [key: string]: number; +} + +interface I2 { + [Symbol.toStringTag]: string; + [key: number]: boolean; +} + +declare const mySymbol: unique symbol; + +interface I3 { + [mySymbol]: string; + [key: string]: number; +} + +interface I4 { + [mySymbol]: string; + [key: number]: boolean; +} \ No newline at end of file From 4aca0c81218a9623e7629dbc37ef764bf7494dd0 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 16 Jan 2018 16:58:56 -0800 Subject: [PATCH 182/189] Fix destructuring assignment when assignment target is RHS --- src/compiler/transformers/destructuring.ts | 40 ++++++++++++++++++- src/compiler/types.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- .../destructuringReassignsRightHandSide.js | 18 +++++++++ ...estructuringReassignsRightHandSide.symbols | 21 ++++++++++ .../destructuringReassignsRightHandSide.types | 27 +++++++++++++ tests/baselines/reference/objectRest.js | 6 +-- .../destructuringReassignsRightHandSide.ts | 9 +++++ 8 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/destructuringReassignsRightHandSide.js create mode 100644 tests/baselines/reference/destructuringReassignsRightHandSide.symbols create mode 100644 tests/baselines/reference/destructuringReassignsRightHandSide.types create mode 100644 tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index a283275d066..bafe43b0b15 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -70,7 +70,13 @@ namespace ts { if (value) { value = visitNode(value, visitor, isExpression); - if (needsValue) { + + if (isIdentifier(value) && bindingOrAssignmentElementAssignsToName(node, value.escapedText)) { + // If the right-hand value of the assignment is also an assignment target then + // we need to cache the right-hand value. + value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ false, location); + } + else if (needsValue) { // If the right-hand value of the destructuring assignment needs to be preserved (as // is the case when the destructuring assignment is part of a larger expression), // then we need to cache the right-hand value. @@ -123,6 +129,27 @@ namespace ts { } } + function bindingOrAssignmentElementAssignsToName(element: BindingOrAssignmentElement, escapedName: __String): boolean { + const target = getTargetOfBindingOrAssignmentElement(element); + if (isBindingOrAssignmentPattern(target)) { + return bindingOrAssignmentPatternAssignsToName(target, escapedName); + } + else if (isIdentifier(target)) { + return target.escapedText === escapedName; + } + return false; + } + + function bindingOrAssignmentPatternAssignsToName(pattern: BindingOrAssignmentPattern, escapedName: __String): boolean { + const elements = getElementsOfBindingOrAssignmentPattern(pattern); + for (const element of elements) { + if (bindingOrAssignmentElementAssignsToName(element, escapedName)) { + return true; + } + } + return false; + } + /** * Flattens a VariableDeclaration or ParameterDeclaration to one or more variable declarations. * @@ -157,6 +184,17 @@ namespace ts { createArrayBindingOrAssignmentElement: makeBindingElement, visitor }; + + if (isVariableDeclaration(node)) { + let initializer = getInitializerOfBindingOrAssignmentElement(node); + if (initializer && isIdentifier(initializer) && bindingOrAssignmentElementAssignsToName(node, initializer.escapedText)) { + // If the right-hand value of the assignment is also an assignment target then + // we need to cache the right-hand value. + initializer = ensureIdentifier(flattenContext, initializer, /*reuseIdentifierExpressions*/ false, initializer); + node = updateVariableDeclaration(node, node.name, node.type, initializer); + } + } + flattenBindingOrAssignmentElement(flattenContext, node, rval, node, skipInitializer); if (pendingExpressions) { const temp = createTempVariable(/*recordTempVariable*/ undefined); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 7bac69d4a77..9d970b88197 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1467,7 +1467,7 @@ namespace ts { | SpreadAssignment // AssignmentRestProperty ; - export type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Expression; + export type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Identifier | PropertyAccessExpression | ElementAccessExpression | OmittedExpression; export type ObjectBindingOrAssignmentPattern = ObjectBindingPattern diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 45ad8135e2b..ce90fef044e 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -877,7 +877,7 @@ declare namespace ts { type DestructuringAssignment = ObjectDestructuringAssignment | ArrayDestructuringAssignment; type BindingOrAssignmentElement = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment | OmittedExpression | SpreadElement | ArrayLiteralExpression | ObjectLiteralExpression | AssignmentExpression | Identifier | PropertyAccessExpression | ElementAccessExpression; type BindingOrAssignmentElementRestIndicator = DotDotDotToken | SpreadElement | SpreadAssignment; - type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Expression; + type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Identifier | PropertyAccessExpression | ElementAccessExpression | OmittedExpression; type ObjectBindingOrAssignmentPattern = ObjectBindingPattern | ObjectLiteralExpression; type ArrayBindingOrAssignmentPattern = ArrayBindingPattern | ArrayLiteralExpression; type AssignmentPattern = ObjectLiteralExpression | ArrayLiteralExpression; diff --git a/tests/baselines/reference/destructuringReassignsRightHandSide.js b/tests/baselines/reference/destructuringReassignsRightHandSide.js new file mode 100644 index 00000000000..b893202aa1e --- /dev/null +++ b/tests/baselines/reference/destructuringReassignsRightHandSide.js @@ -0,0 +1,18 @@ +//// [destructuringReassignsRightHandSide.ts] +var foo: any = { foo: 1, bar: 2 }; +var bar: any; + +// reassignment in destructuring pattern +({ foo, bar } = foo); + +// reassignment in subsequent var +var { foo, baz } = foo; + +//// [destructuringReassignsRightHandSide.js] +var foo = { foo: 1, bar: 2 }; +var bar; +// reassignment in destructuring pattern +(_a = foo, foo = _a.foo, bar = _a.bar); +// reassignment in subsequent var +var _b = foo, foo = _b.foo, baz = _b.baz; +var _a; diff --git a/tests/baselines/reference/destructuringReassignsRightHandSide.symbols b/tests/baselines/reference/destructuringReassignsRightHandSide.symbols new file mode 100644 index 00000000000..a0b68b7fe53 --- /dev/null +++ b/tests/baselines/reference/destructuringReassignsRightHandSide.symbols @@ -0,0 +1,21 @@ +=== tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts === +var foo: any = { foo: 1, bar: 2 }; +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 3), Decl(destructuringReassignsRightHandSide.ts, 7, 5)) +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 16)) +>bar : Symbol(bar, Decl(destructuringReassignsRightHandSide.ts, 0, 24)) + +var bar: any; +>bar : Symbol(bar, Decl(destructuringReassignsRightHandSide.ts, 1, 3)) + +// reassignment in destructuring pattern +({ foo, bar } = foo); +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 4, 2)) +>bar : Symbol(bar, Decl(destructuringReassignsRightHandSide.ts, 4, 7)) +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 3), Decl(destructuringReassignsRightHandSide.ts, 7, 5)) + +// reassignment in subsequent var +var { foo, baz } = foo; +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 3), Decl(destructuringReassignsRightHandSide.ts, 7, 5)) +>baz : Symbol(baz, Decl(destructuringReassignsRightHandSide.ts, 7, 10)) +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 3), Decl(destructuringReassignsRightHandSide.ts, 7, 5)) + diff --git a/tests/baselines/reference/destructuringReassignsRightHandSide.types b/tests/baselines/reference/destructuringReassignsRightHandSide.types new file mode 100644 index 00000000000..f5ba19820e0 --- /dev/null +++ b/tests/baselines/reference/destructuringReassignsRightHandSide.types @@ -0,0 +1,27 @@ +=== tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts === +var foo: any = { foo: 1, bar: 2 }; +>foo : any +>{ foo: 1, bar: 2 } : { foo: number; bar: number; } +>foo : number +>1 : 1 +>bar : number +>2 : 2 + +var bar: any; +>bar : any + +// reassignment in destructuring pattern +({ foo, bar } = foo); +>({ foo, bar } = foo) : any +>{ foo, bar } = foo : any +>{ foo, bar } : { foo: any; bar: any; } +>foo : any +>bar : any +>foo : any + +// reassignment in subsequent var +var { foo, baz } = foo; +>foo : any +>baz : any +>foo : any + diff --git a/tests/baselines/reference/objectRest.js b/tests/baselines/reference/objectRest.js index 3576ffb286c..c314377f807 100644 --- a/tests/baselines/reference/objectRest.js +++ b/tests/baselines/reference/objectRest.js @@ -85,10 +85,10 @@ var i = removable; var { removed } = i, removableRest2 = __rest(i, ["removed"]); let computed = 'b'; let computed2 = 'a'; -var _g = computed, stillNotGreat = o[_g], _h = computed2, soSo = o[_h], o = __rest(o, [typeof _g === "symbol" ? _g : _g + "", typeof _h === "symbol" ? _h : _h + ""]); -(_j = computed, stillNotGreat = o[_j], _k = computed2, soSo = o[_k], o = __rest(o, [typeof _j === "symbol" ? _j : _j + "", typeof _k === "symbol" ? _k : _k + ""])); +var _g = o, _h = computed, stillNotGreat = _g[_h], _j = computed2, soSo = _g[_j], o = __rest(_g, [typeof _h === "symbol" ? _h : _h + "", typeof _j === "symbol" ? _j : _j + ""]); +(_k = o, _l = computed, stillNotGreat = _k[_l], _m = computed2, soSo = _k[_m], o = __rest(_k, [typeof _l === "symbol" ? _l : _l + "", typeof _m === "symbol" ? _m : _m + ""])); var noContextualType = (_a) => { var { aNumber = 12 } = _a, notEmptyObject = __rest(_a, ["aNumber"]); return aNumber + notEmptyObject.anythingGoes; }; -var _d, _f, _j, _k; +var _d, _f, _k, _l, _m; diff --git a/tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts b/tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts new file mode 100644 index 00000000000..042ed5d5248 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts @@ -0,0 +1,9 @@ +// @target: es5 +var foo: any = { foo: 1, bar: 2 }; +var bar: any; + +// reassignment in destructuring pattern +({ foo, bar } = foo); + +// reassignment in subsequent var +var { foo, baz } = foo; \ No newline at end of file From 964565e06968259fc4e6de6f1e88ab5e0663a94a Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 16 Jan 2018 23:31:46 -0800 Subject: [PATCH 183/189] Update authors for release 2.7 --- .mailmap | 28 ++++++++++++++++++++++++++-- AUTHORS.md | 24 ++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/.mailmap b/.mailmap index 98f004c58dc..80487998c95 100644 --- a/.mailmap +++ b/.mailmap @@ -140,7 +140,7 @@ Mike Busyrev Mine Starks Mine Starks Mohamed Hegazy ncoley # Natalie Coley -Nathan Shively-Sanders +Nathan Shively-Sanders Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Nathan Yee Nima Zahedi Noah Chen @@ -287,4 +287,28 @@ Stas Vilchik Taras Mankovski Thomas den Hollander Vakhurin Sergey -Zeeshan Ahmed \ No newline at end of file +Zeeshan Ahmed +Orta # Orta Therox +IdeaHunter # @IdeaHunter +kujon # Jakub Korzeniowski +Matt @begincalendar +meyer # @meyer +micbou # @micbou +Alan Agius +Alex Khomchenko +Oussama Ben Brahim benbraou +Cameron Taggart +csigs csigs +Eugene Timokhov +Kris Zyp +Jing Ma +Martin Hiller +Mike Morearty +Priyantha Lankapura <403912+lankaapura@users.noreply.github.com> +Remo H. Jansen +Sean Barag +Sharon Rolel +Stanislav Iliev +Wenlu Wang <805037171@163.com> wenlu.wang <805037171@163.com> kingwl <805037171@163.com> +Wilson Hobbs +Yuval Greenfield \ No newline at end of file diff --git a/AUTHORS.md b/AUTHORS.md index c554a588715..0dfaddb7a25 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -6,8 +6,10 @@ TypeScript is authored by: * Adrian Leonhard * Ahmad Farid * Akshar Patel +* Alan Agius * Alex Chugaev * Alex Eagle +* Alex Khomchenko * Alexander Kuvaev * Alexander Rusakov * Ali Sabzevari @@ -47,6 +49,7 @@ TypeScript is authored by: * Brett Mayen * Bryan Forbes * Caitlin Potter +* Cameron Taggart * @cedvdb * Charles Pierce * Charly POLY @@ -56,6 +59,7 @@ TypeScript is authored by: * Colby Russell * Colin Snover * Cotton Hou +* csigs * Cyrus Najmabadi * Dafrok Zhang * Dahan Gong @@ -85,6 +89,7 @@ TypeScript is authored by: * Erik McClenney * Ethan Resnick * Ethan Rubio +* Eugene Timokhov * Evan Martin * Evan Sebastian * Eyas Sharaiha @@ -111,6 +116,7 @@ TypeScript is authored by: * Herrington Darkholme * Homa Wong * Iain Monro +* @IdeaHunter * Igor Novozhilov * Ika * Ingvar Stepanyan @@ -118,6 +124,7 @@ TypeScript is authored by: * Ivan Enderlin * Ivo Gabe de Wolff * Iwata Hidetaka +* Jakub Korzeniowski * Jakub Młokosiewicz * James Henry * James Whitney @@ -130,6 +137,7 @@ TypeScript is authored by: * Jed Mao * Jeffrey Morlan * Jesse Schalken +* Jing Ma * Jiri Tobisek * Joe Calzaretta * Joe Chung @@ -160,6 +168,7 @@ TypeScript is authored by: * Kevin Lang * Kitson Kelly * Klaus Meinhardt +* Kris Zyp * Kyle Kelley * Kārlis Gaņģis * Lorant Pinter @@ -170,8 +179,10 @@ TypeScript is authored by: * Manish Giri * Marin Marinov * Marius Schulz +* Martin Hiller * Martin Vseticka * Masahiro Wakame +* Matt * Matt Bierner * Matt McCutchen * Matt Mitchell @@ -179,10 +190,13 @@ TypeScript is authored by: * Mattias Buelens * Max Deepfield * Maxwell Paul Brickner +* @meyer * Micah Zoltu +* @micbou * Michael * Michael Bromley * Mike Busyrev +* Mike Morearty * Mine Starks * Mohamed Hegazy * Mohsen Azimi @@ -198,7 +212,9 @@ TypeScript is authored by: * Oleg Mihailik * Oleksandr Chekhovskyi * Omer Sheikh +* Orta Therox * Oskar Segersva¨rd +* Oussama Ben Brahim * Patrick Zhong * Paul Jolly * Paul van Brenk @@ -210,11 +226,13 @@ TypeScript is authored by: * Piero Cangianiello * @piloopin * Prayag Verma +* Priyantha Lankapura * @progre * Punya Biswal * Rado Kirov * Raj Dosanjh * Reiner Dolp +* Remo H. Jansen * Richard Karmazín * Richard Knoll * Richard Sentino @@ -227,8 +245,10 @@ TypeScript is authored by: * Ryohei Ikegami * Sam El-Husseini * Sarangan Rajamanickam +* Sean Barag * Sergey Rubanov * Sergey Shandar +* Sharon Rolel * Sheetal Nandi * Shengping Zhong * Shyyko Serhiy @@ -237,6 +257,7 @@ TypeScript is authored by: * Solal Pirelli * Soo Jae Hwang * Stan Thomas +* Stanislav Iliev * Stanislav Sysoev * Stas Vilchik * Steve Lucco @@ -268,11 +289,14 @@ TypeScript is authored by: * Vilic Vane * Vladimir Kurchatkin * Vladimir Matveev +* Wenlu Wang * Wesley Wigham * William Orr +* Wilson Hobbs * York Yao * @yortus * Yuichi Nukiyama +* Yuval Greenfield * Zeeshan Ahmed * Zev Spitz * Zhengbo Li \ No newline at end of file From be607bd28f3969275f3f10a867b9e21731aaac5b Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 17 Jan 2018 07:33:03 -0800 Subject: [PATCH 184/189] getStringLiteralCompletionEntries: switch on parent.type (#21169) * getStringLiteralCompletionEntries: switch on parent.type * Use a 'default' case and reduce findPrecedingToken calls * fromType -> fromContextualType --- src/services/completions.ts | 148 ++++++++++++++++++++---------------- src/services/utilities.ts | 3 +- 2 files changed, 85 insertions(+), 66 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index ac1eb8f6a46..2afac10a944 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -35,11 +35,14 @@ namespace ts.Completions { return entries && pathCompletionsInfo(entries); } - if (isInString(sourceFile, position)) { - return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log); + const contextToken = findPrecedingToken(position, sourceFile); + + if (isInString(sourceFile, position, contextToken)) { + return !contextToken || !isStringLiteral(contextToken) && !isNoSubstitutionTemplateLiteral(contextToken) + ? undefined + : getStringLiteralCompletionEntries(sourceFile, contextToken, position, typeChecker, compilerOptions, host, log); } - const contextToken = findPrecedingToken(position, sourceFile); if (contextToken && isBreakOrContinueStatement(contextToken.parent) && (contextToken.kind === SyntaxKind.BreakKeyword || contextToken.kind === SyntaxKind.ContinueKeyword || contextToken.kind === SyntaxKind.Identifier)) { return getLabelCompletionAtPosition(contextToken.parent); @@ -261,70 +264,87 @@ namespace ts.Completions { } } - function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined { - const node = findPrecedingToken(position, sourceFile); - if (!node || !isStringLiteral(node) && !isNoSubstitutionTemplateLiteral(node)) { - return undefined; - } + function getStringLiteralCompletionEntries(sourceFile: SourceFile, node: StringLiteralLike, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined { + switch (node.parent.kind) { + case SyntaxKind.LiteralType: + switch (node.parent.parent.kind) { + case SyntaxKind.TypeReference: + // TODO: GH#21168 + return undefined; + case SyntaxKind.IndexedAccessType: + // Get all apparent property names + // i.e. interface Foo { + // foo: string; + // bar: string; + // } + // let x: Foo["/*completion position*/"] + const type = typeChecker.getTypeFromTypeNode((node.parent.parent as IndexedAccessTypeNode).objectType); + return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, sourceFile, type, typeChecker, compilerOptions.target, log); + default: + return undefined; + } - if (node.parent.kind === SyntaxKind.PropertyAssignment && - node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression && - (node.parent).name === node) { - // Get quoted name of properties of the object literal expression - // i.e. interface ConfigFiles { - // 'jspm:dev': string - // } - // let files: ConfigFiles = { - // '/*completion position*/' - // } - // - // function foo(c: ConfigFiles) {} - // foo({ - // '/*completion position*/' - // }); - return getStringLiteralCompletionEntriesFromPropertyAssignment(node.parent, sourceFile, typeChecker, compilerOptions.target, log); - } - else if (isElementAccessExpression(node.parent) && node.parent.argumentExpression === node) { - // Get all names of properties on the expression - // i.e. interface A { - // 'prop1': string - // } - // let a: A; - // a['/*completion position*/'] - const type = typeChecker.getTypeAtLocation(node.parent.expression); - return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, sourceFile, type, typeChecker, compilerOptions.target, log); - } - else if (node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration - || isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || isImportCall(node.parent) - || isExpressionOfExternalModuleImportEqualsDeclaration(node)) { - // Get all known external module names or complete a path to a module - // i.e. import * as ns from "/*completion position*/"; - // var y = import("/*completion position*/"); - // import x = require("/*completion position*/"); - // var y = require("/*completion position*/"); - // export * from "/*completion position*/"; - const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker); - return pathCompletionsInfo(entries); - } - else if (isIndexedAccessTypeNode(node.parent.parent)) { - // Get all apparent property names - // i.e. interface Foo { - // foo: string; - // bar: string; - // } - // let x: Foo["/*completion position*/"] - const type = typeChecker.getTypeFromTypeNode(node.parent.parent.objectType); - return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, sourceFile, type, typeChecker, compilerOptions.target, log); - } - else { - const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile); - if (argumentInfo) { - // Get string literal completions from specialized signatures of the target - // i.e. declare function f(a: 'A'); - // f("/*completion position*/") - return getStringLiteralCompletionEntriesFromCallExpression(argumentInfo, typeChecker); + case SyntaxKind.PropertyAssignment: + if (node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression && + (node.parent).name === node) { + // Get quoted name of properties of the object literal expression + // i.e. interface ConfigFiles { + // 'jspm:dev': string + // } + // let files: ConfigFiles = { + // '/*completion position*/' + // } + // + // function foo(c: ConfigFiles) {} + // foo({ + // '/*completion position*/' + // }); + return getStringLiteralCompletionEntriesFromPropertyAssignment(node.parent, sourceFile, typeChecker, compilerOptions.target, log); + } + return fromContextualType(); + + case SyntaxKind.ElementAccessExpression: { + const { expression, argumentExpression } = node.parent as ElementAccessExpression; + if (node === argumentExpression) { + // Get all names of properties on the expression + // i.e. interface A { + // 'prop1': string + // } + // let a: A; + // a['/*completion position*/'] + const type = typeChecker.getTypeAtLocation(expression); + return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, sourceFile, type, typeChecker, compilerOptions.target, log); + } + break; } + case SyntaxKind.CallExpression: + case SyntaxKind.NewExpression: + if (!isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) && !isImportCall(node.parent)) { + const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile); + // Get string literal completions from specialized signatures of the target + // i.e. declare function f(a: 'A'); + // f("/*completion position*/") + return argumentInfo ? getStringLiteralCompletionEntriesFromCallExpression(argumentInfo, typeChecker) : fromContextualType(); + } + // falls through + + case SyntaxKind.ImportDeclaration: + case SyntaxKind.ExportDeclaration: + case SyntaxKind.ExternalModuleReference: + // Get all known external module names or complete a path to a module + // i.e. import * as ns from "/*completion position*/"; + // var y = import("/*completion position*/"); + // import x = require("/*completion position*/"); + // var y = require("/*completion position*/"); + // export * from "/*completion position*/"; + return pathCompletionsInfo(PathCompletions.getStringLiteralCompletionsFromModuleNames(sourceFile, node as StringLiteral, compilerOptions, host, typeChecker)); + + default: + return fromContextualType(); + } + + function fromContextualType(): CompletionInfo { // Get completion for string literal from string literal type // i.e. var x: "hi" | "hello" = "/*completion position*/" return getStringLiteralCompletionEntriesFromType(getContextualTypeFromParent(node, typeChecker), typeChecker); diff --git a/src/services/utilities.ts b/src/services/utilities.ts index c5694625493..abfe5a7a55d 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -833,8 +833,7 @@ namespace ts { } } - export function isInString(sourceFile: SourceFile, position: number): boolean { - const previousToken = findPrecedingToken(position, sourceFile); + export function isInString(sourceFile: SourceFile, position: number, previousToken = findPrecedingToken(position, sourceFile)): boolean { if (previousToken && isStringTextContainingNode(previousToken)) { const start = previousToken.getStart(); const end = previousToken.getEnd(); From 2ca688a87d028c7791fdfc0fb3220e11e0e8559d Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 18 Jan 2018 00:42:40 +0700 Subject: [PATCH 185/189] Remove the colon from the message in tsconfig.json (#21174) * Add additional diagnostic message for tsconfig.json * Add a way to override description for tsconfig.json * Modify reference tsconfig.json in tests * Don't have to differentiate cmdline and tsconfig.json description This reverts commit efe57733cac305533c61c7bea3d51b302bbb4d19 and 94f9e67a247f2d73ddff6935083f76812efd2a21. * Remove colon from diagnostic message code 6079 * Remove colon from localized messages code 6079 * Revert "Remove colon from localized messages code 6079" Not changing files on src/loc because they are managed using automated tools. This reverts commit e91f52348e17bf829db2418020c4281203d03e05. --- src/compiler/commandLineParser.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- .../tsConfig/Default initialized TSConfig/tsconfig.json | 2 +- .../tsconfig.json | 2 +- .../tsconfig.json | 2 +- .../Initialized TSConfig with files options/tsconfig.json | 2 +- .../tsconfig.json | 2 +- .../tsconfig.json | 2 +- .../tsconfig.json | 2 +- .../tsconfig.json | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 4813d4b4300..eb9f1e3cf34 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -151,7 +151,7 @@ namespace ts { }, showInSimplifiedHelpView: true, category: Diagnostics.Basic_Options, - description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon + description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation }, { name: "allowJs", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index cf5ccb1397d..785ac6f953b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3015,7 +3015,7 @@ "category": "Message", "code": 6078 }, - "Specify library files to be included in the compilation: ": { + "Specify library files to be included in the compilation.": { "category": "Message", "code": 6079 }, diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index 26cf24cc2e4..cb57cd1366b 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index 5d7960c8254..6614dd9e48e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index 353cb68ea95..8c19ad58bed 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 4a28e6f2491..f5e2b163a21 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index 46ae199430d..ced3eae17b8 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "lib": ["es5","es2015.promise"], /* Specify library files to be included in the compilation: */ + "lib": ["es5","es2015.promise"], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index 26cf24cc2e4..cb57cd1366b 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index 069305e2d35..1356e2258f7 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "lib": ["es5","es2015.core"], /* Specify library files to be included in the compilation: */ + "lib": ["es5","es2015.core"], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index 9e1c409f56e..473280f675e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ From 18a2fc82f7d35528ae31032ade15e2ea07ab3f54 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 17 Jan 2018 11:06:09 -0800 Subject: [PATCH 186/189] Accept tsserverlibrary.d.ts and fix gulpfile --- Gulpfile.ts | 2 +- tests/baselines/reference/api/tsserverlibrary.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index 2909b10471a..0c410bdfb08 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -528,7 +528,7 @@ gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile, typesMapJson], (do 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() .pipe(sourcemaps.init()) - .pipe(newer(tsserverLibraryFile)) + .pipe(newer({ dest: tsserverLibraryFile, extra: ["src/compiler/**/*.ts", "src/services/**/*.ts"] })) .pipe(serverLibraryProject()); return merge2([ diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index e57b52942f4..a0dfa5f5d17 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -877,7 +877,7 @@ declare namespace ts { type DestructuringAssignment = ObjectDestructuringAssignment | ArrayDestructuringAssignment; type BindingOrAssignmentElement = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment | OmittedExpression | SpreadElement | ArrayLiteralExpression | ObjectLiteralExpression | AssignmentExpression | Identifier | PropertyAccessExpression | ElementAccessExpression; type BindingOrAssignmentElementRestIndicator = DotDotDotToken | SpreadElement | SpreadAssignment; - type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Expression; + type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Identifier | PropertyAccessExpression | ElementAccessExpression | OmittedExpression; type ObjectBindingOrAssignmentPattern = ObjectBindingPattern | ObjectLiteralExpression; type ArrayBindingOrAssignmentPattern = ArrayBindingPattern | ArrayLiteralExpression; type AssignmentPattern = ObjectLiteralExpression | ArrayLiteralExpression; From 61fb845b87f768c9e2a1e700902d04ac938f30b6 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 17 Jan 2018 11:14:03 -0800 Subject: [PATCH 187/189] Get packageId for relative import within a package (#21130) * Get packageId for relative import within a package * Code review * Rename things and add comments * Improve documentation * Test for scoped packages --- src/compiler/moduleNameResolver.ts | 43 +++++++++++++++++- ...catePackage_relativeImportWithinPackage.js | 45 +++++++++++++++++++ ...ackage_relativeImportWithinPackage.symbols | 44 ++++++++++++++++++ ...age_relativeImportWithinPackage.trace.json | 45 +++++++++++++++++++ ...ePackage_relativeImportWithinPackage.types | 45 +++++++++++++++++++ ...kage_relativeImportWithinPackage_scoped.js | 45 +++++++++++++++++++ ...relativeImportWithinPackage_scoped.symbols | 44 ++++++++++++++++++ ...ativeImportWithinPackage_scoped.trace.json | 45 +++++++++++++++++++ ...e_relativeImportWithinPackage_scoped.types | 45 +++++++++++++++++++ ...catePackage_relativeImportWithinPackage.ts | 38 ++++++++++++++++ ...kage_relativeImportWithinPackage_scoped.ts | 38 ++++++++++++++++ 11 files changed, 476 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types create mode 100644 tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts create mode 100644 tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 018bddd420b..e8639ea3d5f 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -801,7 +801,9 @@ namespace ts { } const resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); if (resolvedFromFile) { - return noPackageId(resolvedFromFile); + const nm = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile.path) : undefined; + const packageId = nm && getPackageJsonInfo(nm.packageDirectory, nm.subModuleName, failedLookupLocations, /*onlyRecordFailures*/ false, state).packageId; + return withPackageId(packageId, resolvedFromFile); } } if (!onlyRecordFailures) { @@ -816,6 +818,45 @@ namespace ts { return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson); } + const nodeModulesPathPart = "/node_modules/"; + + /** + * This will be called on the successfully resolved path from `loadModuleFromFile`. + * (Not neeeded for `loadModuleFromNodeModules` as that looks up the `package.json` as part of resolution.) + * + * packageDirectory is the directory of the package itself. + * subModuleName is the path within the package. + * For `blah/node_modules/foo/index.d.ts` this is { packageDirectory: "foo", subModuleName: "" }. (Part before "/node_modules/" is ignored.) + * For `/node_modules/foo/bar.d.ts` this is { packageDirectory: "foo", subModuleName": "bar" }. + * For `/node_modules/@types/foo/bar/index.d.ts` this is { packageDirectory: "@types/foo", subModuleName: "bar" }. + */ + function parseNodeModuleFromPath(path: string): { packageDirectory: string, subModuleName: string } | undefined { + path = normalizePath(path); + const idx = path.lastIndexOf(nodeModulesPathPart); + if (idx === -1) { + return undefined; + } + + const indexAfterNodeModules = idx + nodeModulesPathPart.length; + let indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterNodeModules); + if (path.charCodeAt(indexAfterNodeModules) === CharacterCodes.at) { + indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName); + } + const packageDirectory = path.slice(0, indexAfterPackageName); + const subModuleName = removeExtensionAndIndex(path.slice(indexAfterPackageName + 1)); + return { packageDirectory, subModuleName }; + } + + function moveToNextDirectorySeparatorIfAvailable(path: string, prevSeparatorIndex: number): number { + const nextSeparatorIndex = path.indexOf(directorySeparator, prevSeparatorIndex + 1); + return nextSeparatorIndex === -1 ? prevSeparatorIndex : nextSeparatorIndex; + } + + function removeExtensionAndIndex(path: string): string { + const noExtension = removeFileExtension(path); + return noExtension === "index" ? "" : removeSuffix(noExtension, "/index"); + } + /* @internal */ export function directoryProbablyExists(directoryName: string, host: { directoryExists?: (directoryName: string) => boolean }): boolean { // if host does not support 'directoryExists' assume that directory will exist diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js new file mode 100644 index 00000000000..5236a93f931 --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts] //// + +//// [package.json] +{ + "name": "foo", + "version": "1.2.3" +} + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [index.d.ts] +import { C } from "foo"; +export const o: C; + +//// [use.d.ts] +import { C } from "./index"; +export function use(o: C): void; + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [package.json] +{ + "name": "foo", + "version": "1.2.3" +} + +//// [index.ts] +import { use } from "foo/use"; +import { o } from "a"; + +use(o); + + +//// [index.js] +"use strict"; +exports.__esModule = true; +var use_1 = require("foo/use"); +var a_1 = require("a"); +use_1.use(a_1.o); diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols new file mode 100644 index 00000000000..19809675af2 --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols @@ -0,0 +1,44 @@ +=== /index.ts === +import { use } from "foo/use"; +>use : Symbol(use, Decl(index.ts, 0, 8)) + +import { o } from "a"; +>o : Symbol(o, Decl(index.ts, 1, 8)) + +use(o); +>use : Symbol(use, Decl(index.ts, 0, 8)) +>o : Symbol(o, Decl(index.ts, 1, 8)) + +=== /node_modules/a/node_modules/foo/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + +=== /node_modules/a/index.d.ts === +import { C } from "foo"; +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +export const o: C; +>o : Symbol(o, Decl(index.d.ts, 1, 12)) +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +=== /node_modules/foo/use.d.ts === +import { C } from "./index"; +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +export function use(o: C): void; +>use : Symbol(use, Decl(use.d.ts, 0, 28)) +>o : Symbol(o, Decl(use.d.ts, 1, 20)) +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +=== /node_modules/foo/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json new file mode 100644 index 00000000000..45f70fd8145 --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json @@ -0,0 +1,45 @@ +[ + "======== Resolving module 'foo/use' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo/use' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "File '/node_modules/foo/use.ts' does not exist.", + "File '/node_modules/foo/use.tsx' does not exist.", + "File '/node_modules/foo/use.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/foo/use.d.ts', result '/node_modules/foo/use.d.ts'.", + "======== Module name 'foo/use' was successfully resolved to '/node_modules/foo/use.d.ts'. ========", + "======== Resolving module 'a' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/a/package.json' does not exist.", + "File '/node_modules/a.ts' does not exist.", + "File '/node_modules/a.tsx' does not exist.", + "File '/node_modules/a.d.ts' does not exist.", + "File '/node_modules/a/index.ts' does not exist.", + "File '/node_modules/a/index.tsx' does not exist.", + "File '/node_modules/a/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/index.d.ts', result '/node_modules/a/index.d.ts'.", + "======== Module name 'a' was successfully resolved to '/node_modules/a/index.d.ts'. ========", + "======== Resolving module './index' from '/node_modules/foo/use.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module as file / folder, candidate module location '/node_modules/foo/index', target file type 'TypeScript'.", + "File '/node_modules/foo/index.ts' does not exist.", + "File '/node_modules/foo/index.tsx' does not exist.", + "File '/node_modules/foo/index.d.ts' exist - use it as a name resolution result.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "======== Module name './index' was successfully resolved to '/node_modules/foo/index.d.ts'. ========", + "======== Resolving module 'foo' from '/node_modules/a/index.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/a/node_modules/foo/package.json'.", + "File '/node_modules/a/node_modules/foo.ts' does not exist.", + "File '/node_modules/a/node_modules/foo.tsx' does not exist.", + "File '/node_modules/a/node_modules/foo.d.ts' does not exist.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "File '/node_modules/a/node_modules/foo/index.ts' does not exist.", + "File '/node_modules/a/node_modules/foo/index.tsx' does not exist.", + "File '/node_modules/a/node_modules/foo/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/node_modules/foo/index.d.ts', result '/node_modules/a/node_modules/foo/index.d.ts'.", + "======== Module name 'foo' was successfully resolved to '/node_modules/a/node_modules/foo/index.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types new file mode 100644 index 00000000000..33931774a1b --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types @@ -0,0 +1,45 @@ +=== /index.ts === +import { use } from "foo/use"; +>use : (o: C) => void + +import { o } from "a"; +>o : C + +use(o); +>use(o) : void +>use : (o: C) => void +>o : C + +=== /node_modules/a/node_modules/foo/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + +=== /node_modules/a/index.d.ts === +import { C } from "foo"; +>C : typeof C + +export const o: C; +>o : C +>C : C + +=== /node_modules/foo/use.d.ts === +import { C } from "./index"; +>C : typeof C + +export function use(o: C): void; +>use : (o: C) => void +>o : C +>C : C + +=== /node_modules/foo/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js new file mode 100644 index 00000000000..822c03ca18d --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts] //// + +//// [package.json] +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [index.d.ts] +import { C } from "@foo/bar"; +export const o: C; + +//// [use.d.ts] +import { C } from "./index"; +export function use(o: C): void; + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [package.json] +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +//// [index.ts] +import { use } from "@foo/bar/use"; +import { o } from "a"; + +use(o); + + +//// [index.js] +"use strict"; +exports.__esModule = true; +var use_1 = require("@foo/bar/use"); +var a_1 = require("a"); +use_1.use(a_1.o); diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols new file mode 100644 index 00000000000..38cd37e023b --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols @@ -0,0 +1,44 @@ +=== /index.ts === +import { use } from "@foo/bar/use"; +>use : Symbol(use, Decl(index.ts, 0, 8)) + +import { o } from "a"; +>o : Symbol(o, Decl(index.ts, 1, 8)) + +use(o); +>use : Symbol(use, Decl(index.ts, 0, 8)) +>o : Symbol(o, Decl(index.ts, 1, 8)) + +=== /node_modules/a/node_modules/@foo/bar/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + +=== /node_modules/a/index.d.ts === +import { C } from "@foo/bar"; +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +export const o: C; +>o : Symbol(o, Decl(index.d.ts, 1, 12)) +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +=== /node_modules/@foo/bar/use.d.ts === +import { C } from "./index"; +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +export function use(o: C): void; +>use : Symbol(use, Decl(use.d.ts, 0, 28)) +>o : Symbol(o, Decl(use.d.ts, 1, 20)) +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +=== /node_modules/@foo/bar/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json new file mode 100644 index 00000000000..cae4195aa3d --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json @@ -0,0 +1,45 @@ +[ + "======== Resolving module '@foo/bar/use' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module '@foo/bar/use' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/@foo/bar/package.json'.", + "File '/node_modules/@foo/bar/use.ts' does not exist.", + "File '/node_modules/@foo/bar/use.tsx' does not exist.", + "File '/node_modules/@foo/bar/use.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/@foo/bar/use.d.ts', result '/node_modules/@foo/bar/use.d.ts'.", + "======== Module name '@foo/bar/use' was successfully resolved to '/node_modules/@foo/bar/use.d.ts'. ========", + "======== Resolving module 'a' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/a/package.json' does not exist.", + "File '/node_modules/a.ts' does not exist.", + "File '/node_modules/a.tsx' does not exist.", + "File '/node_modules/a.d.ts' does not exist.", + "File '/node_modules/a/index.ts' does not exist.", + "File '/node_modules/a/index.tsx' does not exist.", + "File '/node_modules/a/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/index.d.ts', result '/node_modules/a/index.d.ts'.", + "======== Module name 'a' was successfully resolved to '/node_modules/a/index.d.ts'. ========", + "======== Resolving module './index' from '/node_modules/@foo/bar/use.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module as file / folder, candidate module location '/node_modules/@foo/bar/index', target file type 'TypeScript'.", + "File '/node_modules/@foo/bar/index.ts' does not exist.", + "File '/node_modules/@foo/bar/index.tsx' does not exist.", + "File '/node_modules/@foo/bar/index.d.ts' exist - use it as a name resolution result.", + "Found 'package.json' at '/node_modules/@foo/bar/package.json'.", + "======== Module name './index' was successfully resolved to '/node_modules/@foo/bar/index.d.ts'. ========", + "======== Resolving module '@foo/bar' from '/node_modules/a/index.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module '@foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/a/node_modules/@foo/bar/package.json'.", + "File '/node_modules/a/node_modules/@foo/bar.ts' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar.tsx' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar.d.ts' does not exist.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "File '/node_modules/a/node_modules/@foo/bar/index.ts' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar/index.tsx' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/node_modules/@foo/bar/index.d.ts', result '/node_modules/a/node_modules/@foo/bar/index.d.ts'.", + "======== Module name '@foo/bar' was successfully resolved to '/node_modules/a/node_modules/@foo/bar/index.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types new file mode 100644 index 00000000000..7be2442bf3b --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types @@ -0,0 +1,45 @@ +=== /index.ts === +import { use } from "@foo/bar/use"; +>use : (o: C) => void + +import { o } from "a"; +>o : C + +use(o); +>use(o) : void +>use : (o: C) => void +>o : C + +=== /node_modules/a/node_modules/@foo/bar/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + +=== /node_modules/a/index.d.ts === +import { C } from "@foo/bar"; +>C : typeof C + +export const o: C; +>o : C +>C : C + +=== /node_modules/@foo/bar/use.d.ts === +import { C } from "./index"; +>C : typeof C + +export function use(o: C): void; +>use : (o: C) => void +>o : C +>C : C + +=== /node_modules/@foo/bar/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + diff --git a/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts new file mode 100644 index 00000000000..02ae0c58d02 --- /dev/null +++ b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts @@ -0,0 +1,38 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// @Filename: /node_modules/a/node_modules/foo/package.json +{ + "name": "foo", + "version": "1.2.3" +} + +// @Filename: /node_modules/a/node_modules/foo/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/a/index.d.ts +import { C } from "foo"; +export const o: C; + +// @Filename: /node_modules/foo/use.d.ts +import { C } from "./index"; +export function use(o: C): void; + +// @Filename: /node_modules/foo/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/foo/package.json +{ + "name": "foo", + "version": "1.2.3" +} + +// @Filename: /index.ts +import { use } from "foo/use"; +import { o } from "a"; + +use(o); diff --git a/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts new file mode 100644 index 00000000000..5ccf69a5a8d --- /dev/null +++ b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts @@ -0,0 +1,38 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// @Filename: /node_modules/a/node_modules/@foo/bar/package.json +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +// @Filename: /node_modules/a/node_modules/@foo/bar/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/a/index.d.ts +import { C } from "@foo/bar"; +export const o: C; + +// @Filename: /node_modules/@foo/bar/use.d.ts +import { C } from "./index"; +export function use(o: C): void; + +// @Filename: /node_modules/@foo/bar/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/@foo/bar/package.json +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +// @Filename: /index.ts +import { use } from "@foo/bar/use"; +import { o } from "a"; + +use(o); From c549bb57375ee686477e88fd21182c4b5b5c9e9b Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 17 Jan 2018 11:27:21 -0800 Subject: [PATCH 188/189] Fix bug: getNonNullableType before getting signatures of method (#21212) --- src/compiler/checker.ts | 2 +- tests/cases/fourslash/completionsOptionalMethod.ts | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/completionsOptionalMethod.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 489fff16e2c..b3f06788131 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15815,7 +15815,7 @@ namespace ts { } function isValidMethodAccess(method: Symbol, type: Type) { const propType = getTypeOfFuncClassEnumModule(method); - const signatures = getSignaturesOfType(propType, SignatureKind.Call); + const signatures = getSignaturesOfType(getNonNullableType(propType), SignatureKind.Call); Debug.assert(signatures.length !== 0); return signatures.some(sig => { const thisType = getThisTypeOfSignature(sig); diff --git a/tests/cases/fourslash/completionsOptionalMethod.ts b/tests/cases/fourslash/completionsOptionalMethod.ts new file mode 100644 index 00000000000..72399f177f2 --- /dev/null +++ b/tests/cases/fourslash/completionsOptionalMethod.ts @@ -0,0 +1,8 @@ +/// + +// @strictNullChecks: true + +////declare const x: { m?(): void }; +////x./**/ + +verify.completionsAt("", ["m"]); From b363f4f9cd6ef98f9451ccdcc7321d151195200b Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 17 Jan 2018 11:41:23 -0800 Subject: [PATCH 189/189] Log packageId in --traceResolution (#21233) --- src/compiler/diagnosticMessages.json | 4 ++++ src/compiler/moduleNameResolver.ts | 11 ++++++++--- src/compiler/program.ts | 2 +- src/compiler/utilities.ts | 5 +++++ ...catePackage_relativeImportWithinPackage.trace.json | 6 +++--- ...kage_relativeImportWithinPackage_scoped.trace.json | 6 +++--- ...Resolution_packageJson_yesAtPackageRoot.trace.json | 4 ++-- ...Json_yesAtPackageRoot_fakeScopedPackage.trace.json | 4 ++-- 8 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 785ac6f953b..6a14aab2aee 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3451,6 +3451,10 @@ "category": "Error", "code": 6189 }, + "Found 'package.json' at '{0}'. Package ID is '{1}'.": { + "category": "Message", + "code": 6190 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index e8639ea3d5f..f72876bd5fc 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -960,13 +960,18 @@ namespace ts { const directoryExists = !onlyRecordFailures && directoryProbablyExists(nodeModuleDirectory, host); const packageJsonPath = pathToPackageJson(nodeModuleDirectory); if (directoryExists && host.fileExists(packageJsonPath)) { - if (traceEnabled) { - trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath); - } const packageJsonContent = readJson(packageJsonPath, host); const packageId: PackageId = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string" ? { name: packageJsonContent.name, subModuleName, version: packageJsonContent.version } : undefined; + if (traceEnabled) { + if (packageId) { + trace(host, Diagnostics.Found_package_json_at_0_Package_ID_is_1, packageJsonPath, packageIdToString(packageId)); + } + else { + trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath); + } + } return { found: true, packageJsonContent, packageId }; } else { diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 0d1bbf233a3..37fae7195ab 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1817,7 +1817,7 @@ namespace ts { }, shouldCreateNewSourceFile); if (packageId) { - const packageIdKey = `${packageId.name}/${packageId.subModuleName}@${packageId.version}`; + const packageIdKey = packageIdToString(packageId); const fileFromPackageId = packageIdToSourceFile.get(packageIdKey); if (fileFromPackageId) { // Some other SourceFile already exists with this package name and version. diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 357e5179865..ffcdf42c67e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -116,6 +116,11 @@ namespace ts { return a === b || a && b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version; } + export function packageIdToString({ name, subModuleName, version }: PackageId): string { + const fullName = subModuleName ? `${name}/${subModuleName}` : name; + return `${fullName}@${version}`; + } + export function typeDirectiveIsEqualTo(oldResolution: ResolvedTypeReferenceDirective, newResolution: ResolvedTypeReferenceDirective): boolean { return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary; } diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json index 45f70fd8145..ae3917e931a 100644 --- a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json @@ -2,7 +2,7 @@ "======== Resolving module 'foo/use' from '/index.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/use' from 'node_modules' folder, target file type 'TypeScript'.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/use@1.2.3'.", "File '/node_modules/foo/use.ts' does not exist.", "File '/node_modules/foo/use.tsx' does not exist.", "File '/node_modules/foo/use.d.ts' exist - use it as a name resolution result.", @@ -26,12 +26,12 @@ "File '/node_modules/foo/index.ts' does not exist.", "File '/node_modules/foo/index.tsx' does not exist.", "File '/node_modules/foo/index.d.ts' exist - use it as a name resolution result.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo@1.2.3'.", "======== Module name './index' was successfully resolved to '/node_modules/foo/index.d.ts'. ========", "======== Resolving module 'foo' from '/node_modules/a/index.d.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", - "Found 'package.json' at '/node_modules/a/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/a/node_modules/foo/package.json'. Package ID is 'foo@1.2.3'.", "File '/node_modules/a/node_modules/foo.ts' does not exist.", "File '/node_modules/a/node_modules/foo.tsx' does not exist.", "File '/node_modules/a/node_modules/foo.d.ts' does not exist.", diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json index cae4195aa3d..a753e3dfb9a 100644 --- a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json @@ -2,7 +2,7 @@ "======== Resolving module '@foo/bar/use' from '/index.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module '@foo/bar/use' from 'node_modules' folder, target file type 'TypeScript'.", - "Found 'package.json' at '/node_modules/@foo/bar/package.json'.", + "Found 'package.json' at '/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar/use@1.2.3'.", "File '/node_modules/@foo/bar/use.ts' does not exist.", "File '/node_modules/@foo/bar/use.tsx' does not exist.", "File '/node_modules/@foo/bar/use.d.ts' exist - use it as a name resolution result.", @@ -26,12 +26,12 @@ "File '/node_modules/@foo/bar/index.ts' does not exist.", "File '/node_modules/@foo/bar/index.tsx' does not exist.", "File '/node_modules/@foo/bar/index.d.ts' exist - use it as a name resolution result.", - "Found 'package.json' at '/node_modules/@foo/bar/package.json'.", + "Found 'package.json' at '/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar@1.2.3'.", "======== Module name './index' was successfully resolved to '/node_modules/@foo/bar/index.d.ts'. ========", "======== Resolving module '@foo/bar' from '/node_modules/a/index.d.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module '@foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", - "Found 'package.json' at '/node_modules/a/node_modules/@foo/bar/package.json'.", + "Found 'package.json' at '/node_modules/a/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar@1.2.3'.", "File '/node_modules/a/node_modules/@foo/bar.ts' does not exist.", "File '/node_modules/a/node_modules/@foo/bar.tsx' does not exist.", "File '/node_modules/a/node_modules/@foo/bar.d.ts' does not exist.", diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json index 3a87769891b..e852d58f2b3 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json @@ -3,7 +3,7 @@ "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", "File '/node_modules/foo/bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/bar@1.2.3'.", "File '/node_modules/foo/bar.ts' does not exist.", "File '/node_modules/foo/bar.tsx' does not exist.", "File '/node_modules/foo/bar.d.ts' does not exist.", @@ -13,7 +13,7 @@ "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo/bar' from 'node_modules' folder, target file type 'JavaScript'.", "File '/node_modules/foo/bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/bar@1.2.3'.", "File '/node_modules/foo/bar.js' does not exist.", "File '/node_modules/foo/bar.jsx' does not exist.", "File '/node_modules/foo/bar/index.js' exist - use it as a name resolution result.", diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json index c28189a1f7d..19fe1f125bc 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json @@ -3,7 +3,7 @@ "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/@bar' from 'node_modules' folder, target file type 'TypeScript'.", "File '/node_modules/foo/@bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/@bar@1.2.3'.", "File '/node_modules/foo/@bar.ts' does not exist.", "File '/node_modules/foo/@bar.tsx' does not exist.", "File '/node_modules/foo/@bar.d.ts' does not exist.", @@ -13,7 +13,7 @@ "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo/@bar' from 'node_modules' folder, target file type 'JavaScript'.", "File '/node_modules/foo/@bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/@bar@1.2.3'.", "File '/node_modules/foo/@bar.js' does not exist.", "File '/node_modules/foo/@bar.jsx' does not exist.", "File '/node_modules/foo/@bar/index.js' exist - use it as a name resolution result.",