From 9d48047aa6235c144a530059d88c0f3544cddd14 Mon Sep 17 00:00:00 2001 From: Collins Abitekaniza Date: Wed, 1 May 2019 06:27:55 +0300 Subject: [PATCH 001/182] check if instantiable type constraint allows spread --- src/compiler/checker.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f9c87e94961..9f8458d3cc5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19222,6 +19222,12 @@ namespace ts { } function isValidSpreadType(type: Type): boolean { + if (type.flags & TypeFlags.Instantiable) { + const constraint = getBaseConstraintOfType(type); + if (constraint !== undefined) { + return isValidSpreadType(constraint); + } + } return !!(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.NonPrimitive | TypeFlags.Object | TypeFlags.InstantiableNonPrimitive) || getFalsyFlags(type) & TypeFlags.DefinitelyFalsy && isValidSpreadType(removeDefinitelyFalsyTypes(type)) || type.flags & TypeFlags.UnionOrIntersection && every((type).types, isValidSpreadType)); From 2bb2f9ff6893ccae67a8f17312c3c6b0c6c6d960 Mon Sep 17 00:00:00 2001 From: Collins Abitekaniza Date: Wed, 1 May 2019 07:03:03 +0300 Subject: [PATCH 002/182] add baseline tests for spreading instantiable type --- .../restInvalidArgumentType.errors.txt | 5 +- .../reference/restInvalidArgumentType.types | 2 +- .../spreadInvalidArgumentType.errors.txt | 7 +- .../reference/spreadInvalidArgumentType.js | 4 +- .../spreadInvalidArgumentType.symbols | 2 +- .../reference/spreadInvalidArgumentType.types | 6 +- .../reference/spreadTypeVariable.errors.txt | 37 +++++++++++ .../baselines/reference/spreadTypeVariable.js | 57 +++++++++++++++++ .../reference/spreadTypeVariable.symbols | 64 +++++++++++++++++++ .../reference/spreadTypeVariable.types | 58 +++++++++++++++++ .../compiler/spreadInvalidArgumentType.ts | 2 +- .../types/spread/spreadTypeVariable.ts | 24 +++++++ 12 files changed, 257 insertions(+), 11 deletions(-) create mode 100644 tests/baselines/reference/spreadTypeVariable.errors.txt create mode 100644 tests/baselines/reference/spreadTypeVariable.js create mode 100644 tests/baselines/reference/spreadTypeVariable.symbols create mode 100644 tests/baselines/reference/spreadTypeVariable.types create mode 100644 tests/cases/conformance/types/spread/spreadTypeVariable.ts diff --git a/tests/baselines/reference/restInvalidArgumentType.errors.txt b/tests/baselines/reference/restInvalidArgumentType.errors.txt index 7e0c852316a..22d2528fbb3 100644 --- a/tests/baselines/reference/restInvalidArgumentType.errors.txt +++ b/tests/baselines/reference/restInvalidArgumentType.errors.txt @@ -1,3 +1,4 @@ +tests/cases/compiler/restInvalidArgumentType.ts(30,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(31,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(37,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(40,13): error TS2700: Rest types may only be created from object types. @@ -10,7 +11,7 @@ tests/cases/compiler/restInvalidArgumentType.ts(51,13): error TS2700: Rest types tests/cases/compiler/restInvalidArgumentType.ts(53,13): error TS2700: Rest types may only be created from object types. -==== tests/cases/compiler/restInvalidArgumentType.ts (10 errors) ==== +==== tests/cases/compiler/restInvalidArgumentType.ts (11 errors) ==== enum E { v1, v2 }; function f(p1: T, p2: T[]) { @@ -41,6 +42,8 @@ tests/cases/compiler/restInvalidArgumentType.ts(53,13): error TS2700: Rest types var {...r2} = p2; // OK var {...r3} = t; // Error, generic type paramter var {...r4} = i; // Error, index access + ~~ +!!! error TS2700: Rest types may only be created from object types. var {...r5} = k; // Error, index ~~ !!! error TS2700: Rest types may only be created from object types. diff --git a/tests/baselines/reference/restInvalidArgumentType.types b/tests/baselines/reference/restInvalidArgumentType.types index d88ee53796a..638634e8bea 100644 --- a/tests/baselines/reference/restInvalidArgumentType.types +++ b/tests/baselines/reference/restInvalidArgumentType.types @@ -79,7 +79,7 @@ function f(p1: T, p2: T[]) { >t : T var {...r4} = i; // Error, index access ->r4 : T["b"] +>r4 : any >i : T["b"] var {...r5} = k; // Error, index diff --git a/tests/baselines/reference/spreadInvalidArgumentType.errors.txt b/tests/baselines/reference/spreadInvalidArgumentType.errors.txt index cb2b74b7b19..36bc2b36fe3 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.errors.txt +++ b/tests/baselines/reference/spreadInvalidArgumentType.errors.txt @@ -1,3 +1,4 @@ +tests/cases/compiler/spreadInvalidArgumentType.ts(33,16): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(34,16): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(39,16): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(42,17): error TS2698: Spread types may only be created from object types. @@ -10,7 +11,7 @@ tests/cases/compiler/spreadInvalidArgumentType.ts(53,17): error TS2698: Spread t tests/cases/compiler/spreadInvalidArgumentType.ts(55,17): error TS2698: Spread types may only be created from object types. -==== tests/cases/compiler/spreadInvalidArgumentType.ts (10 errors) ==== +==== tests/cases/compiler/spreadInvalidArgumentType.ts (11 errors) ==== enum E { v1, v2 }; function f(p1: T, p2: T[]) { @@ -43,7 +44,9 @@ tests/cases/compiler/spreadInvalidArgumentType.ts(55,17): error TS2698: Spread t var o1 = { ...p1 }; // OK, generic type paramterre var o2 = { ...p2 }; // OK var o3 = { ...t }; // OK, generic type paramter - var o4 = { ...i }; // OK, index access + var o4 = { ...i }; // Error, index access + ~~~~ +!!! error TS2698: Spread types may only be created from object types. var o5 = { ...k }; // Error, index ~~~~ !!! error TS2698: Spread types may only be created from object types. diff --git a/tests/baselines/reference/spreadInvalidArgumentType.js b/tests/baselines/reference/spreadInvalidArgumentType.js index b1cb2561eca..fc96c5971fb 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.js +++ b/tests/baselines/reference/spreadInvalidArgumentType.js @@ -31,7 +31,7 @@ function f(p1: T, p2: T[]) { var o1 = { ...p1 }; // OK, generic type paramterre var o2 = { ...p2 }; // OK var o3 = { ...t }; // OK, generic type paramter - var o4 = { ...i }; // OK, index access + var o4 = { ...i }; // Error, index access var o5 = { ...k }; // Error, index var o6 = { ...mapped_generic }; // OK, generic mapped object type var o7 = { ...mapped }; // OK, non-generic mapped type @@ -96,7 +96,7 @@ function f(p1, p2) { var o1 = __assign({}, p1); // OK, generic type paramterre var o2 = __assign({}, p2); // OK var o3 = __assign({}, t); // OK, generic type paramter - var o4 = __assign({}, i); // OK, index access + var o4 = __assign({}, i); // Error, index access var o5 = __assign({}, k); // Error, index var o6 = __assign({}, mapped_generic); // OK, generic mapped object type var o7 = __assign({}, mapped); // OK, non-generic mapped type diff --git a/tests/baselines/reference/spreadInvalidArgumentType.symbols b/tests/baselines/reference/spreadInvalidArgumentType.symbols index 8c29a923d37..f4d7af9cca8 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.symbols +++ b/tests/baselines/reference/spreadInvalidArgumentType.symbols @@ -94,7 +94,7 @@ function f(p1: T, p2: T[]) { >o3 : Symbol(o3, Decl(spreadInvalidArgumentType.ts, 31, 7)) >t : Symbol(t, Decl(spreadInvalidArgumentType.ts, 3, 7)) - var o4 = { ...i }; // OK, index access + var o4 = { ...i }; // Error, index access >o4 : Symbol(o4, Decl(spreadInvalidArgumentType.ts, 32, 7)) >i : Symbol(i, Decl(spreadInvalidArgumentType.ts, 5, 7)) diff --git a/tests/baselines/reference/spreadInvalidArgumentType.types b/tests/baselines/reference/spreadInvalidArgumentType.types index 8a833c966ff..ec1b7faa9ec 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.types +++ b/tests/baselines/reference/spreadInvalidArgumentType.types @@ -82,9 +82,9 @@ function f(p1: T, p2: T[]) { >{ ...t } : T >t : T - var o4 = { ...i }; // OK, index access ->o4 : T["b"] ->{ ...i } : T["b"] + var o4 = { ...i }; // Error, index access +>o4 : any +>{ ...i } : any >i : T["b"] var o5 = { ...k }; // Error, index diff --git a/tests/baselines/reference/spreadTypeVariable.errors.txt b/tests/baselines/reference/spreadTypeVariable.errors.txt new file mode 100644 index 00000000000..b3ac4188670 --- /dev/null +++ b/tests/baselines/reference/spreadTypeVariable.errors.txt @@ -0,0 +1,37 @@ +tests/cases/conformance/types/spread/spreadTypeVariable.ts(2,12): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/spreadTypeVariable.ts(10,12): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/spreadTypeVariable.ts(14,12): error TS2698: Spread types may only be created from object types. + + +==== tests/cases/conformance/types/spread/spreadTypeVariable.ts (3 errors) ==== + function f1(arg: T) { + return { ...arg }; + ~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + } + + function f2(arg: T) { + return { ...arg } + } + + function f3(arg: T) { + return { ...arg } + ~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + } + + function f4(arg: T) { + return { ...arg } + ~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + } + + function f5(arg: T) { + return { ...arg } + } + + function f6(arg: T) { + return { ...arg } + } + + \ No newline at end of file diff --git a/tests/baselines/reference/spreadTypeVariable.js b/tests/baselines/reference/spreadTypeVariable.js new file mode 100644 index 00000000000..7574faab99e --- /dev/null +++ b/tests/baselines/reference/spreadTypeVariable.js @@ -0,0 +1,57 @@ +//// [spreadTypeVariable.ts] +function f1(arg: T) { + return { ...arg }; +} + +function f2(arg: T) { + return { ...arg } +} + +function f3(arg: T) { + return { ...arg } +} + +function f4(arg: T) { + return { ...arg } +} + +function f5(arg: T) { + return { ...arg } +} + +function f6(arg: T) { + return { ...arg } +} + + + +//// [spreadTypeVariable.js] +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +function f1(arg) { + return __assign({}, arg); +} +function f2(arg) { + return __assign({}, arg); +} +function f3(arg) { + return __assign({}, arg); +} +function f4(arg) { + return __assign({}, arg); +} +function f5(arg) { + return __assign({}, arg); +} +function f6(arg) { + return __assign({}, arg); +} diff --git a/tests/baselines/reference/spreadTypeVariable.symbols b/tests/baselines/reference/spreadTypeVariable.symbols new file mode 100644 index 00000000000..dee763309a0 --- /dev/null +++ b/tests/baselines/reference/spreadTypeVariable.symbols @@ -0,0 +1,64 @@ +=== tests/cases/conformance/types/spread/spreadTypeVariable.ts === +function f1(arg: T) { +>f1 : Symbol(f1, Decl(spreadTypeVariable.ts, 0, 0)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 0, 12)) +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 0, 30)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 0, 12)) + + return { ...arg }; +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 0, 30)) +} + +function f2(arg: T) { +>f2 : Symbol(f2, Decl(spreadTypeVariable.ts, 2, 1)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 4, 12)) +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 4, 32)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 4, 12)) + + return { ...arg } +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 4, 32)) +} + +function f3(arg: T) { +>f3 : Symbol(f3, Decl(spreadTypeVariable.ts, 6, 1)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 8, 12)) +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 8, 41)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 8, 12)) + + return { ...arg } +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 8, 41)) +} + +function f4(arg: T) { +>f4 : Symbol(f4, Decl(spreadTypeVariable.ts, 10, 1)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 12, 12)) +>key : Symbol(key, Decl(spreadTypeVariable.ts, 12, 34)) +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 12, 55)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 12, 12)) + + return { ...arg } +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 12, 55)) +} + +function f5(arg: T) { +>f5 : Symbol(f5, Decl(spreadTypeVariable.ts, 14, 1)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 16, 12)) +>key : Symbol(key, Decl(spreadTypeVariable.ts, 16, 36)) +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 16, 57)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 16, 12)) + + return { ...arg } +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 16, 57)) +} + +function f6(arg: T) { +>f6 : Symbol(f6, Decl(spreadTypeVariable.ts, 18, 1)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 20, 12)) +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 20, 15)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 20, 12)) + + return { ...arg } +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 20, 15)) +} + + diff --git a/tests/baselines/reference/spreadTypeVariable.types b/tests/baselines/reference/spreadTypeVariable.types new file mode 100644 index 00000000000..c5de712fb19 --- /dev/null +++ b/tests/baselines/reference/spreadTypeVariable.types @@ -0,0 +1,58 @@ +=== tests/cases/conformance/types/spread/spreadTypeVariable.ts === +function f1(arg: T) { +>f1 : (arg: T) => any +>arg : T + + return { ...arg }; +>{ ...arg } : any +>arg : T +} + +function f2(arg: T) { +>f2 : (arg: T) => T +>arg : T + + return { ...arg } +>{ ...arg } : T +>arg : T +} + +function f3(arg: T) { +>f3 : (arg: T) => any +>arg : T + + return { ...arg } +>{ ...arg } : any +>arg : T +} + +function f4(arg: T) { +>f4 : (arg: T) => any +>key : string +>arg : T + + return { ...arg } +>{ ...arg } : any +>arg : T +} + +function f5(arg: T) { +>f5 : (arg: T) => T +>key : string +>arg : T + + return { ...arg } +>{ ...arg } : T +>arg : T +} + +function f6(arg: T) { +>f6 : (arg: T) => T +>arg : T + + return { ...arg } +>{ ...arg } : T +>arg : T +} + + diff --git a/tests/cases/compiler/spreadInvalidArgumentType.ts b/tests/cases/compiler/spreadInvalidArgumentType.ts index d75d606cc73..82e59fbac59 100644 --- a/tests/cases/compiler/spreadInvalidArgumentType.ts +++ b/tests/cases/compiler/spreadInvalidArgumentType.ts @@ -30,7 +30,7 @@ function f(p1: T, p2: T[]) { var o1 = { ...p1 }; // OK, generic type paramterre var o2 = { ...p2 }; // OK var o3 = { ...t }; // OK, generic type paramter - var o4 = { ...i }; // OK, index access + var o4 = { ...i }; // Error, index access var o5 = { ...k }; // Error, index var o6 = { ...mapped_generic }; // OK, generic mapped object type var o7 = { ...mapped }; // OK, non-generic mapped type diff --git a/tests/cases/conformance/types/spread/spreadTypeVariable.ts b/tests/cases/conformance/types/spread/spreadTypeVariable.ts new file mode 100644 index 00000000000..7a0054cfc86 --- /dev/null +++ b/tests/cases/conformance/types/spread/spreadTypeVariable.ts @@ -0,0 +1,24 @@ +function f1(arg: T) { + return { ...arg }; +} + +function f2(arg: T) { + return { ...arg } +} + +function f3(arg: T) { + return { ...arg } +} + +function f4(arg: T) { + return { ...arg } +} + +function f5(arg: T) { + return { ...arg } +} + +function f6(arg: T) { + return { ...arg } +} + From d17e662bca3701f3be6e0d5c461894ad3511eaa9 Mon Sep 17 00:00:00 2001 From: Yuya Tanaka Date: Mon, 13 May 2019 16:45:56 +0900 Subject: [PATCH 003/182] Fix outdated comments for unknown type --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 64834befee1..42e5dc91e63 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7474,7 +7474,7 @@ namespace ts { else { // Otherwise, get the declared constraint type, and if the constraint type is a type parameter, // get the constraint of that type parameter. If the resulting type is an indexed type 'keyof T', - // the modifiers type is T. Otherwise, the modifiers type is {}. + // the modifiers type is T. Otherwise, the modifiers type is unknown. const declaredType = getTypeFromMappedTypeNode(type.declaration); const constraint = getConstraintTypeFromMappedType(declaredType); const extendedConstraint = constraint && constraint.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(constraint) : constraint; @@ -22570,7 +22570,7 @@ namespace ts { links.type = contextualType; const decl = parameter.valueDeclaration as ParameterDeclaration; if (decl.name.kind !== SyntaxKind.Identifier) { - // if inference didn't come up with anything but {}, fall back to the binding pattern if present. + // if inference didn't come up with anything but unknown, fall back to the binding pattern if present. if (links.type === unknownType) { links.type = getTypeFromBindingPattern(decl.name); } From f1a0a7f863a0b247471626a0188c42c59ddbe18e Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Mon, 17 Jun 2019 13:30:07 -0700 Subject: [PATCH 004/182] Don't let the additional property setting on an object show up as a definition for the lanmguage server --- src/services/goToDefinition.ts | 12 ++++++++---- .../goToDefinitionPropertyAssignment.ts | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 tests/cases/fourslash/goToDefinitionPropertyAssignment.ts diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 8f495aadfe1..19959871500 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -26,7 +26,7 @@ namespace ts.GoToDefinition { if (!symbol) { return getDefinitionInfoForIndexSignatures(node, typeChecker); } - + const calledDeclaration = tryGetSignatureDeclaration(typeChecker, node); // Don't go to the component constructor definition for a JSX element, just go to the component definition. if (calledDeclaration && !(isJsxOpeningLikeElement(node.parent) && isConstructorLike(calledDeclaration))) { @@ -233,20 +233,24 @@ namespace ts.GoToDefinition { } function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node): DefinitionInfo[] | undefined { - return getConstructSignatureDefinition() || getCallSignatureDefinition() || map(symbol.declarations, declaration => createDefinitionInfo(declaration, typeChecker, symbol, node)); + // There are cases when you extend a function by adding properties to it afterwards, + // we want to strip those extra properties + const filteredDeclarations = symbol.declarations.filter(d => !ts.isAssignmentDeclaration(d) || d === symbol.valueDeclaration) + + return getConstructSignatureDefinition() || getCallSignatureDefinition() || map(filteredDeclarations, declaration => createDefinitionInfo(declaration, typeChecker, symbol, node)); function getConstructSignatureDefinition(): DefinitionInfo[] | undefined { // Applicable only if we are in a new expression, or we are on a constructor declaration // and in either case the symbol has a construct signature definition, i.e. class if (symbol.flags & SymbolFlags.Class && (isNewExpressionTarget(node) || node.kind === SyntaxKind.ConstructorKeyword)) { - const cls = find(symbol.declarations, isClassLike) || Debug.fail("Expected declaration to have at least one class-like declaration"); + const cls = find(filteredDeclarations, isClassLike) || Debug.fail("Expected declaration to have at least one class-like declaration"); return getSignatureDefinition(cls.members, /*selectConstructors*/ true); } } function getCallSignatureDefinition(): DefinitionInfo[] | undefined { return isCallOrNewExpressionTarget(node) || isNameOfFunctionDeclaration(node) - ? getSignatureDefinition(symbol.declarations, /*selectConstructors*/ false) + ? getSignatureDefinition(filteredDeclarations, /*selectConstructors*/ false) : undefined; } diff --git a/tests/cases/fourslash/goToDefinitionPropertyAssignment.ts b/tests/cases/fourslash/goToDefinitionPropertyAssignment.ts new file mode 100644 index 00000000000..5da8604f548 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionPropertyAssignment.ts @@ -0,0 +1,16 @@ +/// + +//// export const /*FunctionResult*/Component = () => { return "OK"} +//// Component./*PropertyResult*/displayName = 'Component' +//// +//// [|/*FunctionClick*/Component|] +//// +//// Component.[|/*PropertyClick*/displayName|] + +verify.goToDefinition("FunctionClick", "FunctionResult") + +verify.goToDefinition("PropertyClick", "PropertyResult") + +// export const Component = () => { return "OK"} +// Component.displayName = 'Component' + From 6b33dda121e98b9b64e5d04f5f5828c4cddb5168 Mon Sep 17 00:00:00 2001 From: sisisin Date: Wed, 19 Jun 2019 19:08:01 +0900 Subject: [PATCH 005/182] chore(tsserver): fix typo --- src/services/importTracker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index 2734d059000..7724292d444 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -434,7 +434,7 @@ namespace ts.FindAllReferences { /** * Given a local reference, we might notice that it's an import/export and recursively search for references of that. * If at an import, look locally for the symbol it imports. - * If an an export, look for all imports of it. + * If at an export, look for all imports of it. * This doesn't handle export specifiers; that is done in `getReferencesAtExportSpecifier`. * @param comingFromExport If we are doing a search for all exports, don't bother looking backwards for the imported symbol, since that's the reason we're here. */ From ddbf7e198d8a01967f2d20366dfeb8ad07a28543 Mon Sep 17 00:00:00 2001 From: 0verk1ll Date: Wed, 17 Jul 2019 16:57:25 -0400 Subject: [PATCH 006/182] Add Semicolons to Gulpfile.js --- Gulpfile.js | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Gulpfile.js b/Gulpfile.js index 42987e4fd8d..d5c40a1625d 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -41,7 +41,7 @@ const generateLibs = () => { .pipe(concat(relativeTarget, { newLine: "\n\n" })) .pipe(dest("built/local")))); }; -task("lib", generateLibs) +task("lib", generateLibs); task("lib").description = "Builds the library targets"; const cleanLib = () => del(libs.map(lib => lib.target)); @@ -168,7 +168,7 @@ task("services", series(preBuild, buildServices)); task("services").description = "Builds the language service"; task("services").flags = { " --built": "Compile using the built version of the compiler." -} +}; const cleanServices = async () => { if (fs.existsSync("built/local/typescriptServices.tsconfig.json")) { @@ -200,14 +200,14 @@ task("watch-services", series(preBuild, parallel(watchLib, watchDiagnostics, wat task("watch-services").description = "Watches for changes and rebuild language service only"; task("watch-services").flags = { " --built": "Compile using the built version of the compiler." -} +}; const buildServer = () => buildProject("src/tsserver", cmdLineOptions); task("tsserver", series(preBuild, buildServer)); task("tsserver").description = "Builds the language server"; task("tsserver").flags = { " --built": "Compile using the built version of the compiler." -} +}; const cleanServer = () => cleanProject("src/tsserver"); cleanTasks.push(cleanServer); @@ -219,13 +219,13 @@ task("watch-tsserver", series(preBuild, parallel(watchLib, watchDiagnostics, wat task("watch-tsserver").description = "Watch for changes and rebuild the language server only"; task("watch-tsserver").flags = { " --built": "Compile using the built version of the compiler." -} +}; task("min", series(preBuild, parallel(buildTsc, buildServer))); task("min").description = "Builds only tsc and tsserver"; task("min").flags = { " --built": "Compile using the built version of the compiler." -} +}; task("clean-min", series(cleanTsc, cleanServer)); task("clean-min").description = "Cleans outputs for tsc and tsserver"; @@ -234,7 +234,7 @@ task("watch-min", series(preBuild, parallel(watchLib, watchDiagnostics, watchTsc task("watch-min").description = "Watches for changes to a tsc and tsserver only"; task("watch-min").flags = { " --built": "Compile using the built version of the compiler." -} +}; const buildLssl = (() => { // build tsserverlibrary.out.js @@ -268,7 +268,7 @@ task("lssl", series(preBuild, buildLssl)); task("lssl").description = "Builds language service server library"; task("lssl").flags = { " --built": "Compile using the built version of the compiler." -} +}; const cleanLssl = async () => { if (fs.existsSync("built/local/tsserverlibrary.tsconfig.json")) { @@ -302,14 +302,14 @@ task("watch-lssl", series(preBuild, parallel(watchLib, watchDiagnostics, watchLs task("watch-lssl").description = "Watch for changes and rebuild tsserverlibrary only"; task("watch-lssl").flags = { " --built": "Compile using the built version of the compiler." -} +}; const buildTests = () => buildProject("src/testRunner"); task("tests", series(preBuild, parallel(buildLssl, buildTests))); task("tests").description = "Builds the test infrastructure"; task("tests").flags = { " --built": "Compile using the built version of the compiler." -} +}; const cleanTests = () => cleanProject("src/testRunner"); cleanTasks.push(cleanTests); @@ -381,13 +381,13 @@ task("local", series(buildFoldStart, preBuild, parallel(localize, buildTsc, buil task("local").description = "Builds the full compiler and services"; task("local").flags = { " --built": "Compile using the built version of the compiler." -} +}; task("watch-local", series(preBuild, parallel(watchLib, watchDiagnostics, watchTsc, watchServices, watchServer, watchLssl))); task("watch-local").description = "Watches for changes to projects in src/ (but does not execute tests)."; task("watch-local").flags = { " --built": "Compile using the built version of the compiler." -} +}; const generateCodeCoverage = () => exec("istanbul", ["cover", "node_modules/mocha/bin/_mocha", "--", "-R", "min", "-t", "" + cmdLineOptions.testTimeout, "built/local/run.js"]); task("generate-code-coverage", series(preBuild, buildTests, generateCodeCoverage)); @@ -417,7 +417,7 @@ task("runtests").flags = { " --built": "Compile using the built version of the compiler.", " --shards": "Total number of shards running tests (default: 1)", " --shardId": "1-based ID of this shard (default: 1)", -} +}; const runTestsParallel = () => runConsoleTests("built/local/run.js", "min", /*runInParallel*/ true, /*watchMode*/ false); task("runtests-parallel", series(preBuild, preTest, runTestsParallel, postTest)); @@ -478,7 +478,7 @@ task("tsc-instrumented", series(lkgPreBuild, parallel(localize, buildTsc, buildS task("tsc-instrumented").description = "Builds an instrumented tsc.js"; task("tsc-instrumented").flags = { "-t --tests=": "The test to run." -} +}; // TODO(rbuckton): Determine if we still need this task. Depending on a relative // path here seems like a bad idea. @@ -533,7 +533,7 @@ task("LKG", series(lkgPreBuild, parallel(localize, buildTsc, buildServer, buildS task("LKG").description = "Makes a new LKG out of the built js files"; task("LKG").flags = { " --built": "Compile using the built version of the compiler.", -} +}; const generateSpec = () => exec("cscript", ["//nologo", "scripts/word2md.js", path.resolve("doc/TypeScript Language Specification.docx"), path.resolve("doc/spec.md")]); task("generate-spec", series(buildScripts, generateSpec)); @@ -542,15 +542,15 @@ task("generate-spec").description = "Generates a Markdown version of the Languag task("clean", series(parallel(cleanTasks), cleanBuilt)); task("clean").description = "Cleans build outputs"; -const configureNightly = () => exec(process.execPath, ["scripts/configurePrerelease.js", "dev", "package.json", "src/compiler/core.ts"]) +const configureNightly = () => exec(process.execPath, ["scripts/configurePrerelease.js", "dev", "package.json", "src/compiler/core.ts"]); task("configure-nightly", series(buildScripts, configureNightly)); task("configure-nightly").description = "Runs scripts/configurePrerelease.ts to prepare a build for nightly publishing"; -const configureInsiders = () => exec(process.execPath, ["scripts/configurePrerelease.js", "insiders", "package.json", "src/compiler/core.ts"]) +const configureInsiders = () => exec(process.execPath, ["scripts/configurePrerelease.js", "insiders", "package.json", "src/compiler/core.ts"]); task("configure-insiders", series(buildScripts, configureInsiders)); task("configure-insiders").description = "Runs scripts/configurePrerelease.ts to prepare a build for insiders publishing"; -const configureExperimental = () => exec(process.execPath, ["scripts/configurePrerelease.js", "experimental", "package.json", "src/compiler/core.ts"]) +const configureExperimental = () => exec(process.execPath, ["scripts/configurePrerelease.js", "experimental", "package.json", "src/compiler/core.ts"]); task("configure-experimental", series(buildScripts, configureExperimental)); task("configure-experimental").description = "Runs scripts/configurePrerelease.ts to prepare a build for experimental publishing"; From 395d1515eeefe5f52aab8a1365824bd0eba49215 Mon Sep 17 00:00:00 2001 From: "Salisbury, Tom" Date: Thu, 18 Jul 2019 12:32:43 +0100 Subject: [PATCH 007/182] #32458 stop ES5 __values with no Symbol.iterator getting stuck in loop --- src/compiler/factory.ts | 7 +- src/testRunner/tsconfig.json | 1 + src/testRunner/unittests/evaluation/forOf.ts | 119 ++++++++++++++++++ tests/baselines/reference/ES5For-of33.js | 7 +- tests/baselines/reference/ES5For-of33.js.map | 2 +- .../reference/ES5For-of33.sourcemap.txt | 63 +++++----- tests/baselines/reference/ES5For-of34.js | 7 +- tests/baselines/reference/ES5For-of34.js.map | 2 +- .../reference/ES5For-of34.sourcemap.txt | 95 +++++++------- tests/baselines/reference/ES5For-of35.js | 7 +- tests/baselines/reference/ES5For-of35.js.map | 2 +- .../reference/ES5For-of35.sourcemap.txt | 69 +++++----- tests/baselines/reference/ES5For-of36.js | 7 +- tests/baselines/reference/ES5For-of36.js.map | 2 +- .../reference/ES5For-of36.sourcemap.txt | 69 +++++----- tests/baselines/reference/ES5For-of37.js | 7 +- ...blockScopedBindingsInDownlevelGenerator.js | 7 +- ...mitter.asyncGenerators.classMethods.es5.js | 14 ++- ...syncGenerators.functionDeclarations.es5.js | 14 ++- ...asyncGenerators.functionExpressions.es5.js | 14 ++- ...syncGenerators.objectLiteralMethods.es5.js | 14 ++- ...eclarationBindingPatterns01_ES5iterable.js | 7 +- 22 files changed, 338 insertions(+), 198 deletions(-) create mode 100644 src/testRunner/unittests/evaluation/forOf.ts diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 1f0294423a5..82b4a3fb59f 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -3636,15 +3636,16 @@ namespace ts { name: "typescript:values", scoped: false, text: ` - var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; + var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); };` }; diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index 659dd426b79..d69feffb787 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -75,6 +75,7 @@ "unittests/evaluation/asyncGenerator.ts", "unittests/evaluation/awaiter.ts", "unittests/evaluation/forAwaitOf.ts", + "unittests/evaluation/forOf.ts", "unittests/evaluation/objectRest.ts", "unittests/services/cancellableLanguageServiceOperations.ts", "unittests/services/colorization.ts", diff --git a/src/testRunner/unittests/evaluation/forOf.ts b/src/testRunner/unittests/evaluation/forOf.ts new file mode 100644 index 00000000000..3d9352cf926 --- /dev/null +++ b/src/testRunner/unittests/evaluation/forOf.ts @@ -0,0 +1,119 @@ +describe("unittests:: evaluation:: forOfEvaluation", () => { + it("es5 over a array with no Symbol", () => { + const result = evaluator.evaluateTypeScript(` + Symbol = undefined; + export var output = []; + export function main() { + let x = [1,2,3]; + + for (let value of x) { + output.push(value); + } + } + `, { downlevelIteration: true, target: ts.ScriptTarget.ES5 }); + + result.main(); + + assert.strictEqual(result.output[0], 1); + assert.strictEqual(result.output[1], 2); + assert.strictEqual(result.output[2], 3); + + }); + + it("es5 over a string with no Symbol", () => { + const result = evaluator.evaluateTypeScript(` + Symbol = undefined; + export var output = []; + export function main() { + let x = "hello"; + + for (let value of x) { + output.push(value); + } + } + `, { downlevelIteration: true, target: ts.ScriptTarget.ES5 }); + + result.main(); + + assert.strictEqual(result.output[0], "h"); + assert.strictEqual(result.output[1], "e"); + assert.strictEqual(result.output[2], "l"); + assert.strictEqual(result.output[3], "l"); + assert.strictEqual(result.output[4], "o"); + }); + + it("es5 over undefined with no Symbol", () => { + const result = evaluator.evaluateTypeScript(` + Symbol = undefined; + export function main() { + let x = undefined; + + for (let value of x) { + } + } + `, { downlevelIteration: true, target: ts.ScriptTarget.ES5 }); + + assert.throws(() => result.main(), "Symbol.iterator is not defined"); + }); + + it("es5 over undefined with Symbol", () => { + const result = evaluator.evaluateTypeScript(` + export function main() { + let x = undefined; + + for (let value of x) { + } + } + `, { downlevelIteration: true, target: ts.ScriptTarget.ES5 }); + + assert.throws(() => result.main(), "undefined is not iterable (cannot read property Symbol(Symbol.iterator))"); + }); + + it("es5 over object with no Symbol.iterator with no Symbol", () => { + const result = evaluator.evaluateTypeScript(` + Symbol = undefined; + export function main() { + let x = {} as any; + + for (let value of x) { + } + } + `, { downlevelIteration: true, target: ts.ScriptTarget.ES5 }); + + assert.throws(() => result.main(), "Symbol.iterator is not defined"); + }); + + it("es5 over object with no Symbol.iterator with Symbol", () => { + const result = evaluator.evaluateTypeScript(` + export function main() { + let x = {} as any; + + for (let value of x) { + } + } + `, { downlevelIteration: true, target: ts.ScriptTarget.ES5 }); + + assert.throws(() => result.main(), "Object not iterable"); + }); + + it("es5 over object with Symbol.iterator", () => { + const result = evaluator.evaluateTypeScript(` + export var output = []; + export function main() { + let thing : any = {}; + thing[Symbol.iterator] = () => { + let i = 0; + return { next() { i++; return this; }, value: i, done: i < 10 }; + }; + + for (let value of thing) + { + output.push(value) + } + + }`, { downlevelIteration: true, target: ts.ScriptTarget.ES5 }); + + result.main(); + }); + +}); \ No newline at end of file diff --git a/tests/baselines/reference/ES5For-of33.js b/tests/baselines/reference/ES5For-of33.js index 8a7bacbf52d..900f32b6407 100644 --- a/tests/baselines/reference/ES5For-of33.js +++ b/tests/baselines/reference/ES5For-of33.js @@ -4,15 +4,16 @@ for (var v of ['a', 'b', 'c']) { } //// [ES5For-of33.js] -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; var e_1, _a; try { diff --git a/tests/baselines/reference/ES5For-of33.js.map b/tests/baselines/reference/ES5For-of33.js.map index c2a28ecec79..368ef47a3f5 100644 --- a/tests/baselines/reference/ES5For-of33.js.map +++ b/tests/baselines/reference/ES5For-of33.js.map @@ -1,2 +1,2 @@ //// [ES5For-of33.js.map] -{"version":3,"file":"ES5For-of33.js","sourceRoot":"","sources":["ES5For-of33.ts"],"names":[],"mappings":";;;;;;;;;;;;IAAA,KAAc,IAAA,KAAA,SAAA,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA,gBAAA,4BAAE;QAA1B,IAAI,CAAC,WAAA;QACN,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;KAClB"} \ No newline at end of file +{"version":3,"file":"ES5For-of33.js","sourceRoot":"","sources":["ES5For-of33.ts"],"names":[],"mappings":";;;;;;;;;;;;;IAAA,KAAc,IAAA,KAAA,SAAA,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA,gBAAA,4BAAE;QAA1B,IAAI,CAAC,WAAA;QACN,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;KAClB"} \ No newline at end of file diff --git a/tests/baselines/reference/ES5For-of33.sourcemap.txt b/tests/baselines/reference/ES5For-of33.sourcemap.txt index 8438d558c74..f6be2e8fb11 100644 --- a/tests/baselines/reference/ES5For-of33.sourcemap.txt +++ b/tests/baselines/reference/ES5For-of33.sourcemap.txt @@ -8,15 +8,16 @@ sources: ES5For-of33.ts emittedFile:tests/cases/conformance/statements/for-ofStatements/ES5For-of33.js sourceFile:ES5For-of33.ts ------------------------------------------------------------------- ->>>var __values = (this && this.__values) || function (o) { ->>> var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +>>>var __values = (this && this.__values) || function(o) { +>>> var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; >>> if (m) return m.call(o); ->>> return { +>>> if (o && typeof o.length === "number") return { >>> next: function () { >>> if (o && i >= o.length) o = void 0; >>> return { value: o && o[i++], done: !o }; >>> } >>> }; +>>> throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); >>>}; >>>var e_1, _a; >>>try { @@ -51,21 +52,21 @@ sourceFile:ES5For-of33.ts 13> 14> 15> ) -1 >Emitted(13, 5) Source(1, 1) + SourceIndex(0) -2 >Emitted(13, 10) Source(1, 15) + SourceIndex(0) -3 >Emitted(13, 14) Source(1, 15) + SourceIndex(0) -4 >Emitted(13, 19) Source(1, 15) + SourceIndex(0) -5 >Emitted(13, 28) Source(1, 15) + SourceIndex(0) -6 >Emitted(13, 29) Source(1, 16) + SourceIndex(0) -7 >Emitted(13, 32) Source(1, 19) + SourceIndex(0) -8 >Emitted(13, 34) Source(1, 21) + SourceIndex(0) -9 >Emitted(13, 37) Source(1, 24) + SourceIndex(0) -10>Emitted(13, 39) Source(1, 26) + SourceIndex(0) -11>Emitted(13, 42) Source(1, 29) + SourceIndex(0) -12>Emitted(13, 43) Source(1, 30) + SourceIndex(0) -13>Emitted(13, 44) Source(1, 30) + SourceIndex(0) -14>Emitted(13, 60) Source(1, 30) + SourceIndex(0) -15>Emitted(13, 88) Source(1, 32) + SourceIndex(0) +1 >Emitted(14, 5) Source(1, 1) + SourceIndex(0) +2 >Emitted(14, 10) Source(1, 15) + SourceIndex(0) +3 >Emitted(14, 14) Source(1, 15) + SourceIndex(0) +4 >Emitted(14, 19) Source(1, 15) + SourceIndex(0) +5 >Emitted(14, 28) Source(1, 15) + SourceIndex(0) +6 >Emitted(14, 29) Source(1, 16) + SourceIndex(0) +7 >Emitted(14, 32) Source(1, 19) + SourceIndex(0) +8 >Emitted(14, 34) Source(1, 21) + SourceIndex(0) +9 >Emitted(14, 37) Source(1, 24) + SourceIndex(0) +10>Emitted(14, 39) Source(1, 26) + SourceIndex(0) +11>Emitted(14, 42) Source(1, 29) + SourceIndex(0) +12>Emitted(14, 43) Source(1, 30) + SourceIndex(0) +13>Emitted(14, 44) Source(1, 30) + SourceIndex(0) +14>Emitted(14, 60) Source(1, 30) + SourceIndex(0) +15>Emitted(14, 88) Source(1, 32) + SourceIndex(0) --- >>> var v = _c.value; 1 >^^^^^^^^ @@ -76,10 +77,10 @@ sourceFile:ES5For-of33.ts 2 > var 3 > v 4 > -1 >Emitted(14, 9) Source(1, 6) + SourceIndex(0) -2 >Emitted(14, 13) Source(1, 10) + SourceIndex(0) -3 >Emitted(14, 14) Source(1, 11) + SourceIndex(0) -4 >Emitted(14, 25) Source(1, 11) + SourceIndex(0) +1 >Emitted(15, 9) Source(1, 6) + SourceIndex(0) +2 >Emitted(15, 13) Source(1, 10) + SourceIndex(0) +3 >Emitted(15, 14) Source(1, 11) + SourceIndex(0) +4 >Emitted(15, 25) Source(1, 11) + SourceIndex(0) --- >>> console.log(v); 1 >^^^^^^^^ @@ -99,20 +100,20 @@ sourceFile:ES5For-of33.ts 6 > v 7 > ) 8 > ; -1 >Emitted(15, 9) Source(2, 5) + SourceIndex(0) -2 >Emitted(15, 16) Source(2, 12) + SourceIndex(0) -3 >Emitted(15, 17) Source(2, 13) + SourceIndex(0) -4 >Emitted(15, 20) Source(2, 16) + SourceIndex(0) -5 >Emitted(15, 21) Source(2, 17) + SourceIndex(0) -6 >Emitted(15, 22) Source(2, 18) + SourceIndex(0) -7 >Emitted(15, 23) Source(2, 19) + SourceIndex(0) -8 >Emitted(15, 24) Source(2, 20) + SourceIndex(0) +1 >Emitted(16, 9) Source(2, 5) + SourceIndex(0) +2 >Emitted(16, 16) Source(2, 12) + SourceIndex(0) +3 >Emitted(16, 17) Source(2, 13) + SourceIndex(0) +4 >Emitted(16, 20) Source(2, 16) + SourceIndex(0) +5 >Emitted(16, 21) Source(2, 17) + SourceIndex(0) +6 >Emitted(16, 22) Source(2, 18) + SourceIndex(0) +7 >Emitted(16, 23) Source(2, 19) + SourceIndex(0) +8 >Emitted(16, 24) Source(2, 20) + SourceIndex(0) --- >>> } 1 >^^^^^ 1 > >} -1 >Emitted(16, 6) Source(3, 2) + SourceIndex(0) +1 >Emitted(17, 6) Source(3, 2) + SourceIndex(0) --- >>>} >>>catch (e_1_1) { e_1 = { error: e_1_1 }; } diff --git a/tests/baselines/reference/ES5For-of34.js b/tests/baselines/reference/ES5For-of34.js index 821cec60ee1..d4ab664d009 100644 --- a/tests/baselines/reference/ES5For-of34.js +++ b/tests/baselines/reference/ES5For-of34.js @@ -7,15 +7,16 @@ for (foo().x of ['a', 'b', 'c']) { } //// [ES5For-of34.js] -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; var e_1, _a; function foo() { diff --git a/tests/baselines/reference/ES5For-of34.js.map b/tests/baselines/reference/ES5For-of34.js.map index 6bf7fd0baed..9535e73615c 100644 --- a/tests/baselines/reference/ES5For-of34.js.map +++ b/tests/baselines/reference/ES5For-of34.js.map @@ -1,2 +1,2 @@ //// [ES5For-of34.js.map] -{"version":3,"file":"ES5For-of34.js","sourceRoot":"","sources":["ES5For-of34.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,SAAS,GAAG;IACR,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACpB,CAAC;;IACD,KAAgB,IAAA,KAAA,SAAA,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA,gBAAA,4BAAE;QAA5B,GAAG,EAAE,CAAC,CAAC,WAAA;QACR,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;KACnB"} \ No newline at end of file +{"version":3,"file":"ES5For-of34.js","sourceRoot":"","sources":["ES5For-of34.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,SAAS,GAAG;IACR,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACpB,CAAC;;IACD,KAAgB,IAAA,KAAA,SAAA,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA,gBAAA,4BAAE;QAA5B,GAAG,EAAE,CAAC,CAAC,WAAA;QACR,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;KACnB"} \ No newline at end of file diff --git a/tests/baselines/reference/ES5For-of34.sourcemap.txt b/tests/baselines/reference/ES5For-of34.sourcemap.txt index 06e93f578e2..e64aa5cdb8c 100644 --- a/tests/baselines/reference/ES5For-of34.sourcemap.txt +++ b/tests/baselines/reference/ES5For-of34.sourcemap.txt @@ -8,15 +8,16 @@ sources: ES5For-of34.ts emittedFile:tests/cases/conformance/statements/for-ofStatements/ES5For-of34.js sourceFile:ES5For-of34.ts ------------------------------------------------------------------- ->>>var __values = (this && this.__values) || function (o) { ->>> var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +>>>var __values = (this && this.__values) || function(o) { +>>> var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; >>> if (m) return m.call(o); ->>> return { +>>> if (o && typeof o.length === "number") return { >>> next: function () { >>> if (o && i >= o.length) o = void 0; >>> return { value: o && o[i++], done: !o }; >>> } >>> }; +>>> throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); >>>}; >>>var e_1, _a; >>>function foo() { @@ -27,9 +28,9 @@ sourceFile:ES5For-of34.ts 1 > 2 >function 3 > foo -1 >Emitted(12, 1) Source(1, 1) + SourceIndex(0) -2 >Emitted(12, 10) Source(1, 10) + SourceIndex(0) -3 >Emitted(12, 13) Source(1, 13) + SourceIndex(0) +1 >Emitted(13, 1) Source(1, 1) + SourceIndex(0) +2 >Emitted(13, 10) Source(1, 10) + SourceIndex(0) +3 >Emitted(13, 13) Source(1, 13) + SourceIndex(0) --- >>> return { x: 0 }; 1->^^^^ @@ -49,14 +50,14 @@ sourceFile:ES5For-of34.ts 6 > 0 7 > } 8 > ; -1->Emitted(13, 5) Source(2, 5) + SourceIndex(0) -2 >Emitted(13, 12) Source(2, 12) + SourceIndex(0) -3 >Emitted(13, 14) Source(2, 14) + SourceIndex(0) -4 >Emitted(13, 15) Source(2, 15) + SourceIndex(0) -5 >Emitted(13, 17) Source(2, 17) + SourceIndex(0) -6 >Emitted(13, 18) Source(2, 18) + SourceIndex(0) -7 >Emitted(13, 20) Source(2, 20) + SourceIndex(0) -8 >Emitted(13, 21) Source(2, 21) + SourceIndex(0) +1->Emitted(14, 5) Source(2, 5) + SourceIndex(0) +2 >Emitted(14, 12) Source(2, 12) + SourceIndex(0) +3 >Emitted(14, 14) Source(2, 14) + SourceIndex(0) +4 >Emitted(14, 15) Source(2, 15) + SourceIndex(0) +5 >Emitted(14, 17) Source(2, 17) + SourceIndex(0) +6 >Emitted(14, 18) Source(2, 18) + SourceIndex(0) +7 >Emitted(14, 20) Source(2, 20) + SourceIndex(0) +8 >Emitted(14, 21) Source(2, 21) + SourceIndex(0) --- >>>} 1 > @@ -65,8 +66,8 @@ sourceFile:ES5For-of34.ts 1 > > 2 >} -1 >Emitted(14, 1) Source(3, 1) + SourceIndex(0) -2 >Emitted(14, 2) Source(3, 2) + SourceIndex(0) +1 >Emitted(15, 1) Source(3, 1) + SourceIndex(0) +2 >Emitted(15, 2) Source(3, 2) + SourceIndex(0) --- >>>try { >>> for (var _b = __values(['a', 'b', 'c']), _c = _b.next(); !_c.done; _c = _b.next()) { @@ -101,21 +102,21 @@ sourceFile:ES5For-of34.ts 13> 14> 15> ) -1->Emitted(16, 5) Source(4, 1) + SourceIndex(0) -2 >Emitted(16, 10) Source(4, 17) + SourceIndex(0) -3 >Emitted(16, 14) Source(4, 17) + SourceIndex(0) -4 >Emitted(16, 19) Source(4, 17) + SourceIndex(0) -5 >Emitted(16, 28) Source(4, 17) + SourceIndex(0) -6 >Emitted(16, 29) Source(4, 18) + SourceIndex(0) -7 >Emitted(16, 32) Source(4, 21) + SourceIndex(0) -8 >Emitted(16, 34) Source(4, 23) + SourceIndex(0) -9 >Emitted(16, 37) Source(4, 26) + SourceIndex(0) -10>Emitted(16, 39) Source(4, 28) + SourceIndex(0) -11>Emitted(16, 42) Source(4, 31) + SourceIndex(0) -12>Emitted(16, 43) Source(4, 32) + SourceIndex(0) -13>Emitted(16, 44) Source(4, 32) + SourceIndex(0) -14>Emitted(16, 60) Source(4, 32) + SourceIndex(0) -15>Emitted(16, 88) Source(4, 34) + SourceIndex(0) +1->Emitted(17, 5) Source(4, 1) + SourceIndex(0) +2 >Emitted(17, 10) Source(4, 17) + SourceIndex(0) +3 >Emitted(17, 14) Source(4, 17) + SourceIndex(0) +4 >Emitted(17, 19) Source(4, 17) + SourceIndex(0) +5 >Emitted(17, 28) Source(4, 17) + SourceIndex(0) +6 >Emitted(17, 29) Source(4, 18) + SourceIndex(0) +7 >Emitted(17, 32) Source(4, 21) + SourceIndex(0) +8 >Emitted(17, 34) Source(4, 23) + SourceIndex(0) +9 >Emitted(17, 37) Source(4, 26) + SourceIndex(0) +10>Emitted(17, 39) Source(4, 28) + SourceIndex(0) +11>Emitted(17, 42) Source(4, 31) + SourceIndex(0) +12>Emitted(17, 43) Source(4, 32) + SourceIndex(0) +13>Emitted(17, 44) Source(4, 32) + SourceIndex(0) +14>Emitted(17, 60) Source(4, 32) + SourceIndex(0) +15>Emitted(17, 88) Source(4, 34) + SourceIndex(0) --- >>> foo().x = _c.value; 1 >^^^^^^^^ @@ -130,12 +131,12 @@ sourceFile:ES5For-of34.ts 4 > . 5 > x 6 > -1 >Emitted(17, 9) Source(4, 6) + SourceIndex(0) -2 >Emitted(17, 12) Source(4, 9) + SourceIndex(0) -3 >Emitted(17, 14) Source(4, 11) + SourceIndex(0) -4 >Emitted(17, 15) Source(4, 12) + SourceIndex(0) -5 >Emitted(17, 16) Source(4, 13) + SourceIndex(0) -6 >Emitted(17, 27) Source(4, 13) + SourceIndex(0) +1 >Emitted(18, 9) Source(4, 6) + SourceIndex(0) +2 >Emitted(18, 12) Source(4, 9) + SourceIndex(0) +3 >Emitted(18, 14) Source(4, 11) + SourceIndex(0) +4 >Emitted(18, 15) Source(4, 12) + SourceIndex(0) +5 >Emitted(18, 16) Source(4, 13) + SourceIndex(0) +6 >Emitted(18, 27) Source(4, 13) + SourceIndex(0) --- >>> var p = foo().x; 1 >^^^^^^^^ @@ -157,21 +158,21 @@ sourceFile:ES5For-of34.ts 7 > . 8 > x 9 > ; -1 >Emitted(18, 9) Source(5, 5) + SourceIndex(0) -2 >Emitted(18, 13) Source(5, 9) + SourceIndex(0) -3 >Emitted(18, 14) Source(5, 10) + SourceIndex(0) -4 >Emitted(18, 17) Source(5, 13) + SourceIndex(0) -5 >Emitted(18, 20) Source(5, 16) + SourceIndex(0) -6 >Emitted(18, 22) Source(5, 18) + SourceIndex(0) -7 >Emitted(18, 23) Source(5, 19) + SourceIndex(0) -8 >Emitted(18, 24) Source(5, 20) + SourceIndex(0) -9 >Emitted(18, 25) Source(5, 21) + SourceIndex(0) +1 >Emitted(19, 9) Source(5, 5) + SourceIndex(0) +2 >Emitted(19, 13) Source(5, 9) + SourceIndex(0) +3 >Emitted(19, 14) Source(5, 10) + SourceIndex(0) +4 >Emitted(19, 17) Source(5, 13) + SourceIndex(0) +5 >Emitted(19, 20) Source(5, 16) + SourceIndex(0) +6 >Emitted(19, 22) Source(5, 18) + SourceIndex(0) +7 >Emitted(19, 23) Source(5, 19) + SourceIndex(0) +8 >Emitted(19, 24) Source(5, 20) + SourceIndex(0) +9 >Emitted(19, 25) Source(5, 21) + SourceIndex(0) --- >>> } 1 >^^^^^ 1 > >} -1 >Emitted(19, 6) Source(6, 2) + SourceIndex(0) +1 >Emitted(20, 6) Source(6, 2) + SourceIndex(0) --- >>>} >>>catch (e_1_1) { e_1 = { error: e_1_1 }; } diff --git a/tests/baselines/reference/ES5For-of35.js b/tests/baselines/reference/ES5For-of35.js index 608ce967479..1158ae5ede1 100644 --- a/tests/baselines/reference/ES5For-of35.js +++ b/tests/baselines/reference/ES5For-of35.js @@ -5,15 +5,16 @@ for (const {x: a = 0, y: b = 1} of [2, 3]) { } //// [ES5For-of35.js] -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; var e_1, _a; try { diff --git a/tests/baselines/reference/ES5For-of35.js.map b/tests/baselines/reference/ES5For-of35.js.map index ca243e5bde5..ff69685616b 100644 --- a/tests/baselines/reference/ES5For-of35.js.map +++ b/tests/baselines/reference/ES5For-of35.js.map @@ -1,2 +1,2 @@ //// [ES5For-of35.js.map] -{"version":3,"file":"ES5For-of35.js","sourceRoot":"","sources":["ES5For-of35.ts"],"names":[],"mappings":";;;;;;;;;;;;IAAA,KAAmC,IAAA,KAAA,SAAA,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA,gBAAA,4BAAE;QAAhC,IAAA,aAAoB,EAAnB,SAAQ,EAAR,0BAAQ,EAAE,SAAQ,EAAR,0BAAQ;QAC1B,CAAC,CAAC;QACF,CAAC,CAAC;KACL"} \ No newline at end of file +{"version":3,"file":"ES5For-of35.js","sourceRoot":"","sources":["ES5For-of35.ts"],"names":[],"mappings":";;;;;;;;;;;;;IAAA,KAAmC,IAAA,KAAA,SAAA,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA,gBAAA,4BAAE;QAAhC,IAAA,aAAoB,EAAnB,SAAQ,EAAR,0BAAQ,EAAE,SAAQ,EAAR,0BAAQ;QAC1B,CAAC,CAAC;QACF,CAAC,CAAC;KACL"} \ No newline at end of file diff --git a/tests/baselines/reference/ES5For-of35.sourcemap.txt b/tests/baselines/reference/ES5For-of35.sourcemap.txt index 907fc3ce690..1cabb7af3b6 100644 --- a/tests/baselines/reference/ES5For-of35.sourcemap.txt +++ b/tests/baselines/reference/ES5For-of35.sourcemap.txt @@ -8,15 +8,16 @@ sources: ES5For-of35.ts emittedFile:tests/cases/conformance/statements/for-ofStatements/ES5For-of35.js sourceFile:ES5For-of35.ts ------------------------------------------------------------------- ->>>var __values = (this && this.__values) || function (o) { ->>> var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +>>>var __values = (this && this.__values) || function(o) { +>>> var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; >>> if (m) return m.call(o); ->>> return { +>>> if (o && typeof o.length === "number") return { >>> next: function () { >>> if (o && i >= o.length) o = void 0; >>> return { value: o && o[i++], done: !o }; >>> } >>> }; +>>> throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); >>>}; >>>var e_1, _a; >>>try { @@ -48,19 +49,19 @@ sourceFile:ES5For-of35.ts 11> 12> 13> ) -1 >Emitted(13, 5) Source(1, 1) + SourceIndex(0) -2 >Emitted(13, 10) Source(1, 36) + SourceIndex(0) -3 >Emitted(13, 14) Source(1, 36) + SourceIndex(0) -4 >Emitted(13, 19) Source(1, 36) + SourceIndex(0) -5 >Emitted(13, 28) Source(1, 36) + SourceIndex(0) -6 >Emitted(13, 29) Source(1, 37) + SourceIndex(0) -7 >Emitted(13, 30) Source(1, 38) + SourceIndex(0) -8 >Emitted(13, 32) Source(1, 40) + SourceIndex(0) -9 >Emitted(13, 33) Source(1, 41) + SourceIndex(0) -10>Emitted(13, 34) Source(1, 42) + SourceIndex(0) -11>Emitted(13, 35) Source(1, 42) + SourceIndex(0) -12>Emitted(13, 51) Source(1, 42) + SourceIndex(0) -13>Emitted(13, 79) Source(1, 44) + SourceIndex(0) +1 >Emitted(14, 5) Source(1, 1) + SourceIndex(0) +2 >Emitted(14, 10) Source(1, 36) + SourceIndex(0) +3 >Emitted(14, 14) Source(1, 36) + SourceIndex(0) +4 >Emitted(14, 19) Source(1, 36) + SourceIndex(0) +5 >Emitted(14, 28) Source(1, 36) + SourceIndex(0) +6 >Emitted(14, 29) Source(1, 37) + SourceIndex(0) +7 >Emitted(14, 30) Source(1, 38) + SourceIndex(0) +8 >Emitted(14, 32) Source(1, 40) + SourceIndex(0) +9 >Emitted(14, 33) Source(1, 41) + SourceIndex(0) +10>Emitted(14, 34) Source(1, 42) + SourceIndex(0) +11>Emitted(14, 35) Source(1, 42) + SourceIndex(0) +12>Emitted(14, 51) Source(1, 42) + SourceIndex(0) +13>Emitted(14, 79) Source(1, 44) + SourceIndex(0) --- >>> var _d = _c.value, _e = _d.x, a = _e === void 0 ? 0 : _e, _f = _d.y, b = _f === void 0 ? 1 : _f; 1->^^^^^^^^ @@ -85,17 +86,17 @@ sourceFile:ES5For-of35.ts 9 > y: b = 1 10> 11> y: b = 1 -1->Emitted(14, 9) Source(1, 12) + SourceIndex(0) -2 >Emitted(14, 13) Source(1, 12) + SourceIndex(0) -3 >Emitted(14, 26) Source(1, 32) + SourceIndex(0) -4 >Emitted(14, 28) Source(1, 13) + SourceIndex(0) -5 >Emitted(14, 37) Source(1, 21) + SourceIndex(0) -6 >Emitted(14, 39) Source(1, 13) + SourceIndex(0) -7 >Emitted(14, 65) Source(1, 21) + SourceIndex(0) -8 >Emitted(14, 67) Source(1, 23) + SourceIndex(0) -9 >Emitted(14, 76) Source(1, 31) + SourceIndex(0) -10>Emitted(14, 78) Source(1, 23) + SourceIndex(0) -11>Emitted(14, 104) Source(1, 31) + SourceIndex(0) +1->Emitted(15, 9) Source(1, 12) + SourceIndex(0) +2 >Emitted(15, 13) Source(1, 12) + SourceIndex(0) +3 >Emitted(15, 26) Source(1, 32) + SourceIndex(0) +4 >Emitted(15, 28) Source(1, 13) + SourceIndex(0) +5 >Emitted(15, 37) Source(1, 21) + SourceIndex(0) +6 >Emitted(15, 39) Source(1, 13) + SourceIndex(0) +7 >Emitted(15, 65) Source(1, 21) + SourceIndex(0) +8 >Emitted(15, 67) Source(1, 23) + SourceIndex(0) +9 >Emitted(15, 76) Source(1, 31) + SourceIndex(0) +10>Emitted(15, 78) Source(1, 23) + SourceIndex(0) +11>Emitted(15, 104) Source(1, 31) + SourceIndex(0) --- >>> a; 1 >^^^^^^^^ @@ -106,9 +107,9 @@ sourceFile:ES5For-of35.ts > 2 > a 3 > ; -1 >Emitted(15, 9) Source(2, 5) + SourceIndex(0) -2 >Emitted(15, 10) Source(2, 6) + SourceIndex(0) -3 >Emitted(15, 11) Source(2, 7) + SourceIndex(0) +1 >Emitted(16, 9) Source(2, 5) + SourceIndex(0) +2 >Emitted(16, 10) Source(2, 6) + SourceIndex(0) +3 >Emitted(16, 11) Source(2, 7) + SourceIndex(0) --- >>> b; 1->^^^^^^^^ @@ -118,15 +119,15 @@ sourceFile:ES5For-of35.ts > 2 > b 3 > ; -1->Emitted(16, 9) Source(3, 5) + SourceIndex(0) -2 >Emitted(16, 10) Source(3, 6) + SourceIndex(0) -3 >Emitted(16, 11) Source(3, 7) + SourceIndex(0) +1->Emitted(17, 9) Source(3, 5) + SourceIndex(0) +2 >Emitted(17, 10) Source(3, 6) + SourceIndex(0) +3 >Emitted(17, 11) Source(3, 7) + SourceIndex(0) --- >>> } 1 >^^^^^ 1 > >} -1 >Emitted(17, 6) Source(4, 2) + SourceIndex(0) +1 >Emitted(18, 6) Source(4, 2) + SourceIndex(0) --- >>>} >>>catch (e_1_1) { e_1 = { error: e_1_1 }; } diff --git a/tests/baselines/reference/ES5For-of36.js b/tests/baselines/reference/ES5For-of36.js index 5d53b241466..f08a178256d 100644 --- a/tests/baselines/reference/ES5For-of36.js +++ b/tests/baselines/reference/ES5For-of36.js @@ -5,15 +5,16 @@ for (let [a = 0, b = 1] of [2, 3]) { } //// [ES5For-of36.js] -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; diff --git a/tests/baselines/reference/ES5For-of36.js.map b/tests/baselines/reference/ES5For-of36.js.map index 09fdb4fd820..9ea2aa31df2 100644 --- a/tests/baselines/reference/ES5For-of36.js.map +++ b/tests/baselines/reference/ES5For-of36.js.map @@ -1,2 +1,2 @@ //// [ES5For-of36.js.map] -{"version":3,"file":"ES5For-of36.js","sourceRoot":"","sources":["ES5For-of36.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAA,KAA2B,IAAA,KAAA,SAAA,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA,gBAAA,4BAAE;QAA1B,IAAA,wBAAc,EAAb,UAAK,EAAL,0BAAK,EAAE,UAAK,EAAL,0BAAK;QAClB,CAAC,CAAC;QACF,CAAC,CAAC;KACL"} \ No newline at end of file +{"version":3,"file":"ES5For-of36.js","sourceRoot":"","sources":["ES5For-of36.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAA,KAA2B,IAAA,KAAA,SAAA,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA,gBAAA,4BAAE;QAA1B,IAAA,wBAAc,EAAb,UAAK,EAAL,0BAAK,EAAE,UAAK,EAAL,0BAAK;QAClB,CAAC,CAAC;QACF,CAAC,CAAC;KACL"} \ No newline at end of file diff --git a/tests/baselines/reference/ES5For-of36.sourcemap.txt b/tests/baselines/reference/ES5For-of36.sourcemap.txt index c3ac87f51ca..b1977e55d81 100644 --- a/tests/baselines/reference/ES5For-of36.sourcemap.txt +++ b/tests/baselines/reference/ES5For-of36.sourcemap.txt @@ -8,15 +8,16 @@ sources: ES5For-of36.ts emittedFile:tests/cases/conformance/statements/for-ofStatements/ES5For-of36.js sourceFile:ES5For-of36.ts ------------------------------------------------------------------- ->>>var __values = (this && this.__values) || function (o) { ->>> var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +>>>var __values = (this && this.__values) || function(o) { +>>> var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; >>> if (m) return m.call(o); ->>> return { +>>> if (o && typeof o.length === "number") return { >>> next: function () { >>> if (o && i >= o.length) o = void 0; >>> return { value: o && o[i++], done: !o }; >>> } >>> }; +>>> throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); >>>}; >>>var __read = (this && this.__read) || function (o, n) { >>> var m = typeof Symbol === "function" && o[Symbol.iterator]; @@ -64,19 +65,19 @@ sourceFile:ES5For-of36.ts 11> 12> 13> ) -1 >Emitted(29, 5) Source(1, 1) + SourceIndex(0) -2 >Emitted(29, 10) Source(1, 28) + SourceIndex(0) -3 >Emitted(29, 14) Source(1, 28) + SourceIndex(0) -4 >Emitted(29, 19) Source(1, 28) + SourceIndex(0) -5 >Emitted(29, 28) Source(1, 28) + SourceIndex(0) -6 >Emitted(29, 29) Source(1, 29) + SourceIndex(0) -7 >Emitted(29, 30) Source(1, 30) + SourceIndex(0) -8 >Emitted(29, 32) Source(1, 32) + SourceIndex(0) -9 >Emitted(29, 33) Source(1, 33) + SourceIndex(0) -10>Emitted(29, 34) Source(1, 34) + SourceIndex(0) -11>Emitted(29, 35) Source(1, 34) + SourceIndex(0) -12>Emitted(29, 51) Source(1, 34) + SourceIndex(0) -13>Emitted(29, 79) Source(1, 36) + SourceIndex(0) +1 >Emitted(30, 5) Source(1, 1) + SourceIndex(0) +2 >Emitted(30, 10) Source(1, 28) + SourceIndex(0) +3 >Emitted(30, 14) Source(1, 28) + SourceIndex(0) +4 >Emitted(30, 19) Source(1, 28) + SourceIndex(0) +5 >Emitted(30, 28) Source(1, 28) + SourceIndex(0) +6 >Emitted(30, 29) Source(1, 29) + SourceIndex(0) +7 >Emitted(30, 30) Source(1, 30) + SourceIndex(0) +8 >Emitted(30, 32) Source(1, 32) + SourceIndex(0) +9 >Emitted(30, 33) Source(1, 33) + SourceIndex(0) +10>Emitted(30, 34) Source(1, 34) + SourceIndex(0) +11>Emitted(30, 35) Source(1, 34) + SourceIndex(0) +12>Emitted(30, 51) Source(1, 34) + SourceIndex(0) +13>Emitted(30, 79) Source(1, 36) + SourceIndex(0) --- >>> var _d = __read(_c.value, 2), _e = _d[0], a = _e === void 0 ? 0 : _e, _f = _d[1], b = _f === void 0 ? 1 : _f; 1->^^^^^^^^ @@ -101,17 +102,17 @@ sourceFile:ES5For-of36.ts 9 > b = 1 10> 11> b = 1 -1->Emitted(30, 9) Source(1, 10) + SourceIndex(0) -2 >Emitted(30, 13) Source(1, 10) + SourceIndex(0) -3 >Emitted(30, 37) Source(1, 24) + SourceIndex(0) -4 >Emitted(30, 39) Source(1, 11) + SourceIndex(0) -5 >Emitted(30, 49) Source(1, 16) + SourceIndex(0) -6 >Emitted(30, 51) Source(1, 11) + SourceIndex(0) -7 >Emitted(30, 77) Source(1, 16) + SourceIndex(0) -8 >Emitted(30, 79) Source(1, 18) + SourceIndex(0) -9 >Emitted(30, 89) Source(1, 23) + SourceIndex(0) -10>Emitted(30, 91) Source(1, 18) + SourceIndex(0) -11>Emitted(30, 117) Source(1, 23) + SourceIndex(0) +1->Emitted(31, 9) Source(1, 10) + SourceIndex(0) +2 >Emitted(31, 13) Source(1, 10) + SourceIndex(0) +3 >Emitted(31, 37) Source(1, 24) + SourceIndex(0) +4 >Emitted(31, 39) Source(1, 11) + SourceIndex(0) +5 >Emitted(31, 49) Source(1, 16) + SourceIndex(0) +6 >Emitted(31, 51) Source(1, 11) + SourceIndex(0) +7 >Emitted(31, 77) Source(1, 16) + SourceIndex(0) +8 >Emitted(31, 79) Source(1, 18) + SourceIndex(0) +9 >Emitted(31, 89) Source(1, 23) + SourceIndex(0) +10>Emitted(31, 91) Source(1, 18) + SourceIndex(0) +11>Emitted(31, 117) Source(1, 23) + SourceIndex(0) --- >>> a; 1 >^^^^^^^^ @@ -122,9 +123,9 @@ sourceFile:ES5For-of36.ts > 2 > a 3 > ; -1 >Emitted(31, 9) Source(2, 5) + SourceIndex(0) -2 >Emitted(31, 10) Source(2, 6) + SourceIndex(0) -3 >Emitted(31, 11) Source(2, 7) + SourceIndex(0) +1 >Emitted(32, 9) Source(2, 5) + SourceIndex(0) +2 >Emitted(32, 10) Source(2, 6) + SourceIndex(0) +3 >Emitted(32, 11) Source(2, 7) + SourceIndex(0) --- >>> b; 1->^^^^^^^^ @@ -134,15 +135,15 @@ sourceFile:ES5For-of36.ts > 2 > b 3 > ; -1->Emitted(32, 9) Source(3, 5) + SourceIndex(0) -2 >Emitted(32, 10) Source(3, 6) + SourceIndex(0) -3 >Emitted(32, 11) Source(3, 7) + SourceIndex(0) +1->Emitted(33, 9) Source(3, 5) + SourceIndex(0) +2 >Emitted(33, 10) Source(3, 6) + SourceIndex(0) +3 >Emitted(33, 11) Source(3, 7) + SourceIndex(0) --- >>> } 1 >^^^^^ 1 > >} -1 >Emitted(33, 6) Source(4, 2) + SourceIndex(0) +1 >Emitted(34, 6) Source(4, 2) + SourceIndex(0) --- >>>} >>>catch (e_1_1) { e_1 = { error: e_1_1 }; } diff --git a/tests/baselines/reference/ES5For-of37.js b/tests/baselines/reference/ES5For-of37.js index c9ea0236187..ada2710249f 100644 --- a/tests/baselines/reference/ES5For-of37.js +++ b/tests/baselines/reference/ES5For-of37.js @@ -17,15 +17,16 @@ for (const i of [0, 1, 2, 3, 4]) { //// [ES5For-of37.js] // https://github.com/microsoft/TypeScript/issues/30083 -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; var e_1, _a, e_2, _b; try { diff --git a/tests/baselines/reference/blockScopedBindingsInDownlevelGenerator.js b/tests/baselines/reference/blockScopedBindingsInDownlevelGenerator.js index 9bb07d80b00..a0bc036f2a7 100644 --- a/tests/baselines/reference/blockScopedBindingsInDownlevelGenerator.js +++ b/tests/baselines/reference/blockScopedBindingsInDownlevelGenerator.js @@ -34,15 +34,16 @@ 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 __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; function a() { var _loop_1, _a, _b, i, e_1_1; diff --git a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js index 25b01aa5956..629cd3b0d9b 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js @@ -282,15 +282,16 @@ 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 __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; var C4 = /** @class */ (function () { function C4() { @@ -363,15 +364,16 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } }; -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; var C5 = /** @class */ (function () { function C5() { diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js index d4f6cd74132..622195d09df 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js @@ -236,15 +236,16 @@ 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 __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; function f4() { return __asyncGenerator(this, arguments, function f4_1() { @@ -312,15 +313,16 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } }; -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; function f5() { return __asyncGenerator(this, arguments, function f5_1() { diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js index 55efe59aeba..7d8b9ad649b 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js @@ -236,15 +236,16 @@ 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 __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; var f4 = function () { return __asyncGenerator(this, arguments, function () { @@ -312,15 +313,16 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } }; -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; var f5 = function () { return __asyncGenerator(this, arguments, function () { diff --git a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js index 845d84e2c29..8677898f05d 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js @@ -256,15 +256,16 @@ 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 __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; var o4 = { f: function () { @@ -334,15 +335,16 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } }; -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; var o5 = { f: function () { diff --git a/tests/baselines/reference/emptyVariableDeclarationBindingPatterns01_ES5iterable.js b/tests/baselines/reference/emptyVariableDeclarationBindingPatterns01_ES5iterable.js index 80b2b04b8f0..e1a2a828b5c 100644 --- a/tests/baselines/reference/emptyVariableDeclarationBindingPatterns01_ES5iterable.js +++ b/tests/baselines/reference/emptyVariableDeclarationBindingPatterns01_ES5iterable.js @@ -65,15 +65,16 @@ var __read = (this && this.__read) || function (o, n) { } return ar; }; -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object not iterable." : "Symbol.iterator is not defined."); }; (function () { var a; From aa12ec440c9fcd1e74576c615cd3bf889fcc74db Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Thu, 25 Jul 2019 09:47:57 -0700 Subject: [PATCH 008/182] Fix smart select on last blank line of file (#32544) * Fix SmartSelection on last blank line of file * Add baseline --- src/services/smartSelection.ts | 7 +++++++ .../reference/smartSelection_lastBlankLine.baseline | 5 +++++ tests/cases/fourslash/smartSelection_lastBlankLine.ts | 5 +++++ 3 files changed, 17 insertions(+) create mode 100644 tests/baselines/reference/smartSelection_lastBlankLine.baseline create mode 100644 tests/cases/fourslash/smartSelection_lastBlankLine.ts diff --git a/src/services/smartSelection.ts b/src/services/smartSelection.ts index d0423ce031e..3765c39ed7a 100644 --- a/src/services/smartSelection.ts +++ b/src/services/smartSelection.ts @@ -64,6 +64,13 @@ namespace ts.SmartSelectionRange { parentNode = node; break; } + + // If we made it to the end of the for loop, we’re done. + // In practice, I’ve only seen this happen at the very end + // of a SourceFile. + if (i === children.length - 1) { + break outer; + } } } diff --git a/tests/baselines/reference/smartSelection_lastBlankLine.baseline b/tests/baselines/reference/smartSelection_lastBlankLine.baseline new file mode 100644 index 00000000000..3cbad44aac4 --- /dev/null +++ b/tests/baselines/reference/smartSelection_lastBlankLine.baseline @@ -0,0 +1,5 @@ +class C {} +/**/ + + +class C {}↲ diff --git a/tests/cases/fourslash/smartSelection_lastBlankLine.ts b/tests/cases/fourslash/smartSelection_lastBlankLine.ts new file mode 100644 index 00000000000..2f5cc3f07fc --- /dev/null +++ b/tests/cases/fourslash/smartSelection_lastBlankLine.ts @@ -0,0 +1,5 @@ +/// +////class C {} +/////**/ + +verify.baselineSmartSelection(); From dc415c5c5e81d6578f58cb1847d0c27926e8a005 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 25 Jul 2019 09:56:36 -0700 Subject: [PATCH 009/182] Infer between closely matching types in unions and intersections --- src/compiler/checker.ts | 116 +++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 60 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f56f56223cf..54c8d05e502 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15497,37 +15497,27 @@ namespace ts { } return; } - // Find each source constituent type that has an identically matching target constituent - // type, and for each such type infer from the type to itself. When inferring from a - // type to itself we effectively find all type parameter occurrences within that type - // and infer themselves as their type arguments. We have special handling for numeric - // and string literals because the number and string types are not represented as unions - // of all their possible values. - let matchingTypes: Type[] | undefined; - for (const t of (source).types) { - const matched = findMatchedType(t, target); - if (matched) { - (matchingTypes || (matchingTypes = [])).push(matched); - inferFromTypes(matched, matched); - } - } - // Next, to improve the quality of inferences, reduce the source and target types by - // removing the identically matched constituents. For example, when inferring from - // 'string | string[]' to 'string | T' we reduce the types to 'string[]' and 'T'. - if (matchingTypes) { - const s = removeTypesFromUnionOrIntersection(source, matchingTypes); - const t = removeTypesFromUnionOrIntersection(target, matchingTypes); - if (!(s && t)) return; - source = s; - target = t; - } - } - else if (target.flags & TypeFlags.Union && !(target.flags & TypeFlags.EnumLiteral) || target.flags & TypeFlags.Intersection) { - const matched = findMatchedType(source, target); - if (matched) { - inferFromTypes(matched, matched); + // First, infer between exactly matching source and target constituents and remove + // the matching types. Types exactly match when they are identical or, in union + // types, when the source is a literal and the target is the corresponding primitive. + const matching = target.flags & TypeFlags.Union ? isTypeOrBaseExactlyMatchedBy : isTypeExactlyMatchedBy; + const [tempSources, tempTargets] = inferFromMatchingTypes((source).types, (target).types, matching); + // Next, infer between closely matching source and target constituents and remove + // the matching types. Types closely match when they are instantiations of the same + // object type or instantiations of the same type alias. + const [sources, targets] = inferFromMatchingTypes(tempSources, tempTargets, isTypeCloselyMatchedBy); + if (sources.length === 0 || targets.length === 0) { return; } + source = source.flags & TypeFlags.Union ? getUnionType(sources) : getIntersectionType(sources); + target = target.flags & TypeFlags.Union ? getUnionType(targets) : getIntersectionType(targets); + } + else if (target.flags & TypeFlags.Union && !(target.flags & TypeFlags.EnumLiteral) || target.flags & TypeFlags.Intersection) { + // This block of code is an optimized version of the block above for the simpler case + // of a singleton source type. + const matching = target.flags & TypeFlags.Union ? isTypeOrBaseExactlyMatchedBy : isTypeExactlyMatchedBy; + if (inferFromMatchingType(source, (target).types, matching)) return; + if (inferFromMatchingType(source, (target).types, isTypeCloselyMatchedBy)) return; } else if (target.flags & (TypeFlags.IndexedAccess | TypeFlags.Substitution)) { target = getActualTypeVariable(target); @@ -15675,6 +15665,35 @@ namespace ts { visited.set(key, inferenceCount - startCount); } + function inferFromMatchingType(source: Type, targets: Type[], matches: (s: Type, t: Type) => boolean) { + let matched = false; + for (const t of targets) { + if (matches(source, t)) { + inferFromTypes(source, t); + matched = true; + } + } + return matched; + } + + function inferFromMatchingTypes(sources: Type[], targets: Type[], matches: (s: Type, t: Type) => boolean): [Type[], Type[]] { + let matchedSources: Type[] | undefined; + let matchedTargets: Type[] | undefined; + for (const t of targets) { + for (const s of sources) { + if (matches(s, t)) { + inferFromTypes(s, t); + matchedSources = appendIfUnique(matchedSources, s); + matchedTargets = appendIfUnique(matchedTargets, t); + } + } + } + return [ + matchedSources ? filter(sources, t => !contains(matchedSources, t)) : sources, + matchedTargets ? filter(targets, t => !contains(matchedTargets, t)) : targets, + ]; + } + function inferFromTypeArguments(sourceTypes: readonly Type[], targetTypes: readonly Type[], variances: readonly VarianceFlags[]) { const count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length; for (let i = 0; i < count; i++) { @@ -15955,47 +15974,24 @@ namespace ts { } } - function isMatchableType(type: Type) { + function isNonObjectOrAnonymousType(type: Type) { // We exclude non-anonymous object types because some frameworks (e.g. Ember) rely on the ability to // infer between types that don't witness their type variables. Such types would otherwise be eliminated // because they appear identical. return !(type.flags & TypeFlags.Object) || !!(getObjectFlags(type) & ObjectFlags.Anonymous); } - function typeMatchedBySomeType(type: Type, types: Type[]): boolean { - for (const t of types) { - if (t === type || isMatchableType(t) && isMatchableType(type) && isTypeIdenticalTo(t, type)) { - return true; - } - } - return false; + function isTypeExactlyMatchedBy(s: Type, t: Type) { + return s === t || isNonObjectOrAnonymousType(s) && isNonObjectOrAnonymousType(t) && isTypeIdenticalTo(s, t); } - function findMatchedType(type: Type, target: UnionOrIntersectionType) { - if (typeMatchedBySomeType(type, target.types)) { - return type; - } - if (type.flags & (TypeFlags.NumberLiteral | TypeFlags.StringLiteral) && target.flags & TypeFlags.Union) { - const base = getBaseTypeOfLiteralType(type); - if (typeMatchedBySomeType(base, target.types)) { - return base; - } - } - return undefined; + function isTypeOrBaseExactlyMatchedBy(s: Type, t: Type) { + return isTypeExactlyMatchedBy(s, t) || !!(s.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) && isTypeIdenticalTo(getBaseTypeOfLiteralType(s), t); } - /** - * Return a new union or intersection type computed by removing a given set of types - * from a given union or intersection type. - */ - function removeTypesFromUnionOrIntersection(type: UnionOrIntersectionType, typesToRemove: Type[]) { - const reducedTypes: Type[] = []; - for (const t of type.types) { - if (!typeMatchedBySomeType(t, typesToRemove)) { - reducedTypes.push(t); - } - } - return reducedTypes.length ? type.flags & TypeFlags.Union ? getUnionType(reducedTypes) : getIntersectionType(reducedTypes) : undefined; + function isTypeCloselyMatchedBy(s: Type, t: Type) { + return !!(s.flags & TypeFlags.Object && t.flags & TypeFlags.Object && s.symbol && s.symbol === t.symbol || + s.aliasSymbol && s.aliasTypeArguments && s.aliasSymbol === t.aliasSymbol); } function hasPrimitiveConstraint(type: TypeParameter): boolean { From 772bee5e84f80a7e76c623b1c39d1eb80d8e9b4a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 25 Jul 2019 10:23:03 -0700 Subject: [PATCH 010/182] Property assignment uses parent type annotation (#32553) * Property assignment uses parent type annotation First draft, will write full explanation later. Also makes sure that jsdoc is ignored in TS. It was not before. * Update baselines --- src/compiler/checker.ts | 25 +++++++---- .../expandoFunctionContextualTypes.types | 2 +- .../expandoFunctionContextualTypesJs.types | 2 +- .../propertyAssignmentUseParentType1.js | 26 +++++++++++ .../propertyAssignmentUseParentType1.symbols | 35 +++++++++++++++ .../propertyAssignmentUseParentType1.types | 44 +++++++++++++++++++ ...ropertyAssignmentUseParentType2.errors.txt | 24 ++++++++++ .../propertyAssignmentUseParentType2.symbols | 30 +++++++++++++ .../propertyAssignmentUseParentType2.types | 42 ++++++++++++++++++ .../salsa/propertyAssignmentUseParentType1.ts | 13 ++++++ .../salsa/propertyAssignmentUseParentType2.ts | 18 ++++++++ 11 files changed, 250 insertions(+), 11 deletions(-) create mode 100644 tests/baselines/reference/propertyAssignmentUseParentType1.js create mode 100644 tests/baselines/reference/propertyAssignmentUseParentType1.symbols create mode 100644 tests/baselines/reference/propertyAssignmentUseParentType1.types create mode 100644 tests/baselines/reference/propertyAssignmentUseParentType2.errors.txt create mode 100644 tests/baselines/reference/propertyAssignmentUseParentType2.symbols create mode 100644 tests/baselines/reference/propertyAssignmentUseParentType2.types create mode 100644 tests/cases/conformance/salsa/propertyAssignmentUseParentType1.ts create mode 100644 tests/cases/conformance/salsa/propertyAssignmentUseParentType2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f56f56223cf..2f466267f9d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5396,7 +5396,7 @@ namespace ts { return undefined; } - function getWidenedTypeFromAssignmentDeclaration(symbol: Symbol, resolvedSymbol?: Symbol) { + function getWidenedTypeForAssignmentDeclaration(symbol: Symbol, resolvedSymbol?: Symbol) { // function/class/{} initializers are themselves containers, so they won't merge in the same way as other initializers const container = getAssignedExpandoInitializer(symbol.valueDeclaration); if (container) { @@ -5429,7 +5429,7 @@ namespace ts { } } if (!isCallExpression(expression)) { - jsdocType = getJSDocTypeFromAssignmentDeclaration(jsdocType, expression, symbol, declaration); + jsdocType = getAnnotatedTypeForAssignmentDeclaration(jsdocType, expression, symbol, declaration); } if (!jsdocType) { (types || (types = [])).push((isBinaryExpression(expression) || isCallExpression(expression)) ? getInitializerTypeFromAssignmentDeclaration(symbol, resolvedSymbol, expression, kind) : neverType); @@ -5478,8 +5478,8 @@ namespace ts { return type; } - function getJSDocTypeFromAssignmentDeclaration(declaredType: Type | undefined, expression: Expression, _symbol: Symbol, declaration: Declaration) { - const typeNode = getJSDocType(expression.parent); + function getAnnotatedTypeForAssignmentDeclaration(declaredType: Type | undefined, expression: Expression, symbol: Symbol, declaration: Declaration) { + const typeNode = getEffectiveTypeAnnotationNode(expression.parent); if (typeNode) { const type = getWidenedType(getTypeFromTypeNode(typeNode)); if (!declaredType) { @@ -5489,6 +5489,13 @@ namespace ts { errorNextVariableOrPropertyDeclarationMustHaveSameType(/*firstDeclaration*/ undefined, declaredType, declaration, type); } } + if (symbol.parent) { + const typeNode = getEffectiveTypeAnnotationNode(symbol.parent.valueDeclaration); + if (typeNode) { + return getTypeOfPropertyOfType(getTypeFromTypeNode(typeNode), symbol.escapedName); + } + } + return declaredType; } @@ -5783,7 +5790,7 @@ namespace ts { } else if (isInJSFile(declaration) && (isCallExpression(declaration) || isBinaryExpression(declaration) || isPropertyAccessExpression(declaration) && isBinaryExpression(declaration.parent))) { - type = getWidenedTypeFromAssignmentDeclaration(symbol); + type = getWidenedTypeForAssignmentDeclaration(symbol); } else if (isJSDocPropertyLikeTag(declaration) || isPropertyAccessExpression(declaration) @@ -5798,7 +5805,7 @@ namespace ts { return getTypeOfFuncClassEnumModule(symbol); } type = isBinaryExpression(declaration.parent) ? - getWidenedTypeFromAssignmentDeclaration(symbol) : + getWidenedTypeForAssignmentDeclaration(symbol) : tryGetTypeFromEffectiveTypeNode(declaration) || anyType; } else if (isPropertyAssignment(declaration)) { @@ -5969,7 +5976,7 @@ namespace ts { } else if (declaration.kind === SyntaxKind.BinaryExpression || declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) { - return getWidenedTypeFromAssignmentDeclaration(symbol); + return getWidenedTypeForAssignmentDeclaration(symbol); } else if (symbol.flags & SymbolFlags.ValueModule && declaration && isSourceFile(declaration) && declaration.commonJsModuleIndicator) { const resolvedModule = resolveExternalModuleSymbol(symbol); @@ -5978,7 +5985,7 @@ namespace ts { return errorType; } const exportEquals = getMergedSymbol(symbol.exports!.get(InternalSymbolName.ExportEquals)!); - const type = getWidenedTypeFromAssignmentDeclaration(exportEquals, exportEquals === resolvedModule ? undefined : resolvedModule); + const type = getWidenedTypeForAssignmentDeclaration(exportEquals, exportEquals === resolvedModule ? undefined : resolvedModule); if (!popTypeResolution()) { return reportCircularityError(symbol); } @@ -19157,7 +19164,7 @@ namespace ts { } /** - * Woah! Do you really want to use this function? + * Whoa! Do you really want to use this function? * * Unless you're trying to get the *non-apparent* type for a * value-literal type or you're authoring relevant portions of this algorithm, diff --git a/tests/baselines/reference/expandoFunctionContextualTypes.types b/tests/baselines/reference/expandoFunctionContextualTypes.types index e1eca92659c..915b168776f 100644 --- a/tests/baselines/reference/expandoFunctionContextualTypes.types +++ b/tests/baselines/reference/expandoFunctionContextualTypes.types @@ -12,7 +12,7 @@ interface StatelessComponent

{ const MyComponent: StatelessComponent = () => null as any; >MyComponent : StatelessComponent ->() => null as any : { (): any; defaultProps: { color: "red"; }; } +>() => null as any : { (): any; defaultProps: Partial; } >null as any : any >null : null diff --git a/tests/baselines/reference/expandoFunctionContextualTypesJs.types b/tests/baselines/reference/expandoFunctionContextualTypesJs.types index 081c57c0dac..82442a9db4a 100644 --- a/tests/baselines/reference/expandoFunctionContextualTypesJs.types +++ b/tests/baselines/reference/expandoFunctionContextualTypesJs.types @@ -10,7 +10,7 @@ */ const MyComponent = () => /* @type {any} */(null); >MyComponent : { (): any; defaultProps?: Partial<{ color: "red" | "blue"; }>; } ->() => /* @type {any} */(null) : { (): any; defaultProps: { color: "red"; }; } +>() => /* @type {any} */(null) : { (): any; defaultProps: Partial<{ color: "red" | "blue"; }>; } >(null) : null >null : null diff --git a/tests/baselines/reference/propertyAssignmentUseParentType1.js b/tests/baselines/reference/propertyAssignmentUseParentType1.js new file mode 100644 index 00000000000..5e839a31da4 --- /dev/null +++ b/tests/baselines/reference/propertyAssignmentUseParentType1.js @@ -0,0 +1,26 @@ +//// [propertyAssignmentUseParentType1.ts] +interface N { + (): boolean + num: 123; +} +export const interfaced: N = () => true; +interfaced.num = 123; + +export const inlined: { (): boolean; nun: 456 } = () => true; +inlined.nun = 456; + +export const ignoreJsdoc = () => true; +/** @type {string} make sure to ignore jsdoc! */ +ignoreJsdoc.extra = 111 + + +//// [propertyAssignmentUseParentType1.js] +"use strict"; +exports.__esModule = true; +exports.interfaced = function () { return true; }; +exports.interfaced.num = 123; +exports.inlined = function () { return true; }; +exports.inlined.nun = 456; +exports.ignoreJsdoc = function () { return true; }; +/** @type {string} make sure to ignore jsdoc! */ +exports.ignoreJsdoc.extra = 111; diff --git a/tests/baselines/reference/propertyAssignmentUseParentType1.symbols b/tests/baselines/reference/propertyAssignmentUseParentType1.symbols new file mode 100644 index 00000000000..081e2f12604 --- /dev/null +++ b/tests/baselines/reference/propertyAssignmentUseParentType1.symbols @@ -0,0 +1,35 @@ +=== tests/cases/conformance/salsa/propertyAssignmentUseParentType1.ts === +interface N { +>N : Symbol(N, Decl(propertyAssignmentUseParentType1.ts, 0, 0)) + + (): boolean + num: 123; +>num : Symbol(N.num, Decl(propertyAssignmentUseParentType1.ts, 1, 15)) +} +export const interfaced: N = () => true; +>interfaced : Symbol(interfaced, Decl(propertyAssignmentUseParentType1.ts, 4, 12), Decl(propertyAssignmentUseParentType1.ts, 4, 40)) +>N : Symbol(N, Decl(propertyAssignmentUseParentType1.ts, 0, 0)) + +interfaced.num = 123; +>interfaced.num : Symbol(N.num, Decl(propertyAssignmentUseParentType1.ts, 1, 15)) +>interfaced : Symbol(interfaced, Decl(propertyAssignmentUseParentType1.ts, 4, 12), Decl(propertyAssignmentUseParentType1.ts, 4, 40)) +>num : Symbol(N.num, Decl(propertyAssignmentUseParentType1.ts, 1, 15)) + +export const inlined: { (): boolean; nun: 456 } = () => true; +>inlined : Symbol(inlined, Decl(propertyAssignmentUseParentType1.ts, 7, 12), Decl(propertyAssignmentUseParentType1.ts, 7, 61)) +>nun : Symbol(nun, Decl(propertyAssignmentUseParentType1.ts, 7, 36)) + +inlined.nun = 456; +>inlined.nun : Symbol(nun, Decl(propertyAssignmentUseParentType1.ts, 7, 36)) +>inlined : Symbol(inlined, Decl(propertyAssignmentUseParentType1.ts, 7, 12), Decl(propertyAssignmentUseParentType1.ts, 7, 61)) +>nun : Symbol(nun, Decl(propertyAssignmentUseParentType1.ts, 7, 36)) + +export const ignoreJsdoc = () => true; +>ignoreJsdoc : Symbol(ignoreJsdoc, Decl(propertyAssignmentUseParentType1.ts, 10, 12), Decl(propertyAssignmentUseParentType1.ts, 10, 38)) + +/** @type {string} make sure to ignore jsdoc! */ +ignoreJsdoc.extra = 111 +>ignoreJsdoc.extra : Symbol(ignoreJsdoc.extra, Decl(propertyAssignmentUseParentType1.ts, 10, 38)) +>ignoreJsdoc : Symbol(ignoreJsdoc, Decl(propertyAssignmentUseParentType1.ts, 10, 12), Decl(propertyAssignmentUseParentType1.ts, 10, 38)) +>extra : Symbol(ignoreJsdoc.extra, Decl(propertyAssignmentUseParentType1.ts, 10, 38)) + diff --git a/tests/baselines/reference/propertyAssignmentUseParentType1.types b/tests/baselines/reference/propertyAssignmentUseParentType1.types new file mode 100644 index 00000000000..f3bd5010b20 --- /dev/null +++ b/tests/baselines/reference/propertyAssignmentUseParentType1.types @@ -0,0 +1,44 @@ +=== tests/cases/conformance/salsa/propertyAssignmentUseParentType1.ts === +interface N { + (): boolean + num: 123; +>num : 123 +} +export const interfaced: N = () => true; +>interfaced : N +>() => true : { (): true; num: 123; } +>true : true + +interfaced.num = 123; +>interfaced.num = 123 : 123 +>interfaced.num : 123 +>interfaced : N +>num : 123 +>123 : 123 + +export const inlined: { (): boolean; nun: 456 } = () => true; +>inlined : { (): boolean; nun: 456; } +>nun : 456 +>() => true : { (): true; nun: 456; } +>true : true + +inlined.nun = 456; +>inlined.nun = 456 : 456 +>inlined.nun : 456 +>inlined : { (): boolean; nun: 456; } +>nun : 456 +>456 : 456 + +export const ignoreJsdoc = () => true; +>ignoreJsdoc : { (): boolean; extra: number; } +>() => true : { (): boolean; extra: number; } +>true : true + +/** @type {string} make sure to ignore jsdoc! */ +ignoreJsdoc.extra = 111 +>ignoreJsdoc.extra = 111 : 111 +>ignoreJsdoc.extra : number +>ignoreJsdoc : { (): boolean; extra: number; } +>extra : number +>111 : 111 + diff --git a/tests/baselines/reference/propertyAssignmentUseParentType2.errors.txt b/tests/baselines/reference/propertyAssignmentUseParentType2.errors.txt new file mode 100644 index 00000000000..b88e276b405 --- /dev/null +++ b/tests/baselines/reference/propertyAssignmentUseParentType2.errors.txt @@ -0,0 +1,24 @@ +tests/cases/conformance/salsa/propertyAssignmentUseParentType2.js(11,14): error TS2322: Type '{ (): boolean; nuo: 1000; }' is not assignable to type '{ (): boolean; nuo: 789; }'. + Types of property 'nuo' are incompatible. + Type '1000' is not assignable to type '789'. + + +==== tests/cases/conformance/salsa/propertyAssignmentUseParentType2.js (1 errors) ==== + /** @type {{ (): boolean; nuo: 789 }} */ + export const inlined = () => true + inlined.nuo = 789 + + /** @type {{ (): boolean; nuo: 789 }} */ + export const duplicated = () => true + /** @type {789} */ + duplicated.nuo = 789 + + /** @type {{ (): boolean; nuo: 789 }} */ + export const conflictingDuplicated = () => true + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ (): boolean; nuo: 1000; }' is not assignable to type '{ (): boolean; nuo: 789; }'. +!!! error TS2322: Types of property 'nuo' are incompatible. +!!! error TS2322: Type '1000' is not assignable to type '789'. + /** @type {1000} */ + conflictingDuplicated.nuo = 789 + \ No newline at end of file diff --git a/tests/baselines/reference/propertyAssignmentUseParentType2.symbols b/tests/baselines/reference/propertyAssignmentUseParentType2.symbols new file mode 100644 index 00000000000..93b8b9290da --- /dev/null +++ b/tests/baselines/reference/propertyAssignmentUseParentType2.symbols @@ -0,0 +1,30 @@ +=== tests/cases/conformance/salsa/propertyAssignmentUseParentType2.js === +/** @type {{ (): boolean; nuo: 789 }} */ +export const inlined = () => true +>inlined : Symbol(inlined, Decl(propertyAssignmentUseParentType2.js, 1, 12), Decl(propertyAssignmentUseParentType2.js, 1, 33)) + +inlined.nuo = 789 +>inlined.nuo : Symbol(nuo, Decl(propertyAssignmentUseParentType2.js, 0, 25)) +>inlined : Symbol(inlined, Decl(propertyAssignmentUseParentType2.js, 1, 12), Decl(propertyAssignmentUseParentType2.js, 1, 33)) +>nuo : Symbol(nuo, Decl(propertyAssignmentUseParentType2.js, 0, 25)) + +/** @type {{ (): boolean; nuo: 789 }} */ +export const duplicated = () => true +>duplicated : Symbol(duplicated, Decl(propertyAssignmentUseParentType2.js, 5, 12), Decl(propertyAssignmentUseParentType2.js, 5, 36)) + +/** @type {789} */ +duplicated.nuo = 789 +>duplicated.nuo : Symbol(nuo, Decl(propertyAssignmentUseParentType2.js, 4, 25)) +>duplicated : Symbol(duplicated, Decl(propertyAssignmentUseParentType2.js, 5, 12), Decl(propertyAssignmentUseParentType2.js, 5, 36)) +>nuo : Symbol(nuo, Decl(propertyAssignmentUseParentType2.js, 4, 25)) + +/** @type {{ (): boolean; nuo: 789 }} */ +export const conflictingDuplicated = () => true +>conflictingDuplicated : Symbol(conflictingDuplicated, Decl(propertyAssignmentUseParentType2.js, 10, 12), Decl(propertyAssignmentUseParentType2.js, 10, 47)) + +/** @type {1000} */ +conflictingDuplicated.nuo = 789 +>conflictingDuplicated.nuo : Symbol(nuo, Decl(propertyAssignmentUseParentType2.js, 9, 25)) +>conflictingDuplicated : Symbol(conflictingDuplicated, Decl(propertyAssignmentUseParentType2.js, 10, 12), Decl(propertyAssignmentUseParentType2.js, 10, 47)) +>nuo : Symbol(nuo, Decl(propertyAssignmentUseParentType2.js, 9, 25)) + diff --git a/tests/baselines/reference/propertyAssignmentUseParentType2.types b/tests/baselines/reference/propertyAssignmentUseParentType2.types new file mode 100644 index 00000000000..24118a9ee73 --- /dev/null +++ b/tests/baselines/reference/propertyAssignmentUseParentType2.types @@ -0,0 +1,42 @@ +=== tests/cases/conformance/salsa/propertyAssignmentUseParentType2.js === +/** @type {{ (): boolean; nuo: 789 }} */ +export const inlined = () => true +>inlined : { (): boolean; nuo: 789; } +>() => true : { (): boolean; nuo: 789; } +>true : true + +inlined.nuo = 789 +>inlined.nuo = 789 : 789 +>inlined.nuo : 789 +>inlined : { (): boolean; nuo: 789; } +>nuo : 789 +>789 : 789 + +/** @type {{ (): boolean; nuo: 789 }} */ +export const duplicated = () => true +>duplicated : { (): boolean; nuo: 789; } +>() => true : { (): boolean; nuo: 789; } +>true : true + +/** @type {789} */ +duplicated.nuo = 789 +>duplicated.nuo = 789 : 789 +>duplicated.nuo : 789 +>duplicated : { (): boolean; nuo: 789; } +>nuo : 789 +>789 : 789 + +/** @type {{ (): boolean; nuo: 789 }} */ +export const conflictingDuplicated = () => true +>conflictingDuplicated : { (): boolean; nuo: 789; } +>() => true : { (): boolean; nuo: 1000; } +>true : true + +/** @type {1000} */ +conflictingDuplicated.nuo = 789 +>conflictingDuplicated.nuo = 789 : 789 +>conflictingDuplicated.nuo : 789 +>conflictingDuplicated : { (): boolean; nuo: 789; } +>nuo : 789 +>789 : 789 + diff --git a/tests/cases/conformance/salsa/propertyAssignmentUseParentType1.ts b/tests/cases/conformance/salsa/propertyAssignmentUseParentType1.ts new file mode 100644 index 00000000000..500ae6f2fe3 --- /dev/null +++ b/tests/cases/conformance/salsa/propertyAssignmentUseParentType1.ts @@ -0,0 +1,13 @@ +interface N { + (): boolean + num: 123; +} +export const interfaced: N = () => true; +interfaced.num = 123; + +export const inlined: { (): boolean; nun: 456 } = () => true; +inlined.nun = 456; + +export const ignoreJsdoc = () => true; +/** @type {string} make sure to ignore jsdoc! */ +ignoreJsdoc.extra = 111 diff --git a/tests/cases/conformance/salsa/propertyAssignmentUseParentType2.ts b/tests/cases/conformance/salsa/propertyAssignmentUseParentType2.ts new file mode 100644 index 00000000000..53696abbf81 --- /dev/null +++ b/tests/cases/conformance/salsa/propertyAssignmentUseParentType2.ts @@ -0,0 +1,18 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: propertyAssignmentUseParentType2.js + +/** @type {{ (): boolean; nuo: 789 }} */ +export const inlined = () => true +inlined.nuo = 789 + +/** @type {{ (): boolean; nuo: 789 }} */ +export const duplicated = () => true +/** @type {789} */ +duplicated.nuo = 789 + +/** @type {{ (): boolean; nuo: 789 }} */ +export const conflictingDuplicated = () => true +/** @type {1000} */ +conflictingDuplicated.nuo = 789 From 35de142943ea867f302fc8318afa9e9f9bb7c0ad Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 25 Jul 2019 11:50:50 -0700 Subject: [PATCH 011/182] Accept new baselines --- ...nalNoInfiniteInstantiationDepth.errors.txt | 26 +++++++------------ ...ferredInferenceAllowsAssignment.errors.txt | 26 +++++++------------ 2 files changed, 20 insertions(+), 32 deletions(-) diff --git a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt index c7a323f1283..4fad6997145 100644 --- a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt +++ b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt @@ -45,14 +45,11 @@ tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfin Type 'TInjectedProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. ==== tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts (1 errors) ==== @@ -167,12 +164,9 @@ tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfin !!! error TS2344: Type 'TInjectedProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. !!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. !!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. \ No newline at end of file diff --git a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt index 0556ae25c91..0acfd4a8365 100644 --- a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt +++ b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt @@ -45,14 +45,11 @@ tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50): Type 'TInjectedProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. ==== tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts (1 errors) ==== @@ -180,14 +177,11 @@ tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50): !!! error TS2344: Type 'TInjectedProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. !!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. !!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. >; declare const connect: { From b9d27c0f2ce5df82b8899aca94ed752b626978b0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 25 Jul 2019 11:52:08 -0700 Subject: [PATCH 012/182] Add regression tests --- .../unionAndIntersectionInference3.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts b/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts index aad083a626b..17057de2b84 100644 --- a/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts +++ b/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts @@ -1,7 +1,42 @@ // @strict: true +// @target: esnext // Repro from #30720 type Maybe = T | undefined; declare function concatMaybe(...args: (Maybe | Maybe[])[]): T[]; concatMaybe([1, 2, 3], 4); + +// Repros from #32247 + +const g: (com: () => Iterator | AsyncIterator) => Promise = async (com: () => Iterator | AsyncIterator): Promise => { + throw com; +}; + +interface Foo1 { + test(value: T): void; +} + +interface Bar1 { + test(value: T | PromiseLike): void; +} + +declare let f1: (x: Foo1 | Bar1) => Promise; +declare let f2: (x: Foo1 | Bar1) => Promise; + +f1 = f2; +f2 = f1; + +type Foo2 = { + test(value: T): void; +} + +type Bar2 = { + test(value: T | PromiseLike): void; +} + +declare let g1: (x: Foo2 | Bar2) => Promise; +declare let g2: (x: Foo2 | Bar2) => Promise; + +g1 = g2; +g2 = g1; From 540134840da0acea39f103b12719392c41b9a67d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 25 Jul 2019 11:52:15 -0700 Subject: [PATCH 013/182] Accept new baselines --- .../unionAndIntersectionInference3.js | 42 ++++++ .../unionAndIntersectionInference3.symbols | 142 ++++++++++++++++++ .../unionAndIntersectionInference3.types | 77 ++++++++++ 3 files changed, 261 insertions(+) diff --git a/tests/baselines/reference/unionAndIntersectionInference3.js b/tests/baselines/reference/unionAndIntersectionInference3.js index 4cc0c2f667e..c9f5cffa1f7 100644 --- a/tests/baselines/reference/unionAndIntersectionInference3.js +++ b/tests/baselines/reference/unionAndIntersectionInference3.js @@ -4,9 +4,51 @@ type Maybe = T | undefined; declare function concatMaybe(...args: (Maybe | Maybe[])[]): T[]; concatMaybe([1, 2, 3], 4); + +// Repros from #32247 + +const g: (com: () => Iterator | AsyncIterator) => Promise = async (com: () => Iterator | AsyncIterator): Promise => { + throw com; +}; + +interface Foo1 { + test(value: T): void; +} + +interface Bar1 { + test(value: T | PromiseLike): void; +} + +declare let f1: (x: Foo1 | Bar1) => Promise; +declare let f2: (x: Foo1 | Bar1) => Promise; + +f1 = f2; +f2 = f1; + +type Foo2 = { + test(value: T): void; +} + +type Bar2 = { + test(value: T | PromiseLike): void; +} + +declare let g1: (x: Foo2 | Bar2) => Promise; +declare let g2: (x: Foo2 | Bar2) => Promise; + +g1 = g2; +g2 = g1; //// [unionAndIntersectionInference3.js] "use strict"; // Repro from #30720 concatMaybe([1, 2, 3], 4); +// Repros from #32247 +const g = async (com) => { + throw com; +}; +f1 = f2; +f2 = f1; +g1 = g2; +g2 = g1; diff --git a/tests/baselines/reference/unionAndIntersectionInference3.symbols b/tests/baselines/reference/unionAndIntersectionInference3.symbols index be24bc0cc77..b854ee1ce42 100644 --- a/tests/baselines/reference/unionAndIntersectionInference3.symbols +++ b/tests/baselines/reference/unionAndIntersectionInference3.symbols @@ -19,3 +19,145 @@ declare function concatMaybe(...args: (Maybe | Maybe[])[]): T[]; concatMaybe([1, 2, 3], 4); >concatMaybe : Symbol(concatMaybe, Decl(unionAndIntersectionInference3.ts, 2, 30)) +// Repros from #32247 + +const g: (com: () => Iterator | AsyncIterator) => Promise = async (com: () => Iterator | AsyncIterator): Promise => { +>g : Symbol(g, Decl(unionAndIntersectionInference3.ts, 8, 5)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 10)) +>R : Symbol(R, Decl(unionAndIntersectionInference3.ts, 8, 12)) +>S : Symbol(S, Decl(unionAndIntersectionInference3.ts, 8, 15)) +>com : Symbol(com, Decl(unionAndIntersectionInference3.ts, 8, 19)) +>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>S : Symbol(S, Decl(unionAndIntersectionInference3.ts, 8, 15)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 10)) +>R : Symbol(R, Decl(unionAndIntersectionInference3.ts, 8, 12)) +>AsyncIterator : Symbol(AsyncIterator, Decl(lib.es2018.asynciterable.d.ts, --, --)) +>S : Symbol(S, Decl(unionAndIntersectionInference3.ts, 8, 15)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 10)) +>R : Symbol(R, Decl(unionAndIntersectionInference3.ts, 8, 12)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 10)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 97)) +>R : Symbol(R, Decl(unionAndIntersectionInference3.ts, 8, 99)) +>S : Symbol(S, Decl(unionAndIntersectionInference3.ts, 8, 102)) +>com : Symbol(com, Decl(unionAndIntersectionInference3.ts, 8, 106)) +>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>S : Symbol(S, Decl(unionAndIntersectionInference3.ts, 8, 102)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 97)) +>R : Symbol(R, Decl(unionAndIntersectionInference3.ts, 8, 99)) +>AsyncIterator : Symbol(AsyncIterator, Decl(lib.es2018.asynciterable.d.ts, --, --)) +>S : Symbol(S, Decl(unionAndIntersectionInference3.ts, 8, 102)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 97)) +>R : Symbol(R, Decl(unionAndIntersectionInference3.ts, 8, 99)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 97)) + + throw com; +>com : Symbol(com, Decl(unionAndIntersectionInference3.ts, 8, 106)) + +}; + +interface Foo1 { +>Foo1 : Symbol(Foo1, Decl(unionAndIntersectionInference3.ts, 10, 2)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 12, 15)) + + test(value: T): void; +>test : Symbol(Foo1.test, Decl(unionAndIntersectionInference3.ts, 12, 19)) +>value : Symbol(value, Decl(unionAndIntersectionInference3.ts, 13, 9)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 12, 15)) +} + +interface Bar1 { +>Bar1 : Symbol(Bar1, Decl(unionAndIntersectionInference3.ts, 14, 1)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 16, 15)) + + test(value: T | PromiseLike): void; +>test : Symbol(Bar1.test, Decl(unionAndIntersectionInference3.ts, 16, 19)) +>value : Symbol(value, Decl(unionAndIntersectionInference3.ts, 17, 9)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 16, 15)) +>PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 16, 15)) +} + +declare let f1: (x: Foo1 | Bar1) => Promise; +>f1 : Symbol(f1, Decl(unionAndIntersectionInference3.ts, 20, 11)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 20, 17)) +>x : Symbol(x, Decl(unionAndIntersectionInference3.ts, 20, 20)) +>Foo1 : Symbol(Foo1, Decl(unionAndIntersectionInference3.ts, 10, 2)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 20, 17)) +>Bar1 : Symbol(Bar1, Decl(unionAndIntersectionInference3.ts, 14, 1)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 20, 17)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 20, 17)) + +declare let f2: (x: Foo1 | Bar1) => Promise; +>f2 : Symbol(f2, Decl(unionAndIntersectionInference3.ts, 21, 11)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 21, 17)) +>x : Symbol(x, Decl(unionAndIntersectionInference3.ts, 21, 20)) +>Foo1 : Symbol(Foo1, Decl(unionAndIntersectionInference3.ts, 10, 2)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 21, 17)) +>Bar1 : Symbol(Bar1, Decl(unionAndIntersectionInference3.ts, 14, 1)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 21, 17)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 21, 17)) + +f1 = f2; +>f1 : Symbol(f1, Decl(unionAndIntersectionInference3.ts, 20, 11)) +>f2 : Symbol(f2, Decl(unionAndIntersectionInference3.ts, 21, 11)) + +f2 = f1; +>f2 : Symbol(f2, Decl(unionAndIntersectionInference3.ts, 21, 11)) +>f1 : Symbol(f1, Decl(unionAndIntersectionInference3.ts, 20, 11)) + +type Foo2 = { +>Foo2 : Symbol(Foo2, Decl(unionAndIntersectionInference3.ts, 24, 8)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 26, 10)) + + test(value: T): void; +>test : Symbol(test, Decl(unionAndIntersectionInference3.ts, 26, 16)) +>value : Symbol(value, Decl(unionAndIntersectionInference3.ts, 27, 9)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 26, 10)) +} + +type Bar2 = { +>Bar2 : Symbol(Bar2, Decl(unionAndIntersectionInference3.ts, 28, 1)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 30, 10)) + + test(value: T | PromiseLike): void; +>test : Symbol(test, Decl(unionAndIntersectionInference3.ts, 30, 16)) +>value : Symbol(value, Decl(unionAndIntersectionInference3.ts, 31, 9)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 30, 10)) +>PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 30, 10)) +} + +declare let g1: (x: Foo2 | Bar2) => Promise; +>g1 : Symbol(g1, Decl(unionAndIntersectionInference3.ts, 34, 11)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 34, 17)) +>x : Symbol(x, Decl(unionAndIntersectionInference3.ts, 34, 20)) +>Foo2 : Symbol(Foo2, Decl(unionAndIntersectionInference3.ts, 24, 8)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 34, 17)) +>Bar2 : Symbol(Bar2, Decl(unionAndIntersectionInference3.ts, 28, 1)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 34, 17)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 34, 17)) + +declare let g2: (x: Foo2 | Bar2) => Promise; +>g2 : Symbol(g2, Decl(unionAndIntersectionInference3.ts, 35, 11)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 35, 17)) +>x : Symbol(x, Decl(unionAndIntersectionInference3.ts, 35, 20)) +>Foo2 : Symbol(Foo2, Decl(unionAndIntersectionInference3.ts, 24, 8)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 35, 17)) +>Bar2 : Symbol(Bar2, Decl(unionAndIntersectionInference3.ts, 28, 1)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 35, 17)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 35, 17)) + +g1 = g2; +>g1 : Symbol(g1, Decl(unionAndIntersectionInference3.ts, 34, 11)) +>g2 : Symbol(g2, Decl(unionAndIntersectionInference3.ts, 35, 11)) + +g2 = g1; +>g2 : Symbol(g2, Decl(unionAndIntersectionInference3.ts, 35, 11)) +>g1 : Symbol(g1, Decl(unionAndIntersectionInference3.ts, 34, 11)) + diff --git a/tests/baselines/reference/unionAndIntersectionInference3.types b/tests/baselines/reference/unionAndIntersectionInference3.types index 8497cb1e516..acbca0a1eae 100644 --- a/tests/baselines/reference/unionAndIntersectionInference3.types +++ b/tests/baselines/reference/unionAndIntersectionInference3.types @@ -17,3 +17,80 @@ concatMaybe([1, 2, 3], 4); >3 : 3 >4 : 4 +// Repros from #32247 + +const g: (com: () => Iterator | AsyncIterator) => Promise = async (com: () => Iterator | AsyncIterator): Promise => { +>g : (com: () => Iterator | AsyncIterator) => Promise +>com : () => Iterator | AsyncIterator +>async (com: () => Iterator | AsyncIterator): Promise => { throw com;} : (com: () => Iterator | AsyncIterator) => Promise +>com : () => Iterator | AsyncIterator + + throw com; +>com : () => Iterator | AsyncIterator + +}; + +interface Foo1 { + test(value: T): void; +>test : (value: T) => void +>value : T +} + +interface Bar1 { + test(value: T | PromiseLike): void; +>test : (value: T | PromiseLike) => void +>value : T | PromiseLike +} + +declare let f1: (x: Foo1 | Bar1) => Promise; +>f1 : (x: Foo1 | Bar1) => Promise +>x : Foo1 | Bar1 + +declare let f2: (x: Foo1 | Bar1) => Promise; +>f2 : (x: Foo1 | Bar1) => Promise +>x : Foo1 | Bar1 + +f1 = f2; +>f1 = f2 : (x: Foo1 | Bar1) => Promise +>f1 : (x: Foo1 | Bar1) => Promise +>f2 : (x: Foo1 | Bar1) => Promise + +f2 = f1; +>f2 = f1 : (x: Foo1 | Bar1) => Promise +>f2 : (x: Foo1 | Bar1) => Promise +>f1 : (x: Foo1 | Bar1) => Promise + +type Foo2 = { +>Foo2 : Foo2 + + test(value: T): void; +>test : (value: T) => void +>value : T +} + +type Bar2 = { +>Bar2 : Bar2 + + test(value: T | PromiseLike): void; +>test : (value: T | PromiseLike) => void +>value : T | PromiseLike +} + +declare let g1: (x: Foo2 | Bar2) => Promise; +>g1 : (x: Foo2 | Bar2) => Promise +>x : Foo2 | Bar2 + +declare let g2: (x: Foo2 | Bar2) => Promise; +>g2 : (x: Foo2 | Bar2) => Promise +>x : Foo2 | Bar2 + +g1 = g2; +>g1 = g2 : (x: Foo2 | Bar2) => Promise +>g1 : (x: Foo2 | Bar2) => Promise +>g2 : (x: Foo2 | Bar2) => Promise + +g2 = g1; +>g2 = g1 : (x: Foo2 | Bar2) => Promise +>g2 : (x: Foo2 | Bar2) => Promise +>g1 : (x: Foo2 | Bar2) => Promise + From ee623c1ae69b46774c2779c28c3fb438f3514072 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 25 Jul 2019 11:57:23 -0700 Subject: [PATCH 014/182] Add test case before change where config project is created just to remove it --- .../unittests/tsserver/inferredProjects.ts | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/testRunner/unittests/tsserver/inferredProjects.ts b/src/testRunner/unittests/tsserver/inferredProjects.ts index 0bc14809aaa..6882f2ed5c5 100644 --- a/src/testRunner/unittests/tsserver/inferredProjects.ts +++ b/src/testRunner/unittests/tsserver/inferredProjects.ts @@ -345,5 +345,68 @@ namespace ts.projectSystem { it("inferred projects per project root with case insensitive system", () => { verifyProjectRootWithCaseSensitivity(/*useCaseSensitiveFileNames*/ false); }); + + it("should still retain configured project created while opening the file", () => { + const projectRoot = "/user/username/projects/project"; + const appFile: File = { + path: `${projectRoot}/app.ts`, + content: `const app = 20;` + }; + const config: File = { + path: `${projectRoot}/tsconfig.json`, + content: "{}" + }; + const jsFile1: File = { + path: `${projectRoot}/jsFile1.js`, + content: `const jsFile1 = 10;` + }; + const jsFile2: File = { + path: `${projectRoot}/jsFile2.js`, + content: `const jsFile2 = 10;` + }; + const host = createServerHost([appFile, libFile, config, jsFile1, jsFile2]); + const projectService = createProjectService(host); + const originalSet = projectService.configuredProjects.set; + const originalDelete = projectService.configuredProjects.delete; + const configuredCreated = createMap(); + const configuredRemoved = createMap(); + projectService.configuredProjects.set = (key, value) => { + assert.isFalse(configuredCreated.has(key)); + configuredCreated.set(key, true); + return originalSet.call(projectService.configuredProjects, key, value); + }; + projectService.configuredProjects.delete = key => { + assert.isFalse(configuredRemoved.has(key)); + configuredRemoved.set(key, true); + return originalDelete.call(projectService.configuredProjects, key); + }; + + projectService.openClientFile(jsFile1.path); + checkNumberOfProjects(projectService, { inferredProjects: 1 }); + checkProjectActualFiles(projectService.inferredProjects[0], [jsFile1.path, libFile.path]); + checkConfiguredProjectCreatedAndDeleted(); + + projectService.closeClientFile(jsFile1.path); + checkNumberOfProjects(projectService, { inferredProjects: 1 }); + projectService.openClientFile(jsFile2.path); + checkNumberOfProjects(projectService, { inferredProjects: 1 }); + checkProjectActualFiles(projectService.inferredProjects[0], [jsFile2.path, libFile.path]); + checkConfiguredProjectCreatedAndDeleted(); + + projectService.openClientFile(jsFile1.path); + checkNumberOfProjects(projectService, { inferredProjects: 2 }); + checkProjectActualFiles(projectService.inferredProjects[0], [jsFile2.path, libFile.path]); + checkProjectActualFiles(projectService.inferredProjects[1], [jsFile1.path, libFile.path]); + checkConfiguredProjectCreatedAndDeleted(); + + function checkConfiguredProjectCreatedAndDeleted() { + assert.equal(configuredCreated.size, 1); + assert.isTrue(configuredCreated.has(config.path)); + assert.equal(configuredRemoved.size, 1); + assert.isTrue(configuredRemoved.has(config.path)); + configuredCreated.clear(); + configuredRemoved.clear(); + } + }); }); } From 10ee85c98c9027321bc88fc8e42f4d759c7c0c63 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 25 Jul 2019 12:28:09 -0700 Subject: [PATCH 015/182] Retain the configured project opened during opening client file even if opened file isnt included in that project This helps not create and remove project on every open if tsconfig file isnt referenced by any open file --- src/server/editorServices.ts | 41 ++++++++++++++----- .../unittests/tsserver/configuredProjects.ts | 14 +++---- .../unittests/tsserver/inferredProjects.ts | 40 ++++++++++++++---- src/testRunner/unittests/tsserver/projects.ts | 18 ++++++-- 4 files changed, 83 insertions(+), 30 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index df9f0e3ee01..a25256a3aec 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -284,6 +284,10 @@ namespace ts.server { configFileErrors?: ReadonlyArray; } + interface AssignProjectResult extends OpenConfiguredProjectResult { + defaultConfigProject: ConfiguredProject | undefined; + } + interface FilePropertyReader { getFileName(f: T): string; getScriptKind(f: T, extraFileExtensions?: FileExtensionInfo[]): ScriptKind; @@ -2635,10 +2639,11 @@ namespace ts.server { return info; } - private assignProjectToOpenedScriptInfo(info: ScriptInfo): OpenConfiguredProjectResult { + private assignProjectToOpenedScriptInfo(info: ScriptInfo): AssignProjectResult { let configFileName: NormalizedPath | undefined; let configFileErrors: ReadonlyArray | undefined; let project: ConfiguredProject | ExternalProject | undefined = this.findExternalProjectContainingOpenScriptInfo(info); + let defaultConfigProject: ConfiguredProject | undefined; if (!project && !this.syntaxOnly) { // Checking syntaxOnly is an optimization configFileName = this.getConfigFileNameForFile(info); if (configFileName) { @@ -2659,6 +2664,7 @@ namespace ts.server { // Ensure project is ready to check if it contains opened script info updateProjectIfDirty(project); } + defaultConfigProject = project; } } @@ -2678,13 +2684,13 @@ namespace ts.server { this.assignOrphanScriptInfoToInferredProject(info, this.openFiles.get(info.path)); } Debug.assert(!info.isOrphan()); - return { configFileName, configFileErrors }; + return { configFileName, configFileErrors, defaultConfigProject }; } - private cleanupAfterOpeningFile() { + private cleanupAfterOpeningFile(toRetainConfigProjects: ConfiguredProject[] | ConfiguredProject | undefined) { // This was postponed from closeOpenFile to after opening next file, // so that we can reuse the project if we need to right away - this.removeOrphanConfiguredProjects(); + this.removeOrphanConfiguredProjects(toRetainConfigProjects); // Remove orphan inferred projects now that we have reused projects // We need to create a duplicate because we cant guarantee order after removal @@ -2705,14 +2711,22 @@ namespace ts.server { openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult { const info = this.getOrCreateOpenScriptInfo(fileName, fileContent, scriptKind, hasMixedContent, projectRootPath); - const result = this.assignProjectToOpenedScriptInfo(info); - this.cleanupAfterOpeningFile(); + const { defaultConfigProject, ...result } = this.assignProjectToOpenedScriptInfo(info); + this.cleanupAfterOpeningFile(defaultConfigProject); this.telemetryOnOpenFile(info); return result; } - private removeOrphanConfiguredProjects() { + private removeOrphanConfiguredProjects(toRetainConfiguredProjects: ConfiguredProject[] | ConfiguredProject | undefined) { const toRemoveConfiguredProjects = cloneMap(this.configuredProjects); + if (toRetainConfiguredProjects) { + if (isArray(toRetainConfiguredProjects)) { + toRetainConfiguredProjects.forEach(retainConfiguredProject); + } + else { + retainConfiguredProject(toRetainConfiguredProjects); + } + } // Do not remove configured projects that are used as original projects of other this.inferredProjects.forEach(markOriginalProjectsAsUsed); @@ -2720,7 +2734,7 @@ namespace ts.server { this.configuredProjects.forEach(project => { // If project has open ref (there are more than zero references from external project/open file), keep it alive as well as any project it references if (project.hasOpenRef()) { - toRemoveConfiguredProjects.delete(project.canonicalConfigFilePath); + retainConfiguredProject(project); markOriginalProjectsAsUsed(project); } else { @@ -2729,7 +2743,7 @@ namespace ts.server { if (ref) { const refProject = this.configuredProjects.get(ref.sourceFile.path); if (refProject && refProject.hasOpenRef()) { - toRemoveConfiguredProjects.delete(project.canonicalConfigFilePath); + retainConfiguredProject(project); } } }); @@ -2744,6 +2758,10 @@ namespace ts.server { project.originalConfiguredProjects.forEach((_value, configuredProjectPath) => toRemoveConfiguredProjects.delete(configuredProjectPath)); } } + + function retainConfiguredProject(project: ConfiguredProject) { + toRemoveConfiguredProjects.delete(project.canonicalConfigFilePath); + } } private removeOrphanScriptInfos() { @@ -2886,8 +2904,9 @@ namespace ts.server { } // All the script infos now exist, so ok to go update projects for open files + let defaultConfigProjects: ConfiguredProject[] | undefined; if (openScriptInfos) { - openScriptInfos.forEach(info => this.assignProjectToOpenedScriptInfo(info)); + defaultConfigProjects = mapDefined(openScriptInfos, info => this.assignProjectToOpenedScriptInfo(info).defaultConfigProject); } // While closing files there could be open files that needed assigning new inferred projects, do it now @@ -2896,7 +2915,7 @@ namespace ts.server { } // Cleanup projects - this.cleanupAfterOpeningFile(); + this.cleanupAfterOpeningFile(defaultConfigProjects); // Telemetry forEach(openScriptInfos, info => this.telemetryOnOpenFile(info)); diff --git a/src/testRunner/unittests/tsserver/configuredProjects.ts b/src/testRunner/unittests/tsserver/configuredProjects.ts index a72c9924303..7d066cd9473 100644 --- a/src/testRunner/unittests/tsserver/configuredProjects.ts +++ b/src/testRunner/unittests/tsserver/configuredProjects.ts @@ -866,12 +866,12 @@ namespace ts.projectSystem { const projectService = createProjectService(host); projectService.openClientFile(file1.path); host.runQueuedTimeoutCallbacks(); - // Since there is no file open from configFile it would be closed - checkNumberOfConfiguredProjects(projectService, 0); - checkNumberOfInferredProjects(projectService, 1); + // Since file1 refers to config file as the default project, it needs to be kept alive + checkNumberOfProjects(projectService, { inferredProjects: 1, configuredProjects: 1 }); const inferredProject = projectService.inferredProjects[0]; assert.isTrue(inferredProject.containsFile(file1.path)); + assert.isFalse(projectService.configuredProjects.get(configFile.path)!.containsFile(file1.path)); }); it("should be able to handle @types if input file list is empty", () => { @@ -898,8 +898,8 @@ namespace ts.projectSystem { const projectService = createProjectService(host); projectService.openClientFile(f.path); - // Since no file from the configured project is open, it would be closed immediately - projectService.checkNumberOfProjects({ configuredProjects: 0, inferredProjects: 1 }); + // Since f refers to config file as the default project, it needs to be kept alive + projectService.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: 1 }); }); it("should tolerate invalid include files that start in subDirectory", () => { @@ -924,8 +924,8 @@ namespace ts.projectSystem { const projectService = createProjectService(host); projectService.openClientFile(f.path); - // Since no file from the configured project is open, it would be closed immediately - projectService.checkNumberOfProjects({ configuredProjects: 0, inferredProjects: 1 }); + // Since f refers to config file as the default project, it needs to be kept alive + projectService.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: 1 }); }); it("Changed module resolution reflected when specifying files list", () => { diff --git a/src/testRunner/unittests/tsserver/inferredProjects.ts b/src/testRunner/unittests/tsserver/inferredProjects.ts index 6882f2ed5c5..44ff8292acd 100644 --- a/src/testRunner/unittests/tsserver/inferredProjects.ts +++ b/src/testRunner/unittests/tsserver/inferredProjects.ts @@ -381,30 +381,54 @@ namespace ts.projectSystem { return originalDelete.call(projectService.configuredProjects, key); }; + // Do not remove config project when opening jsFile that is not present as part of config project projectService.openClientFile(jsFile1.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + checkNumberOfProjects(projectService, { inferredProjects: 1, configuredProjects: 1 }); checkProjectActualFiles(projectService.inferredProjects[0], [jsFile1.path, libFile.path]); - checkConfiguredProjectCreatedAndDeleted(); + const project = projectService.configuredProjects.get(config.path)!; + checkProjectActualFiles(project, [appFile.path, config.path, libFile.path]); + checkConfiguredProjectCreatedAndNotDeleted(); + // Do not remove config project when opening jsFile that is not present as part of config project projectService.closeClientFile(jsFile1.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + checkNumberOfProjects(projectService, { inferredProjects: 1, configuredProjects: 1 }); projectService.openClientFile(jsFile2.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + checkNumberOfProjects(projectService, { inferredProjects: 1, configuredProjects: 1 }); checkProjectActualFiles(projectService.inferredProjects[0], [jsFile2.path, libFile.path]); - checkConfiguredProjectCreatedAndDeleted(); + checkProjectActualFiles(project, [appFile.path, config.path, libFile.path]); + checkConfiguredProjectNotCreatedAndNotDeleted(); + // Do not remove config project when opening jsFile that is not present as part of config project projectService.openClientFile(jsFile1.path); + checkNumberOfProjects(projectService, { inferredProjects: 2, configuredProjects: 1 }); + checkProjectActualFiles(projectService.inferredProjects[0], [jsFile2.path, libFile.path]); + checkProjectActualFiles(projectService.inferredProjects[1], [jsFile1.path, libFile.path]); + checkProjectActualFiles(project, [appFile.path, config.path, libFile.path]); + checkConfiguredProjectNotCreatedAndNotDeleted(); + + // When opening file that doesnt fall back to the config file, we remove the config project + projectService.openClientFile(libFile.path); checkNumberOfProjects(projectService, { inferredProjects: 2 }); checkProjectActualFiles(projectService.inferredProjects[0], [jsFile2.path, libFile.path]); checkProjectActualFiles(projectService.inferredProjects[1], [jsFile1.path, libFile.path]); - checkConfiguredProjectCreatedAndDeleted(); + checkConfiguredProjectNotCreatedButDeleted(); - function checkConfiguredProjectCreatedAndDeleted() { + function checkConfiguredProjectCreatedAndNotDeleted() { assert.equal(configuredCreated.size, 1); assert.isTrue(configuredCreated.has(config.path)); + assert.equal(configuredRemoved.size, 0); + configuredCreated.clear(); + } + + function checkConfiguredProjectNotCreatedAndNotDeleted() { + assert.equal(configuredCreated.size, 0); + assert.equal(configuredRemoved.size, 0); + } + + function checkConfiguredProjectNotCreatedButDeleted() { + assert.equal(configuredCreated.size, 0); assert.equal(configuredRemoved.size, 1); assert.isTrue(configuredRemoved.has(config.path)); - configuredCreated.clear(); configuredRemoved.clear(); } }); diff --git a/src/testRunner/unittests/tsserver/projects.ts b/src/testRunner/unittests/tsserver/projects.ts index abb21669f8a..78d22615256 100644 --- a/src/testRunner/unittests/tsserver/projects.ts +++ b/src/testRunner/unittests/tsserver/projects.ts @@ -634,13 +634,17 @@ namespace ts.projectSystem { path: "/a/main.js", content: "var y = 1" }; + const f3 = { + path: "/main.js", + content: "var y = 1" + }; const config = { path: "/a/tsconfig.json", content: JSON.stringify({ compilerOptions: { allowJs: true } }) }; - const host = createServerHost([f1, f2, config]); + const host = createServerHost([f1, f2, f3, config]); const projectService = createProjectService(host); projectService.setHostConfiguration({ extraFileExtensions: [ @@ -652,13 +656,19 @@ namespace ts.projectSystem { projectService.checkNumberOfProjects({ configuredProjects: 1 }); checkProjectActualFiles(configuredProjectAt(projectService, 0), [f1.path, config.path]); - // Should close configured project with next file open + // Since f2 refers to config file as the default project, it needs to be kept alive projectService.closeClientFile(f1.path); - projectService.openClientFile(f2.path); + projectService.checkNumberOfProjects({ inferredProjects: 1, configuredProjects: 1 }); + assert.isDefined(projectService.configuredProjects.get(config.path)); + checkProjectActualFiles(projectService.inferredProjects[0], [f2.path]); + + // Should close configured project with next file open + projectService.closeClientFile(f2.path); + projectService.openClientFile(f3.path); projectService.checkNumberOfProjects({ inferredProjects: 1 }); assert.isUndefined(projectService.configuredProjects.get(config.path)); - checkProjectActualFiles(projectService.inferredProjects[0], [f2.path]); + checkProjectActualFiles(projectService.inferredProjects[0], [f3.path]); }); it("tsconfig script block support", () => { From 4c76bae8880d97d01847064cd98befba8f42028a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 25 Jul 2019 14:03:17 -0700 Subject: [PATCH 016/182] Don't exclude non-anonymous object types in identity checks --- src/compiler/checker.ts | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 54c8d05e502..0f8326c1fac 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15500,7 +15500,7 @@ namespace ts { // First, infer between exactly matching source and target constituents and remove // the matching types. Types exactly match when they are identical or, in union // types, when the source is a literal and the target is the corresponding primitive. - const matching = target.flags & TypeFlags.Union ? isTypeOrBaseExactlyMatchedBy : isTypeExactlyMatchedBy; + const matching = target.flags & TypeFlags.Union ? isTypeOrBaseIdenticalTo : isTypeIdenticalTo; const [tempSources, tempTargets] = inferFromMatchingTypes((source).types, (target).types, matching); // Next, infer between closely matching source and target constituents and remove // the matching types. Types closely match when they are instantiations of the same @@ -15515,7 +15515,7 @@ namespace ts { else if (target.flags & TypeFlags.Union && !(target.flags & TypeFlags.EnumLiteral) || target.flags & TypeFlags.Intersection) { // This block of code is an optimized version of the block above for the simpler case // of a singleton source type. - const matching = target.flags & TypeFlags.Union ? isTypeOrBaseExactlyMatchedBy : isTypeExactlyMatchedBy; + const matching = target.flags & TypeFlags.Union ? isTypeOrBaseIdenticalTo : isTypeIdenticalTo; if (inferFromMatchingType(source, (target).types, matching)) return; if (inferFromMatchingType(source, (target).types, isTypeCloselyMatchedBy)) return; } @@ -15974,19 +15974,8 @@ namespace ts { } } - function isNonObjectOrAnonymousType(type: Type) { - // We exclude non-anonymous object types because some frameworks (e.g. Ember) rely on the ability to - // infer between types that don't witness their type variables. Such types would otherwise be eliminated - // because they appear identical. - return !(type.flags & TypeFlags.Object) || !!(getObjectFlags(type) & ObjectFlags.Anonymous); - } - - function isTypeExactlyMatchedBy(s: Type, t: Type) { - return s === t || isNonObjectOrAnonymousType(s) && isNonObjectOrAnonymousType(t) && isTypeIdenticalTo(s, t); - } - - function isTypeOrBaseExactlyMatchedBy(s: Type, t: Type) { - return isTypeExactlyMatchedBy(s, t) || !!(s.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) && isTypeIdenticalTo(getBaseTypeOfLiteralType(s), t); + function isTypeOrBaseIdenticalTo(s: Type, t: Type) { + return isTypeIdenticalTo(s, t) || !!(s.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) && isTypeIdenticalTo(getBaseTypeOfLiteralType(s), t); } function isTypeCloselyMatchedBy(s: Type, t: Type) { From 9647506d8c6dea0c2531f5f4867971e419799e1f Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 24 Jul 2019 15:57:46 -0700 Subject: [PATCH 017/182] Support classification of triple-slash references Note: not restricted to the element and attribute names that actually bind --- src/services/classifier.ts | 83 +++++++++++++++++++ .../syntacticClassificationsTripleSlash1.ts | 15 ++++ .../syntacticClassificationsTripleSlash10.ts | 13 +++ .../syntacticClassificationsTripleSlash11.ts | 15 ++++ .../syntacticClassificationsTripleSlash12.ts | 19 +++++ .../syntacticClassificationsTripleSlash13.ts | 16 ++++ .../syntacticClassificationsTripleSlash14.ts | 7 ++ .../syntacticClassificationsTripleSlash15.ts | 25 ++++++ .../syntacticClassificationsTripleSlash16.ts | 17 ++++ .../syntacticClassificationsTripleSlash2.ts | 16 ++++ .../syntacticClassificationsTripleSlash3.ts | 19 +++++ .../syntacticClassificationsTripleSlash4.ts | 8 ++ .../syntacticClassificationsTripleSlash5.ts | 9 ++ .../syntacticClassificationsTripleSlash6.ts | 10 +++ .../syntacticClassificationsTripleSlash7.ts | 10 +++ .../syntacticClassificationsTripleSlash8.ts | 10 +++ .../syntacticClassificationsTripleSlash9.ts | 10 +++ 17 files changed, 302 insertions(+) create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash1.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash10.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash11.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash12.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash13.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash14.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash15.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash16.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash2.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash3.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash4.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash5.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash6.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash7.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash8.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsTripleSlash9.ts diff --git a/src/services/classifier.ts b/src/services/classifier.ts index f85a69681de..f1db477481f 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -683,6 +683,11 @@ namespace ts { return; } } + else if (kind === SyntaxKind.SingleLineCommentTrivia) { + if (tryClassifyTripleSlashComment(start, width)) { + return; + } + } // Simple comment. Just add as is. pushCommentRange(start, width); @@ -755,6 +760,84 @@ namespace ts { } } + function tryClassifyTripleSlashComment(start: number, width: number): boolean { + const tripleSlashXMLCommentRegEx = /^(\/\/\/\s*)(<)(?:(\S+)((?:[^/]|\/[^>])*)(\/>)?)?/im; + const attributeRegex = /(\S+)(\s*)(=)(\s*)('[^']+'|"[^"]+")/img; + + const text = sourceFile.text.substr(start, width); + const match = tripleSlashXMLCommentRegEx.exec(text); + if (!match) { + return false; + } + + let pos = start; + + pushCommentRange(pos, match[1].length); // /// + pos += match[1].length; + + pushClassification(pos, match[2].length, ClassificationType.punctuation); // < + pos += match[2].length; + + if (!match[3]) { + return true; + } + + pushClassification(pos, match[3].length, ClassificationType.jsxSelfClosingTagName); // element name + pos += match[3].length; + + const attrText = match[4]; + let attrPos = pos; + while (true) { + const attrMatch = attributeRegex.exec(attrText); + if (!attrMatch) { + break; + } + + const newAttrPos = pos + attrMatch.index; + if (newAttrPos > attrPos) { + pushCommentRange(attrPos, newAttrPos - attrPos); + attrPos = newAttrPos; + } + + pushClassification(attrPos, attrMatch[1].length, ClassificationType.jsxAttribute); // attribute name + attrPos += attrMatch[1].length; + + if (attrMatch[2].length) { + pushCommentRange(attrPos, attrMatch[2].length); // whitespace + attrPos += attrMatch[2].length; + } + + pushClassification(attrPos, attrMatch[3].length, ClassificationType.operator); // = + attrPos += attrMatch[3].length; + + if (attrMatch[4].length) { + pushCommentRange(attrPos, attrMatch[4].length); // whitespace + attrPos += attrMatch[4].length; + } + + pushClassification(attrPos, attrMatch[5].length, ClassificationType.jsxAttributeStringLiteralValue); // attribute value + attrPos += attrMatch[5].length; + } + + pos += match[4].length; + + if (pos > attrPos) { + pushCommentRange(attrPos, pos - attrPos); + } + + if (match[5]) { + pushClassification(pos, match[5].length, ClassificationType.punctuation); // /> + pos += match[5].length; + } + + const end = start + width; + if (pos < end) { + pushCommentRange(pos, end - pos); + } + + return true; + } + function processJSDocTemplateTag(tag: JSDocTemplateTag) { for (const child of tag.getChildren()) { processElement(child); diff --git a/tests/cases/fourslash/syntacticClassificationsTripleSlash1.ts b/tests/cases/fourslash/syntacticClassificationsTripleSlash1.ts new file mode 100644 index 00000000000..13c27669ad5 --- /dev/null +++ b/tests/cases/fourslash/syntacticClassificationsTripleSlash1.ts @@ -0,0 +1,15 @@ +/// + +//// /// + +var c = classification; +verify.syntacticClassificationsAre( + c.comment("/// "), + c.punctuation("<"), + c.jsxSelfClosingTagName("reference"), + c.comment(" "), + c.jsxAttribute("path"), + c.operator("="), + c.jsxAttributeStringLiteralValue("\"./module.ts\""), + c.comment(" "), + c.punctuation("/>")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsTripleSlash10.ts b/tests/cases/fourslash/syntacticClassificationsTripleSlash10.ts new file mode 100644 index 00000000000..d1bb681b92e --- /dev/null +++ b/tests/cases/fourslash/syntacticClassificationsTripleSlash10.ts @@ -0,0 +1,13 @@ +/// + +//// /// + +//// /// + +//// /// + +var c = classification; +verify.syntacticClassificationsAre( + c.comment("/// "), + c.punctuation("<"), + c.jsxSelfClosingTagName("reference"), + c.comment(" "), + c.jsxAttribute("path"), + c.operator("="), + c.jsxAttributeStringLiteralValue("\"./module.ts\""), + c.comment(" bad "), + c.jsxAttribute("types"), + c.operator("="), + c.jsxAttributeStringLiteralValue("\"node\""), + c.comment(" "), + c.punctuation("/>")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsTripleSlash13.ts b/tests/cases/fourslash/syntacticClassificationsTripleSlash13.ts new file mode 100644 index 00000000000..182b01f7560 --- /dev/null +++ b/tests/cases/fourslash/syntacticClassificationsTripleSlash13.ts @@ -0,0 +1,16 @@ +/// + +//// /// trailing + +var c = classification; +verify.syntacticClassificationsAre( + c.comment("/// "), + c.punctuation("<"), + c.jsxSelfClosingTagName("reference"), + c.comment(" "), + c.jsxAttribute("path"), + c.operator("="), + c.jsxAttributeStringLiteralValue("\"./module.ts\""), + c.comment(" "), + c.punctuation("/>"), + c.comment(" trailing")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsTripleSlash14.ts b/tests/cases/fourslash/syntacticClassificationsTripleSlash14.ts new file mode 100644 index 00000000000..a7d16fea02c --- /dev/null +++ b/tests/cases/fourslash/syntacticClassificationsTripleSlash14.ts @@ -0,0 +1,7 @@ +/// + +//// /// nonElement + +var c = classification; +verify.syntacticClassificationsAre( + c.comment("/// nonElement")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsTripleSlash15.ts b/tests/cases/fourslash/syntacticClassificationsTripleSlash15.ts new file mode 100644 index 00000000000..8ec5ebbea5d --- /dev/null +++ b/tests/cases/fourslash/syntacticClassificationsTripleSlash15.ts @@ -0,0 +1,25 @@ +/// + +//// /// +//// /// + +var c = classification; +verify.syntacticClassificationsAre( + c.comment("/// "), + c.punctuation("<"), + c.jsxSelfClosingTagName("reference"), + c.comment(" "), + c.jsxAttribute("path"), + c.operator("="), + c.jsxAttributeStringLiteralValue("\"./module1.ts\""), + c.comment(" "), + c.punctuation("/>"), + c.comment("/// "), + c.punctuation("<"), + c.jsxSelfClosingTagName("reference"), + c.comment(" "), + c.jsxAttribute("path"), + c.operator("="), + c.jsxAttributeStringLiteralValue("\"./module2.ts\""), + c.comment(" "), + c.punctuation("/>")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsTripleSlash16.ts b/tests/cases/fourslash/syntacticClassificationsTripleSlash16.ts new file mode 100644 index 00000000000..1dbee22cb59 --- /dev/null +++ b/tests/cases/fourslash/syntacticClassificationsTripleSlash16.ts @@ -0,0 +1,17 @@ +/// + +//// /// +//// 1 + +var c = classification; +verify.syntacticClassificationsAre( + c.comment("/// "), + c.punctuation("<"), + c.jsxSelfClosingTagName("reference"), + c.comment(" "), + c.jsxAttribute("path"), + c.operator("="), + c.jsxAttributeStringLiteralValue("\"./module.ts\""), + c.comment(" "), + c.punctuation("/>"), + c.numericLiteral("1")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsTripleSlash2.ts b/tests/cases/fourslash/syntacticClassificationsTripleSlash2.ts new file mode 100644 index 00000000000..278d66dcb4a --- /dev/null +++ b/tests/cases/fourslash/syntacticClassificationsTripleSlash2.ts @@ -0,0 +1,16 @@ +/// + +//// /// + +var c = classification; +verify.syntacticClassificationsAre( + c.comment("///"), + c.punctuation("<"), + c.jsxSelfClosingTagName("reference"), + c.comment(" "), + c.jsxAttribute("path"), + c.comment(" "), + c.operator("="), + c.comment(" "), + c.jsxAttributeStringLiteralValue("\"./module.ts\""), + c.punctuation("/>")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsTripleSlash3.ts b/tests/cases/fourslash/syntacticClassificationsTripleSlash3.ts new file mode 100644 index 00000000000..11d3b2462be --- /dev/null +++ b/tests/cases/fourslash/syntacticClassificationsTripleSlash3.ts @@ -0,0 +1,19 @@ +/// + +//// /// + +var c = classification; +verify.syntacticClassificationsAre( + c.comment("/// "), + c.punctuation("<"), + c.jsxSelfClosingTagName("reference"), + c.comment(" "), + c.jsxAttribute("path"), + c.operator("="), + c.jsxAttributeStringLiteralValue("\"./module.ts\""), + c.comment(" "), + c.jsxAttribute("types"), + c.operator("="), + c.jsxAttributeStringLiteralValue("\"node\""), + c.comment(" "), + c.punctuation("/>")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsTripleSlash4.ts b/tests/cases/fourslash/syntacticClassificationsTripleSlash4.ts new file mode 100644 index 00000000000..e656c811377 --- /dev/null +++ b/tests/cases/fourslash/syntacticClassificationsTripleSlash4.ts @@ -0,0 +1,8 @@ +/// + +//// /// < + +var c = classification; +verify.syntacticClassificationsAre( + c.comment("/// "), + c.punctuation("<")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsTripleSlash5.ts b/tests/cases/fourslash/syntacticClassificationsTripleSlash5.ts new file mode 100644 index 00000000000..c6f1de38f28 --- /dev/null +++ b/tests/cases/fourslash/syntacticClassificationsTripleSlash5.ts @@ -0,0 +1,9 @@ +/// + +//// /// + +//// /// + +//// /// + +//// /// + +//// /// Date: Thu, 25 Jul 2019 17:10:31 -0400 Subject: [PATCH 018/182] Handle namepaths inside JSDoc type expressions a bit better - fixes #31298 --- src/compiler/parser.ts | 8 +++ src/compiler/types.ts | 7 +++ .../reference/api/tsserverlibrary.d.ts | 57 ++++++++++--------- tests/baselines/reference/api/typescript.d.ts | 57 ++++++++++--------- .../noAssertForUnparseableTypedefs.errors.txt | 9 +-- .../fourslash/jsDocDontBreakWithNamespaces.ts | 17 ++++++ 6 files changed, 97 insertions(+), 58 deletions(-) create mode 100644 tests/cases/fourslash/jsDocDontBreakWithNamespaces.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 254be93000b..9762302b7a2 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2429,8 +2429,16 @@ namespace ts { function parseJSDocType(): TypeNode { scanner.setInJSDocType(true); const dotdotdot = parseOptionalToken(SyntaxKind.DotDotDotToken); + const moduleSpecifier = parseOptionalToken(SyntaxKind.ModuleKeyword); let type = parseTypeOrTypePredicate(); scanner.setInJSDocType(false); + if (moduleSpecifier) { + const moduleTag = createNode(SyntaxKind.JSDocNamepathType, moduleSpecifier.pos) as JSDocNamepathType; + while (token() !== SyntaxKind.CloseBraceToken && token() !== SyntaxKind.EndOfFileToken) { + nextTokenJSDoc(); + } + type = finishNode(moduleTag); + } if (dotdotdot) { const variadic = createNode(SyntaxKind.JSDocVariadicType, dotdotdot.pos) as JSDocVariadicType; variadic.type = type; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 67c85147aed..e1461071e20 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -455,6 +455,8 @@ namespace ts { JSDocOptionalType, JSDocFunctionType, JSDocVariadicType, + // https://jsdoc.app/about-namepaths.html + JSDocNamepathType, JSDocComment, JSDocTypeLiteral, JSDocSignature, @@ -2430,6 +2432,11 @@ namespace ts { type: TypeNode; } + export interface JSDocNamepathType extends JSDocType { + kind: SyntaxKind.JSDocNamepathType; + type: TypeNode; + } + export type JSDocTypeReferencingNode = JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType; export interface JSDoc extends Node { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index c2bad61505b..549cb6368f9 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -374,29 +374,30 @@ declare namespace ts { JSDocOptionalType = 294, JSDocFunctionType = 295, JSDocVariadicType = 296, - JSDocComment = 297, - JSDocTypeLiteral = 298, - JSDocSignature = 299, - JSDocTag = 300, - JSDocAugmentsTag = 301, - JSDocAuthorTag = 302, - JSDocClassTag = 303, - JSDocCallbackTag = 304, - JSDocEnumTag = 305, - JSDocParameterTag = 306, - JSDocReturnTag = 307, - JSDocThisTag = 308, - JSDocTypeTag = 309, - JSDocTemplateTag = 310, - JSDocTypedefTag = 311, - JSDocPropertyTag = 312, - SyntaxList = 313, - NotEmittedStatement = 314, - PartiallyEmittedExpression = 315, - CommaListExpression = 316, - MergeDeclarationMarker = 317, - EndOfDeclarationMarker = 318, - Count = 319, + JSDocNamepathType = 297, + JSDocComment = 298, + JSDocTypeLiteral = 299, + JSDocSignature = 300, + JSDocTag = 301, + JSDocAugmentsTag = 302, + JSDocAuthorTag = 303, + JSDocClassTag = 304, + JSDocCallbackTag = 305, + JSDocEnumTag = 306, + JSDocParameterTag = 307, + JSDocReturnTag = 308, + JSDocThisTag = 309, + JSDocTypeTag = 310, + JSDocTemplateTag = 311, + JSDocTypedefTag = 312, + JSDocPropertyTag = 313, + SyntaxList = 314, + NotEmittedStatement = 315, + PartiallyEmittedExpression = 316, + CommaListExpression = 317, + MergeDeclarationMarker = 318, + EndOfDeclarationMarker = 319, + Count = 320, FirstAssignment = 60, LastAssignment = 72, FirstCompoundAssignment = 61, @@ -423,9 +424,9 @@ declare namespace ts { LastBinaryOperator = 72, FirstNode = 149, FirstJSDocNode = 289, - LastJSDocNode = 312, - FirstJSDocTagNode = 300, - LastJSDocTagNode = 312, + LastJSDocNode = 313, + FirstJSDocTagNode = 301, + LastJSDocTagNode = 313, } enum NodeFlags { None = 0, @@ -1558,6 +1559,10 @@ declare namespace ts { kind: SyntaxKind.JSDocVariadicType; type: TypeNode; } + interface JSDocNamepathType extends JSDocType { + kind: SyntaxKind.JSDocNamepathType; + type: TypeNode; + } type JSDocTypeReferencingNode = JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType; interface JSDoc extends Node { kind: SyntaxKind.JSDocComment; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 7a2559bbc22..935aff356f8 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -374,29 +374,30 @@ declare namespace ts { JSDocOptionalType = 294, JSDocFunctionType = 295, JSDocVariadicType = 296, - JSDocComment = 297, - JSDocTypeLiteral = 298, - JSDocSignature = 299, - JSDocTag = 300, - JSDocAugmentsTag = 301, - JSDocAuthorTag = 302, - JSDocClassTag = 303, - JSDocCallbackTag = 304, - JSDocEnumTag = 305, - JSDocParameterTag = 306, - JSDocReturnTag = 307, - JSDocThisTag = 308, - JSDocTypeTag = 309, - JSDocTemplateTag = 310, - JSDocTypedefTag = 311, - JSDocPropertyTag = 312, - SyntaxList = 313, - NotEmittedStatement = 314, - PartiallyEmittedExpression = 315, - CommaListExpression = 316, - MergeDeclarationMarker = 317, - EndOfDeclarationMarker = 318, - Count = 319, + JSDocNamepathType = 297, + JSDocComment = 298, + JSDocTypeLiteral = 299, + JSDocSignature = 300, + JSDocTag = 301, + JSDocAugmentsTag = 302, + JSDocAuthorTag = 303, + JSDocClassTag = 304, + JSDocCallbackTag = 305, + JSDocEnumTag = 306, + JSDocParameterTag = 307, + JSDocReturnTag = 308, + JSDocThisTag = 309, + JSDocTypeTag = 310, + JSDocTemplateTag = 311, + JSDocTypedefTag = 312, + JSDocPropertyTag = 313, + SyntaxList = 314, + NotEmittedStatement = 315, + PartiallyEmittedExpression = 316, + CommaListExpression = 317, + MergeDeclarationMarker = 318, + EndOfDeclarationMarker = 319, + Count = 320, FirstAssignment = 60, LastAssignment = 72, FirstCompoundAssignment = 61, @@ -423,9 +424,9 @@ declare namespace ts { LastBinaryOperator = 72, FirstNode = 149, FirstJSDocNode = 289, - LastJSDocNode = 312, - FirstJSDocTagNode = 300, - LastJSDocTagNode = 312, + LastJSDocNode = 313, + FirstJSDocTagNode = 301, + LastJSDocTagNode = 313, } enum NodeFlags { None = 0, @@ -1558,6 +1559,10 @@ declare namespace ts { kind: SyntaxKind.JSDocVariadicType; type: TypeNode; } + interface JSDocNamepathType extends JSDocType { + kind: SyntaxKind.JSDocNamepathType; + type: TypeNode; + } type JSDocTypeReferencingNode = JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType; interface JSDoc extends Node { kind: SyntaxKind.JSDocComment; diff --git a/tests/baselines/reference/noAssertForUnparseableTypedefs.errors.txt b/tests/baselines/reference/noAssertForUnparseableTypedefs.errors.txt index b131c8adac0..a0b1f6210ba 100644 --- a/tests/baselines/reference/noAssertForUnparseableTypedefs.errors.txt +++ b/tests/baselines/reference/noAssertForUnparseableTypedefs.errors.txt @@ -1,14 +1,11 @@ -tests/cases/conformance/jsdoc/bug26693.js(1,15): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`. -tests/cases/conformance/jsdoc/bug26693.js(1,21): error TS1005: '}' expected. +tests/cases/conformance/jsdoc/bug26693.js(1,21): error TS1110: Type expected. tests/cases/conformance/jsdoc/bug26693.js(2,22): error TS2307: Cannot find module 'nope'. -==== tests/cases/conformance/jsdoc/bug26693.js (3 errors) ==== +==== tests/cases/conformance/jsdoc/bug26693.js (2 errors) ==== /** @typedef {module:locale} hi */ - ~~~~~~ -!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`. ~ -!!! error TS1005: '}' expected. +!!! error TS1110: Type expected. import { nope } from 'nope'; ~~~~~~ !!! error TS2307: Cannot find module 'nope'. diff --git a/tests/cases/fourslash/jsDocDontBreakWithNamespaces.ts b/tests/cases/fourslash/jsDocDontBreakWithNamespaces.ts new file mode 100644 index 00000000000..7807d5d30d1 --- /dev/null +++ b/tests/cases/fourslash/jsDocDontBreakWithNamespaces.ts @@ -0,0 +1,17 @@ +/// +// @allowJs: true +// @Filename: 31298.js +/////** +//// * @returns {module:@nodefuel/web~Webserver~wsServer#hello} Websocket server object +//// */ +////function foo() { } +////foo(''/**/); + +verify.signatureHelp({ + marker: "", + text: "foo(): any", + docComment: "", + tags: [ + { name: "returns", text: "Websocket server object" }, + ], +}); From 599e36a0685fbeebddc00e8cb36b76fb52b9f0c8 Mon Sep 17 00:00:00 2001 From: Jesse Trinity <42591254+jessetrinity@users.noreply.github.com> Date: Thu, 25 Jul 2019 21:29:12 -0700 Subject: [PATCH 019/182] Decrement line ends if they end with a carriage return. (#31220) * Decrement line ends if they end with a carriage return. * Changed handling of newlines and inlined regex operation. * fixed misname of hintSpan * added tests * revert inline of regex match and use getLineEndOfPosition * fixed lint error and changed a silly thing in tests --- src/services/outliningElementsCollector.ts | 5 ++--- .../unittests/services/hostNewLineSupport.ts | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index a23eddf0628..6e5e2b963e8 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -71,9 +71,8 @@ namespace ts.OutliningElementsCollector { function addRegionOutliningSpans(sourceFile: SourceFile, out: Push): void { const regions: OutliningSpan[] = []; const lineStarts = sourceFile.getLineStarts(); - for (let i = 0; i < lineStarts.length; i++) { - const currentLineStart = lineStarts[i]; - const lineEnd = i + 1 === lineStarts.length ? sourceFile.getEnd() : lineStarts[i + 1] - 1; + for (const currentLineStart of lineStarts) { + const lineEnd = sourceFile.getLineEndOfPosition(currentLineStart); const lineText = sourceFile.text.substring(currentLineStart, lineEnd); const result = isRegionDelimiter(lineText); if (!result || isInComment(sourceFile, currentLineStart)) { diff --git a/src/testRunner/unittests/services/hostNewLineSupport.ts b/src/testRunner/unittests/services/hostNewLineSupport.ts index cafe4813431..48bc124f3bc 100644 --- a/src/testRunner/unittests/services/hostNewLineSupport.ts +++ b/src/testRunner/unittests/services/hostNewLineSupport.ts @@ -38,6 +38,18 @@ namespace ts { verifyNewLines(content, { newLine: NewLineKind.LineFeed }); } + function verifyOutliningSpanNewLines(content: string, options: CompilerOptions) { + const ls = testLSWithFiles(options, [{ + content, + fileOptions: {}, + unitName: "input.ts" + }]); + const span = ls.getOutliningSpans("input.ts")[0]; + const textAfterSpanCollapse = content.substring(span.textSpan.start + span.textSpan.length); + assert(textAfterSpanCollapse.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines"); + assert(!textAfterSpanCollapse.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines"); + } + it("should exist and respect provided compiler options", () => { verifyBothNewLines(` function foo() { @@ -45,5 +57,15 @@ namespace ts { } `); }); + + it("should respect CRLF line endings around outlining spans", () => { + verifyOutliningSpanNewLines("// comment not included\r\n// #region name\r\nlet x: string = \"x\";\r\n// #endregion name\r\n", + { newLine: NewLineKind.CarriageReturnLineFeed }); + }); + + it("should respect LF line endings around outlining spans", () => { + verifyOutliningSpanNewLines("// comment not included\n// #region name\nlet x: string = \"x\";\n// #endregion name\n\n", + { newLine: NewLineKind.LineFeed }); + }); }); } From 00f41e5693e55ede6a243b8fe0f4d982081ef2dd Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 26 Jul 2019 11:03:31 -0700 Subject: [PATCH 020/182] Less aggressive reduction of intersection types --- src/compiler/checker.ts | 70 +++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0f8326c1fac..8ef7b3453a2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15310,7 +15310,7 @@ namespace ts { objectFlags & ObjectFlags.Reference && forEach((type).typeArguments, couldContainTypeVariables) || objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations || objectFlags & ObjectFlags.Mapped || - type.flags & TypeFlags.UnionOrIntersection && couldUnionOrIntersectionContainTypeVariables(type)); + type.flags & TypeFlags.UnionOrIntersection && !(type.flags & TypeFlags.EnumLiteral) && couldUnionOrIntersectionContainTypeVariables(type)); } function couldUnionOrIntersectionContainTypeVariables(type: UnionOrIntersectionType): boolean { @@ -15487,37 +15487,47 @@ namespace ts { inferFromTypeArguments(source.aliasTypeArguments, target.aliasTypeArguments!, getAliasVariances(source.aliasSymbol)); return; } - if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union && !(source.flags & TypeFlags.EnumLiteral && target.flags & TypeFlags.EnumLiteral) || - source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) { - // Source and target are both unions or both intersections. If source and target - // are the same type, just relate each constituent type to itself. - if (source === target) { - for (const t of (source).types) { - inferFromTypes(t, t); - } - return; + if (source === target && source.flags & TypeFlags.UnionOrIntersection) { + // When source and target are the same union or intersection type, just relate each constituent + // type to itself. + for (const t of (source).types) { + inferFromTypes(t, t); } - // First, infer between exactly matching source and target constituents and remove - // the matching types. Types exactly match when they are identical or, in union - // types, when the source is a literal and the target is the corresponding primitive. - const matching = target.flags & TypeFlags.Union ? isTypeOrBaseIdenticalTo : isTypeIdenticalTo; - const [tempSources, tempTargets] = inferFromMatchingTypes((source).types, (target).types, matching); - // Next, infer between closely matching source and target constituents and remove - // the matching types. Types closely match when they are instantiations of the same - // object type or instantiations of the same type alias. - const [sources, targets] = inferFromMatchingTypes(tempSources, tempTargets, isTypeCloselyMatchedBy); - if (sources.length === 0 || targets.length === 0) { - return; - } - source = source.flags & TypeFlags.Union ? getUnionType(sources) : getIntersectionType(sources); - target = target.flags & TypeFlags.Union ? getUnionType(targets) : getIntersectionType(targets); + return; } - else if (target.flags & TypeFlags.Union && !(target.flags & TypeFlags.EnumLiteral) || target.flags & TypeFlags.Intersection) { - // This block of code is an optimized version of the block above for the simpler case - // of a singleton source type. - const matching = target.flags & TypeFlags.Union ? isTypeOrBaseIdenticalTo : isTypeIdenticalTo; - if (inferFromMatchingType(source, (target).types, matching)) return; - if (inferFromMatchingType(source, (target).types, isTypeCloselyMatchedBy)) return; + if (target.flags & TypeFlags.Union) { + if (source.flags & TypeFlags.Union) { + // First, infer between identically matching source and target constituents and remove the + // matching types. + const [tempSources, tempTargets] = inferFromMatchingTypes((source).types, (target).types, isTypeOrBaseIdenticalTo); + // Next, infer between closely matching source and target constituents and remove + // the matching types. Types closely match when they are instantiations of the same + // object type or instantiations of the same type alias. + const [sources, targets] = inferFromMatchingTypes(tempSources, tempTargets, isTypeCloselyMatchedBy); + if (sources.length === 0 || targets.length === 0) { + return; + } + source = getUnionType(sources); + target = getUnionType(targets); + } + else { + if (inferFromMatchingType(source, (target).types, isTypeOrBaseIdenticalTo)) return; + if (inferFromMatchingType(source, (target).types, isTypeCloselyMatchedBy)) return; + } + } + else if (target.flags & TypeFlags.Intersection && some((target).types, t => !!getInferenceInfoForType(t))) { + if (source.flags & TypeFlags.Intersection) { + // Infer between identically matching source and target constituents and remove the matching types. + const [sources, targets] = inferFromMatchingTypes((source).types, (target).types, isTypeIdenticalTo); + if (sources.length === 0 || targets.length === 0) { + return; + } + source = getIntersectionType(sources); + target = getIntersectionType(targets); + } + else if (!(source.flags & TypeFlags.Union)) { + if (inferFromMatchingType(source, (target).types, isTypeIdenticalTo)) return; + } } else if (target.flags & (TypeFlags.IndexedAccess | TypeFlags.Substitution)) { target = getActualTypeVariable(target); From bb87332e73a1024dd3aa1b0fef18575cb504057d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 26 Jul 2019 13:12:44 -0700 Subject: [PATCH 021/182] Add more comments --- src/compiler/checker.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8ef7b3453a2..a69751673f6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15516,6 +15516,10 @@ namespace ts { } } else if (target.flags & TypeFlags.Intersection && some((target).types, t => !!getInferenceInfoForType(t))) { + // We reduce intersection types only when they contain naked type parameters. For example, when + // inferring from 'string[] & { extra: any }' to 'string[] & T' we want to remove string[] and + // infer { extra: any } for T. But when inferring to 'string[] & Iterable' we want to keep the + // string[] on the source side and infer string for T. if (source.flags & TypeFlags.Intersection) { // Infer between identically matching source and target constituents and remove the matching types. const [sources, targets] = inferFromMatchingTypes((source).types, (target).types, isTypeIdenticalTo); From ec38799e2a1a9df776882e20d89604c85ec3015f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 26 Jul 2019 13:17:00 -0700 Subject: [PATCH 022/182] Add more tests --- .../unionAndIntersectionInference3.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts b/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts index 17057de2b84..d64b1973695 100644 --- a/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts +++ b/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts @@ -40,3 +40,17 @@ declare let g2: (x: Foo2 | Bar2) => Promise; g1 = g2; g2 = g1; + +// Repro from #32572 + +declare function foo1(obj: string[] & Iterable): T; +declare function foo2(obj: string[] & T): T; + +declare let sa: string[]; +declare let sx: string[] & { extra: number }; + +let x1 = foo1(sa); // string +let y1 = foo1(sx); // string + +let x2 = foo2(sa); // unknown +let y2 = foo2(sx); // { extra: number } From 1ea4008120a20c4cca416af2096c5f3a46da7063 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 26 Jul 2019 13:17:06 -0700 Subject: [PATCH 023/182] Accept new baselines --- .../unionAndIntersectionInference3.js | 18 ++++++++ .../unionAndIntersectionInference3.symbols | 44 +++++++++++++++++++ .../unionAndIntersectionInference3.types | 41 +++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/tests/baselines/reference/unionAndIntersectionInference3.js b/tests/baselines/reference/unionAndIntersectionInference3.js index c9f5cffa1f7..415d98220a5 100644 --- a/tests/baselines/reference/unionAndIntersectionInference3.js +++ b/tests/baselines/reference/unionAndIntersectionInference3.js @@ -38,6 +38,20 @@ declare let g2: (x: Foo2 | Bar2) => Promise; g1 = g2; g2 = g1; + +// Repro from #32572 + +declare function foo1(obj: string[] & Iterable): T; +declare function foo2(obj: string[] & T): T; + +declare let sa: string[]; +declare let sx: string[] & { extra: number }; + +let x1 = foo1(sa); // string +let y1 = foo1(sx); // string + +let x2 = foo2(sa); // unknown +let y2 = foo2(sx); // { extra: number } //// [unionAndIntersectionInference3.js] @@ -52,3 +66,7 @@ f1 = f2; f2 = f1; g1 = g2; g2 = g1; +let x1 = foo1(sa); // string +let y1 = foo1(sx); // string +let x2 = foo2(sa); // unknown +let y2 = foo2(sx); // { extra: number } diff --git a/tests/baselines/reference/unionAndIntersectionInference3.symbols b/tests/baselines/reference/unionAndIntersectionInference3.symbols index b854ee1ce42..1d237951b4f 100644 --- a/tests/baselines/reference/unionAndIntersectionInference3.symbols +++ b/tests/baselines/reference/unionAndIntersectionInference3.symbols @@ -161,3 +161,47 @@ g2 = g1; >g2 : Symbol(g2, Decl(unionAndIntersectionInference3.ts, 35, 11)) >g1 : Symbol(g1, Decl(unionAndIntersectionInference3.ts, 34, 11)) +// Repro from #32572 + +declare function foo1(obj: string[] & Iterable): T; +>foo1 : Symbol(foo1, Decl(unionAndIntersectionInference3.ts, 38, 8)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 42, 22)) +>obj : Symbol(obj, Decl(unionAndIntersectionInference3.ts, 42, 25)) +>Iterable : Symbol(Iterable, Decl(lib.es2015.iterable.d.ts, --, --)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 42, 22)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 42, 22)) + +declare function foo2(obj: string[] & T): T; +>foo2 : Symbol(foo2, Decl(unionAndIntersectionInference3.ts, 42, 57)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 43, 22)) +>obj : Symbol(obj, Decl(unionAndIntersectionInference3.ts, 43, 25)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 43, 22)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 43, 22)) + +declare let sa: string[]; +>sa : Symbol(sa, Decl(unionAndIntersectionInference3.ts, 45, 11)) + +declare let sx: string[] & { extra: number }; +>sx : Symbol(sx, Decl(unionAndIntersectionInference3.ts, 46, 11)) +>extra : Symbol(extra, Decl(unionAndIntersectionInference3.ts, 46, 28)) + +let x1 = foo1(sa); // string +>x1 : Symbol(x1, Decl(unionAndIntersectionInference3.ts, 48, 3)) +>foo1 : Symbol(foo1, Decl(unionAndIntersectionInference3.ts, 38, 8)) +>sa : Symbol(sa, Decl(unionAndIntersectionInference3.ts, 45, 11)) + +let y1 = foo1(sx); // string +>y1 : Symbol(y1, Decl(unionAndIntersectionInference3.ts, 49, 3)) +>foo1 : Symbol(foo1, Decl(unionAndIntersectionInference3.ts, 38, 8)) +>sx : Symbol(sx, Decl(unionAndIntersectionInference3.ts, 46, 11)) + +let x2 = foo2(sa); // unknown +>x2 : Symbol(x2, Decl(unionAndIntersectionInference3.ts, 51, 3)) +>foo2 : Symbol(foo2, Decl(unionAndIntersectionInference3.ts, 42, 57)) +>sa : Symbol(sa, Decl(unionAndIntersectionInference3.ts, 45, 11)) + +let y2 = foo2(sx); // { extra: number } +>y2 : Symbol(y2, Decl(unionAndIntersectionInference3.ts, 52, 3)) +>foo2 : Symbol(foo2, Decl(unionAndIntersectionInference3.ts, 42, 57)) +>sx : Symbol(sx, Decl(unionAndIntersectionInference3.ts, 46, 11)) + diff --git a/tests/baselines/reference/unionAndIntersectionInference3.types b/tests/baselines/reference/unionAndIntersectionInference3.types index acbca0a1eae..fb507474321 100644 --- a/tests/baselines/reference/unionAndIntersectionInference3.types +++ b/tests/baselines/reference/unionAndIntersectionInference3.types @@ -94,3 +94,44 @@ g2 = g1; >g2 : (x: Foo2 | Bar2) => Promise >g1 : (x: Foo2 | Bar2) => Promise +// Repro from #32572 + +declare function foo1(obj: string[] & Iterable): T; +>foo1 : (obj: string[] & Iterable) => T +>obj : string[] & Iterable + +declare function foo2(obj: string[] & T): T; +>foo2 : (obj: string[] & T) => T +>obj : string[] & T + +declare let sa: string[]; +>sa : string[] + +declare let sx: string[] & { extra: number }; +>sx : string[] & { extra: number; } +>extra : number + +let x1 = foo1(sa); // string +>x1 : string +>foo1(sa) : string +>foo1 : (obj: string[] & Iterable) => T +>sa : string[] + +let y1 = foo1(sx); // string +>y1 : string +>foo1(sx) : string +>foo1 : (obj: string[] & Iterable) => T +>sx : string[] & { extra: number; } + +let x2 = foo2(sa); // unknown +>x2 : unknown +>foo2(sa) : unknown +>foo2 : (obj: string[] & T) => T +>sa : string[] + +let y2 = foo2(sx); // { extra: number } +>y2 : { extra: number; } +>foo2(sx) : { extra: number; } +>foo2 : (obj: string[] & T) => T +>sx : string[] & { extra: number; } + From 2a4930f4ec75e8accd78744bd02b608d0cef9e4d Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 26 Jul 2019 13:57:22 -0700 Subject: [PATCH 024/182] Bind a jsdoc enum as SymbolFlags.TypeAlias and not SymbolFlags.Enum (#32520) * Bind a jsdoc enum as SymbolFlags.TypeAlias and not SymbolFlags.Enum * Actually include an @enum tag as a declaration * Add enum tag refs into a couple more syntax kind lists * accept symbol baseline update --- src/compiler/binder.ts | 21 +++++++------ src/compiler/checker.ts | 30 +++++++------------ src/compiler/types.ts | 3 +- src/compiler/utilities.ts | 10 ++++--- src/harness/typeWriter.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 3 +- tests/baselines/reference/api/typescript.d.ts | 3 +- tests/baselines/reference/enumTag.symbols | 16 +++++----- .../enumTagCircularReference.errors.txt | 6 ++-- .../enumTagCircularReference.symbols | 2 +- .../reference/enumTagImported.symbols | 2 +- .../enumTagUseBeforeDefCrash.symbols | 2 +- .../reference/enumTagUseBeforeDefCrash.types | 2 +- tests/cases/fourslash/findAllRefs_jsEnum.ts | 2 +- tests/cases/fourslash/quickInfoJsdocEnum.ts | 5 ++-- 15 files changed, 52 insertions(+), 57 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 38d5ed24eae..d18ab45a347 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -120,7 +120,7 @@ namespace ts { let thisParentContainer: Node; // Container one level up let blockScopeContainer: Node; let lastContainer: Node; - let delayedTypeAliases: (JSDocTypedefTag | JSDocCallbackTag)[]; + let delayedTypeAliases: (JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag)[]; let seenThisKeyword: boolean; // state used by control flow analysis @@ -732,7 +732,8 @@ namespace ts { break; case SyntaxKind.JSDocTypedefTag: case SyntaxKind.JSDocCallbackTag: - bindJSDocTypeAlias(node as JSDocTypedefTag | JSDocCallbackTag); + case SyntaxKind.JSDocEnumTag: + bindJSDocTypeAlias(node as JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag); break; // In source files and blocks, bind functions first to match hoisting that occurs at runtime case SyntaxKind.SourceFile: { @@ -1436,9 +1437,9 @@ namespace ts { } } - function bindJSDocTypeAlias(node: JSDocTypedefTag | JSDocCallbackTag) { + function bindJSDocTypeAlias(node: JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag) { node.tagName.parent = node; - if (node.fullName) { + if (node.kind !== SyntaxKind.JSDocEnumTag && node.fullName) { setParentPointers(node, node.fullName); } } @@ -1805,7 +1806,7 @@ namespace ts { currentFlow = { flags: FlowFlags.Start }; parent = typeAlias; bind(typeAlias.typeExpression); - if (!typeAlias.fullName || typeAlias.fullName.kind === SyntaxKind.Identifier) { + if (isJSDocEnumTag(typeAlias) || !typeAlias.fullName || typeAlias.fullName.kind === SyntaxKind.Identifier) { parent = typeAlias.parent; bindBlockScopedDeclaration(typeAlias, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); } @@ -2319,7 +2320,8 @@ namespace ts { return declareSymbolAndAddToSymbolTable(propTag, flags, SymbolFlags.PropertyExcludes); case SyntaxKind.JSDocTypedefTag: case SyntaxKind.JSDocCallbackTag: - return (delayedTypeAliases || (delayedTypeAliases = [])).push(node as JSDocTypedefTag | JSDocCallbackTag); + case SyntaxKind.JSDocEnumTag: + return (delayedTypeAliases || (delayedTypeAliases = [])).push(node as JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag); } } @@ -2766,11 +2768,8 @@ namespace ts { } if (!isBindingPattern(node.name)) { - const isEnum = isInJSFile(node) && !!getJSDocEnumTag(node); - const enumFlags = (isEnum ? SymbolFlags.RegularEnum : SymbolFlags.None); - const enumExcludes = (isEnum ? SymbolFlags.RegularEnumExcludes : SymbolFlags.None); if (isBlockOrCatchScoped(node)) { - bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable | enumFlags, SymbolFlags.BlockScopedVariableExcludes | enumExcludes); + bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); } else if (isParameterDeclaration(node)) { // It is safe to walk up parent chain to find whether the node is a destructuring parameter declaration @@ -2785,7 +2784,7 @@ namespace ts { declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); } else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable | enumFlags, SymbolFlags.FunctionScopedVariableExcludes | enumExcludes); + declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); } } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2f466267f9d..834fb3eccfa 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1680,6 +1680,7 @@ namespace ts { break; case SyntaxKind.JSDocTypedefTag: case SyntaxKind.JSDocCallbackTag: + case SyntaxKind.JSDocEnumTag: // js type aliases do not resolve names from their host, so skip past it location = getJSDocHost(location); break; @@ -2025,7 +2026,7 @@ namespace ts { // Block-scoped variables cannot be used before their definition const declaration = find( result.declarations, - d => isBlockOrCatchScoped(d) || isClassLike(d) || (d.kind === SyntaxKind.EnumDeclaration) || isInJSFile(d) && !!getJSDocEnumTag(d)); + d => isBlockOrCatchScoped(d) || isClassLike(d) || (d.kind === SyntaxKind.EnumDeclaration)); if (declaration === undefined) return Debug.fail("Declaration to checkResolvedBlockScopedVariable is undefined"); @@ -4851,6 +4852,7 @@ namespace ts { switch (node.kind) { case SyntaxKind.JSDocCallbackTag: case SyntaxKind.JSDocTypedefTag: + case SyntaxKind.JSDocEnumTag: // Top-level jsdoc type aliases are considered exported // First parent is comment node, second is hosting declaration or token; we only care about those tokens or declarations whose parent is a source file return !!(node.parent && node.parent.parent && node.parent.parent.parent && isSourceFile(node.parent.parent.parent)); @@ -6156,6 +6158,7 @@ namespace ts { case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.JSDocTemplateTag: case SyntaxKind.JSDocTypedefTag: + case SyntaxKind.JSDocEnumTag: case SyntaxKind.JSDocCallbackTag: case SyntaxKind.MappedType: case SyntaxKind.ConditionalType: @@ -6489,8 +6492,10 @@ namespace ts { return errorType; } - const declaration = find(symbol.declarations, d => - isJSDocTypeAlias(d) || d.kind === SyntaxKind.TypeAliasDeclaration); + const declaration = find(symbol.declarations, isTypeAlias); + if (!declaration) { + return Debug.fail("Type alias symbol with no valid declaration found"); + } const typeNode = isJSDocTypeAlias(declaration) ? declaration.typeExpression : declaration.type; // If typeNode is missing, we will error in checkJSDocTypedefTag. let type = typeNode ? getTypeFromTypeNode(typeNode) : errorType; @@ -6507,7 +6512,7 @@ namespace ts { } else { type = errorType; - error(declaration.name, Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol)); + error(isJSDocEnumTag(declaration) ? declaration : declaration.name || declaration, Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol)); } links.declaredType = type; } @@ -9159,21 +9164,6 @@ namespace ts { return type; } - // JS enums are 'string' or 'number', not an enum type. - const enumTag = isInJSFile(node) && symbol.valueDeclaration && getJSDocEnumTag(symbol.valueDeclaration); - if (enumTag) { - const links = getNodeLinks(enumTag); - if (!pushTypeResolution(enumTag, TypeSystemPropertyName.EnumTagType)) { - return errorType; - } - let type = enumTag.typeExpression ? getTypeFromTypeNode(enumTag.typeExpression) : errorType; - if (!popTypeResolution()) { - type = errorType; - error(node, Diagnostics.Enum_type_0_circularly_references_itself, symbolToString(symbol)); - } - return (links.resolvedEnumType = type); - } - // Get type from reference to named type that cannot be generic (enum or type parameter) const res = tryGetDeclaredTypeOfSymbol(symbol); if (res) { @@ -26409,6 +26399,7 @@ namespace ts { // A jsdoc typedef and callback are, by definition, type aliases case SyntaxKind.JSDocTypedefTag: case SyntaxKind.JSDocCallbackTag: + case SyntaxKind.JSDocEnumTag: return DeclarationSpaces.ExportType; case SyntaxKind.ModuleDeclaration: return isAmbientModule(d as ModuleDeclaration) || getModuleInstanceState(d as ModuleDeclaration) !== ModuleInstanceState.NonInstantiated @@ -30325,6 +30316,7 @@ namespace ts { return checkJSDocAugmentsTag(node as JSDocAugmentsTag); case SyntaxKind.JSDocTypedefTag: case SyntaxKind.JSDocCallbackTag: + case SyntaxKind.JSDocEnumTag: return checkJSDocTypeAliasTag(node as JSDocTypedefTag); case SyntaxKind.JSDocTemplateTag: return checkJSDocTemplateTag(node as JSDocTemplateTag); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 67c85147aed..099f7705f84 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2466,7 +2466,8 @@ namespace ts { kind: SyntaxKind.JSDocClassTag; } - export interface JSDocEnumTag extends JSDocTag { + export interface JSDocEnumTag extends JSDocTag, Declaration { + parent: JSDoc; kind: SyntaxKind.JSDocEnumTag; typeExpression?: JSDocTypeExpression; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f3282d43723..d13e12a6f19 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2147,11 +2147,11 @@ namespace ts { return !!name && name.escapedText === "new"; } - export function isJSDocTypeAlias(node: Node): node is JSDocTypedefTag | JSDocCallbackTag { - return node.kind === SyntaxKind.JSDocTypedefTag || node.kind === SyntaxKind.JSDocCallbackTag; + export function isJSDocTypeAlias(node: Node): node is JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag { + return node.kind === SyntaxKind.JSDocTypedefTag || node.kind === SyntaxKind.JSDocCallbackTag || node.kind === SyntaxKind.JSDocEnumTag; } - export function isTypeAlias(node: Node): node is JSDocTypedefTag | JSDocCallbackTag | TypeAliasDeclaration { + export function isTypeAlias(node: Node): node is JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag | TypeAliasDeclaration { return isJSDocTypeAlias(node) || isTypeAliasDeclaration(node); } @@ -5091,7 +5091,7 @@ namespace ts { * attempt to draw the name from the node the declaration is on (as that declaration is what its' symbol * will be merged with) */ - function nameForNamelessJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined { + function nameForNamelessJSDocTypedef(declaration: JSDocTypedefTag | JSDocEnumTag): Identifier | undefined { const hostNode = declaration.parent.parent; if (!hostNode) { return undefined; @@ -5177,6 +5177,8 @@ namespace ts { } case SyntaxKind.JSDocTypedefTag: return getNameOfJSDocTypedef(declaration as JSDocTypedefTag); + case SyntaxKind.JSDocEnumTag: + return nameForNamelessJSDocTypedef(declaration as JSDocEnumTag); case SyntaxKind.ExportAssignment: { const { expression } = declaration as ExportAssignment; return isIdentifier(expression) ? expression : undefined; diff --git a/src/harness/typeWriter.ts b/src/harness/typeWriter.ts index b0b20c92e64..e8b4401b846 100644 --- a/src/harness/typeWriter.ts +++ b/src/harness/typeWriter.ts @@ -97,7 +97,7 @@ class TypeWriterWalker { if (!isSymbolWalk) { // Don't try to get the type of something that's already a type. // Exception for `T` in `type T = something` because that may evaluate to some interesting type. - if (ts.isPartOfTypeNode(node) || ts.isIdentifier(node) && !(ts.getMeaningFromDeclaration(node.parent) & ts.SemanticMeaning.Value) && !(ts.isTypeAlias(node.parent) && node.parent.name === node)) { + if (ts.isPartOfTypeNode(node) || ts.isIdentifier(node) && !(ts.getMeaningFromDeclaration(node.parent) & ts.SemanticMeaning.Value) && !(ts.isTypeAliasDeclaration(node.parent) && node.parent.name === node)) { return undefined; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index c2bad61505b..6d81a6f08ab 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1589,7 +1589,8 @@ declare namespace ts { interface JSDocClassTag extends JSDocTag { kind: SyntaxKind.JSDocClassTag; } - interface JSDocEnumTag extends JSDocTag { + interface JSDocEnumTag extends JSDocTag, Declaration { + parent: JSDoc; kind: SyntaxKind.JSDocEnumTag; typeExpression?: JSDocTypeExpression; } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 7a2559bbc22..ebd2d1471f7 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1589,7 +1589,8 @@ declare namespace ts { interface JSDocClassTag extends JSDocTag { kind: SyntaxKind.JSDocClassTag; } - interface JSDocEnumTag extends JSDocTag { + interface JSDocEnumTag extends JSDocTag, Declaration { + parent: JSDoc; kind: SyntaxKind.JSDocEnumTag; typeExpression?: JSDocTypeExpression; } diff --git a/tests/baselines/reference/enumTag.symbols b/tests/baselines/reference/enumTag.symbols index a54b9f4a3d8..87bcd6961a5 100644 --- a/tests/baselines/reference/enumTag.symbols +++ b/tests/baselines/reference/enumTag.symbols @@ -1,7 +1,7 @@ === tests/cases/conformance/jsdoc/a.js === /** @enum {string} */ const Target = { ->Target : Symbol(Target, Decl(a.js, 1, 5)) +>Target : Symbol(Target, Decl(a.js, 1, 5), Decl(a.js, 0, 4)) START: "start", >START : Symbol(START, Decl(a.js, 1, 16)) @@ -21,7 +21,7 @@ const Target = { } /** @enum number */ const Second = { ->Second : Symbol(Second, Decl(a.js, 10, 5)) +>Second : Symbol(Second, Decl(a.js, 10, 5), Decl(a.js, 9, 4)) MISTAKE: "end", >MISTAKE : Symbol(MISTAKE, Decl(a.js, 10, 16)) @@ -35,7 +35,7 @@ const Second = { } /** @enum {function(number): number} */ const Fs = { ->Fs : Symbol(Fs, Decl(a.js, 17, 5)) +>Fs : Symbol(Fs, Decl(a.js, 17, 5), Decl(a.js, 16, 4)) ADD1: n => n + 1, >ADD1 : Symbol(ADD1, Decl(a.js, 17, 12)) @@ -82,17 +82,17 @@ function consume(t,s,f) { var v = Target.START >v : Symbol(v, Decl(a.js, 35, 7)) >Target.START : Symbol(START, Decl(a.js, 1, 16)) ->Target : Symbol(Target, Decl(a.js, 1, 5)) +>Target : Symbol(Target, Decl(a.js, 1, 5), Decl(a.js, 0, 4)) >START : Symbol(START, Decl(a.js, 1, 16)) v = Target.UNKNOWN // error, can't find 'UNKNOWN' >v : Symbol(v, Decl(a.js, 35, 7)) ->Target : Symbol(Target, Decl(a.js, 1, 5)) +>Target : Symbol(Target, Decl(a.js, 1, 5), Decl(a.js, 0, 4)) v = Second.MISTAKE // meh..ok, I guess? >v : Symbol(v, Decl(a.js, 35, 7)) >Second.MISTAKE : Symbol(MISTAKE, Decl(a.js, 10, 16)) ->Second : Symbol(Second, Decl(a.js, 10, 5)) +>Second : Symbol(Second, Decl(a.js, 10, 5), Decl(a.js, 9, 4)) >MISTAKE : Symbol(MISTAKE, Decl(a.js, 10, 16)) v = 'something else' // allowed, like Typescript's classic enums and unlike its string enums @@ -105,14 +105,14 @@ function ff(s) { // element access with arbitrary string is an error only with noImplicitAny if (!Target[s]) { ->Target : Symbol(Target, Decl(a.js, 1, 5)) +>Target : Symbol(Target, Decl(a.js, 1, 5), Decl(a.js, 0, 4)) >s : Symbol(s, Decl(a.js, 41, 12)) return null } else { return Target[s] ->Target : Symbol(Target, Decl(a.js, 1, 5)) +>Target : Symbol(Target, Decl(a.js, 1, 5), Decl(a.js, 0, 4)) >s : Symbol(s, Decl(a.js, 41, 12)) } } diff --git a/tests/baselines/reference/enumTagCircularReference.errors.txt b/tests/baselines/reference/enumTagCircularReference.errors.txt index f876b5a33da..f42be3719f9 100644 --- a/tests/baselines/reference/enumTagCircularReference.errors.txt +++ b/tests/baselines/reference/enumTagCircularReference.errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/jsdoc/bug27142.js(1,12): error TS2586: Enum type 'E' circularly references itself. +tests/cases/conformance/jsdoc/bug27142.js(1,5): error TS2456: Type alias 'E' circularly references itself. ==== tests/cases/conformance/jsdoc/bug27142.js (1 errors) ==== /** @enum {E} */ - ~ -!!! error TS2586: Enum type 'E' circularly references itself. + ~~~~~~~~~ +!!! error TS2456: Type alias 'E' circularly references itself. const E = { x: 0 }; \ No newline at end of file diff --git a/tests/baselines/reference/enumTagCircularReference.symbols b/tests/baselines/reference/enumTagCircularReference.symbols index e3c594ac9d1..1236c02e392 100644 --- a/tests/baselines/reference/enumTagCircularReference.symbols +++ b/tests/baselines/reference/enumTagCircularReference.symbols @@ -1,6 +1,6 @@ === tests/cases/conformance/jsdoc/bug27142.js === /** @enum {E} */ const E = { x: 0 }; ->E : Symbol(E, Decl(bug27142.js, 1, 5)) +>E : Symbol(E, Decl(bug27142.js, 1, 5), Decl(bug27142.js, 0, 4)) >x : Symbol(x, Decl(bug27142.js, 1, 11)) diff --git a/tests/baselines/reference/enumTagImported.symbols b/tests/baselines/reference/enumTagImported.symbols index ab9ab5eceb1..a79198aaae1 100644 --- a/tests/baselines/reference/enumTagImported.symbols +++ b/tests/baselines/reference/enumTagImported.symbols @@ -23,7 +23,7 @@ const tist = TestEnum.ADD === tests/cases/conformance/jsdoc/mod1.js === /** @enum {string} */ export const TestEnum = { ->TestEnum : Symbol(TestEnum, Decl(mod1.js, 1, 12)) +>TestEnum : Symbol(TestEnum, Decl(mod1.js, 1, 12), Decl(mod1.js, 0, 4)) ADD: 'add', >ADD : Symbol(ADD, Decl(mod1.js, 1, 25)) diff --git a/tests/baselines/reference/enumTagUseBeforeDefCrash.symbols b/tests/baselines/reference/enumTagUseBeforeDefCrash.symbols index 1cef96a9823..8ec8a90e64b 100644 --- a/tests/baselines/reference/enumTagUseBeforeDefCrash.symbols +++ b/tests/baselines/reference/enumTagUseBeforeDefCrash.symbols @@ -3,7 +3,7 @@ * @enum {number} */ var foo = { }; ->foo : Symbol(foo, Decl(bug27134.js, 3, 3)) +>foo : Symbol(foo, Decl(bug27134.js, 3, 3), Decl(bug27134.js, 1, 3)) /** * @type {foo} diff --git a/tests/baselines/reference/enumTagUseBeforeDefCrash.types b/tests/baselines/reference/enumTagUseBeforeDefCrash.types index 159781fee05..d9f800d0d03 100644 --- a/tests/baselines/reference/enumTagUseBeforeDefCrash.types +++ b/tests/baselines/reference/enumTagUseBeforeDefCrash.types @@ -3,7 +3,7 @@ * @enum {number} */ var foo = { }; ->foo : typeof foo +>foo : {} >{ } : {} /** diff --git a/tests/cases/fourslash/findAllRefs_jsEnum.ts b/tests/cases/fourslash/findAllRefs_jsEnum.ts index f9033d6c588..d492cd84de4 100644 --- a/tests/cases/fourslash/findAllRefs_jsEnum.ts +++ b/tests/cases/fourslash/findAllRefs_jsEnum.ts @@ -10,7 +10,7 @@ ////const e = [|E|].A; verify.singleReferenceGroup( -`enum E +`type E = string const E: { A: string; }`, "E"); diff --git a/tests/cases/fourslash/quickInfoJsdocEnum.ts b/tests/cases/fourslash/quickInfoJsdocEnum.ts index 9ef3b1edc78..b8264b52110 100644 --- a/tests/cases/fourslash/quickInfoJsdocEnum.ts +++ b/tests/cases/fourslash/quickInfoJsdocEnum.ts @@ -18,11 +18,10 @@ verify.noErrors(); verify.quickInfoAt("type", -`enum E`, +`type E = number`, "Doc"); verify.quickInfoAt("value", -`enum E -const E: { +`const E: { A: number; }`, "Doc"); From 3d09010dc8916446f3e7a00df7845bc982ae721f Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Fri, 26 Jul 2019 14:56:03 -0700 Subject: [PATCH 025/182] Intersect 'this' types in union signatures (#32538) * Intersect this types in union signatures * Actually update baselines --- src/compiler/checker.ts | 13 +- .../unionThisTypeInFunctions.errors.txt | 34 ++++ .../reference/unionThisTypeInFunctions.js | 4 +- .../unionThisTypeInFunctions.symbols | 2 +- .../reference/unionThisTypeInFunctions.types | 4 +- .../unionTypeCallSignatures5.errors.txt | 19 ++ .../reference/unionTypeCallSignatures5.types | 2 +- .../unionTypeCallSignatures6.errors.txt | 98 +++++++++ .../reference/unionTypeCallSignatures6.js | 69 +++++++ .../unionTypeCallSignatures6.symbols | 187 ++++++++++++++++++ .../reference/unionTypeCallSignatures6.types | 150 ++++++++++++++ .../thisType/unionThisTypeInFunctions.ts | 2 +- .../types/union/unionTypeCallSignatures6.ts | 55 ++++++ 13 files changed, 626 insertions(+), 13 deletions(-) create mode 100644 tests/baselines/reference/unionThisTypeInFunctions.errors.txt create mode 100644 tests/baselines/reference/unionTypeCallSignatures5.errors.txt create mode 100644 tests/baselines/reference/unionTypeCallSignatures6.errors.txt create mode 100644 tests/baselines/reference/unionTypeCallSignatures6.js create mode 100644 tests/baselines/reference/unionTypeCallSignatures6.symbols create mode 100644 tests/baselines/reference/unionTypeCallSignatures6.types create mode 100644 tests/cases/conformance/types/union/unionTypeCallSignatures6.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 834fb3eccfa..f8242ed6df7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7181,8 +7181,9 @@ namespace ts { } let result: Signature[] | undefined; for (let i = 0; i < signatureLists.length; i++) { - // Allow matching non-generic signatures to have excess parameters and different return types - const match = i === listIndex ? signature : findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ true, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true); + // Allow matching non-generic signatures to have excess parameters and different return types. + // Prefer matching this types if possible. + const match = i === listIndex ? signature : findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ true, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ true); if (!match) { return undefined; } @@ -7205,7 +7206,7 @@ namespace ts { } for (const signature of signatureLists[i]) { // Only process signatures with parameter lists that aren't already in the result list - if (!result || !findMatchingSignature(result, signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true)) { + if (!result || !findMatchingSignature(result, signature, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ true)) { const unionSignatures = findMatchingSignatures(signatureLists, signature, i); if (unionSignatures) { let s = signature; @@ -7214,7 +7215,7 @@ namespace ts { let thisParameter = signature.thisParameter; const firstThisParameterOfUnionSignatures = forEach(unionSignatures, sig => sig.thisParameter); if (firstThisParameterOfUnionSignatures) { - const thisType = getUnionType(map(unionSignatures, sig => sig.thisParameter ? getTypeOfSymbol(sig.thisParameter) : anyType), UnionReduction.Subtype); + const thisType = getIntersectionType(mapDefined(unionSignatures, sig => sig.thisParameter && getTypeOfSymbol(sig.thisParameter))); thisParameter = createSymbolWithType(firstThisParameterOfUnionSignatures, thisType); } s = createUnionSignature(signature, unionSignatures); @@ -7253,8 +7254,8 @@ namespace ts { } // A signature `this` type might be a read or a write position... It's very possible that it should be invariant // and we should refuse to merge signatures if there are `this` types and they do not match. However, so as to be - // permissive when calling, for now, we'll union the `this` types just like the overlapping-union-signature check does - const thisType = getUnionType([getTypeOfSymbol(left), getTypeOfSymbol(right)], UnionReduction.Subtype); + // permissive when calling, for now, we'll intersect the `this` types just like we do for param types in union signatures. + const thisType = getIntersectionType([getTypeOfSymbol(left), getTypeOfSymbol(right)]); return createSymbolWithType(left, thisType); } diff --git a/tests/baselines/reference/unionThisTypeInFunctions.errors.txt b/tests/baselines/reference/unionThisTypeInFunctions.errors.txt new file mode 100644 index 00000000000..db03a5426fb --- /dev/null +++ b/tests/baselines/reference/unionThisTypeInFunctions.errors.txt @@ -0,0 +1,34 @@ +tests/cases/conformance/types/thisType/unionThisTypeInFunctions.ts(10,5): error TS2684: The 'this' context of type 'Real | Fake' is not assignable to method's 'this' of type 'Real & Fake'. + Type 'Real' is not assignable to type 'Real & Fake'. + Type 'Real' is not assignable to type 'Fake'. + Types of property 'method' are incompatible. + Type '(this: Real, n: number) => void' is not assignable to type '(this: Fake, n: number) => void'. + The 'this' types of each signature are incompatible. + Type 'Fake' is not assignable to type 'Real'. + Types of property 'data' are incompatible. + Type 'number' is not assignable to type 'string'. + + +==== tests/cases/conformance/types/thisType/unionThisTypeInFunctions.ts (1 errors) ==== + interface Real { + method(this: this, n: number): void; + data: string; + } + interface Fake { + method(this: this, n: number): void; + data: number; + } + function test(r: Real | Fake) { + r.method(12); // error + ~ +!!! error TS2684: The 'this' context of type 'Real | Fake' is not assignable to method's 'this' of type 'Real & Fake'. +!!! error TS2684: Type 'Real' is not assignable to type 'Real & Fake'. +!!! error TS2684: Type 'Real' is not assignable to type 'Fake'. +!!! error TS2684: Types of property 'method' are incompatible. +!!! error TS2684: Type '(this: Real, n: number) => void' is not assignable to type '(this: Fake, n: number) => void'. +!!! error TS2684: The 'this' types of each signature are incompatible. +!!! error TS2684: Type 'Fake' is not assignable to type 'Real'. +!!! error TS2684: Types of property 'data' are incompatible. +!!! error TS2684: Type 'number' is not assignable to type 'string'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/unionThisTypeInFunctions.js b/tests/baselines/reference/unionThisTypeInFunctions.js index 0d4b535ff8b..dca64b6d893 100644 --- a/tests/baselines/reference/unionThisTypeInFunctions.js +++ b/tests/baselines/reference/unionThisTypeInFunctions.js @@ -8,11 +8,11 @@ interface Fake { data: number; } function test(r: Real | Fake) { - r.method(12); + r.method(12); // error } //// [unionThisTypeInFunctions.js] function test(r) { - r.method(12); + r.method(12); // error } diff --git a/tests/baselines/reference/unionThisTypeInFunctions.symbols b/tests/baselines/reference/unionThisTypeInFunctions.symbols index eada1231750..b907519626a 100644 --- a/tests/baselines/reference/unionThisTypeInFunctions.symbols +++ b/tests/baselines/reference/unionThisTypeInFunctions.symbols @@ -27,7 +27,7 @@ function test(r: Real | Fake) { >Real : Symbol(Real, Decl(unionThisTypeInFunctions.ts, 0, 0)) >Fake : Symbol(Fake, Decl(unionThisTypeInFunctions.ts, 3, 1)) - r.method(12); + r.method(12); // error >r.method : Symbol(method, Decl(unionThisTypeInFunctions.ts, 0, 16), Decl(unionThisTypeInFunctions.ts, 4, 16)) >r : Symbol(r, Decl(unionThisTypeInFunctions.ts, 8, 14)) >method : Symbol(method, Decl(unionThisTypeInFunctions.ts, 0, 16), Decl(unionThisTypeInFunctions.ts, 4, 16)) diff --git a/tests/baselines/reference/unionThisTypeInFunctions.types b/tests/baselines/reference/unionThisTypeInFunctions.types index 44c03d73a61..af987759a55 100644 --- a/tests/baselines/reference/unionThisTypeInFunctions.types +++ b/tests/baselines/reference/unionThisTypeInFunctions.types @@ -21,8 +21,8 @@ function test(r: Real | Fake) { >test : (r: Real | Fake) => void >r : Real | Fake - r.method(12); ->r.method(12) : void + r.method(12); // error +>r.method(12) : any >r.method : ((this: Real, n: number) => void) | ((this: Fake, n: number) => void) >r : Real | Fake >method : ((this: Real, n: number) => void) | ((this: Fake, n: number) => void) diff --git a/tests/baselines/reference/unionTypeCallSignatures5.errors.txt b/tests/baselines/reference/unionTypeCallSignatures5.errors.txt new file mode 100644 index 00000000000..2dc6ebb002b --- /dev/null +++ b/tests/baselines/reference/unionTypeCallSignatures5.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/types/union/unionTypeCallSignatures5.ts(12,1): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'never'. + + +==== tests/cases/conformance/types/union/unionTypeCallSignatures5.ts (1 errors) ==== + // #31485 + interface A { + (this: void, b?: number): void; + } + interface B { + (this: number, b?: number): void; + } + interface C { + (i: number): void; + } + declare const fn: A | B | C; + fn(0); + ~~~~~ +!!! error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'never'. + \ No newline at end of file diff --git a/tests/baselines/reference/unionTypeCallSignatures5.types b/tests/baselines/reference/unionTypeCallSignatures5.types index 53ce4ea6550..b9b5a6fbc0d 100644 --- a/tests/baselines/reference/unionTypeCallSignatures5.types +++ b/tests/baselines/reference/unionTypeCallSignatures5.types @@ -18,7 +18,7 @@ declare const fn: A | B | C; >fn : A | B | C fn(0); ->fn(0) : void +>fn(0) : any >fn : A | B | C >0 : 0 diff --git a/tests/baselines/reference/unionTypeCallSignatures6.errors.txt b/tests/baselines/reference/unionTypeCallSignatures6.errors.txt new file mode 100644 index 00000000000..51b18b204a7 --- /dev/null +++ b/tests/baselines/reference/unionTypeCallSignatures6.errors.txt @@ -0,0 +1,98 @@ +tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(11,1): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. + Type 'void' is not assignable to type 'A'. +tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(13,1): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A'. +tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(38,4): error TS2349: This expression is not callable. + Each member of the union type 'F3 | F4' has signatures, but none of those signatures are compatible with each other. +tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(39,1): error TS2684: The 'this' context of type 'A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; }' is not assignable to method's 'this' of type 'B'. + Property 'b' is missing in type 'A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; }' but required in type 'B'. +tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(48,1): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. + Type 'void' is not assignable to type 'A'. +tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(55,1): error TS2769: No overload matches this call. + Overload 1 of 2, '(this: A & B & C): void', gave the following error. + The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B & C'. + Type 'void' is not assignable to type 'A'. + Overload 2 of 2, '(this: A & B): void', gave the following error. + The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. + Type 'void' is not assignable to type 'A'. + + +==== tests/cases/conformance/types/union/unionTypeCallSignatures6.ts (6 errors) ==== + type A = { a: string }; + type B = { b: number }; + type C = { c: string }; + type D = { d: number }; + type F0 = () => void; + + // #31547 + type F1 = (this: A) => void; + type F2 = (this: B) => void; + declare var f1: F1 | F2; + f1(); // error + ~~~~ +!!! error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. +!!! error TS2684: Type 'void' is not assignable to type 'A'. + declare var f2: F0 | F1; + f2(); // error + ~~~~ +!!! error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A'. + + interface F3 { + (this: A): void; + (this: B): void; + } + interface F4 { + (this: C): void; + (this: D): void; + } + interface F5 { + (this: C): void; + (this: B): void; + } + + declare var x1: A & C & { + f0: F0 | F3; + f1: F1 | F3; + f2: F1 | F4; + f3: F3 | F4; + f4: F3 | F5; + } + x1.f0(); + x1.f1(); + x1.f2(); + x1.f3(); // error + ~~ +!!! error TS2349: This expression is not callable. +!!! error TS2349: Each member of the union type 'F3 | F4' has signatures, but none of those signatures are compatible with each other. + x1.f4(); // error + ~~ +!!! error TS2684: The 'this' context of type 'A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; }' is not assignable to method's 'this' of type 'B'. +!!! error TS2684: Property 'b' is missing in type 'A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; }' but required in type 'B'. +!!! related TS2728 tests/cases/conformance/types/union/unionTypeCallSignatures6.ts:2:12: 'b' is declared here. + + declare var x2: A & B & { + f4: F3 | F5; + } + x2.f4(); + + type F6 = (this: A & B) => void; + declare var f3: F1 | F6; + f3(); // error + ~~~~ +!!! error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. +!!! error TS2684: Type 'void' is not assignable to type 'A'. + + interface F7 { + (this: A & B & C): void; + (this: A & B): void; + } + declare var f4: F6 | F7; + f4(); // error + ~~~~ +!!! error TS2769: No overload matches this call. +!!! error TS2769: Overload 1 of 2, '(this: A & B & C): void', gave the following error. +!!! error TS2769: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B & C'. +!!! error TS2769: Type 'void' is not assignable to type 'A'. +!!! error TS2769: Overload 2 of 2, '(this: A & B): void', gave the following error. +!!! error TS2769: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. +!!! error TS2769: Type 'void' is not assignable to type 'A'. + \ No newline at end of file diff --git a/tests/baselines/reference/unionTypeCallSignatures6.js b/tests/baselines/reference/unionTypeCallSignatures6.js new file mode 100644 index 00000000000..32e0518cbb8 --- /dev/null +++ b/tests/baselines/reference/unionTypeCallSignatures6.js @@ -0,0 +1,69 @@ +//// [unionTypeCallSignatures6.ts] +type A = { a: string }; +type B = { b: number }; +type C = { c: string }; +type D = { d: number }; +type F0 = () => void; + +// #31547 +type F1 = (this: A) => void; +type F2 = (this: B) => void; +declare var f1: F1 | F2; +f1(); // error +declare var f2: F0 | F1; +f2(); // error + +interface F3 { + (this: A): void; + (this: B): void; +} +interface F4 { + (this: C): void; + (this: D): void; +} +interface F5 { + (this: C): void; + (this: B): void; +} + +declare var x1: A & C & { + f0: F0 | F3; + f1: F1 | F3; + f2: F1 | F4; + f3: F3 | F4; + f4: F3 | F5; +} +x1.f0(); +x1.f1(); +x1.f2(); +x1.f3(); // error +x1.f4(); // error + +declare var x2: A & B & { + f4: F3 | F5; +} +x2.f4(); + +type F6 = (this: A & B) => void; +declare var f3: F1 | F6; +f3(); // error + +interface F7 { + (this: A & B & C): void; + (this: A & B): void; +} +declare var f4: F6 | F7; +f4(); // error + + +//// [unionTypeCallSignatures6.js] +f1(); // error +f2(); // error +x1.f0(); +x1.f1(); +x1.f2(); +x1.f3(); // error +x1.f4(); // error +x2.f4(); +f3(); // error +f4(); // error diff --git a/tests/baselines/reference/unionTypeCallSignatures6.symbols b/tests/baselines/reference/unionTypeCallSignatures6.symbols new file mode 100644 index 00000000000..87d1928f069 --- /dev/null +++ b/tests/baselines/reference/unionTypeCallSignatures6.symbols @@ -0,0 +1,187 @@ +=== tests/cases/conformance/types/union/unionTypeCallSignatures6.ts === +type A = { a: string }; +>A : Symbol(A, Decl(unionTypeCallSignatures6.ts, 0, 0)) +>a : Symbol(a, Decl(unionTypeCallSignatures6.ts, 0, 10)) + +type B = { b: number }; +>B : Symbol(B, Decl(unionTypeCallSignatures6.ts, 0, 23)) +>b : Symbol(b, Decl(unionTypeCallSignatures6.ts, 1, 10)) + +type C = { c: string }; +>C : Symbol(C, Decl(unionTypeCallSignatures6.ts, 1, 23)) +>c : Symbol(c, Decl(unionTypeCallSignatures6.ts, 2, 10)) + +type D = { d: number }; +>D : Symbol(D, Decl(unionTypeCallSignatures6.ts, 2, 23)) +>d : Symbol(d, Decl(unionTypeCallSignatures6.ts, 3, 10)) + +type F0 = () => void; +>F0 : Symbol(F0, Decl(unionTypeCallSignatures6.ts, 3, 23)) + +// #31547 +type F1 = (this: A) => void; +>F1 : Symbol(F1, Decl(unionTypeCallSignatures6.ts, 4, 21)) +>this : Symbol(this, Decl(unionTypeCallSignatures6.ts, 7, 11)) +>A : Symbol(A, Decl(unionTypeCallSignatures6.ts, 0, 0)) + +type F2 = (this: B) => void; +>F2 : Symbol(F2, Decl(unionTypeCallSignatures6.ts, 7, 28)) +>this : Symbol(this, Decl(unionTypeCallSignatures6.ts, 8, 11)) +>B : Symbol(B, Decl(unionTypeCallSignatures6.ts, 0, 23)) + +declare var f1: F1 | F2; +>f1 : Symbol(f1, Decl(unionTypeCallSignatures6.ts, 9, 11)) +>F1 : Symbol(F1, Decl(unionTypeCallSignatures6.ts, 4, 21)) +>F2 : Symbol(F2, Decl(unionTypeCallSignatures6.ts, 7, 28)) + +f1(); // error +>f1 : Symbol(f1, Decl(unionTypeCallSignatures6.ts, 9, 11)) + +declare var f2: F0 | F1; +>f2 : Symbol(f2, Decl(unionTypeCallSignatures6.ts, 11, 11)) +>F0 : Symbol(F0, Decl(unionTypeCallSignatures6.ts, 3, 23)) +>F1 : Symbol(F1, Decl(unionTypeCallSignatures6.ts, 4, 21)) + +f2(); // error +>f2 : Symbol(f2, Decl(unionTypeCallSignatures6.ts, 11, 11)) + +interface F3 { +>F3 : Symbol(F3, Decl(unionTypeCallSignatures6.ts, 12, 5)) + + (this: A): void; +>this : Symbol(this, Decl(unionTypeCallSignatures6.ts, 15, 3)) +>A : Symbol(A, Decl(unionTypeCallSignatures6.ts, 0, 0)) + + (this: B): void; +>this : Symbol(this, Decl(unionTypeCallSignatures6.ts, 16, 3)) +>B : Symbol(B, Decl(unionTypeCallSignatures6.ts, 0, 23)) +} +interface F4 { +>F4 : Symbol(F4, Decl(unionTypeCallSignatures6.ts, 17, 1)) + + (this: C): void; +>this : Symbol(this, Decl(unionTypeCallSignatures6.ts, 19, 3)) +>C : Symbol(C, Decl(unionTypeCallSignatures6.ts, 1, 23)) + + (this: D): void; +>this : Symbol(this, Decl(unionTypeCallSignatures6.ts, 20, 3)) +>D : Symbol(D, Decl(unionTypeCallSignatures6.ts, 2, 23)) +} +interface F5 { +>F5 : Symbol(F5, Decl(unionTypeCallSignatures6.ts, 21, 1)) + + (this: C): void; +>this : Symbol(this, Decl(unionTypeCallSignatures6.ts, 23, 3)) +>C : Symbol(C, Decl(unionTypeCallSignatures6.ts, 1, 23)) + + (this: B): void; +>this : Symbol(this, Decl(unionTypeCallSignatures6.ts, 24, 3)) +>B : Symbol(B, Decl(unionTypeCallSignatures6.ts, 0, 23)) +} + +declare var x1: A & C & { +>x1 : Symbol(x1, Decl(unionTypeCallSignatures6.ts, 27, 11)) +>A : Symbol(A, Decl(unionTypeCallSignatures6.ts, 0, 0)) +>C : Symbol(C, Decl(unionTypeCallSignatures6.ts, 1, 23)) + + f0: F0 | F3; +>f0 : Symbol(f0, Decl(unionTypeCallSignatures6.ts, 27, 25)) +>F0 : Symbol(F0, Decl(unionTypeCallSignatures6.ts, 3, 23)) +>F3 : Symbol(F3, Decl(unionTypeCallSignatures6.ts, 12, 5)) + + f1: F1 | F3; +>f1 : Symbol(f1, Decl(unionTypeCallSignatures6.ts, 28, 14)) +>F1 : Symbol(F1, Decl(unionTypeCallSignatures6.ts, 4, 21)) +>F3 : Symbol(F3, Decl(unionTypeCallSignatures6.ts, 12, 5)) + + f2: F1 | F4; +>f2 : Symbol(f2, Decl(unionTypeCallSignatures6.ts, 29, 14)) +>F1 : Symbol(F1, Decl(unionTypeCallSignatures6.ts, 4, 21)) +>F4 : Symbol(F4, Decl(unionTypeCallSignatures6.ts, 17, 1)) + + f3: F3 | F4; +>f3 : Symbol(f3, Decl(unionTypeCallSignatures6.ts, 30, 14)) +>F3 : Symbol(F3, Decl(unionTypeCallSignatures6.ts, 12, 5)) +>F4 : Symbol(F4, Decl(unionTypeCallSignatures6.ts, 17, 1)) + + f4: F3 | F5; +>f4 : Symbol(f4, Decl(unionTypeCallSignatures6.ts, 31, 14)) +>F3 : Symbol(F3, Decl(unionTypeCallSignatures6.ts, 12, 5)) +>F5 : Symbol(F5, Decl(unionTypeCallSignatures6.ts, 21, 1)) +} +x1.f0(); +>x1.f0 : Symbol(f0, Decl(unionTypeCallSignatures6.ts, 27, 25)) +>x1 : Symbol(x1, Decl(unionTypeCallSignatures6.ts, 27, 11)) +>f0 : Symbol(f0, Decl(unionTypeCallSignatures6.ts, 27, 25)) + +x1.f1(); +>x1.f1 : Symbol(f1, Decl(unionTypeCallSignatures6.ts, 28, 14)) +>x1 : Symbol(x1, Decl(unionTypeCallSignatures6.ts, 27, 11)) +>f1 : Symbol(f1, Decl(unionTypeCallSignatures6.ts, 28, 14)) + +x1.f2(); +>x1.f2 : Symbol(f2, Decl(unionTypeCallSignatures6.ts, 29, 14)) +>x1 : Symbol(x1, Decl(unionTypeCallSignatures6.ts, 27, 11)) +>f2 : Symbol(f2, Decl(unionTypeCallSignatures6.ts, 29, 14)) + +x1.f3(); // error +>x1.f3 : Symbol(f3, Decl(unionTypeCallSignatures6.ts, 30, 14)) +>x1 : Symbol(x1, Decl(unionTypeCallSignatures6.ts, 27, 11)) +>f3 : Symbol(f3, Decl(unionTypeCallSignatures6.ts, 30, 14)) + +x1.f4(); // error +>x1.f4 : Symbol(f4, Decl(unionTypeCallSignatures6.ts, 31, 14)) +>x1 : Symbol(x1, Decl(unionTypeCallSignatures6.ts, 27, 11)) +>f4 : Symbol(f4, Decl(unionTypeCallSignatures6.ts, 31, 14)) + +declare var x2: A & B & { +>x2 : Symbol(x2, Decl(unionTypeCallSignatures6.ts, 40, 11)) +>A : Symbol(A, Decl(unionTypeCallSignatures6.ts, 0, 0)) +>B : Symbol(B, Decl(unionTypeCallSignatures6.ts, 0, 23)) + + f4: F3 | F5; +>f4 : Symbol(f4, Decl(unionTypeCallSignatures6.ts, 40, 25)) +>F3 : Symbol(F3, Decl(unionTypeCallSignatures6.ts, 12, 5)) +>F5 : Symbol(F5, Decl(unionTypeCallSignatures6.ts, 21, 1)) +} +x2.f4(); +>x2.f4 : Symbol(f4, Decl(unionTypeCallSignatures6.ts, 40, 25)) +>x2 : Symbol(x2, Decl(unionTypeCallSignatures6.ts, 40, 11)) +>f4 : Symbol(f4, Decl(unionTypeCallSignatures6.ts, 40, 25)) + +type F6 = (this: A & B) => void; +>F6 : Symbol(F6, Decl(unionTypeCallSignatures6.ts, 43, 8)) +>this : Symbol(this, Decl(unionTypeCallSignatures6.ts, 45, 11)) +>A : Symbol(A, Decl(unionTypeCallSignatures6.ts, 0, 0)) +>B : Symbol(B, Decl(unionTypeCallSignatures6.ts, 0, 23)) + +declare var f3: F1 | F6; +>f3 : Symbol(f3, Decl(unionTypeCallSignatures6.ts, 46, 11)) +>F1 : Symbol(F1, Decl(unionTypeCallSignatures6.ts, 4, 21)) +>F6 : Symbol(F6, Decl(unionTypeCallSignatures6.ts, 43, 8)) + +f3(); // error +>f3 : Symbol(f3, Decl(unionTypeCallSignatures6.ts, 46, 11)) + +interface F7 { +>F7 : Symbol(F7, Decl(unionTypeCallSignatures6.ts, 47, 5)) + + (this: A & B & C): void; +>this : Symbol(this, Decl(unionTypeCallSignatures6.ts, 50, 3)) +>A : Symbol(A, Decl(unionTypeCallSignatures6.ts, 0, 0)) +>B : Symbol(B, Decl(unionTypeCallSignatures6.ts, 0, 23)) +>C : Symbol(C, Decl(unionTypeCallSignatures6.ts, 1, 23)) + + (this: A & B): void; +>this : Symbol(this, Decl(unionTypeCallSignatures6.ts, 51, 3)) +>A : Symbol(A, Decl(unionTypeCallSignatures6.ts, 0, 0)) +>B : Symbol(B, Decl(unionTypeCallSignatures6.ts, 0, 23)) +} +declare var f4: F6 | F7; +>f4 : Symbol(f4, Decl(unionTypeCallSignatures6.ts, 53, 11)) +>F6 : Symbol(F6, Decl(unionTypeCallSignatures6.ts, 43, 8)) +>F7 : Symbol(F7, Decl(unionTypeCallSignatures6.ts, 47, 5)) + +f4(); // error +>f4 : Symbol(f4, Decl(unionTypeCallSignatures6.ts, 53, 11)) + diff --git a/tests/baselines/reference/unionTypeCallSignatures6.types b/tests/baselines/reference/unionTypeCallSignatures6.types new file mode 100644 index 00000000000..930c91b1109 --- /dev/null +++ b/tests/baselines/reference/unionTypeCallSignatures6.types @@ -0,0 +1,150 @@ +=== tests/cases/conformance/types/union/unionTypeCallSignatures6.ts === +type A = { a: string }; +>A : A +>a : string + +type B = { b: number }; +>B : B +>b : number + +type C = { c: string }; +>C : C +>c : string + +type D = { d: number }; +>D : D +>d : number + +type F0 = () => void; +>F0 : F0 + +// #31547 +type F1 = (this: A) => void; +>F1 : F1 +>this : A + +type F2 = (this: B) => void; +>F2 : F2 +>this : B + +declare var f1: F1 | F2; +>f1 : F1 | F2 + +f1(); // error +>f1() : any +>f1 : F1 | F2 + +declare var f2: F0 | F1; +>f2 : F1 | F0 + +f2(); // error +>f2() : any +>f2 : F1 | F0 + +interface F3 { + (this: A): void; +>this : A + + (this: B): void; +>this : B +} +interface F4 { + (this: C): void; +>this : C + + (this: D): void; +>this : D +} +interface F5 { + (this: C): void; +>this : C + + (this: B): void; +>this : B +} + +declare var x1: A & C & { +>x1 : A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; } + + f0: F0 | F3; +>f0 : F0 | F3 + + f1: F1 | F3; +>f1 : F1 | F3 + + f2: F1 | F4; +>f2 : F1 | F4 + + f3: F3 | F4; +>f3 : F3 | F4 + + f4: F3 | F5; +>f4 : F3 | F5 +} +x1.f0(); +>x1.f0() : void +>x1.f0 : F0 | F3 +>x1 : A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; } +>f0 : F0 | F3 + +x1.f1(); +>x1.f1() : void +>x1.f1 : F1 | F3 +>x1 : A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; } +>f1 : F1 | F3 + +x1.f2(); +>x1.f2() : void +>x1.f2 : F1 | F4 +>x1 : A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; } +>f2 : F1 | F4 + +x1.f3(); // error +>x1.f3() : any +>x1.f3 : F3 | F4 +>x1 : A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; } +>f3 : F3 | F4 + +x1.f4(); // error +>x1.f4() : any +>x1.f4 : F3 | F5 +>x1 : A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; } +>f4 : F3 | F5 + +declare var x2: A & B & { +>x2 : A & B & { f4: F3 | F5; } + + f4: F3 | F5; +>f4 : F3 | F5 +} +x2.f4(); +>x2.f4() : void +>x2.f4 : F3 | F5 +>x2 : A & B & { f4: F3 | F5; } +>f4 : F3 | F5 + +type F6 = (this: A & B) => void; +>F6 : F6 +>this : A & B + +declare var f3: F1 | F6; +>f3 : F1 | F6 + +f3(); // error +>f3() : any +>f3 : F1 | F6 + +interface F7 { + (this: A & B & C): void; +>this : A & B & C + + (this: A & B): void; +>this : A & B +} +declare var f4: F6 | F7; +>f4 : F6 | F7 + +f4(); // error +>f4() : any +>f4 : F6 | F7 + diff --git a/tests/cases/conformance/types/thisType/unionThisTypeInFunctions.ts b/tests/cases/conformance/types/thisType/unionThisTypeInFunctions.ts index 4f74058cc48..a35019d372e 100644 --- a/tests/cases/conformance/types/thisType/unionThisTypeInFunctions.ts +++ b/tests/cases/conformance/types/thisType/unionThisTypeInFunctions.ts @@ -7,5 +7,5 @@ interface Fake { data: number; } function test(r: Real | Fake) { - r.method(12); + r.method(12); // error } diff --git a/tests/cases/conformance/types/union/unionTypeCallSignatures6.ts b/tests/cases/conformance/types/union/unionTypeCallSignatures6.ts new file mode 100644 index 00000000000..0fe98847205 --- /dev/null +++ b/tests/cases/conformance/types/union/unionTypeCallSignatures6.ts @@ -0,0 +1,55 @@ +type A = { a: string }; +type B = { b: number }; +type C = { c: string }; +type D = { d: number }; +type F0 = () => void; + +// #31547 +type F1 = (this: A) => void; +type F2 = (this: B) => void; +declare var f1: F1 | F2; +f1(); // error +declare var f2: F0 | F1; +f2(); // error + +interface F3 { + (this: A): void; + (this: B): void; +} +interface F4 { + (this: C): void; + (this: D): void; +} +interface F5 { + (this: C): void; + (this: B): void; +} + +declare var x1: A & C & { + f0: F0 | F3; + f1: F1 | F3; + f2: F1 | F4; + f3: F3 | F4; + f4: F3 | F5; +} +x1.f0(); +x1.f1(); +x1.f2(); +x1.f3(); // error +x1.f4(); // error + +declare var x2: A & B & { + f4: F3 | F5; +} +x2.f4(); + +type F6 = (this: A & B) => void; +declare var f3: F1 | F6; +f3(); // error + +interface F7 { + (this: A & B & C): void; + (this: A & B): void; +} +declare var f4: F6 | F7; +f4(); // error From a9e0a7766e30eff61f76ca85b380e65f45c8eb12 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 27 Jul 2019 08:50:26 -0700 Subject: [PATCH 026/182] Record full inference status in visitation cache --- src/compiler/checker.ts | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a69751673f6..27c8a027cbc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15462,7 +15462,7 @@ namespace ts { let visited: Map; let bivariant = false; let propagationType: Type; - let inferenceCount = 0; + let inferenceMatch = false; let inferenceIncomplete = false; let allowComplexConstraintInference = true; inferFromTypes(originalSource, originalTarget); @@ -15576,7 +15576,7 @@ namespace ts { clearCachedInferences(inferences); } } - inferenceCount++; + inferenceMatch = true; return; } else { @@ -15668,15 +15668,21 @@ namespace ts { function invokeOnce(source: Type, target: Type, action: (source: Type, target: Type) => void) { const key = source.id + "," + target.id; - const count = visited && visited.get(key); - if (count !== undefined) { - inferenceCount += count; + const status = visited && visited.get(key); + if (status !== undefined) { + if (status & 1) inferenceMatch = true; + if (status & 2) inferenceIncomplete = true; return; } (visited || (visited = createMap())).set(key, 0); - const startCount = inferenceCount; + const saveInferenceMatch = inferenceMatch; + const saveInferenceIncomplete = inferenceIncomplete; + inferenceMatch = false; + inferenceIncomplete = false; action(source, target); - visited.set(key, inferenceCount - startCount); + visited.set(key, (inferenceMatch ? 1 : 0) | (inferenceIncomplete ? 2 : 0)); + inferenceMatch = inferenceMatch || saveInferenceMatch; + inferenceIncomplete = inferenceIncomplete || saveInferenceIncomplete; } function inferFromMatchingType(source: Type, targets: Type[], matches: (s: Type, t: Type) => boolean) { @@ -15759,9 +15765,11 @@ namespace ts { } else { for (let i = 0; i < sources.length; i++) { - const count = inferenceCount; + const saveInferenceMatch = inferenceMatch; + inferenceMatch = false; inferFromTypes(sources[i], t); - if (count !== inferenceCount) matched[i] = true; + if (inferenceMatch) matched[i] = true; + inferenceMatch = inferenceMatch || saveInferenceMatch; } } } From 58ff76abf663190a91ada6e3f23e9b3fed417af0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 28 Jul 2019 09:01:11 -0700 Subject: [PATCH 027/182] Properly instantiate contextual type for object literal methods --- src/compiler/checker.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f8242ed6df7..1ad92eebc21 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19099,10 +19099,13 @@ namespace ts { // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily // be "pushed" onto a node using the contextualType property. - function getApparentTypeOfContextualType(node: Expression, contextFlags?: ContextFlags): Type | undefined { - const contextualType = instantiateContextualType(getContextualType(node, contextFlags), node, contextFlags); - if (contextualType) { - const apparentType = mapType(contextualType, getApparentType, /*noReductions*/ true); + function getApparentTypeOfContextualType(node: Expression | MethodDeclaration, contextFlags?: ContextFlags): Type | undefined { + const contextualType = isObjectLiteralMethod(node) ? + getContextualTypeForObjectLiteralMethod(node, contextFlags) : + getContextualType(node, contextFlags); + const instantiatedType = instantiateContextualType(contextualType, node, contextFlags); + if (instantiatedType) { + const apparentType = mapType(instantiatedType, getApparentType, /*noReductions*/ true); if (apparentType.flags & TypeFlags.Union) { if (isObjectLiteralExpression(node)) { return discriminateContextualTypeByObjectMembers(node, apparentType as UnionType); @@ -19426,9 +19429,7 @@ namespace ts { if (typeTagSignature) { return typeTagSignature; } - const type = isObjectLiteralMethod(node) ? - getContextualTypeForObjectLiteralMethod(node, ContextFlags.Signature) : - getApparentTypeOfContextualType(node, ContextFlags.Signature); + const type = getApparentTypeOfContextualType(node, ContextFlags.Signature); if (!type) { return undefined; } From a717d3ab44b2cacc9e0fb36861bbe7c428bba6fc Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 28 Jul 2019 09:05:57 -0700 Subject: [PATCH 028/182] Add regression test --- tests/cases/compiler/instantiateContextualTypes.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/cases/compiler/instantiateContextualTypes.ts b/tests/cases/compiler/instantiateContextualTypes.ts index 3165011ecff..4059bd5202e 100644 --- a/tests/cases/compiler/instantiateContextualTypes.ts +++ b/tests/cases/compiler/instantiateContextualTypes.ts @@ -174,3 +174,13 @@ class Interesting { declare function invoke(f: () => T): T; let xx: 0 | 1 | 2 = invoke(() => 1); + +// Repro from #32416 + +declare function assignPartial(target: T, partial: Partial): T; + +let obj = { + foo(bar: string) {} +} + +assignPartial(obj, { foo(...args) {} }); // args has type [string] From 4a17581f67a0c0cd413adcd7ce0e0ffe30698122 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 28 Jul 2019 09:06:04 -0700 Subject: [PATCH 029/182] Accept new baselines --- .../reference/instantiateContextualTypes.js | 14 ++++++++++ .../instantiateContextualTypes.symbols | 26 +++++++++++++++++++ .../instantiateContextualTypes.types | 24 +++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/tests/baselines/reference/instantiateContextualTypes.js b/tests/baselines/reference/instantiateContextualTypes.js index 9de6bfb612c..46d87cb1153 100644 --- a/tests/baselines/reference/instantiateContextualTypes.js +++ b/tests/baselines/reference/instantiateContextualTypes.js @@ -172,6 +172,16 @@ class Interesting { declare function invoke(f: () => T): T; let xx: 0 | 1 | 2 = invoke(() => 1); + +// Repro from #32416 + +declare function assignPartial(target: T, partial: Partial): T; + +let obj = { + foo(bar: string) {} +} + +assignPartial(obj, { foo(...args) {} }); // args has type [string] //// [instantiateContextualTypes.js] @@ -222,3 +232,7 @@ class Interesting { } } let xx = invoke(() => 1); +let obj = { + foo(bar) { } +}; +assignPartial(obj, { foo(...args) { } }); // args has type [string] diff --git a/tests/baselines/reference/instantiateContextualTypes.symbols b/tests/baselines/reference/instantiateContextualTypes.symbols index 1250edd585b..d3e8a7a317c 100644 --- a/tests/baselines/reference/instantiateContextualTypes.symbols +++ b/tests/baselines/reference/instantiateContextualTypes.symbols @@ -481,3 +481,29 @@ let xx: 0 | 1 | 2 = invoke(() => 1); >xx : Symbol(xx, Decl(instantiateContextualTypes.ts, 172, 3)) >invoke : Symbol(invoke, Decl(instantiateContextualTypes.ts, 166, 1)) +// Repro from #32416 + +declare function assignPartial(target: T, partial: Partial): T; +>assignPartial : Symbol(assignPartial, Decl(instantiateContextualTypes.ts, 172, 36)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 176, 31)) +>target : Symbol(target, Decl(instantiateContextualTypes.ts, 176, 34)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 176, 31)) +>partial : Symbol(partial, Decl(instantiateContextualTypes.ts, 176, 44)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 176, 31)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 176, 31)) + +let obj = { +>obj : Symbol(obj, Decl(instantiateContextualTypes.ts, 178, 3)) + + foo(bar: string) {} +>foo : Symbol(foo, Decl(instantiateContextualTypes.ts, 178, 11)) +>bar : Symbol(bar, Decl(instantiateContextualTypes.ts, 179, 6)) +} + +assignPartial(obj, { foo(...args) {} }); // args has type [string] +>assignPartial : Symbol(assignPartial, Decl(instantiateContextualTypes.ts, 172, 36)) +>obj : Symbol(obj, Decl(instantiateContextualTypes.ts, 178, 3)) +>foo : Symbol(foo, Decl(instantiateContextualTypes.ts, 182, 20)) +>args : Symbol(args, Decl(instantiateContextualTypes.ts, 182, 25)) + diff --git a/tests/baselines/reference/instantiateContextualTypes.types b/tests/baselines/reference/instantiateContextualTypes.types index 88e6ca7e4dd..b5317b6f756 100644 --- a/tests/baselines/reference/instantiateContextualTypes.types +++ b/tests/baselines/reference/instantiateContextualTypes.types @@ -422,3 +422,27 @@ let xx: 0 | 1 | 2 = invoke(() => 1); >() => 1 : () => 1 >1 : 1 +// Repro from #32416 + +declare function assignPartial(target: T, partial: Partial): T; +>assignPartial : (target: T, partial: Partial) => T +>target : T +>partial : Partial + +let obj = { +>obj : { foo(bar: string): void; } +>{ foo(bar: string) {}} : { foo(bar: string): void; } + + foo(bar: string) {} +>foo : (bar: string) => void +>bar : string +} + +assignPartial(obj, { foo(...args) {} }); // args has type [string] +>assignPartial(obj, { foo(...args) {} }) : { foo(bar: string): void; } +>assignPartial : (target: T, partial: Partial) => T +>obj : { foo(bar: string): void; } +>{ foo(...args) {} } : { foo(bar: string): void; } +>foo : (bar: string) => void +>args : [string] + From 30aad9db8dc6fe09fe4e21fe973e984c35c201dc Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Mon, 29 Jul 2019 09:46:42 -0400 Subject: [PATCH 030/182] Support more terminators for parsing jsdoc filepaths --- src/compiler/parser.ts | 12 ++++++----- src/compiler/scanner.ts | 2 +- src/harness/fourslash.ts | 4 ++++ src/services/classifier.ts | 1 + .../fourslash/jsDocDontBreakWithNamespaces.ts | 20 ++++++++++++++++--- 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9762302b7a2..b585adb04ac 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2428,17 +2428,19 @@ namespace ts { function parseJSDocType(): TypeNode { scanner.setInJSDocType(true); - const dotdotdot = parseOptionalToken(SyntaxKind.DotDotDotToken); const moduleSpecifier = parseOptionalToken(SyntaxKind.ModuleKeyword); - let type = parseTypeOrTypePredicate(); - scanner.setInJSDocType(false); if (moduleSpecifier) { const moduleTag = createNode(SyntaxKind.JSDocNamepathType, moduleSpecifier.pos) as JSDocNamepathType; - while (token() !== SyntaxKind.CloseBraceToken && token() !== SyntaxKind.EndOfFileToken) { + const terminators = [SyntaxKind.CloseBraceToken, SyntaxKind.EndOfFileToken, SyntaxKind.CommaToken, SyntaxKind.CloseParenToken]; + while (terminators.indexOf(token()) < 0) { nextTokenJSDoc(); } - type = finishNode(moduleTag); + return finishNode(moduleTag); } + + const dotdotdot = parseOptionalToken(SyntaxKind.DotDotDotToken); + let type = parseTypeOrTypePredicate(); + scanner.setInJSDocType(false); if (dotdotdot) { const variadic = createNode(SyntaxKind.JSDocVariadicType, dotdotdot.pos) as JSDocVariadicType; variadic.type = type; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index f949893171a..3109da91788 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -1983,7 +1983,7 @@ namespace ts { // First non-whitespace character on this line. let firstNonWhitespace = 0; // These initial values are special because the first line is: - // firstNonWhitespace = 0 to indicate that we want leading whitspace, + // firstNonWhitespace = 0 to indicate that we want leading whitespace, while (pos < end) { char = text.charCodeAt(pos); diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index f12506be2fb..b59f4e15dc4 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1268,6 +1268,10 @@ namespace FourSlash { private verifySignatureHelpWorker(options: FourSlashInterface.VerifySignatureHelpOptions) { const help = this.getSignatureHelp({ triggerReason: options.triggerReason })!; + if (!help) { + this.raiseError("Could not get a help signature"); + } + const selectedItem = help.items[help.selectedItemIndex]; // Argument index may exceed number of parameters const currentParameter = selectedItem.parameters[help.argumentIndex] as ts.SignatureHelpParameter | undefined; diff --git a/src/services/classifier.ts b/src/services/classifier.ts index f85a69681de..5da0354dc13 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -1,4 +1,5 @@ namespace ts { + /** The classifier is used for syntactic highlighting in editors via the TSServer */ export function createClassifier(): Classifier { const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false); diff --git a/tests/cases/fourslash/jsDocDontBreakWithNamespaces.ts b/tests/cases/fourslash/jsDocDontBreakWithNamespaces.ts index 7807d5d30d1..5be2f3e7b62 100644 --- a/tests/cases/fourslash/jsDocDontBreakWithNamespaces.ts +++ b/tests/cases/fourslash/jsDocDontBreakWithNamespaces.ts @@ -5,13 +5,27 @@ //// * @returns {module:@nodefuel/web~Webserver~wsServer#hello} Websocket server object //// */ ////function foo() { } -////foo(''/**/); +////foo(''/*foo*/); +//// +/////** +//// * @type {module:xxxxx} */ +//// */ +////function bar() { } +////bar(''/*bar*/); + verify.signatureHelp({ - marker: "", + marker: "foo", text: "foo(): any", docComment: "", tags: [ - { name: "returns", text: "Websocket server object" }, + { name: "returns", text: "Websocket server object" }, ], }); + +verify.signatureHelp({ + marker: "bar", + text: "bar(): void", + docComment: "", + tags: [], +}); From b963e1a2a7e3b1056ee2552927fa08fcc51e4c7d Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 29 Jul 2019 10:33:43 -0700 Subject: [PATCH 031/182] Update LKG (#32578) * Update LKG * Add @types/node version bump * Small paatches/casts to be compatible with latest node * Accept API baseline update * Make internal NodeBuffer compatable with latest Buffer * Why do we even have an internal buffer type * Sync up internal buffer type better * Fix lint * Readd mroe missing Buffer methods --- lib/enu/diagnosticMessages.generated.json.lcg | 424 +- lib/it/diagnosticMessages.generated.json | 4 +- lib/ja/diagnosticMessages.generated.json | 4 +- lib/ko/diagnosticMessages.generated.json | 140 +- lib/lib.dom.d.ts | 4022 ++- lib/lib.dom.iterable.d.ts | 111 +- lib/lib.es2015.collection.d.ts | 2 +- lib/lib.es2015.core.d.ts | 18 +- lib/lib.es2015.generator.d.ts | 10 +- lib/lib.es2015.iterable.d.ts | 26 +- lib/lib.es2015.promise.d.ts | 70 +- lib/lib.es2018.asyncgenerator.d.ts | 79 + lib/lib.es2018.asynciterable.d.ts | 9 +- lib/lib.es2018.d.ts | 1 + lib/lib.es2019.d.ts | 1 + lib/lib.es2019.object.d.ts | 35 + lib/lib.es2019.string.d.ts | 4 +- lib/lib.es2020.d.ts | 23 + lib/lib.es2020.full.d.ts | 25 + lib/lib.es2020.string.d.ts | 30 + lib/lib.es2020.symbol.wellknown.d.ts | 39 + lib/lib.es5.d.ts | 81 +- lib/lib.esnext.bigint.d.ts | 8 +- lib/lib.webworker.d.ts | 2245 +- lib/pl/diagnosticMessages.generated.json | 4 +- lib/protocol.d.ts | 57 +- lib/ru/diagnosticMessages.generated.json | 4 +- lib/tsc.js | 20474 ++++++----- lib/tsserver.js | 30143 +++++++++------- lib/tsserverlibrary.d.ts | 861 +- lib/tsserverlibrary.js | 30124 ++++++++------- lib/typescript.d.ts | 793 +- lib/typescript.js | 29662 ++++++++------- lib/typescriptServices.d.ts | 793 +- lib/typescriptServices.js | 29662 ++++++++------- lib/typingsInstaller.js | 23362 ++++++------ lib/zh-cn/diagnosticMessages.generated.json | 2 +- package.json | 2 +- src/compiler/sys.ts | 114 +- src/harness/harness.ts | 2 +- src/testRunner/externalCompileRunner.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 1124 +- tests/baselines/reference/api/typescript.d.ts | 1055 +- 43 files changed, 100855 insertions(+), 74796 deletions(-) create mode 100644 lib/lib.es2018.asyncgenerator.d.ts create mode 100644 lib/lib.es2019.object.d.ts create mode 100644 lib/lib.es2020.d.ts create mode 100644 lib/lib.es2020.full.d.ts create mode 100644 lib/lib.es2020.string.d.ts create mode 100644 lib/lib.es2020.symbol.wellknown.d.ts diff --git a/lib/enu/diagnosticMessages.generated.json.lcg b/lib/enu/diagnosticMessages.generated.json.lcg index 0b66fd7760c..77e5d6f2236 100644 --- a/lib/enu/diagnosticMessages.generated.json.lcg +++ b/lib/enu/diagnosticMessages.generated.json.lcg @@ -141,9 +141,9 @@ - + - + @@ -189,12 +189,6 @@ - - - - - - @@ -675,12 +669,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -849,6 +867,12 @@ + + + + + + @@ -867,6 +891,12 @@ + + + + + + @@ -1209,6 +1239,12 @@ + + + + + + @@ -1413,18 +1449,18 @@ - - - - - - + + + + + + @@ -1593,12 +1629,6 @@ - - - - - - @@ -1617,6 +1647,24 @@ + + + + + + + + + + + + + + + + + + @@ -1683,12 +1731,6 @@ - - - - - - @@ -1863,6 +1905,12 @@ + + + + + + @@ -2037,6 +2085,12 @@ + + + + + + @@ -2061,12 +2115,6 @@ - - - - - - @@ -2151,6 +2199,12 @@ + + + + + + @@ -2187,6 +2241,12 @@ + + + + + + {1}'?]]> @@ -2199,6 +2259,12 @@ + + + + + + @@ -2421,6 +2487,24 @@ + + + + + + + + + + + + + + + + + + @@ -2433,6 +2517,12 @@ + + + + + + @@ -2663,7 +2753,7 @@ - + @@ -2811,6 +2901,24 @@ + + + + + + + + + + + + + + + + + + @@ -2865,9 +2973,9 @@ - + - + @@ -2925,6 +3033,12 @@ + + + + + + @@ -2955,12 +3069,6 @@ - - - - - - @@ -3033,18 +3141,6 @@ - - - - - - - - - - - - @@ -3063,9 +3159,9 @@ - + - + @@ -3333,6 +3429,12 @@ + + + + + + @@ -3597,6 +3699,12 @@ + + + + + + @@ -3795,6 +3903,12 @@ + + + + + + @@ -3891,6 +4005,12 @@ + + + + + + @@ -3945,6 +4065,24 @@ + + + + + + + + + + + + + + + + + + @@ -3963,6 +4101,18 @@ + + + + + + + + + + + + @@ -3987,6 +4137,18 @@ + + + + + + + + + + + + @@ -4173,6 +4335,12 @@ + + + + + + @@ -4233,6 +4401,12 @@ + + + + + + @@ -4503,6 +4677,12 @@ + + + + + + @@ -4587,12 +4767,6 @@ - - - - - - @@ -4911,6 +5085,12 @@ + + + + + + @@ -4959,6 +5139,12 @@ + + + + + + @@ -5601,6 +5787,18 @@ + + + + + + + + + + + + @@ -5679,6 +5877,12 @@ + + + + + + @@ -5715,6 +5919,18 @@ + + + + + + + + + + + + @@ -5889,6 +6105,12 @@ + + + + + + @@ -5901,15 +6123,15 @@ - + - + - + - + @@ -5955,6 +6177,18 @@ + + + + + + + + + + + + @@ -5967,6 +6201,12 @@ + + + + + + @@ -5991,6 +6231,12 @@ + + + + + + @@ -6045,6 +6291,18 @@ + + + + + + + + + + + + @@ -6375,6 +6633,12 @@ + + + + + + @@ -6717,6 +6981,12 @@ + + + + + + @@ -6891,6 +7161,12 @@ + + + + + + @@ -6915,6 +7191,12 @@ + + + + + + @@ -7137,6 +7419,12 @@ + + + + + + @@ -7227,6 +7515,12 @@ + + + + + + diff --git a/lib/it/diagnosticMessages.generated.json b/lib/it/diagnosticMessages.generated.json index 9f8ef7d48f4..51981810ba2 100644 --- a/lib/it/diagnosticMessages.generated.json +++ b/lib/it/diagnosticMessages.generated.json @@ -355,7 +355,7 @@ "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_7017": "L'elemento contiene implicitamente un tipo 'any' perché al tipo '{0}' non è assegnata alcuna firma dell'indice.", "Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files_6164": "Crea un BOM (Byte Order Mark) UTF-8 all'inizio dei file di output.", "Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file_6151": "Crea un unico file con i mapping di origine invece di file separati.", - "Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap__6152": "Crea l'origine unitamente alle mappe di origine all'interno di un unico file. Richiede l'impostazione di '--inlineSourceMap' o '--sourceMap'.", + "Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap__6152": "Crea l'origine unitamente ai mapping di origine all'interno di un unico file. Richiede l'impostazione di '--inlineSourceMap' o '--sourceMap'.", "Enable_all_strict_type_checking_options_6180": "Abilita tutte le opzioni per i controlli del tipo strict.", "Enable_project_compilation_6302": "Abilitare la compilazione dei progetti", "Enable_strict_checking_of_function_types_6186": "Abilita il controllo tassativo dei tipi funzione.", @@ -445,7 +445,7 @@ "Function_overload_must_be_static_2387": "L'overload della funzione deve essere statico.", "Function_overload_must_not_be_static_2388": "L'overload della funzione non deve essere statico.", "Generate_get_and_set_accessors_95046": "Generare le funzioni di accesso 'get' e 'set'", - "Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000": "Genera un sourcemap per ogni file '.d.ts' corrispondente.", + "Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000": "Genera un mapping di origine per ogni file '.d.ts' corrispondente.", "Generates_corresponding_d_ts_file_6002": "Genera il file '.d.ts' corrispondente.", "Generates_corresponding_map_file_6043": "Genera il file '.map' corrispondente.", "Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_typ_7025": "Il tipo del generatore è implicitamente '{0}' perché non contiene alcun valore. Provare a specificare un tipo restituito.", diff --git a/lib/ja/diagnosticMessages.generated.json b/lib/ja/diagnosticMessages.generated.json index 6877a89c753..d3029982ca6 100644 --- a/lib/ja/diagnosticMessages.generated.json +++ b/lib/ja/diagnosticMessages.generated.json @@ -355,7 +355,7 @@ "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_7017": "型 '{0}' にはインデックス シグネチャがないため、要素は暗黙的に 'any' 型になります。", "Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files_6164": "出力ファイルの最初に UTF-8 バイト順マーク(BOM) を生成します。", "Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file_6151": "個々のファイルを持つ代わりに、複数のソース マップを含む単一ファイルを生成します。", - "Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap__6152": "単一ファイル内で sourcemap と共にソースを生成します。'--inlineSourceMap' または '--sourceMap' を設定する必要があります。", + "Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap__6152": "単一ファイル内でソースマップと共にソースを生成します。'--inlineSourceMap' または '--sourceMap' を設定する必要があります。", "Enable_all_strict_type_checking_options_6180": "厳密な型チェックのオプションをすべて有効にします。", "Enable_project_compilation_6302": "プロジェクトのコンパイルを有効にします", "Enable_strict_checking_of_function_types_6186": "関数の型の厳密なチェックを有効にします。", @@ -445,7 +445,7 @@ "Function_overload_must_be_static_2387": "関数のオーバーロードは静的でなければなりません。", "Function_overload_must_not_be_static_2388": "関数のオーバーロードは静的にはできせん。", "Generate_get_and_set_accessors_95046": "'get' および 'set' アクセサーの生成", - "Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000": "対応する各 '.d.ts' ファイルに sourcemap を生成します。", + "Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000": "対応する各 '.d.ts' ファイルにソースマップを生成します。", "Generates_corresponding_d_ts_file_6002": "対応する '.d.ts' ファイルを生成します。", "Generates_corresponding_map_file_6043": "対応する '.map' ファイルを生成します。", "Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_typ_7025": "ジェネレーターは値を生成しないため、暗黙的に型 '{0}' になります。戻り値の型を指定することを検討してください。", diff --git a/lib/ko/diagnosticMessages.generated.json b/lib/ko/diagnosticMessages.generated.json index a1b1320115a..abda4ace91f 100644 --- a/lib/ko/diagnosticMessages.generated.json +++ b/lib/ko/diagnosticMessages.generated.json @@ -309,7 +309,7 @@ "Declare_static_property_0_90027": "'{0}' 정적 속성 선언", "Decorators_are_not_valid_here_1206": "데코레이터는 여기에 사용할 수 없습니다.", "Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name_1207": "동일한 이름의 여러 get/set 접근자에 데코레이터를 적용할 수 없습니다.", - "Default_export_of_the_module_has_or_is_using_private_name_0_4082": "모듈의 기본 내보내기에서 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", + "Default_export_of_the_module_has_or_is_using_private_name_0_4082": "모듈의 기본 내보내기에서 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", "Delete_all_unused_declarations_95024": "사용하지 않는 선언 모두 삭제", "Delete_the_outputs_of_all_projects_6365": "모든 프로젝트의 출력 삭제", "Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react__6084": "[사용되지 않음] 대신 '--jsxFactory'를 사용합니다. 'react' JSX 내보내기를 대상으로 할 경우 createElement에 대해 호출되는 개체를 지정합니다.", @@ -395,10 +395,10 @@ "Export_declarations_are_not_permitted_in_a_namespace_1194": "네임스페이스에서는 내보내기 선언이 허용되지 않습니다.", "Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_2656": "내보낸 외부 패키지 입력 항목 파일 '{0}'은(는) 모듈이 아닙니다. 패키지 작성자에게 문의하여 패키지 정의를 업데이트하세요.", "Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_pack_2654": "내보낸 외부 패키지 입력 항목 파일에는 삼중 슬래시 참조가 포함될 수 없습니다. 패키지 작성자에게 문의하여 패키지 정의를 업데이트하세요.", - "Exported_type_alias_0_has_or_is_using_private_name_1_4081": "내보낸 형식 별칭 '{0}'은(는) '{1}' 전용 이름을 포함하거나 사용 중입니다.", + "Exported_type_alias_0_has_or_is_using_private_name_1_4081": "내보낸 형식 별칭 '{0}'은(는) '{1}' 프라이빗 이름을 포함하거나 사용 중입니다.", "Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4023": "내보낸 변수 '{0}'이(가) 외부 모듈 {2}의 '{1}' 이름을 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Exported_variable_0_has_or_is_using_name_1_from_private_module_2_4024": "내보낸 변수 '{0}'이(가) 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Exported_variable_0_has_or_is_using_private_name_1_4025": "내보낸 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Exported_variable_0_has_or_is_using_name_1_from_private_module_2_4024": "내보낸 변수 '{0}'이(가) 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Exported_variable_0_has_or_is_using_private_name_1_4025": "내보낸 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Exports_and_export_assignments_are_not_permitted_in_module_augmentations_2666": "내보내기 및 내보내기 할당는 모듈 확대에서 허용되지 않습니다.", "Expression_expected_1109": "식이 필요합니다.", "Expression_or_comma_expected_1137": "식 또는 쉼표가 필요합니다.", @@ -471,10 +471,10 @@ "Implement_all_unimplemented_interfaces_95032": "구현되지 않은 인터페이스 모두 구현", "Implement_inherited_abstract_class_90007": "상속된 추상 클래스 구현", "Implement_interface_0_90006": "'{0}' 인터페이스 구현", - "Implements_clause_of_exported_class_0_has_or_is_using_private_name_1_4019": "내보낸 클래스 '{0}'의 Implements 절이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Implements_clause_of_exported_class_0_has_or_is_using_private_name_1_4019": "내보낸 클래스 '{0}'의 Implements 절이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Import_0_from_module_1_90013": "\"{1}\" 모듈에서 '{0}' 가져오기", "Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_1202": "ECMAScript 모듈을 대상으로 하는 경우 할당 가져오기를 사용할 수 없습니다. 대신 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"' 또는 다른 모듈 형식 사용을 고려하세요.", - "Import_declaration_0_is_using_private_name_1_4000": "가져오기 선언 '{0}'이(가) 전용 이름 '{1}'을(를) 사용하고 있습니다.", + "Import_declaration_0_is_using_private_name_1_4000": "가져오기 선언 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 사용하고 있습니다.", "Import_declaration_conflicts_with_local_declaration_of_0_2440": "가져오기 선언이 '{0}'의 로컬 선언과 충돌합니다.", "Import_declarations_in_a_namespace_cannot_reference_a_module_1147": "네임스페이스의 가져오기 선언은 모듈을 참조할 수 없습니다.", "Import_emit_helpers_from_tslib_6139": "'tslib'에서 내보내기 도우미를 가져오세요.", @@ -563,8 +563,8 @@ "Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_d_2652": "병합된 선언 '{0}'에는 기본 내보내기 선언을 포함할 수 없습니다. 대신 별도의 'export default {0}' 선언을 추가하세요.", "Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constru_17013": "메타 속성 '{0}'은(는) 함수 선언, 함수 식 또는 생성기의 본문에서만 사용할 수 있습니다.", "Method_0_cannot_have_an_implementation_because_it_is_marked_abstract_1245": "'{0}' 메서드는 abstract로 표시되어 있으므로 구현이 있을 수 없습니다.", - "Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4101": "내보낸 인터페이스의 '{0}' 메서드가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Method_0_of_exported_interface_has_or_is_using_private_name_1_4102": "내보낸 인터페이스의 '{0}' 메서드가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4101": "내보낸 인터페이스의 '{0}' 메서드가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Method_0_of_exported_interface_has_or_is_using_private_name_1_4102": "내보낸 인터페이스의 '{0}' 메서드가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Modifiers_cannot_appear_here_1184": "한정자를 여기에 표시할 수 없습니다.", "Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_1340": "모듈 '{0}'은(는) 형식을 참조하지 않지만, 여기에서 형식으로 사용됩니다.", "Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here_1339": "모듈 '{0}'은(는) 값을 참조하지 않지만, 여기에서 값으로 사용됩니다.", @@ -639,36 +639,36 @@ "Overload_signatures_must_all_be_ambient_or_non_ambient_2384": "오버로드 시그니처는 모두 앰비언트이거나 앰비언트가 아니어야 합니다.", "Overload_signatures_must_all_be_exported_or_non_exported_2383": "오버로드 시그니처는 모두 내보내거나 모두 내보내지 않아야 합니다.", "Overload_signatures_must_all_be_optional_or_required_2386": "오버로드 시그니처는 모두 선택 사항이거나 필수 사항이어야 합니다.", - "Overload_signatures_must_all_be_public_private_or_protected_2385": "오버로드 시그니처는 모두 공용, 전용 또는 보호된 상태여야 합니다.", + "Overload_signatures_must_all_be_public_private_or_protected_2385": "오버로드 시그니처는 모두 퍼블릭, 프라이빗 또는 보호된 상태여야 합니다.", "Parameter_0_cannot_be_referenced_in_its_initializer_2372": "매개 변수 '{0}'은(는) 해당 이니셜라이저에서 참조할 수 없습니다.", "Parameter_0_implicitly_has_an_1_type_7006": "'{0}' 매개 변수에는 암시적으로 '{1}' 형식이 포함됩니다.", "Parameter_0_is_not_in_the_same_position_as_parameter_1_1227": "'{0}' 매개 변수는 '{1}' 매개 변수와 같은 위치에 있지 않습니다.", - "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4066": "내보낸 인터페이스에 있는 호출 시그니처의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4067": "내보낸 인터페이스에 있는 호출 시그니처의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4066": "내보낸 인터페이스에 있는 호출 시그니처의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4067": "내보낸 인터페이스에 있는 호출 시그니처의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_can_4061": "내보낸 클래스에 있는 생성자의 '{0}' 매개 변수가 외부 모듈 {2}의 '{1}' 이름을 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2_4062": "내보낸 클래스에 있는 생성자의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1_4063": "내보낸 클래스에 있는 생성자의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_mod_4064": "내보낸 인터페이스에 있는 생성자 시그니처의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4065": "내보낸 인터페이스에 있는 생성자 시그니처의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2_4062": "내보낸 클래스에 있는 생성자의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1_4063": "내보낸 클래스에 있는 생성자의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_mod_4064": "내보낸 인터페이스에 있는 생성자 시그니처의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4065": "내보낸 인터페이스에 있는 생성자 시그니처의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4076": "내보낸 함수의 '{0}' 매개 변수가 외부 모듈 {2}의 '{1}' 이름을 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2_4077": "내보낸 함수의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Parameter_0_of_exported_function_has_or_is_using_private_name_1_4078": "내보낸 함수의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4091": "내보낸 인터페이스에 있는 인덱스 시그니처의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1_4092": "내보낸 인터페이스에 있는 인덱스 시그니처의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4074": "내보낸 인터페이스에 있는 메서드의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4075": "내보낸 인터페이스에 있는 메서드의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2_4077": "내보낸 함수의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Parameter_0_of_exported_function_has_or_is_using_private_name_1_4078": "내보낸 함수의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4091": "내보낸 인터페이스에 있는 인덱스 시그니처의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1_4092": "내보낸 인터페이스에 있는 인덱스 시그니처의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4074": "내보낸 인터페이스에 있는 메서드의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4075": "내보낸 인터페이스에 있는 메서드의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_c_4071": "내보낸 클래스에 있는 공용 메서드의 '{0}' 매개 변수가 외부 모듈 {2}의 '{1}' 이름을 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4072": "내보낸 클래스에 있는 공용 메서드의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4073": "내보낸 클래스에 있는 공용 메서드의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4072": "내보낸 클래스에 있는 공용 메서드의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4073": "내보낸 클래스에 있는 공용 메서드의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module__4068": "내보낸 클래스에 있는 공용 정적 메서드의 '{0}' 매개 변수가 외부 모듈 {2}의 '{1}' 이름을 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4069": "내보낸 클래스에 있는 공용 정적 메서드의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4070": "내보낸 클래스에 있는 공용 정적 메서드의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4069": "내보낸 클래스에 있는 공용 정적 메서드의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4070": "내보낸 클래스에 있는 공용 정적 메서드의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Parameter_cannot_have_question_mark_and_initializer_1015": "매개 변수에 물음표와 이니셜라이저를 사용할 수 없습니다.", "Parameter_declaration_expected_1138": "매개 변수 선언이 필요합니다.", - "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4036": "내보낸 클래스에 있는 공용 setter '{0}'의 매개 변수 형식이 전용 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1_4037": "내보낸 클래스에 있는 공용 setter '{0}'의 매개 변수 형식이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_mod_4034": "내보낸 클래스에 있는 공용 정적 setter '{0}'의 매개 변수 형식이 전용 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1_4035": "내보낸 클래스에 있는 공용 정적 setter '{0}'의 매개 변수 형식이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4036": "내보낸 클래스에 있는 공용 setter '{0}'의 매개 변수 형식이 프라이빗 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1_4037": "내보낸 클래스에 있는 공용 setter '{0}'의 매개 변수 형식이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_mod_4034": "내보낸 클래스에 있는 공용 정적 setter '{0}'의 매개 변수 형식이 프라이빗 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1_4035": "내보낸 클래스에 있는 공용 정적 setter '{0}'의 매개 변수 형식이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Parse_in_strict_mode_and_emit_use_strict_for_each_source_file_6141": "strict 모드에서 구문 분석하고 각 소스 파일에 대해 \"use strict\"를 내보냅니다.", "Pattern_0_can_have_at_most_one_Asterisk_character_5061": "'{0}' 패턴에는 '*' 문자를 최대 하나만 사용할 수 있습니다.", "Prefix_0_with_an_underscore_90025": "'{0}' 앞에 밑줄 추가", @@ -709,9 +709,9 @@ "Property_0_is_protected_in_type_1_but_public_in_type_2_2444": "'{0}' 속성은 '{1}' 형식에서는 보호된 속성이지만 '{2}' 형식에서는 공용입니다.", "Property_0_is_used_before_being_assigned_2565": "'{0}' 속성이 할당되기 전에 사용되었습니다.", "Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property_2606": "JSX 분배 특성의 '{0}' 속성을 대상 속성에 할당할 수 없습니다.", - "Property_0_of_exported_class_expression_may_not_be_private_or_protected_4094": "내보낸 클래스 식의 속성 '{0}'이(가) 비공개가 아니거나 보호되지 않을 수 있습니다.", - "Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4032": "내보낸 인터페이스의 '{0}' 속성이 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Property_0_of_exported_interface_has_or_is_using_private_name_1_4033": "내보낸 인터페이스의 '{0}' 속성이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Property_0_of_exported_class_expression_may_not_be_private_or_protected_4094": "내보낸 클래스 식의 속성 '{0}'이(가) 프라이빗이 아니거나 보호되지 않을 수 있습니다.", + "Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4032": "내보낸 인터페이스의 '{0}' 속성이 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Property_0_of_exported_interface_has_or_is_using_private_name_1_4033": "내보낸 인터페이스의 '{0}' 속성이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2_2412": "'{1}' 형식의 '{0}' 속성을 숫자 인덱스 형식 '{2}'에 할당할 수 없습니다.", "Property_0_of_type_1_is_not_assignable_to_string_index_type_2_2411": "'{1}' 형식의 '{0}' 속성을 문자열 인덱스 형식 '{2}'에 할당할 수 없습니다.", "Property_assignment_expected_1136": "속성 할당이 필요합니다.", @@ -720,17 +720,17 @@ "Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_li_1328": "속성 값은 문자열 리터럴, 숫자 리터럴, 'true', 'false', 'null', 개체 리터럴 또는 배열 리터럴이어야 합니다.", "Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3_6179": "'ES5' 또는 'ES3'을 대상으로 할 경우 'for-of', spread 및 소멸의 반복 가능한 개체를 완벽히 지원합니다.", "Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4098": "내보낸 클래스의 공용 메서드 '{0}'이(가) 외부 모듈 {2}의 '{1}' 이름을 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4099": "내보낸 클래스의 공용 메서드 '{0}'이(가) 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Public_method_0_of_exported_class_has_or_is_using_private_name_1_4100": "내보낸 클래스의 공용 메서드의 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4099": "내보낸 클래스의 공용 메서드 '{0}'이(가) 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Public_method_0_of_exported_class_has_or_is_using_private_name_1_4100": "내보낸 클래스의 공용 메서드의 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_name_4029": "내보낸 클래스의 공용 속성 '{0}'이(가) 외부 모듈 {2}의 '{1}' 이름을 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4030": "내보낸 클래스의 공용 속성 '{0}'이(가) 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Public_property_0_of_exported_class_has_or_is_using_private_name_1_4031": "내보낸 클래스의 공용 속성 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4030": "내보낸 클래스의 공용 속성 '{0}'이(가) 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Public_property_0_of_exported_class_has_or_is_using_private_name_1_4031": "내보낸 클래스의 공용 속성 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_4095": "내보낸 클래스의 공용 정적 메서드 '{0}'이(가) 외부 모듈 {2}의 '{1}' 이름을 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4096": "내보낸 클래스에 있는 공용 정적 메서드 '{0}'이(가) 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Public_static_method_0_of_exported_class_has_or_is_using_private_name_1_4097": "내보낸 클래스의 공용 정적 메서드 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4096": "내보낸 클래스에 있는 공용 정적 메서드 '{0}'이(가) 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Public_static_method_0_of_exported_class_has_or_is_using_private_name_1_4097": "내보낸 클래스의 공용 정적 메서드 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot__4026": "내보낸 클래스에 있는 공용 정적 속성 '{0}'이(가) 외부 모듈 {2}의 '{1}' 이름을 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4027": "내보낸 클래스의 공용 정적 속성 '{0}'이(가) 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", - "Public_static_property_0_of_exported_class_has_or_is_using_private_name_1_4028": "내보낸 클래스의 공용 정적 속성 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4027": "내보낸 클래스의 공용 정적 속성 '{0}'이(가) 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.", + "Public_static_property_0_of_exported_class_has_or_is_using_private_name_1_4028": "내보낸 클래스의 공용 정적 속성 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Raise_error_on_expressions_and_declarations_with_an_implied_any_type_6052": "암시된 'any' 형식이 있는 식 및 선언에서 오류를 발생합니다.", "Raise_error_on_this_expressions_with_an_implied_any_type_6115": "암시된 'any' 형식이 있는 'this' 식에서 오류를 발생합니다.", "Redirect_output_structure_to_the_directory_6006": "출력 구조를 디렉터리로 리디렉션합니다.", @@ -765,30 +765,30 @@ "Resolving_with_primary_search_path_0_6121": "기본 검색 경로 '{0}'을(를) 사용하여 확인하는 중입니다.", "Rest_parameter_0_implicitly_has_an_any_type_7019": "Rest 매개 변수 '{0}'에는 암시적으로 'any[]' 형식이 포함됩니다.", "Rest_types_may_only_be_created_from_object_types_2700": "rest 유형은 개체 형식에서만 만들 수 있습니다.", - "Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4046": "내보낸 인터페이스에 있는 호출 시그니처의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", - "Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0_4047": "내보낸 인터페이스에 있는 호출 시그니처의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", - "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_mod_4044": "내보낸 인터페이스에 있는 생성자 시그니처의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", - "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0_4045": "내보낸 인터페이스에 있는 생성자 시그니처의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", + "Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4046": "내보낸 인터페이스에 있는 호출 시그니처의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", + "Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0_4047": "내보낸 인터페이스에 있는 호출 시그니처의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", + "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_mod_4044": "내보낸 인터페이스에 있는 생성자 시그니처의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", + "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0_4045": "내보낸 인터페이스에 있는 생성자 시그니처의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", "Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class_2409": "생성자 시그니처의 반환 형식을 클래스의 인스턴스 형식에 할당할 수 있어야 합니다.", "Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named_4058": "내보낸 함수의 반환 형식이 외부 모듈 {1}의 '{0}' 이름을 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1_4059": "내보낸 함수의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", - "Return_type_of_exported_function_has_or_is_using_private_name_0_4060": "내보낸 함수의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", - "Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4048": "내보낸 인터페이스에 있는 인덱스 시그니처의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", - "Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0_4049": "내보낸 인터페이스에 있는 인덱스 시그니처의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", - "Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4056": "내보낸 인터페이스에 있는 메서드의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", - "Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0_4057": "내보낸 인터페이스에 있는 메서드의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", + "Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1_4059": "내보낸 함수의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", + "Return_type_of_exported_function_has_or_is_using_private_name_0_4060": "내보낸 함수의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", + "Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4048": "내보낸 인터페이스에 있는 인덱스 시그니처의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", + "Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0_4049": "내보낸 인터페이스에 있는 인덱스 시그니처의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", + "Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4056": "내보낸 인터페이스에 있는 메서드의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", + "Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0_4057": "내보낸 인터페이스에 있는 메서드의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_4041": "내보낸 클래스에 있는 공용 getter '{0}'의 반환 형식이 외부 모듈 {2}의 이름 '{1}'을(를) 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4042": "내보낸 클래스에 있는 공용 getter '{0}'의 반환 형식이 전용 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1_4043": "내보낸 클래스에 있는 공용 getter '{0}'의 반환 형식이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4042": "내보낸 클래스에 있는 공용 getter '{0}'의 반환 형식이 프라이빗 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1_4043": "내보낸 클래스에 있는 공용 getter '{0}'의 반환 형식이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_c_4053": "내보낸 클래스에 있는 공용 메서드의 반환 형식이 외부 모듈 {1}의 '{0}' 이름을 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4054": "내보낸 클래스에 있는 공용 메서드의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", - "Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0_4055": "내보낸 클래스에 있는 공용 메서드의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", + "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4054": "내보낸 클래스에 있는 공용 메서드의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", + "Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0_4055": "내보낸 클래스에 있는 공용 메서드의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_modul_4038": "내보낸 클래스에 있는 공용 정적 getter '{0}'의 반환 형식이 외부 모듈 {2}의 이름 '{1}'을(를) 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_4039": "내보낸 클래스에 있는 공용 정적 getter '{0}'의 반환 형식이 전용 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1_4040": "내보낸 클래스에 있는 공용 정적 getter '{0}'의 반환 형식이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_4039": "내보낸 클래스에 있는 공용 정적 getter '{0}'의 반환 형식이 프라이빗 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1_4040": "내보낸 클래스에 있는 공용 정적 getter '{0}'의 반환 형식이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module__4050": "내보낸 클래스에 있는 공용 정적 메서드의 반환 형식이 외부 모듈 {1}의 '{0}' 이름을 가지고 있거나 사용 중이지만 명명할 수 없습니다.", - "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4051": "내보낸 클래스에 있는 공용 정적 메서드의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", - "Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0_4052": "내보낸 클래스에 있는 공용 정적 메서드의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", + "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4051": "내보낸 클래스에 있는 공용 정적 메서드의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.", + "Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0_4052": "내보낸 클래스에 있는 공용 정적 메서드의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.", "Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program_6184": "이전 프로그램에서 변경되지 않았으므로 '{0}'에서 발생하는 모듈 확인을 다시 사용합니다.", "Reusing_resolution_of_module_0_to_file_1_from_old_program_6183": "'{0}' 모듈 확인을 이전 프로그램의 '{1}' 파일에 다시 사용합니다.", "Rewrite_all_as_indexed_access_types_95034": "인덱싱된 액세스 형식으로 모두 다시 작성", @@ -939,15 +939,15 @@ "Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_cal_1321": "비동기 생성기에 있는 'yield' 형식의 피연산자는 유효한 프라미스여야 하거나 호출 가능 'then' 멤버를 포함하지 않아야 합니다.", "Type_parameter_0_has_a_circular_constraint_2313": "형식 매개 변수 '{0}'에 순환 제약 조건이 있습니다.", "Type_parameter_0_has_a_circular_default_2716": "형식 매개 변수 '{0}'에 순환 기본값이 있습니다.", - "Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008": "내보낸 인터페이스에 있는 호출 시그니처의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4006": "내보낸 인터페이스에 있는 생성자 시그니처의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002": "내보낸 클래스의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Type_parameter_0_of_exported_function_has_or_is_using_private_name_1_4016": "내보낸 함수의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004": "내보낸 인터페이스의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1_4083": "내보낸 형식 별칭의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4014": "내보낸 인터페이스에 있는 메서드의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4012": "내보낸 클래스에 있는 공용 메서드의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4010": "내보낸 클래스에 있는 공용 정적 메서드의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008": "내보낸 인터페이스에 있는 호출 시그니처의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4006": "내보낸 인터페이스에 있는 생성자 시그니처의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002": "내보낸 클래스의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Type_parameter_0_of_exported_function_has_or_is_using_private_name_1_4016": "내보낸 함수의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004": "내보낸 인터페이스의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1_4083": "내보낸 형식 별칭의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4014": "내보낸 인터페이스에 있는 메서드의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4012": "내보낸 클래스에 있는 공용 메서드의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4010": "내보낸 클래스에 있는 공용 정적 메서드의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "Type_parameter_declaration_expected_1139": "형식 매개 변수 선언이 필요합니다.", "Type_parameter_list_cannot_be_empty_1098": "형식 매개 변수 목록은 비워 둘 수 없습니다.", "Type_parameter_name_cannot_be_0_2368": "형식 매개 변수 이름은 '{0}'일 수 없습니다.", @@ -955,7 +955,7 @@ "Type_predicate_0_is_not_assignable_to_1_1226": "형식 조건자 '{0}'을(를) '{1}'에 할당할 수 없습니다.", "Type_reference_directive_0_was_not_resolved_6120": "======== 형식 참조 지시문 '{0}'이(가) 확인되지 않았습니다. ========", "Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2_6119": "======== 형식 참조 지시문 '{0}'이(가) '{1}'(으)로 확인되었습니다. 주: {2}. ========", - "Types_have_separate_declarations_of_a_private_property_0_2442": "형식에 별도의 전용 속성 '{0}' 선언이 있습니다.", + "Types_have_separate_declarations_of_a_private_property_0_2442": "형식에 별도의 프라이빗 속성 '{0}' 선언이 있습니다.", "Types_of_parameters_0_and_1_are_incompatible_2328": "'{0}' 및 '{1}' 매개 변수의 형식이 호환되지 않습니다.", "Types_of_property_0_are_incompatible_2326": "'{0}' 속성의 형식이 호환되지 않습니다.", "Unable_to_open_file_0_6050": "'{0}' 파일을 열 수 없습니다.", @@ -1047,8 +1047,8 @@ "export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always__2668": "앰비언트 모듈 및 모듈 확대는 항상 표시되므로 'export' 한정자를 적용할 수 없습니다.", "extends_clause_already_seen_1172": "'extends' 절이 이미 있습니다.", "extends_clause_must_precede_implements_clause_1173": "'extends' 절은 'implements' 절 앞에 와야 합니다.", - "extends_clause_of_exported_class_0_has_or_is_using_private_name_1_4020": "내보낸 클래스 '{0}'의 Extends 절이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", - "extends_clause_of_exported_interface_0_has_or_is_using_private_name_1_4022": "내보낸 인터페이스 '{0}'의 Extends 절이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "extends_clause_of_exported_class_0_has_or_is_using_private_name_1_4020": "내보낸 클래스 '{0}'의 Extends 절이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", + "extends_clause_of_exported_interface_0_has_or_is_using_private_name_1_4022": "내보낸 인터페이스 '{0}'의 Extends 절이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.", "file_6025": "파일", "get_and_set_accessor_must_have_the_same_this_type_2682": "'get' 및 'set' 접근자는 동일한 'this' 형식이어야 합니다.", "get_and_set_accessor_must_have_the_same_type_2380": "'get' 및 'set' 접근자의 형식이 같아야 합니다.", diff --git a/lib/lib.dom.d.ts b/lib/lib.dom.d.ts index 7817a0e4267..92500ffc046 100644 --- a/lib/lib.dom.d.ts +++ b/lib/lib.dom.d.ts @@ -153,6 +153,34 @@ interface AudioWorkletNodeOptions extends AudioNodeOptions { processorOptions?: any; } +interface AuthenticationExtensionsClientInputs { + appid?: string; + authnSel?: AuthenticatorSelectionList; + exts?: boolean; + loc?: boolean; + txAuthGeneric?: txAuthGenericArg; + txAuthSimple?: string; + uvi?: boolean; + uvm?: boolean; +} + +interface AuthenticationExtensionsClientOutputs { + appid?: boolean; + authnSel?: boolean; + exts?: AuthenticationExtensionsSupported; + loc?: Coordinates; + txAuthGeneric?: ArrayBuffer; + txAuthSimple?: string; + uvi?: ArrayBuffer; + uvm?: UvmEntries; +} + +interface AuthenticatorSelectionCriteria { + authenticatorAttachment?: AuthenticatorAttachment; + requireResidentKey?: boolean; + userVerification?: UserVerificationRequirement; +} + interface BiquadFilterOptions extends AudioNodeOptions { Q?: number; detune?: number; @@ -171,7 +199,6 @@ interface ByteLengthChunk { } interface CacheQueryOptions { - cacheName?: string; ignoreMethod?: boolean; ignoreSearch?: boolean; ignoreVary?: boolean; @@ -179,6 +206,7 @@ interface CacheQueryOptions { interface CanvasRenderingContext2DSettings { alpha?: boolean; + desynchronized?: boolean; } interface ChannelMergerOptions extends AudioNodeOptions { @@ -256,7 +284,7 @@ interface ConstrainDoubleRange extends DoubleRange { ideal?: number; } -interface ConstrainLongRange extends LongRange { +interface ConstrainULongRange extends ULongRange { exact?: number; ideal?: number; } @@ -271,6 +299,17 @@ interface ConvolverOptions extends AudioNodeOptions { disableNormalization?: boolean; } +interface CredentialCreationOptions { + publicKey?: PublicKeyCredentialCreationOptions; + signal?: AbortSignal; +} + +interface CredentialRequestOptions { + mediation?: CredentialMediationRequirement; + publicKey?: PublicKeyCredentialRequestOptions; + signal?: AbortSignal; +} + interface CustomEventInit extends EventInit { detail?: T; } @@ -330,21 +369,27 @@ interface DelayOptions extends AudioNodeOptions { maxDelayTime?: number; } -interface DeviceAccelerationDict { +interface DeviceLightEventInit extends EventInit { + value?: number; +} + +interface DeviceMotionEventAccelerationInit { x?: number | null; y?: number | null; z?: number | null; } -interface DeviceLightEventInit extends EventInit { - value?: number; +interface DeviceMotionEventInit extends EventInit { + acceleration?: DeviceMotionEventAccelerationInit; + accelerationIncludingGravity?: DeviceMotionEventAccelerationInit; + interval?: number; + rotationRate?: DeviceMotionEventRotationRateInit; } -interface DeviceMotionEventInit extends EventInit { - acceleration?: DeviceAccelerationDict | null; - accelerationIncludingGravity?: DeviceAccelerationDict | null; - interval?: number | null; - rotationRate?: DeviceRotationRateDict | null; +interface DeviceMotionEventRotationRateInit { + alpha?: number | null; + beta?: number | null; + gamma?: number | null; } interface DeviceOrientationEventInit extends EventInit { @@ -354,10 +399,9 @@ interface DeviceOrientationEventInit extends EventInit { gamma?: number | null; } -interface DeviceRotationRateDict { - alpha?: number | null; - beta?: number | null; - gamma?: number | null; +interface DevicePermissionDescriptor extends PermissionDescriptor { + deviceId?: string; + name: "camera" | "microphone" | "speaker"; } interface DocumentTimelineOptions { @@ -412,6 +456,10 @@ interface EffectTiming { iterations?: number; } +interface ElementCreationOptions { + is?: string; +} + interface ElementDefinitionOptions { extends?: string; } @@ -444,7 +492,6 @@ interface EventModifierInit extends UIEventInit { modifierFnLock?: boolean; modifierHyper?: boolean; modifierNumLock?: boolean; - modifierOS?: boolean; modifierScrollLock?: boolean; modifierSuper?: boolean; modifierSymbol?: boolean; @@ -553,11 +600,27 @@ interface IIRFilterOptions extends AudioNodeOptions { feedforward: number[]; } +interface ImageBitmapRenderingContextSettings { + alpha?: boolean; +} + +interface ImageEncodeOptions { + quality?: number; + type?: string; +} + +interface InputEventInit extends UIEventInit { + data?: string | null; + inputType?: string; + isComposing?: boolean; +} + interface IntersectionObserverEntryInit { boundingClientRect: DOMRectInit; + intersectionRatio: number; intersectionRect: DOMRectInit; isIntersecting: boolean; - rootBounds: DOMRectInit; + rootBounds: DOMRectInit | null; target: Element; time: number; } @@ -595,6 +658,7 @@ interface KeyAlgorithm { interface KeyboardEventInit extends EventModifierInit { code?: string; + isComposing?: boolean; key?: string; location?: number; repeat?: boolean; @@ -616,11 +680,6 @@ interface KeyframeEffectOptions extends EffectTiming { iterationComposite?: IterationCompositeOperation; } -interface LongRange { - max?: number; - min?: number; -} - interface MediaElementAudioSourceOptions { mediaElement: HTMLMediaElement; } @@ -678,39 +737,43 @@ interface MediaStreamTrackAudioSourceOptions { } interface MediaStreamTrackEventInit extends EventInit { - track?: MediaStreamTrack | null; + track: MediaStreamTrack; } interface MediaTrackCapabilities { - aspectRatio?: number | DoubleRange; + aspectRatio?: DoubleRange; + autoGainControl?: boolean[]; + channelCount?: ULongRange; deviceId?: string; echoCancellation?: boolean[]; - facingMode?: string; - frameRate?: number | DoubleRange; + facingMode?: string[]; + frameRate?: DoubleRange; groupId?: string; - height?: number | LongRange; - sampleRate?: number | LongRange; - sampleSize?: number | LongRange; - volume?: number | DoubleRange; - width?: number | LongRange; + height?: ULongRange; + latency?: DoubleRange; + noiseSuppression?: boolean[]; + resizeMode?: string[]; + sampleRate?: ULongRange; + sampleSize?: ULongRange; + width?: ULongRange; } interface MediaTrackConstraintSet { - aspectRatio?: number | ConstrainDoubleRange; - channelCount?: number | ConstrainLongRange; - deviceId?: string | string[] | ConstrainDOMStringParameters; - displaySurface?: string | string[] | ConstrainDOMStringParameters; - echoCancellation?: boolean | ConstrainBooleanParameters; - facingMode?: string | string[] | ConstrainDOMStringParameters; - frameRate?: number | ConstrainDoubleRange; - groupId?: string | string[] | ConstrainDOMStringParameters; - height?: number | ConstrainLongRange; - latency?: number | ConstrainDoubleRange; - logicalSurface?: boolean | ConstrainBooleanParameters; - sampleRate?: number | ConstrainLongRange; - sampleSize?: number | ConstrainLongRange; - volume?: number | ConstrainDoubleRange; - width?: number | ConstrainLongRange; + aspectRatio?: ConstrainDouble; + autoGainControl?: ConstrainBoolean; + channelCount?: ConstrainULong; + deviceId?: ConstrainDOMString; + echoCancellation?: ConstrainBoolean; + facingMode?: ConstrainDOMString; + frameRate?: ConstrainDouble; + groupId?: ConstrainDOMString; + height?: ConstrainULong; + latency?: ConstrainDouble; + noiseSuppression?: ConstrainBoolean; + resizeMode?: ConstrainDOMString; + sampleRate?: ConstrainULong; + sampleSize?: ConstrainULong; + width?: ConstrainULong; } interface MediaTrackConstraints extends MediaTrackConstraintSet { @@ -719,29 +782,37 @@ interface MediaTrackConstraints extends MediaTrackConstraintSet { interface MediaTrackSettings { aspectRatio?: number; + autoGainControl?: boolean; + channelCount?: number; deviceId?: string; echoCancellation?: boolean; facingMode?: string; frameRate?: number; groupId?: string; height?: number; + latency?: number; + noiseSuppression?: boolean; + resizeMode?: string; sampleRate?: number; sampleSize?: number; - volume?: number; width?: number; } interface MediaTrackSupportedConstraints { aspectRatio?: boolean; + autoGainControl?: boolean; + channelCount?: boolean; deviceId?: boolean; echoCancellation?: boolean; facingMode?: boolean; frameRate?: boolean; groupId?: boolean; height?: boolean; + latency?: boolean; + noiseSuppression?: boolean; + resizeMode?: boolean; sampleRate?: boolean; sampleSize?: boolean; - volume?: boolean; width?: boolean; } @@ -753,6 +824,11 @@ interface MessageEventInit extends EventInit { source?: MessageEventSource | null; } +interface MidiPermissionDescriptor extends PermissionDescriptor { + name: "midi"; + sysex?: boolean; +} + interface MouseEventInit extends EventModifierInit { button?: number; buttons?: number; @@ -765,13 +841,38 @@ interface MouseEventInit extends EventModifierInit { screenY?: number; } +interface MultiCacheQueryOptions extends CacheQueryOptions { + cacheName?: string; +} + interface MutationObserverInit { + /** + * Set to a list of attribute local names (without namespace) if not all attribute mutations need to be observed and attributes is true or omitted. + */ attributeFilter?: string[]; + /** + * Set to true if attributes is true or omitted and target's attribute value before the mutation needs to be recorded. + */ attributeOldValue?: boolean; + /** + * Set to true if mutations to target's attributes are to be observed. Can be omitted if attributeOldValue or attributeFilter is specified. + */ attributes?: boolean; + /** + * Set to true if mutations to target's data are to be observed. Can be omitted if characterDataOldValue is specified. + */ characterData?: boolean; + /** + * Set to true if characterData is set to true or omitted and target's data before the mutation needs to be recorded. + */ characterDataOldValue?: boolean; + /** + * Set to true if mutations to target's children are to be observed. + */ childList?: boolean; + /** + * Set to true if mutations to not just target, but also target's descendants are to be observed. + */ subtree?: boolean; } @@ -914,7 +1015,8 @@ interface Pbkdf2Params extends Algorithm { interface PerformanceObserverInit { buffered?: boolean; - entryTypes: string[]; + entryTypes?: string[]; + type?: string; } interface PeriodicWaveConstraints { @@ -926,10 +1028,15 @@ interface PeriodicWaveOptions extends PeriodicWaveConstraints { real?: number[] | Float32Array; } +interface PermissionDescriptor { + name: PermissionName; +} + interface PipeOptions { preventAbort?: boolean; preventCancel?: boolean; preventClose?: boolean; + signal?: AbortSignal; } interface PointerEventInit extends MouseEventInit { @@ -955,6 +1062,10 @@ interface PositionOptions { timeout?: number; } +interface PostMessageOptions { + transfer?: any[]; +} + interface ProgressEventInit extends EventInit { lengthComputable?: boolean; loaded?: number; @@ -973,6 +1084,57 @@ interface PropertyIndexedKeyframes { [property: string]: string | string[] | number | null | (number | null)[] | undefined; } +interface PublicKeyCredentialCreationOptions { + attestation?: AttestationConveyancePreference; + authenticatorSelection?: AuthenticatorSelectionCriteria; + challenge: BufferSource; + excludeCredentials?: PublicKeyCredentialDescriptor[]; + extensions?: AuthenticationExtensionsClientInputs; + pubKeyCredParams: PublicKeyCredentialParameters[]; + rp: PublicKeyCredentialRpEntity; + timeout?: number; + user: PublicKeyCredentialUserEntity; +} + +interface PublicKeyCredentialDescriptor { + id: BufferSource; + transports?: AuthenticatorTransport[]; + type: PublicKeyCredentialType; +} + +interface PublicKeyCredentialEntity { + icon?: string; + name: string; +} + +interface PublicKeyCredentialParameters { + alg: COSEAlgorithmIdentifier; + type: PublicKeyCredentialType; +} + +interface PublicKeyCredentialRequestOptions { + allowCredentials?: PublicKeyCredentialDescriptor[]; + challenge: BufferSource; + extensions?: AuthenticationExtensionsClientInputs; + rpId?: string; + timeout?: number; + userVerification?: UserVerificationRequirement; +} + +interface PublicKeyCredentialRpEntity extends PublicKeyCredentialEntity { + id?: string; +} + +interface PublicKeyCredentialUserEntity extends PublicKeyCredentialEntity { + displayName: string; + id: BufferSource; +} + +interface PushPermissionDescriptor extends PermissionDescriptor { + name: "push"; + userVisibleOnly?: boolean; +} + interface PushSubscriptionJSON { endpoint?: string; expirationTime?: number | null; @@ -1361,18 +1523,57 @@ interface RegistrationOptions { } interface RequestInit { + /** + * A BodyInit object or null to set request's body. + */ body?: BodyInit | null; + /** + * A string indicating how the request will interact with the browser's cache to set request's cache. + */ cache?: RequestCache; + /** + * A string indicating whether credentials will be sent with the request always, never, or only when sent to a same-origin URL. Sets request's credentials. + */ credentials?: RequestCredentials; + /** + * A Headers object, an object literal, or an array of two-item arrays to set request's headers. + */ headers?: HeadersInit; + /** + * A cryptographic hash of the resource to be fetched by request. Sets request's integrity. + */ integrity?: string; + /** + * A boolean to set request's keepalive. + */ keepalive?: boolean; + /** + * A string to set request's method. + */ method?: string; + /** + * A string to indicate whether the request will use CORS, or will be restricted to same-origin URLs. Sets request's mode. + */ mode?: RequestMode; + /** + * A string indicating whether request follows redirects, results in an error upon encountering a redirect, or returns the redirect (in an opaque fashion). Sets request's redirect. + */ redirect?: RequestRedirect; + /** + * A string whose value is a same-origin URL, "about:client", or the empty string, to set request's referrer. + */ referrer?: string; + /** + * A referrer policy to set request's referrerPolicy. + */ referrerPolicy?: ReferrerPolicy; + /** + * An AbortSignal to set request's signal. + */ signal?: AbortSignal | null; + /** + * Can only be null. Used to disassociate request from any Window. + */ window?: any; } @@ -1519,6 +1720,11 @@ interface TextDecoderOptions { ignoreBOM?: boolean; } +interface TextEncoderEncodeIntoResult { + read?: number; + written?: number; +} + interface TouchEventInit extends EventModifierInit { changedTouches?: Touch[]; targetTouches?: Touch[]; @@ -1566,6 +1772,11 @@ interface UIEventInit extends EventInit { view?: Window | null; } +interface ULongRange { + max?: number; + min?: number; +} + interface UnderlyingByteSource { autoAllocateChunkSize?: number; cancel?: ReadableStreamErrorCallback; @@ -1615,14 +1826,15 @@ interface WebAuthnExtensions { } interface WebGLContextAttributes { - alpha?: GLboolean; - antialias?: GLboolean; - depth?: GLboolean; + alpha?: boolean; + antialias?: boolean; + depth?: boolean; + desynchronized?: boolean; failIfMajorPerformanceCaveat?: boolean; powerPreference?: WebGLPowerPreference; - premultipliedAlpha?: GLboolean; - preserveDrawingBuffer?: GLboolean; - stencil?: GLboolean; + premultipliedAlpha?: boolean; + preserveDrawingBuffer?: boolean; + stencil?: boolean; } interface WebGLContextEventInit extends EventInit { @@ -1646,10 +1858,17 @@ interface WorkletOptions { credentials?: RequestCredentials; } +interface txAuthGenericArg { + content: ArrayBuffer; + contentType: string; +} + interface EventListener { (evt: Event): void; } +type XPathNSResolver = ((prefix: string | null) => string | null) | { lookupNamespaceURI(prefix: string | null): string | null; }; + /** The ANGLE_instanced_arrays extension is part of the WebGL API and allows to draw the same object, or groups of similar objects multiple times, if they share the same vertex data, primitive count and type. */ interface ANGLE_instanced_arrays { drawArraysInstancedANGLE(mode: GLenum, first: GLint, count: GLsizei, primcount: GLsizei): void; @@ -1658,15 +1877,14 @@ interface ANGLE_instanced_arrays { readonly VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: GLenum; } -/** The AbortController interface represents a controller object that allows you to abort one or more DOM requests as and when desired. */ +/** A controller object that allows you to abort one or more DOM requests as and when desired. */ interface AbortController { /** * Returns the AbortSignal object associated with this object. */ readonly signal: AbortSignal; /** - * Invoking this method will set this object's AbortSignal's aborted flag and - * signal to any observers that the associated activity is to be aborted. + * Invoking this method will set this object's AbortSignal's aborted flag and signal to any observers that the associated activity is to be aborted. */ abort(): void; } @@ -1680,11 +1898,10 @@ interface AbortSignalEventMap { "abort": Event; } -/** The AbortSignal interface represents a signal object that allows you to communicate with a DOM request (such as a Fetch) and abort it if required via an AbortController object. */ +/** A signal object that allows you to communicate with a DOM request (such as a Fetch) and abort it if required via an AbortController object. */ interface AbortSignal extends EventTarget { /** - * Returns true if this AbortSignal's AbortController has signaled to abort, and false - * otherwise. + * Returns true if this AbortSignal's AbortController has signaled to abort, and false otherwise. */ readonly aborted: boolean; onabort: ((this: AbortSignal, ev: Event) => any) | null; @@ -1700,10 +1917,25 @@ declare var AbortSignal: { }; interface AbstractRange { + /** + * Returns true if range is collapsed, and false otherwise. + */ readonly collapsed: boolean; + /** + * Returns range's end node. + */ readonly endContainer: Node; + /** + * Returns range's end offset. + */ readonly endOffset: number; + /** + * Returns range's start node. + */ readonly startContainer: Node; + /** + * Returns range's start offset. + */ readonly startOffset: number; } @@ -1732,7 +1964,7 @@ interface AesCmacParams extends Algorithm { length: number; } -/** The AnalyserNode interface represents a node able to provide real-time frequency and time-domain analysis information. It is an AudioNode that passes the audio stream unchanged from the input to the output, but allows you to take the generated data, process it, and create audio visualizations. */ +/** A node able to provide real-time frequency and time-domain analysis information. It is an AudioNode that passes the audio stream unchanged from the input to the output, but allows you to take the generated data, process it, and create audio visualizations. */ interface AnalyserNode extends AudioNode { fftSize: number; readonly frequencyBinCount: number; @@ -1801,7 +2033,7 @@ declare var AnimationEffect: { new(): AnimationEffect; }; -/** The AnimationEvent interface represents events providing information related to animations. */ +/** Events providing information related to animations. */ interface AnimationEvent extends Event { readonly animationName: string; readonly elapsedTime: number; @@ -1813,6 +2045,11 @@ declare var AnimationEvent: { new(type: string, animationEventInitDict?: AnimationEventInit): AnimationEvent; }; +interface AnimationFrameProvider { + cancelAnimationFrame(handle: number): void; + requestAnimationFrame(callback: FrameRequestCallback): number; +} + interface AnimationPlaybackEvent extends Event { readonly currentTime: number | null; readonly timelineTime: number | null; @@ -1839,7 +2076,7 @@ interface ApplicationCacheEventMap { "error": Event; "noupdate": Event; "obsolete": Event; - "progress": ProgressEvent; + "progress": ProgressEvent; "updateready": Event; } @@ -1857,7 +2094,7 @@ interface ApplicationCache extends EventTarget { /** @deprecated */ onobsolete: ((this: ApplicationCache, ev: Event) => any) | null; /** @deprecated */ - onprogress: ((this: ApplicationCache, ev: ProgressEvent) => any) | null; + onprogress: ((this: ApplicationCache, ev: ProgressEvent) => any) | null; /** @deprecated */ onupdateready: ((this: ApplicationCache, ev: Event) => any) | null; /** @deprecated */ @@ -1891,7 +2128,7 @@ declare var ApplicationCache: { readonly UPDATEREADY: number; }; -/** This type represents a DOM element's attribute as an object. In most DOM methods, you will probably directly retrieve the attribute as a string (e.g., Element.getAttribute(), but certain functions (e.g., Element.getAttributeNode()) or means of iterating give Attr types. */ +/** A DOM element's attribute as an object. In most DOM methods, you will probably directly retrieve the attribute as a string (e.g., Element.getAttribute(), but certain functions (e.g., Element.getAttributeNode()) or means of iterating give Attr types. */ interface Attr extends Node { readonly localName: string; readonly name: string; @@ -1907,7 +2144,7 @@ declare var Attr: { new(): Attr; }; -/** Objects of these types are designed to hold small audio snippets, typically less than 45 s. For longer sounds, objects implementing the MediaElementAudioSourceNode are more suitable. The buffer contains data in the following format:  non-interleaved IEEE754 32-bit linear PCM with a nominal range between -1 and +1, that is, 32bits floating point buffer, with each samples between -1.0 and 1.0. If the AudioBuffer has multiple channels, they are stored in separate buffer. */ +/** A short audio asset residing in memory, created from an audio file using the AudioContext.decodeAudioData() method, or from raw data using AudioContext.createBuffer(). Once put into an AudioBuffer, the audio can then be played by being passed into an AudioBufferSourceNode. */ interface AudioBuffer { readonly duration: number; readonly length: number; @@ -1923,7 +2160,7 @@ declare var AudioBuffer: { new(options: AudioBufferOptions): AudioBuffer; }; -/** The AudioBufferSourceNode interface is an AudioScheduledSourceNode which represents an audio source consisting of in-memory audio data, stored in an AudioBuffer. It's especially useful for playing back audio which has particularly stringent timing accuracy requirements, such as for sounds that must match a specific rhythm and can be kept in memory rather than being played from disk or the network. */ +/** An AudioScheduledSourceNode which represents an audio source consisting of in-memory audio data, stored in an AudioBuffer. It's especially useful for playing back audio which has particularly stringent timing accuracy requirements, such as for sounds that must match a specific rhythm and can be kept in memory rather than being played from disk or the network. */ interface AudioBufferSourceNode extends AudioScheduledSourceNode { buffer: AudioBuffer | null; readonly detune: AudioParam; @@ -1943,7 +2180,7 @@ declare var AudioBufferSourceNode: { new(context: BaseAudioContext, options?: AudioBufferSourceOptions): AudioBufferSourceNode; }; -/** The AudioContext interface represents an audio-processing graph built from audio modules linked together, each represented by an AudioNode. */ +/** An audio-processing graph built from audio modules linked together, each represented by an AudioNode. */ interface AudioContext extends BaseAudioContext { readonly baseLatency: number; readonly outputLatency: number; @@ -1953,6 +2190,7 @@ interface AudioContext extends BaseAudioContext { createMediaStreamSource(mediaStream: MediaStream): MediaStreamAudioSourceNode; createMediaStreamTrackSource(mediaStreamTrack: MediaStreamTrack): MediaStreamTrackAudioSourceNode; getOutputTimestamp(): AudioTimestamp; + resume(): Promise; suspend(): Promise; addEventListener(type: K, listener: (this: AudioContext, ev: BaseAudioContextEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; @@ -1975,7 +2213,7 @@ declare var AudioDestinationNode: { new(): AudioDestinationNode; }; -/** The AudioListener interface represents the position and orientation of the unique person listening to the audio scene, and is used in audio spatialization. All PannerNodes spatialize in relation to the AudioListener stored in the BaseAudioContext.listener attribute. */ +/** The position and orientation of the unique person listening to the audio scene, and is used in audio spatialization. All PannerNodes spatialize in relation to the AudioListener stored in the BaseAudioContext.listener attribute. */ interface AudioListener { readonly forwardX: AudioParam; readonly forwardY: AudioParam; @@ -1997,7 +2235,7 @@ declare var AudioListener: { new(): AudioListener; }; -/** The AudioNode interface is a generic interface for representing an audio processing module. Examples include: */ +/** A generic interface for representing an audio processing module. Examples include: */ interface AudioNode extends EventTarget { channelCount: number; channelCountMode: ChannelCountMode; @@ -2051,7 +2289,7 @@ declare var AudioParamMap: { new(): AudioParamMap; }; -/** The Web Audio API AudioProcessingEvent represents events that occur when a ScriptProcessorNode input buffer is ready to be processed. */ +/** The Web Audio API events that occur when a ScriptProcessorNode input buffer is ready to be processed. */ interface AudioProcessingEvent extends Event { readonly inputBuffer: AudioBuffer; readonly outputBuffer: AudioBuffer; @@ -2082,7 +2320,7 @@ declare var AudioScheduledSourceNode: { new(): AudioScheduledSourceNode; }; -/** The AudioTrack interface represents a single audio track from one of the HTML media elements,