From 9aa99b90c72917347e781d146af577090c0b584d Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 9 Jan 2018 13:15:30 -0800 Subject: [PATCH 01/13] Include directories in completions for path mapping (#21103) --- src/services/pathCompletions.ts | 9 +++++---- tests/cases/fourslash/completionsPaths_pathMapping.ts | 9 ++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 97569e0bae9..65d288e7f8d 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -94,7 +94,7 @@ namespace ts.Completions.PathCompletions { * * both foo.ts and foo.tsx become foo */ - const foundFiles = createMap(); + const foundFiles = createMap(); for (let filePath of files) { filePath = normalizePath(filePath); if (exclude && comparePaths(filePath, exclude, scriptPath, ignoreCase) === Comparison.EqualTo) { @@ -103,7 +103,7 @@ namespace ts.Completions.PathCompletions { const foundFileName = includeExtensions ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath)); - if (!foundFiles.get(foundFileName)) { + if (!foundFiles.has(foundFileName)) { foundFiles.set(foundFileName, true); } } @@ -226,8 +226,9 @@ namespace ts.Completions.PathCompletions { const includeGlob = normalizedSuffix ? "**/*" : "./*"; const matches = tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]); + const directories = tryGetDirectories(host, baseDirectory); // Trim away prefix and suffix - return mapDefined(matches, match => { + return mapDefined(concatenate(matches, directories), match => { const normalizedMatch = normalizePath(match); if (!endsWith(normalizedMatch, normalizedSuffix) || !startsWith(normalizedMatch, completePrefix)) { return; @@ -468,7 +469,7 @@ namespace ts.Completions.PathCompletions { return tryIOAndConsumeErrors(host, host.getDirectories, directoryName); } - function tryReadDirectory(host: LanguageServiceHost, path: string, extensions?: ReadonlyArray, exclude?: ReadonlyArray, include?: ReadonlyArray): string[] { + function tryReadDirectory(host: LanguageServiceHost, path: string, extensions?: ReadonlyArray, exclude?: ReadonlyArray, include?: ReadonlyArray): string[] | undefined { return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include); } diff --git a/tests/cases/fourslash/completionsPaths_pathMapping.ts b/tests/cases/fourslash/completionsPaths_pathMapping.ts index b2ec9ac6198..7a6283bce3a 100644 --- a/tests/cases/fourslash/completionsPaths_pathMapping.ts +++ b/tests/cases/fourslash/completionsPaths_pathMapping.ts @@ -3,6 +3,9 @@ // @Filename: /src/b.ts ////export const x = 0; +// @Filename: /src/dir/x.ts +/////export const x = 0; + // @Filename: /src/a.ts ////import {} from "foo/[|/**/|]"; @@ -17,4 +20,8 @@ ////} const [replacementSpan] = test.ranges(); -verify.completionsAt("", [{ name: "a", replacementSpan }, { name: "b", replacementSpan }]); +verify.completionsAt("", [ + { name: "a", replacementSpan }, + { name: "b", replacementSpan }, + { name: "dir", replacementSpan }, +]); From 8bce69e6bd6bdfe8c2a92a5db6da86ea22bb52a3 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 9 Jan 2018 13:15:47 -0800 Subject: [PATCH 02/13] Add refactoring to convert CommonJS module to ES6 module (#19916) * Add refactoring to convert CommonJS module to ES6 module * Code review * includeGlobals -> excludeGlobals * Improve handling of `module.exports = require("...")` * Allow NoSubstitutionTemplateLiteral as argument to createLiteral --- src/compiler/binder.ts | 54 +- src/compiler/checker.ts | 15 +- src/compiler/core.ts | 27 +- src/compiler/diagnosticMessages.json | 4 + src/compiler/emitter.ts | 28 +- src/compiler/factory.ts | 8 +- src/compiler/types.ts | 8 +- src/compiler/utilities.ts | 5 +- src/harness/fourslash.ts | 11 +- src/services/codefixes/importFixes.ts | 4 +- src/services/refactors/convertToEs6Module.ts | 582 ++++++++++++++++++ src/services/refactors/extractSymbol.ts | 2 +- src/services/refactors/refactors.ts | 1 + src/services/refactors/useDefaultImport.ts | 4 +- src/services/utilities.ts | 4 + .../reference/api/tsserverlibrary.d.ts | 4 +- tests/baselines/reference/api/typescript.d.ts | 4 +- tests/cases/fourslash/fourslash.ts | 1 + ...refactorConvertToEs6Module_export_alias.ts | 18 + ...torConvertToEs6Module_export_dotDefault.ts | 19 + ...orConvertToEs6Module_export_invalidName.ts | 19 + ...vertToEs6Module_export_moduleDotExports.ts | 26 + ...le_export_moduleDotExportsEqualsRequire.ts | 43 ++ ..._export_moduleDotExports_changesImports.ts | 26 + ...refactorConvertToEs6Module_export_named.ts | 19 + ...efactorConvertToEs6Module_export_object.ts | 25 + ...vertToEs6Module_export_object_shorthand.ts | 18 + ...torConvertToEs6Module_export_referenced.ts | 36 ++ ...vertToEs6Module_expressionToDeclaration.ts | 18 + ...tToEs6Module_import_arrayBindingPattern.ts | 15 + ...rtToEs6Module_import_includeDefaultUses.ts | 18 + ...Module_import_multipleUniqueIdentifiers.ts | 20 + ...ule_import_multipleVariableDeclarations.ts | 18 + ...s6Module_import_nameFromModuleSpecifier.ts | 21 + ...ule_import_objectBindingPattern_complex.ts | 15 + ...odule_import_objectBindingPattern_plain.ts | 14 + ...vertToEs6Module_import_onlyNamedImports.ts | 16 + ...onvertToEs6Module_import_propertyAccess.ts | 24 + ...ctorConvertToEs6Module_import_shadowing.ts | 18 + ...torConvertToEs6Module_import_sideEffect.ts | 16 + .../refactorConvertToEs6Module_triggers.ts | 13 + 41 files changed, 1170 insertions(+), 71 deletions(-) create mode 100644 src/services/refactors/convertToEs6Module.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 701b1bfb249..4e4b4f12705 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2289,30 +2289,13 @@ namespace ts { declareSymbol(file.symbol.exports, file.symbol, node.left, SymbolFlags.Property | SymbolFlags.ExportValue, SymbolFlags.None); } - function isExportsOrModuleExportsOrAlias(node: Node): boolean { - return isExportsIdentifier(node) || - isModuleExportsPropertyAccessExpression(node) || - isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(node); - } - - function isNameOfExportsOrModuleExportsAliasDeclaration(node: Identifier): boolean { - const symbol = lookupSymbolForName(node.escapedText); - return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) && - symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(symbol.valueDeclaration.initializer); - } - - function isExportsOrModuleExportsOrAliasOrAssignment(node: Node): boolean { - return isExportsOrModuleExportsOrAlias(node) || - (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && (isExportsOrModuleExportsOrAliasOrAssignment(node.left) || isExportsOrModuleExportsOrAliasOrAssignment(node.right))); - } - function bindModuleExportsAssignment(node: BinaryExpression) { // A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports' // is still pointing to 'module.exports'. // We do not want to consider this as 'export=' since a module can have only one of these. // Similarly we do not want to treat 'module.exports = exports' as an 'export='. const assignedExpression = getRightMostAssignedExpression(node.right); - if (isEmptyObjectLiteral(assignedExpression) || isExportsOrModuleExportsOrAlias(assignedExpression)) { + if (isEmptyObjectLiteral(assignedExpression) || container === file && isExportsOrModuleExportsOrAlias(file, assignedExpression)) { // Mark it as a module in case there are no other exports in the file setCommonJsModuleIndicator(node); return; @@ -2393,7 +2376,7 @@ namespace ts { if (node.kind === SyntaxKind.BinaryExpression) { leftSideOfAssignment.parent = node; } - if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) { + if (container === file && isNameOfExportsOrModuleExportsAliasDeclaration(file, target)) { // This can be an alias for the 'exports' or 'module.exports' names, e.g. // var util = module.exports; // util.property = function ... @@ -2406,11 +2389,7 @@ namespace ts { } function lookupSymbolForName(name: __String) { - const local = container.locals && container.locals.get(name); - if (local) { - return local.exportSymbol || local; - } - return container.symbol && container.symbol.exports && container.symbol.exports.get(name); + return lookupSymbolForNameWorker(container, name); } function bindPropertyAssignment(functionName: __String, propertyAccess: PropertyAccessExpression, isPrototypeProperty: boolean) { @@ -2649,6 +2628,33 @@ namespace ts { } } + /* @internal */ + export function isExportsOrModuleExportsOrAlias(sourceFile: SourceFile, node: Expression): boolean { + return isExportsIdentifier(node) || + isModuleExportsPropertyAccessExpression(node) || + isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(sourceFile, node); + } + + function isNameOfExportsOrModuleExportsAliasDeclaration(sourceFile: SourceFile, node: Identifier): boolean { + const symbol = lookupSymbolForNameWorker(sourceFile, node.escapedText); + return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) && + symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, symbol.valueDeclaration.initializer); + } + + function isExportsOrModuleExportsOrAliasOrAssignment(sourceFile: SourceFile, node: Expression): boolean { + return isExportsOrModuleExportsOrAlias(sourceFile, node) || + (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && ( + isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, node.left) || isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, node.right))); + } + + function lookupSymbolForNameWorker(container: Node, name: __String): Symbol | undefined { + const local = container.locals && container.locals.get(name); + if (local) { + return local.exportSymbol || local; + } + return container.symbol && container.symbol.exports && container.symbol.exports.get(name); + } + /** * Computes the transform flags for a node, given the transform flags of its subtree * diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d153eee3034..16bfd7fa7e2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -268,8 +268,8 @@ namespace ts { getSuggestionForNonexistentSymbol: (location, name, meaning) => getSuggestionForNonexistentSymbol(location, escapeLeadingUnderscores(name), meaning), getBaseConstraintOfType, getDefaultFromTypeParameter: type => type && type.flags & TypeFlags.TypeParameter ? getDefaultFromTypeParameter(type as TypeParameter) : undefined, - resolveName(name, location, meaning) { - return resolveName(location, escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); + resolveName(name, location, meaning, excludeGlobals) { + return resolveName(location, escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false, excludeGlobals); }, getJsxNamespace: () => unescapeLeadingUnderscores(getJsxNamespace()), getAccessibleSymbolChain, @@ -952,8 +952,9 @@ namespace ts { nameNotFoundMessage: DiagnosticMessage | undefined, nameArg: __String | Identifier, isUse: boolean, + excludeGlobals = false, suggestedNameNotFoundMessage?: DiagnosticMessage): Symbol { - return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, getSymbol, suggestedNameNotFoundMessage); + return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSymbol, suggestedNameNotFoundMessage); } function resolveNameHelper( @@ -963,6 +964,7 @@ namespace ts { nameNotFoundMessage: DiagnosticMessage, nameArg: __String | Identifier, isUse: boolean, + excludeGlobals: boolean, lookup: typeof getSymbol, suggestedNameNotFoundMessage?: DiagnosticMessage): Symbol { const originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location @@ -1209,7 +1211,9 @@ namespace ts { } } - result = lookup(globals, name, meaning); + if (!excludeGlobals) { + result = lookup(globals, name, meaning); + } } if (!result) { @@ -11889,6 +11893,7 @@ namespace ts { Diagnostics.Cannot_find_name_0, node, !isWriteOnlyAccess(node), + /*excludeGlobals*/ false, Diagnostics.Cannot_find_name_0_Did_you_mean_1) || unknownSymbol; } return links.resolvedSymbol; @@ -16068,7 +16073,7 @@ namespace ts { function getSuggestionForNonexistentSymbol(location: Node, outerName: __String, meaning: SymbolFlags): string { Debug.assert(outerName !== undefined, "outername should always be defined"); - const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, (symbols, name, meaning) => { + const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, /*excludeGlobals*/ false, (symbols, name, meaning) => { Debug.assertEqual(outerName, name, "name should equal outerName"); const symbol = getSymbol(symbols, name, meaning); // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 2e8106e44ba..918dbbd51c0 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -412,12 +412,14 @@ namespace ts { return result; } + export function mapIterator(iter: Iterator, mapFn: (x: T) => U): Iterator { - return { next }; - function next(): { value: U, done: false } | { value: never, done: true } { - const iterRes = iter.next(); - return iterRes.done ? iterRes : { value: mapFn(iterRes.value), done: false }; - } + return { + next() { + const iterRes = iter.next(); + return iterRes.done ? iterRes : { value: mapFn(iterRes.value), done: false }; + } + }; } // Maps from T to T and avoids allocation if all elements map to themselves @@ -551,12 +553,23 @@ namespace ts { return result || array; } + export function mapAllOrFail(array: ReadonlyArray, mapFn: (x: T, i: number) => U | undefined): U[] | undefined { + const result: U[] = []; + for (let i = 0; i < array.length; i++) { + const mapped = mapFn(array[i], i); + if (mapped === undefined) { + return undefined; + } + result.push(mapped); + } + return result; + } + export function mapDefined(array: ReadonlyArray | undefined, mapFn: (x: T, i: number) => U | undefined): U[] { const result: U[] = []; if (array) { for (let i = 0; i < array.length; i++) { - const item = array[i]; - const mapped = mapFn(item, i); + const mapped = mapFn(array[i], i); if (mapped !== undefined) { result.push(mapped); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4a705ce97fe..96be3e99fdc 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3937,5 +3937,9 @@ "Use synthetic 'default' member.": { "category": "Message", "code": 95016 + }, + "Convert to ES6 module": { + "category": "Message", + "code": 95017 } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 7a1d88d3bfd..909dd0feede 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1194,27 +1194,15 @@ namespace ts { // function emitObjectBindingPattern(node: ObjectBindingPattern) { - const elements = node.elements; - if (elements.length === 0) { - write("{}"); - } - else { - write("{"); - emitList(node, elements, ListFormat.ObjectBindingPatternElements); - write("}"); - } + write("{"); + emitList(node, node.elements, ListFormat.ObjectBindingPatternElements); + write("}"); } function emitArrayBindingPattern(node: ArrayBindingPattern) { - const elements = node.elements; - if (elements.length === 0) { - write("[]"); - } - else { - write("["); - emitList(node, node.elements, ListFormat.ArrayBindingPatternElements); - write("]"); - } + write("["); + emitList(node, node.elements, ListFormat.ArrayBindingPatternElements); + write("]"); } function emitBindingElement(node: BindingElement) { @@ -3167,8 +3155,8 @@ namespace ts { TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented, UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine, IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine, - ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings, - ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings, + ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty, + ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty, ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty, ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets, CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine, diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 65c17911488..7ddc8a0cd5f 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -71,11 +71,11 @@ namespace ts { // Literals /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ - export function createLiteral(value: string | StringLiteral | NumericLiteral | Identifier): StringLiteral; + export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; export function createLiteral(value: number): NumericLiteral; export function createLiteral(value: boolean): BooleanLiteral; export function createLiteral(value: string | number | boolean): PrimaryExpression; - export function createLiteral(value: string | number | boolean | StringLiteral | NumericLiteral | Identifier): PrimaryExpression { + export function createLiteral(value: string | number | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): PrimaryExpression { if (typeof value === "number") { return createNumericLiteral(value + ""); } @@ -101,7 +101,7 @@ namespace ts { return node; } - function createLiteralFromNode(sourceNode: StringLiteral | NumericLiteral | Identifier): StringLiteral { + function createLiteralFromNode(sourceNode: StringLiteralLike | NumericLiteral | Identifier): StringLiteral { const node = createStringLiteral(getTextOfIdentifierOrLiteral(sourceNode)); node.textSourceNode = sourceNode; return node; @@ -3626,7 +3626,7 @@ namespace ts { return qualifiedName; } - export function convertToFunctionBody(node: ConciseBody, multiLine?: boolean) { + export function convertToFunctionBody(node: ConciseBody, multiLine?: boolean): Block { return isBlock(node) ? node : setTextRange(createBlock([setTextRange(createReturn(node), node)], multiLine), node); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 623efe08fe8..23798635671 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1149,11 +1149,13 @@ namespace ts { export interface StringLiteral extends LiteralExpression { kind: SyntaxKind.StringLiteral; - /* @internal */ textSourceNode?: Identifier | StringLiteral | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms). + /* @internal */ textSourceNode?: Identifier | StringLiteralLike | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms). /** Note: this is only set when synthesizing a node, not during parsing. */ /* @internal */ singleQuote?: boolean; } + /* @internal */ export type StringLiteralLike = StringLiteral | NoSubstitutionTemplateLiteral; + // Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing. // Consider 'Expression'. Without the brand, 'Expression' is actually no different // (structurally) than 'Node'. Because of this you can pass any Node to a function that @@ -1499,6 +1501,7 @@ namespace ts { kind: SyntaxKind.ArrowFunction; equalsGreaterThanToken: EqualsGreaterThanToken; body: ConciseBody; + name: never; } // The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral, @@ -2156,6 +2159,7 @@ namespace ts { export interface ExportDeclaration extends DeclarationStatement { kind: SyntaxKind.ExportDeclaration; parent?: SourceFile | ModuleBlock; + /** Will not be assigned in the case of `export * from "foo";` */ exportClause?: NamedExports; /** If this is not a StringLiteral it will be a grammar error. */ moduleSpecifier?: Expression; @@ -2878,7 +2882,7 @@ namespace ts { */ /* @internal */ isArrayLikeType(type: Type): boolean; /* @internal */ getAllPossiblePropertiesOfTypes(type: ReadonlyArray): Symbol[]; - /* @internal */ resolveName(name: string, location: Node, meaning: SymbolFlags): Symbol | undefined; + /* @internal */ resolveName(name: string, location: Node, meaning: SymbolFlags, excludeGlobals: boolean): Symbol | undefined; /* @internal */ getJsxNamespace(): string; /** diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a6e8af7e706..37b62fd5d85 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5,6 +5,7 @@ namespace ts { export const emptyArray: never[] = [] as never[]; export const resolvingEmptyArray: never[] = [] as never[]; export const emptyMap: ReadonlyMap = createMap(); + export const emptyUnderscoreEscapedMap: ReadonlyUnderscoreEscapedMap = emptyMap as ReadonlyUnderscoreEscapedMap; export const externalHelpersModuleNameText = "tslib"; @@ -1419,6 +1420,8 @@ namespace ts { * exactly one argument (of the form 'require("name")'). * This function does not test if the node is in a JavaScript file or not. */ + export function isRequireCall(callExpression: Node, checkArgumentIsStringLiteral: true): callExpression is CallExpression & { expression: Identifier, arguments: [StringLiteralLike] }; + export function isRequireCall(callExpression: Node, checkArgumentIsStringLiteral: boolean): callExpression is CallExpression; export function isRequireCall(callExpression: Node, checkArgumentIsStringLiteral: boolean): callExpression is CallExpression { if (callExpression.kind !== SyntaxKind.CallExpression) { return false; @@ -1456,7 +1459,7 @@ namespace ts { return false; } - export function getRightMostAssignedExpression(node: Node) { + export function getRightMostAssignedExpression(node: Expression): Expression { while (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true)) { node = node.right; } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 6a2f71df10e..8c5570f730c 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -454,7 +454,7 @@ namespace FourSlash { const ranges = this.getRanges(); assert(ranges.length); for (const range of ranges) { - this.goToRangeStart(range); + this.selectRange(range); action(); } } @@ -482,6 +482,11 @@ namespace FourSlash { this.selectionEnd = end.position; } + public selectRange(range: Range): void { + this.goToRangeStart(range); + this.selectionEnd = range.end; + } + public moveCaretRight(count = 1) { this.currentCaretPosition += count; this.currentCaretPosition = Math.min(this.currentCaretPosition, this.getFileContent(this.activeFile.fileName).length); @@ -3835,6 +3840,10 @@ namespace FourSlashInterface { public select(startMarker: string, endMarker: string) { this.state.select(startMarker, endMarker); } + + public selectRange(range: FourSlash.Range): void { + this.state.selectRange(range); + } } export class VerifyNegatable { diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 34ebd2417c9..8f69cd95c11 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -746,7 +746,7 @@ namespace ts.codefix { } else if (isJsxOpeningLikeElement(symbolToken.parent) && symbolToken.parent.tagName === symbolToken) { // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`. - symbol = checker.getAliasedSymbol(checker.resolveName(checker.getJsxNamespace(), symbolToken.parent.tagName, SymbolFlags.Value)); + symbol = checker.getAliasedSymbol(checker.resolveName(checker.getJsxNamespace(), symbolToken.parent.tagName, SymbolFlags.Value, /*excludeGlobals*/ false)); symbolName = symbol.name; } else { @@ -867,7 +867,7 @@ namespace ts.codefix { return moduleSpecifierToValidIdentifier(removeFileExtension(getBaseFileName(moduleSymbol.name)), target); } - function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target: ScriptTarget): string { + export function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target: ScriptTarget): string { let res = ""; let lastCharWasValid = true; const firstCharCode = moduleSpecifier.charCodeAt(0); diff --git a/src/services/refactors/convertToEs6Module.ts b/src/services/refactors/convertToEs6Module.ts new file mode 100644 index 00000000000..1046bf90aa6 --- /dev/null +++ b/src/services/refactors/convertToEs6Module.ts @@ -0,0 +1,582 @@ +/* @internal */ +namespace ts.refactor { + const actionName = "Convert to ES6 module"; + + const convertToEs6Module: Refactor = { + name: actionName, + description: getLocaleSpecificMessage(Diagnostics.Convert_to_ES6_module), + getEditsForAction, + getAvailableActions, + }; + + registerRefactor(convertToEs6Module); + + function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { + const { file, startPosition } = context; + if (!isSourceFileJavaScript(file) || !file.commonJsModuleIndicator) { + return undefined; + } + + const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); + return !isAtTriggerLocation(file, node) ? undefined : [ + { + name: convertToEs6Module.name, + description: convertToEs6Module.description, + actions: [ + { + description: convertToEs6Module.description, + name: actionName, + }, + ], + }, + ]; + } + + function isAtTriggerLocation(sourceFile: SourceFile, node: Node, onSecondTry = false): boolean { + switch (node.kind) { + case SyntaxKind.CallExpression: + return isAtTopLevelRequire(node as CallExpression); + case SyntaxKind.PropertyAccessExpression: + return isExportsOrModuleExportsOrAlias(sourceFile, node as PropertyAccessExpression) + || isExportsOrModuleExportsOrAlias(sourceFile, (node as PropertyAccessExpression).expression); + case SyntaxKind.VariableDeclarationList: + const decl = (node as VariableDeclarationList).declarations[0]; + return isExportsOrModuleExportsOrAlias(sourceFile, decl.initializer); + case SyntaxKind.VariableDeclaration: + return isExportsOrModuleExportsOrAlias(sourceFile, (node as VariableDeclaration).initializer); + default: + return isExpression(node) && isExportsOrModuleExportsOrAlias(sourceFile, node) + || !onSecondTry && isAtTriggerLocation(sourceFile, node.parent, /*onSecondTry*/ true); + } + } + + function isAtTopLevelRequire(call: CallExpression): boolean { + if (!isRequireCall(call, /*checkArgumentIsStringLiteral*/ true)) { + return false; + } + const { parent: propAccess } = call; + const varDecl = isPropertyAccessExpression(propAccess) ? propAccess.parent : propAccess; + if (isExpressionStatement(varDecl) && isSourceFile(varDecl.parent)) { // `require("x");` as a statement + return true; + } + if (!isVariableDeclaration(varDecl)) { + return false; + } + const { parent: varDeclList } = varDecl; + if (varDeclList.kind !== SyntaxKind.VariableDeclarationList) { + return false; + } + const { parent: varStatement } = varDeclList; + return varStatement.kind === SyntaxKind.VariableStatement && varStatement.parent.kind === SyntaxKind.SourceFile; + } + + function getEditsForAction(context: RefactorContext, _actionName: string): RefactorEditInfo | undefined { + Debug.assertEqual(actionName, _actionName); + const { file, program } = context; + Debug.assert(isSourceFileJavaScript(file)); + const edits = textChanges.ChangeTracker.with(context, changes => { + const moduleExportsChangedToDefault = convertFileToEs6Module(file, program.getTypeChecker(), changes, program.getCompilerOptions().target); + if (moduleExportsChangedToDefault) { + for (const importingFile of program.getSourceFiles()) { + fixImportOfModuleExports(importingFile, file, changes); + } + } + }); + return { edits, renameFilename: undefined, renameLocation: undefined }; + } + + function fixImportOfModuleExports(importingFile: ts.SourceFile, exportingFile: ts.SourceFile, changes: textChanges.ChangeTracker) { + for (const moduleSpecifier of importingFile.imports) { + const imported = getResolvedModule(importingFile, moduleSpecifier.text); + if (!imported || imported.resolvedFileName !== exportingFile.fileName) { + continue; + } + + const { parent } = moduleSpecifier; + switch (parent.kind) { + case SyntaxKind.ExternalModuleReference: { + const importEq = (parent as ExternalModuleReference).parent; + changes.replaceNode(importingFile, importEq, makeImport(importEq.name, /*namedImports*/ undefined, moduleSpecifier.text)); + break; + } + case SyntaxKind.CallExpression: { + const call = parent as CallExpression; + if (isRequireCall(call, /*checkArgumentIsStringLiteral*/ false)) { + changes.replaceNode(importingFile, parent, createPropertyAccess(getSynthesizedDeepClone(call), "default")); + } + break; + } + } + } + } + + /** @returns Whether we converted a `module.exports =` to a default export. */ + function convertFileToEs6Module(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, target: ScriptTarget): ModuleExportsChanged { + const identifiers: Identifiers = { original: collectFreeIdentifiers(sourceFile), additional: createMap() }; + const exports = collectExportRenames(sourceFile, checker, identifiers); + convertExportsAccesses(sourceFile, exports, changes); + let moduleExportsChangedToDefault = false; + for (const statement of sourceFile.statements) { + const moduleExportsChanged = convertStatement(sourceFile, statement, checker, changes, identifiers, target, exports); + moduleExportsChangedToDefault = moduleExportsChangedToDefault || moduleExportsChanged; + } + return moduleExportsChangedToDefault; + } + + /** + * Contains an entry for each renamed export. + * This is necessary because `exports.x = 0;` does not declare a local variable. + * Converting this to `export const x = 0;` would declare a local, so we must be careful to avoid shadowing. + * If there would be shadowing at either the declaration or at any reference to `exports.x` (now just `x`), we must convert to: + * const _x = 0; + * export { _x as x }; + * This conversion also must place if the exported name is not a valid identifier, e.g. `exports.class = 0;`. + */ + type ExportRenames = ReadonlyMap; + + function collectExportRenames(sourceFile: SourceFile, checker: TypeChecker, identifiers: Identifiers): ExportRenames { + const res = createMap(); + forEachExportReference(sourceFile, node => { + const { text, originalKeywordKind } = node.name; + if (!res.has(text) && (originalKeywordKind !== undefined && isNonContextualKeyword(originalKeywordKind) + || checker.resolveName(node.name.text, node, SymbolFlags.Value, /*excludeGlobals*/ true))) { + // Unconditionally add an underscore in case `text` is a keyword. + res.set(text, makeUniqueName(`_${text}`, identifiers)); + } + }); + return res; + } + + function convertExportsAccesses(sourceFile: SourceFile, exports: ExportRenames, changes: textChanges.ChangeTracker): void { + forEachExportReference(sourceFile, (node, isAssignmentLhs) => { + if (isAssignmentLhs) { + return; + } + const { text } = node.name; + changes.replaceNode(sourceFile, node, createIdentifier(exports.get(text) || text)); + }); + } + + function forEachExportReference(sourceFile: SourceFile, cb: (node: PropertyAccessExpression, isAssignmentLhs: boolean) => void): void { + sourceFile.forEachChild(function recur(node) { + if (isPropertyAccessExpression(node) && isExportsOrModuleExportsOrAlias(sourceFile, node.expression)) { + const { parent } = node; + cb(node, isBinaryExpression(parent) && parent.left === node && parent.operatorToken.kind === SyntaxKind.EqualsToken); + } + node.forEachChild(recur); + }); + } + + /** Whether `module.exports =` was changed to `export default` */ + type ModuleExportsChanged = boolean; + + function convertStatement(sourceFile: SourceFile, statement: Statement, checker: TypeChecker, changes: textChanges.ChangeTracker, identifiers: Identifiers, target: ScriptTarget, exports: ExportRenames): ModuleExportsChanged { + switch (statement.kind) { + case SyntaxKind.VariableStatement: + convertVariableStatement(sourceFile, statement as VariableStatement, changes, checker, identifiers, target); + return false; + case SyntaxKind.ExpressionStatement: { + const { expression } = statement as ExpressionStatement; + switch (expression.kind) { + case SyntaxKind.CallExpression: { + if (isRequireCall(expression, /*checkArgumentIsStringLiteral*/ true)) { + // For side-effecting require() call, just make a side-effecting import. + changes.replaceNode(sourceFile, statement, makeImport(/*name*/ undefined, /*namedImports*/ undefined, expression.arguments[0].text)); + } + return false; + } + case SyntaxKind.BinaryExpression: { + const { left, operatorToken, right } = expression as BinaryExpression; + return operatorToken.kind === SyntaxKind.EqualsToken && convertAssignment(sourceFile, checker, statement as ExpressionStatement, left, right, changes, exports); + } + } + } + // falls through + default: + return false; + } + } + + function convertVariableStatement(sourceFile: SourceFile, statement: VariableStatement, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers, target: ScriptTarget): void { + const { declarationList } = statement as VariableStatement; + let foundImport = false; + const newNodes = flatMap(declarationList.declarations, decl => { + const { name, initializer } = decl; + if (isExportsOrModuleExportsOrAlias(sourceFile, initializer)) { + // `const alias = module.exports;` can be removed. + foundImport = true; + return []; + } + if (isRequireCall(initializer, /*checkArgumentIsStringLiteral*/ true)) { + foundImport = true; + return convertSingleImport(sourceFile, name, initializer.arguments[0].text, changes, checker, identifiers, target); + } + else if (isPropertyAccessExpression(initializer) && isRequireCall(initializer.expression, /*checkArgumentIsStringLiteral*/ true)) { + foundImport = true; + return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0].text, identifiers); + } + else { + // Move it out to its own variable statement. + return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([decl], declarationList.flags)); + } + }); + if (foundImport) { + // useNonAdjustedEndPosition to ensure we don't eat the newline after the statement. + changes.replaceNodeWithNodes(sourceFile, statement, newNodes); + } + } + + /** Converts `const name = require("moduleSpecifier").propertyName` */ + function convertPropertyAccessImport(name: BindingName, propertyName: string, moduleSpecifier: string, identifiers: Identifiers): ReadonlyArray { + switch (name.kind) { + case SyntaxKind.ObjectBindingPattern: + case SyntaxKind.ArrayBindingPattern: { + // `const [a, b] = require("c").d` --> `import { d } from "c"; const [a, b] = d;` + const tmp = makeUniqueName(propertyName, identifiers); + return [ + makeSingleImport(tmp, propertyName, moduleSpecifier), + makeConst(/*modifiers*/ undefined, name, createIdentifier(tmp)), + ]; + } + case SyntaxKind.Identifier: + // `const a = require("b").c` --> `import { c as a } from "./b"; + return [makeSingleImport(name.text, propertyName, moduleSpecifier)]; + default: + Debug.assertNever(name); + } + } + + function convertAssignment( + sourceFile: SourceFile, + checker: TypeChecker, + statement: ExpressionStatement, + left: Expression, + right: Expression, + changes: textChanges.ChangeTracker, + exports: ExportRenames, + ): ModuleExportsChanged { + if (!isPropertyAccessExpression(left)) { + return false; + } + + if (isExportsOrModuleExportsOrAlias(sourceFile, left)) { + if (isExportsOrModuleExportsOrAlias(sourceFile, right)) { + // `const alias = module.exports;` or `module.exports = alias;` can be removed. + changes.deleteNode(sourceFile, statement); + } + else { + let newNodes = isObjectLiteralExpression(right) ? tryChangeModuleExportsObject(right) : undefined; + let changedToDefaultExport = false; + if (!newNodes) { + ([newNodes, changedToDefaultExport] = convertModuleExportsToExportDefault(right, checker)); + } + changes.replaceNodeWithNodes(sourceFile, statement, newNodes); + return changedToDefaultExport; + } + } + else if (isExportsOrModuleExportsOrAlias(sourceFile, left.expression)) { + convertNamedExport(sourceFile, statement, left.name, right, changes, exports); + } + + return false; + } + + /** + * Convert `module.exports = { ... }` to individual exports.. + * We can't always do this if the module has interesting members -- then it will be a default export instead. + */ + function tryChangeModuleExportsObject(object: ObjectLiteralExpression): ReadonlyArray | undefined { + return mapAllOrFail(object.properties, prop => { + switch (prop.kind) { + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + // TODO: Maybe we should handle this? See fourslash test `refactorConvertToEs6Module_export_object_shorthand.ts`. + case SyntaxKind.ShorthandPropertyAssignment: + case SyntaxKind.SpreadAssignment: + return undefined; + case SyntaxKind.PropertyAssignment: { + const { name, initializer } = prop as PropertyAssignment; + return !isIdentifier(name) ? undefined : convertExportsDotXEquals(name.text, initializer); + } + case SyntaxKind.MethodDeclaration: { + const m = prop as MethodDeclaration; + return !isIdentifier(m.name) ? undefined : functionExpressionToDeclaration(m.name.text, [createToken(SyntaxKind.ExportKeyword)], m); + } + default: + Debug.assertNever(prop); + } + }); + } + + function convertNamedExport( + sourceFile: SourceFile, + statement: Statement, + propertyName: Identifier, + right: Expression, + changes: textChanges.ChangeTracker, + exports: ExportRenames, + ): void { + // If "originalKeywordKind" was set, this is e.g. `exports. + const { text } = propertyName; + const rename = exports.get(text); + if (rename !== undefined) { + /* + const _class = 0; + export { _class as class }; + */ + const newNodes = [ + makeConst(/*modifiers*/ undefined, rename, right), + makeExportDeclaration([createExportSpecifier(rename, text)]), + ]; + changes.replaceNodeWithNodes(sourceFile, statement, newNodes); + } + else { + changes.replaceNode(sourceFile, statement, convertExportsDotXEquals(text, right), { useNonAdjustedEndPosition: true }); + } + } + + function convertModuleExportsToExportDefault(exported: Expression, checker: TypeChecker): [ReadonlyArray, ModuleExportsChanged] { + const modifiers = [createToken(SyntaxKind.ExportKeyword), createToken(SyntaxKind.DefaultKeyword)]; + switch (exported.kind) { + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: { + // `module.exports = function f() {}` --> `export default function f() {}` + const fn = exported as FunctionExpression | ArrowFunction; + return [[functionExpressionToDeclaration(fn.name && fn.name.text, modifiers, fn)], true]; + } + case SyntaxKind.ClassExpression: { + // `module.exports = class C {}` --> `export default class C {}` + const cls = exported as ClassExpression; + return [[classExpressionToDeclaration(cls.name && cls.name.text, modifiers, cls)], true]; + } + case SyntaxKind.CallExpression: + if (isRequireCall(exported, /*checkArgumentIsStringLiteral*/ true)) { + return convertReExportAll(exported.arguments[0], checker); + } + // falls through + default: + // `module.exports = 0;` --> `export default 0;` + return [[createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, exported)], true]; + } + } + + function convertReExportAll(reExported: StringLiteralLike, checker: TypeChecker): [ReadonlyArray, ModuleExportsChanged] { + // `module.exports = require("x");` ==> `export * from "x"; export { default } from "x";` + const moduleSpecifier = reExported.text; + const moduleSymbol = checker.getSymbolAtLocation(reExported); + const exports = moduleSymbol ? moduleSymbol.exports : emptyUnderscoreEscapedMap; + return exports.has("export=" as __String) + ? [[reExportDefault(moduleSpecifier)], true] + : !exports.has("default" as __String) + ? [[reExportStar(moduleSpecifier)], false] + // If there's some non-default export, must include both `export *` and `export default`. + : exports.size > 1 ? [[reExportStar(moduleSpecifier), reExportDefault(moduleSpecifier)], true] : [[reExportDefault(moduleSpecifier)], true]; + } + function reExportStar(moduleSpecifier: string): ExportDeclaration { + return makeExportDeclaration(/*exportClause*/ undefined, moduleSpecifier); + } + function reExportDefault(moduleSpecifier: string): ExportDeclaration { + return makeExportDeclaration([createExportSpecifier(/*propertyName*/ undefined, "default")], moduleSpecifier); + } + + function convertExportsDotXEquals(name: string | undefined, exported: Expression): Statement { + const modifiers = [createToken(SyntaxKind.ExportKeyword)]; + switch (exported.kind) { + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + // `exports.f = function() {}` --> `export function f() {}` + return functionExpressionToDeclaration(name, modifiers, exported as FunctionExpression | ArrowFunction); + case SyntaxKind.ClassExpression: + // `exports.C = class {}` --> `export class C {}` + return classExpressionToDeclaration(name, modifiers, exported as ClassExpression); + default: + // `exports.x = 0;` --> `export const x = 0;` + return makeConst(modifiers, createIdentifier(name), exported); + } + } + + /** + * Converts `const <> = require("x");`. + * Returns nodes that will replace the variable declaration for the commonjs import. + * May also make use `changes` to remove qualifiers at the use sites of imports, to change `mod.x` to `x`. + */ + function convertSingleImport( + file: SourceFile, + name: BindingName, + moduleSpecifier: string, + changes: textChanges.ChangeTracker, + checker: TypeChecker, + identifiers: Identifiers, + target: ScriptTarget, + ): ReadonlyArray { + switch (name.kind) { + case SyntaxKind.ObjectBindingPattern: { + const importSpecifiers = mapAllOrFail(name.elements, e => + e.dotDotDotToken || e.initializer || e.propertyName && !isIdentifier(e.propertyName) || !isIdentifier(e.name) + ? undefined + : makeImportSpecifier(e.propertyName && (e.propertyName as Identifier).text, e.name.text)); + if (importSpecifiers) { + return [makeImport(/*name*/ undefined, importSpecifiers, moduleSpecifier)]; + } + } + // falls through -- object destructuring has an interesting pattern and must be a variable declaration + case SyntaxKind.ArrayBindingPattern: { + /* + import x from "x"; + const [a, b, c] = x; + */ + const tmp = makeUniqueName(codefix.moduleSpecifierToValidIdentifier(moduleSpecifier, target), identifiers); + return [ + makeImport(createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier), + makeConst(/*modifiers*/ undefined, getSynthesizedDeepClone(name), createIdentifier(tmp)), + ]; + } + case SyntaxKind.Identifier: + return convertSingleIdentifierImport(file, name, moduleSpecifier, changes, checker, identifiers); + default: + Debug.assertNever(name); + } + } + + /** + * Convert `import x = require("x").` + * Also converts uses like `x.y()` to `y()` and uses a named import. + */ + function convertSingleIdentifierImport(file: SourceFile, name: Identifier, moduleSpecifier: string, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers): ReadonlyArray { + const nameSymbol = checker.getSymbolAtLocation(name); + // Maps from module property name to name actually used. (The same if there isn't shadowing.) + const namedBindingsNames = createMap(); + // True if there is some non-property use like `x()` or `f(x)`. + let needDefaultImport = false; + + for (const use of identifiers.original.get(name.text)) { + if (checker.getSymbolAtLocation(use) !== nameSymbol || use === name) { + // This was a use of a different symbol with the same name, due to shadowing. Ignore. + continue; + } + + const { parent } = use; + if (isPropertyAccessExpression(parent)) { + const { expression, name: { text: propertyName } } = parent; + Debug.assert(expression === use); // Else shouldn't have been in `collectIdentifiers` + let idName = namedBindingsNames.get(propertyName); + if (idName === undefined) { + idName = makeUniqueName(propertyName, identifiers); + namedBindingsNames.set(propertyName, idName); + } + changes.replaceNode(file, parent, createIdentifier(idName)); + } + else { + needDefaultImport = true; + } + } + + const namedBindings = namedBindingsNames.size === 0 ? undefined : arrayFrom(mapIterator(namedBindingsNames.entries(), ([propertyName, idName]) => + createImportSpecifier(propertyName === idName ? undefined : createIdentifier(propertyName), createIdentifier(idName)))); + if (!namedBindings) { + // If it was unused, ensure that we at least import *something*. + needDefaultImport = true; + } + return [makeImport(needDefaultImport ? getSynthesizedDeepClone(name) : undefined, namedBindings, moduleSpecifier)]; + } + + // Identifiers helpers + + function makeUniqueName(name: string, identifiers: Identifiers): string { + while (identifiers.original.has(name) || identifiers.additional.has(name)) { + name = `_${name}`; + } + identifiers.additional.set(name, true); + return name; + } + + /** + * Helps us create unique identifiers. + * `original` refers to the local variable names in the original source file. + * `additional` is any new unique identifiers we've generated. (e.g., we'll generate `_x`, then `__x`.) + */ + interface Identifiers { + readonly original: FreeIdentifiers; + // Additional identifiers we've added. Mutable! + readonly additional: Map; + } + + type FreeIdentifiers = ReadonlyMap>; + function collectFreeIdentifiers(file: SourceFile): FreeIdentifiers { + const map = createMultiMap(); + file.forEachChild(function recur(node) { + if (isIdentifier(node) && isFreeIdentifier(node)) { + map.add(node.text, node); + } + node.forEachChild(recur); + }); + return map; + } + + function isFreeIdentifier(node: Identifier): boolean { + const { parent } = node; + switch (parent.kind) { + case SyntaxKind.PropertyAccessExpression: + return (parent as PropertyAccessExpression).name !== node; + case SyntaxKind.BindingElement: + return (parent as BindingElement).propertyName !== node; + default: + return true; + } + } + + // Node helpers + + function functionExpressionToDeclaration(name: string | undefined, additionalModifiers: ReadonlyArray, fn: FunctionExpression | ArrowFunction | MethodDeclaration): FunctionDeclaration { + return createFunctionDeclaration( + getSynthesizedDeepClones(fn.decorators), // TODO: GH#19915 Don't think this is even legal. + concatenate(additionalModifiers, getSynthesizedDeepClones(fn.modifiers)), + getSynthesizedDeepClone(fn.asteriskToken), + name, + getSynthesizedDeepClones(fn.typeParameters), + getSynthesizedDeepClones(fn.parameters), + getSynthesizedDeepClone(fn.type), + convertToFunctionBody(getSynthesizedDeepClone(fn.body))); + } + + function classExpressionToDeclaration(name: string | undefined, additionalModifiers: ReadonlyArray, cls: ClassExpression): ClassDeclaration { + return createClassDeclaration( + getSynthesizedDeepClones(cls.decorators), // TODO: GH#19915 Don't think this is even legal. + concatenate(additionalModifiers, getSynthesizedDeepClones(cls.modifiers)), + name, + getSynthesizedDeepClones(cls.typeParameters), + getSynthesizedDeepClones(cls.heritageClauses), + getSynthesizedDeepClones(cls.members)); + } + + function makeSingleImport(localName: string, propertyName: string, moduleSpecifier: string): ImportDeclaration { + return propertyName === "default" + ? makeImport(createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier) + : makeImport(/*name*/ undefined, [makeImportSpecifier(propertyName, localName)], moduleSpecifier); + } + + function makeImport(name: Identifier | undefined, namedImports: ReadonlyArray, moduleSpecifier: string): ImportDeclaration { + const importClause = (name || namedImports) && createImportClause(name, namedImports && createNamedImports(namedImports)); + return createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, importClause, createLiteral(moduleSpecifier)); + } + + function makeImportSpecifier(propertyName: string | undefined, name: string): ImportSpecifier { + return createImportSpecifier(propertyName !== undefined && propertyName !== name ? createIdentifier(propertyName) : undefined, createIdentifier(name)); + } + + function makeConst(modifiers: ReadonlyArray | undefined, name: string | BindingName, init: Expression): VariableStatement { + return createVariableStatement( + modifiers, + createVariableDeclarationList( + [createVariableDeclaration(name, /*type*/ undefined, init)], + NodeFlags.Const)); + } + + function makeExportDeclaration(exportSpecifiers: ExportSpecifier[] | undefined, moduleSpecifier?: string): ExportDeclaration { + return createExportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + exportSpecifiers && createNamedExports(exportSpecifiers), + moduleSpecifier === undefined ? undefined : createLiteral(moduleSpecifier)); + } +} diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index b7aa5ac33d1..b3110a0ca36 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1692,7 +1692,7 @@ namespace ts.refactor.extractSymbol { } for (let i = 0; i < scopes.length; i++) { const scope = scopes[i]; - const resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags); + const resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags, /*excludeGlobals*/ false); if (resolvedSymbol === symbol) { continue; } diff --git a/src/services/refactors/refactors.ts b/src/services/refactors/refactors.ts index 3858b198743..8b4561700d5 100644 --- a/src/services/refactors/refactors.ts +++ b/src/services/refactors/refactors.ts @@ -1,5 +1,6 @@ /// /// +/// /// /// /// diff --git a/src/services/refactors/useDefaultImport.ts b/src/services/refactors/useDefaultImport.ts index 56faf082a49..a103168f67b 100644 --- a/src/services/refactors/useDefaultImport.ts +++ b/src/services/refactors/useDefaultImport.ts @@ -23,7 +23,7 @@ namespace ts.refactor.installTypesForPackage { return undefined; } - const module = ts.getResolvedModule(file, importInfo.moduleSpecifier.text); + const module = getResolvedModule(file, importInfo.moduleSpecifier.text); const resolvedFile = program.getSourceFile(module.resolvedFileName); if (!(resolvedFile.externalModuleIndicator && isExportAssignment(resolvedFile.externalModuleIndicator) && resolvedFile.externalModuleIndicator.isExportEquals)) { return undefined; @@ -52,7 +52,7 @@ namespace ts.refactor.installTypesForPackage { } const { importStatement, name, moduleSpecifier } = importInfo; const newImportClause = createImportClause(name, /*namedBindings*/ undefined); - const newImportStatement = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newImportClause, moduleSpecifier); + const newImportStatement = createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newImportClause, moduleSpecifier); return { edits: textChanges.ChangeTracker.with(context, t => t.replaceNode(file, importStatement, newImportStatement)), renameFilename: undefined, diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 9a208ddff9f..8fe12d29313 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1354,6 +1354,10 @@ namespace ts { return visited; } + export function getSynthesizedDeepClones(nodes: NodeArray | undefined): NodeArray | undefined { + return nodes && createNodeArray(nodes.map(getSynthesizedDeepClone), nodes.hasTrailingComma); + } + /** * Sets EmitFlags to suppress leading and trailing trivia on the node. */ diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index b0dc9e3b6eb..3eabea4435a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -901,6 +901,7 @@ declare namespace ts { kind: SyntaxKind.ArrowFunction; equalsGreaterThanToken: EqualsGreaterThanToken; body: ConciseBody; + name: never; } interface LiteralLikeNode extends Node { text: string; @@ -1362,6 +1363,7 @@ declare namespace ts { interface ExportDeclaration extends DeclarationStatement { kind: SyntaxKind.ExportDeclaration; parent?: SourceFile | ModuleBlock; + /** Will not be assigned in the case of `export * from "foo";` */ exportClause?: NamedExports; /** If this is not a StringLiteral it will be a grammar error. */ moduleSpecifier?: Expression; @@ -3288,7 +3290,7 @@ declare namespace ts { declare namespace ts { function createNodeArray(elements?: ReadonlyArray, hasTrailingComma?: boolean): NodeArray; /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ - function createLiteral(value: string | StringLiteral | NumericLiteral | Identifier): StringLiteral; + function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; function createLiteral(value: number): NumericLiteral; function createLiteral(value: boolean): BooleanLiteral; function createLiteral(value: string | number | boolean): PrimaryExpression; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index f839deabcfb..630b7a08a28 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -901,6 +901,7 @@ declare namespace ts { kind: SyntaxKind.ArrowFunction; equalsGreaterThanToken: EqualsGreaterThanToken; body: ConciseBody; + name: never; } interface LiteralLikeNode extends Node { text: string; @@ -1362,6 +1363,7 @@ declare namespace ts { interface ExportDeclaration extends DeclarationStatement { kind: SyntaxKind.ExportDeclaration; parent?: SourceFile | ModuleBlock; + /** Will not be assigned in the case of `export * from "foo";` */ exportClause?: NamedExports; /** If this is not a StringLiteral it will be a grammar error. */ moduleSpecifier?: Expression; @@ -3235,7 +3237,7 @@ declare namespace ts { declare namespace ts { function createNodeArray(elements?: ReadonlyArray, hasTrailingComma?: boolean): NodeArray; /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ - function createLiteral(value: string | StringLiteral | NumericLiteral | Identifier): StringLiteral; + function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; function createLiteral(value: number): NumericLiteral; function createLiteral(value: boolean): BooleanLiteral; function createLiteral(value: string | number | boolean): PrimaryExpression; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 426518794bd..97379957cbf 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -135,6 +135,7 @@ declare namespace FourSlashInterface { file(index: number, content?: string, scriptKindName?: string): any; file(name: string, content?: string, scriptKindName?: string): any; select(startMarker: string, endMarker: string): void; + selectRange(range: Range): void; } class verifyNegatable { private negative; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts new file mode 100644 index 00000000000..6529bb64af0 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const exportsAlias = exports; +////exportsAlias.f = function() {}; +/////*a*/module/*b*/.exports = exportsAlias; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: ` +export function f() { } +`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts new file mode 100644 index 00000000000..1c8633eb4eb --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts @@ -0,0 +1,19 @@ +/// + +// Test that we leave it alone if the name is a keyword. + +// @allowJs: true + +// @Filename: /a.js +/////*a*/exports/*b*/.default = 0; +////exports.default; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `const _default = 0; +export { _default as default }; +_default;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts new file mode 100644 index 00000000000..16b48fcd204 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts @@ -0,0 +1,19 @@ +/// + +// Test that we leave it alone if the name is a keyword. + +// @allowJs: true + +// @Filename: /a.js +/////*a*/exports/*b*/.class = 0; +////exports.async = 1; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `const _class = 0; +export { _class as class }; +export const async = 1;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts new file mode 100644 index 00000000000..ddcf79d0114 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts @@ -0,0 +1,26 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/module/*b*/.exports = function() {} +////module.exports = function f() {} +////module.exports = class {} +////module.exports = class C {} +////module.exports = 0; + +// See also `refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts` + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export default function() { } +export default function f() { } +export default class { +} +export default class C { +} +export default 0;` +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts new file mode 100644 index 00000000000..8d22ea77c2b --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts @@ -0,0 +1,43 @@ +/// + +// @allowJs: true + +// @Filename: /a.d.ts +////export const x: number; + +// @Filename: /b.d.ts +////export default function f() {} + +// @Filename: /c.d.ts +////export default function f(): void; +////export function g(): void; + +// @Filename: /d.ts +////declare const x: number; +////export = x; + +// @Filename: /z.js +// Normally -- just `export *` +/////*a*/module/*b*/.exports = require("./a"); +// If just a default is exported, just `export { default }` +////module.exports = require("./b"); +// May need both +////module.exports = require("./c"); +// For `export =` re-export the "default" since that's what it will be converted to. +////module.exports = require("./d"); +// In untyped case just go with `export *` +////module.exports = require("./unknown"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: +`export * from "./a"; +export { default } from "./b"; +export * from "./c"; +export { default } from "./c"; +export { default } from "./d"; +export * from "./unknown";`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts new file mode 100644 index 00000000000..7b48bd5f91e --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts @@ -0,0 +1,26 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/module/*b*/.exports = 0; + +// @Filename: /b.ts +////import a = require("./a"); + +// @Filename: /c.js +////const a = require("./a"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export default 0;`, +}); + +goTo.file("/b.ts"); +verify.currentFileContentIs('import a from "./a";'); + +goTo.file("/c.js"); +verify.currentFileContentIs('const a = require("./a").default;'); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts new file mode 100644 index 00000000000..8251f90fc0d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts @@ -0,0 +1,19 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/exports/*b*/.f = function() {} +////exports.C = class {} +////exports.x = 0; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export function f() { } +export class C { +} +export const x = 0;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts new file mode 100644 index 00000000000..b18bc94579d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts @@ -0,0 +1,25 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/module/*b*/.exports = { +//// x: 0, +//// f: function() {}, +//// g: () => {}, +//// h() {}, +//// C: class {}, +////}; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export const x = 0; +export function f() { } +export function g() { } +export function h() { } +export class C { +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts new file mode 100644 index 00000000000..05b4903eda3 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts @@ -0,0 +1,18 @@ +/// + +// TODO: Maybe we could transform this to `export function f() {}`. + +// @allowJs: true + +// @Filename: /a.js +////function f() {} +/////*a*/module/*b*/.exports = { f }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `function f() {} +export default { f };`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts new file mode 100644 index 00000000000..da9976fa7d0 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts @@ -0,0 +1,36 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////exports.x = 0; +////exports.x; +//// +////const y = 1; +/////*a*/exports/*b*/.y = y; +////exports.y; +//// +////exports.z = 2; +////function f(z) { +//// exports.z; +////} + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export const x = 0; +x; + +const y = 1; +const _y = y; +export { _y as y }; +_y; + +const _z = 2; +export { _z as z }; +function f(z) { + _z; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts new file mode 100644 index 00000000000..b3b7fbf94c6 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/exports/*b*/.f = async function* f(p) {} +////exports.C = class C extends D { m() {} } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export async function* f(p) { } +export class C extends D { + m() { } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts new file mode 100644 index 00000000000..b33b0a1a160 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts @@ -0,0 +1,15 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const [x, y] = /*a*/require/*b*/("x"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import _x from "x"; +const [x, y] = _x;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts new file mode 100644 index 00000000000..7c5415c1451 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const x = /*a*/require/*b*/("x"); +////x(); +////x.y; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x, { y } from "x"; +x(); +y;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts new file mode 100644 index 00000000000..321a9cccf8b --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts @@ -0,0 +1,20 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const x = require("x"); +////const [a, b] = /*a*/require/*b*/("x"); +////const {c, ...d} = require("x"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x from "x"; +import _x from "x"; +const [a, b] = _x; +import __x from "x"; +const { c, ...d } = __x;` +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts new file mode 100644 index 00000000000..37d65ddc622 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts @@ -0,0 +1,18 @@ +/// + +// Test that we leave it alone if the name is a keyword. + +// @allowJs: true + +// @Filename: /a.js +////const x = /*a*/require/*b*/("x"), y = 0, { z } = require("z"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x from "x"; +const y = 0; +import { z } from "z";`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts new file mode 100644 index 00000000000..0c953b2e7e6 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts @@ -0,0 +1,21 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const [] = /*a0*/require/*b0*/("a-b"); +////const [] = /*a1*/require/*b1*/("0a"); +////const [] = /*a2*/require/*b2*/("1a"); + +goTo.select("a0", "b0"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import aB from "a-b"; +const [] = aB; +import A from "0a"; +const [] = A; +import _A from "1a"; +const [] = _A;` +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts new file mode 100644 index 00000000000..f757db2164a --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts @@ -0,0 +1,15 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const { x: { a, b } } = /*a*/require/*b*/("x"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x from "x"; +const { x: { a, b } } = x;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts new file mode 100644 index 00000000000..474fd4b0f0f --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts @@ -0,0 +1,14 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const { x, y: z } = /*a*/require/*b*/("x"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: 'import { x, y as z } from "x";', +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts new file mode 100644 index 00000000000..bf7e207550e --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts @@ -0,0 +1,16 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const x = /*a*/require/*b*/("x"); +////x.y; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import { y } from "x"; +y;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts new file mode 100644 index 00000000000..57efd5370f2 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts @@ -0,0 +1,24 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const x = /*a*/require/*b*/("x").default; +////const a = require("b").c; +////const a = require("a").a; +////const [a, b] = require("c").d; +////const [a, b] = require("c").a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'. + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x from "x"; +import { c as a } from "b"; +import { a } from "a"; +import { d } from "c"; +const [a, b] = d; +import { a as _a } from "c"; +const [a, b] = _a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'.`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts new file mode 100644 index 00000000000..c389280d75c --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const mod = /*a*/require/*b*/("mod"); +////const x = 0; +////mod.x(x); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import { x as _x } from "mod"; +const x = 0; +_x(x);` +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts new file mode 100644 index 00000000000..2b81c816e20 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts @@ -0,0 +1,16 @@ +/// + +// Test that we leave it alone if the name is a keyword. + +// @allowJs: true + +// @Filename: /a.js +/////*a*/require/*b*/("foo"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: 'import "foo";', +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts b/tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts new file mode 100644 index 00000000000..8d441f47dc3 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts @@ -0,0 +1,13 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////c[|o|]nst [|a|]lias [|=|] [|m|]odule[|.|]export[|s|]; +////[|a|]lias[|.|][|x|] = 0; +////[|module.exports|]; +////[|require("x")|]; +////[|require("x").y;|]; + +goTo.eachRange(() => verify.refactorAvailable("Convert to ES6 module")); + From 90a1df9d92a086ae1d5331790100e94a85e98a26 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 9 Jan 2018 15:43:50 -0800 Subject: [PATCH 03/13] Add test for failure to use correct current directory in inferred project Test for #21040 --- .../unittests/tsserverProjectSystem.ts | 69 +++++++++++++++++++ src/harness/virtualFileSystemWithWatch.ts | 2 +- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 10c5aad92db..188a663b650 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -6488,4 +6488,73 @@ namespace ts.projectSystem { verifyWatchedDirectories(/*useProjectAtRoot*/ false); }); }); + + describe("tsserverProjectSystem typingsInstaller on inferred Project", () => { + it("when projectRootPath is provided", () => { + const projects = "/users/username/projects"; + const projectRootPath = `${projects}/san2`; + const file: FileOrFolder = { + path: `${projectRootPath}/x.js`, + content: "const aaaaaaav = 1;" + }; + + const currentDirectory = `${projects}/anotherProject`; + const packageJsonInCurrentDirectory: FileOrFolder = { + path: `${currentDirectory}/package.json`, + content: JSON.stringify({ + devDependencies: { + "pkgcurrentdirectory": "" + }, + }) + }; + const packageJsonOfPkgcurrentdirectory: FileOrFolder = { + path: `${currentDirectory}/node_modules/pkgcurrentdirectory/package.json`, + content: JSON.stringify({ + name: "pkgcurrentdirectory", + main: "index.js", + typings: "index.d.ts" + }) + }; + const indexOfPkgcurrentdirectory: FileOrFolder = { + path: `${currentDirectory}/node_modules/pkgcurrentdirectory/index.d.ts`, + content: "export function foo() { }" + }; + + const typingsCache = `/users/username/Library/Caches/typescript/2.7`; + const typingsCachePackageJson: FileOrFolder = { + path: `${typingsCache}/package.json`, + content: JSON.stringify({ + devDependencies: { + }, + }) + }; + + const files = [file, packageJsonInCurrentDirectory, packageJsonOfPkgcurrentdirectory, indexOfPkgcurrentdirectory, typingsCachePackageJson]; + const host = createServerHost(files, { currentDirectory }); + + const typesRegistry = createMap(); + typesRegistry.set("pkgcurrentdirectory", void 0); + const typingsInstaller = new TestTypingsInstaller(typingsCache, /*throttleLimit*/ 5, host, typesRegistry); + + const projectService = createProjectService(host, { typingsInstaller }); + + projectService.setCompilerOptionsForInferredProjects({ + module: ModuleKind.CommonJS, + target: ScriptTarget.ES2016, + jsx: JsxEmit.Preserve, + experimentalDecorators: true, + allowJs: true, + allowSyntheticDefaultImports: true, + allowNonTsExtensions: true + }); + + projectService.openClientFile(file.path, file.content, ScriptKind.JS, projectRootPath); + + const project = projectService.inferredProjects[0]; + assert.isDefined(project); + + // Ensure that we use result from types cache when getting ls + assert.isDefined(project.getLanguageService()); + }); + }); } diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index a6fe27ca9c6..921d4674231 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -547,7 +547,7 @@ interface Array {}` } readDirectory(path: string, extensions?: ReadonlyArray, exclude?: ReadonlyArray, include?: ReadonlyArray, depth?: number): string[] { - return ts.matchFiles(this.toNormalizedAbsolutePath(path), extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, (dir) => { + return ts.matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, (dir) => { const directories: string[] = []; const files: string[] = []; const dirEntry = this.fs.get(this.toPath(dir)); From 667751df2ade1f7236b8e462d4ec286773d09762 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 9 Jan 2018 15:59:23 -0800 Subject: [PATCH 04/13] When sending typings request use project's current directory as project root path This ensures that we arent picking typings from folder different from the current directory for the project --- src/harness/unittests/tsserverProjectSystem.ts | 5 ++++- src/server/utilities.ts | 15 +-------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 188a663b650..fe7a2095b86 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -6503,7 +6503,7 @@ namespace ts.projectSystem { path: `${currentDirectory}/package.json`, content: JSON.stringify({ devDependencies: { - "pkgcurrentdirectory": "" + pkgcurrentdirectory: "" }, }) }; @@ -6555,6 +6555,9 @@ namespace ts.projectSystem { // Ensure that we use result from types cache when getting ls assert.isDefined(project.getLanguageService()); + + // Verify that the pkgcurrentdirectory from the current directory isnt picked up + checkProjectActualFiles(project, [file.path]); }); }); } diff --git a/src/server/utilities.ts b/src/server/utilities.ts index d76ff1bf6d0..c44419f8cf3 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -34,19 +34,6 @@ namespace ts.server { export type Types = Msg; } - function getProjectRootPath(project: Project): Path { - switch (project.projectKind) { - case ProjectKind.Configured: - return getDirectoryPath(project.getProjectName()); - case ProjectKind.Inferred: - // TODO: fixme - return ""; - case ProjectKind.External: - const projectName = normalizeSlashes(project.getProjectName()); - return getDirectoryPath(projectName); - } - } - export function createInstallTypingsRequest(project: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray, cachePath?: string): DiscoverTypings { return { projectName: project.getProjectName(), @@ -54,7 +41,7 @@ namespace ts.server { compilerOptions: project.getCompilationSettings(), typeAcquisition, unresolvedImports, - projectRootPath: getProjectRootPath(project), + projectRootPath: project.getCurrentDirectory() as Path, cachePath, kind: "discover" }; From 03fd77657d06398cd55f56c6622ae8584d8a3497 Mon Sep 17 00:00:00 2001 From: Stanislav Iliev Date: Wed, 10 Jan 2018 03:11:57 +0200 Subject: [PATCH 05/13] Issue implicit any errors for mapped types without annotations (#21104) * Fixed #21011 * Updated code of merged message * Reversed message code change and moved error to it's appropriate position * Applied suggested improvements * Fixed wrong diagnostics message in checker * Reverted diagnostic message change --- src/compiler/checker.ts | 8 ++++++++ src/compiler/diagnosticMessages.json | 5 ++++- tests/baselines/reference/anyMappedTypesError.errors.txt | 7 +++++++ tests/baselines/reference/anyMappedTypesError.js | 4 ++++ tests/baselines/reference/anyMappedTypesError.symbols | 5 +++++ tests/baselines/reference/anyMappedTypesError.types | 5 +++++ tests/cases/compiler/anyMappedTypesError.ts | 3 +++ 7 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/anyMappedTypesError.errors.txt create mode 100644 tests/baselines/reference/anyMappedTypesError.js create mode 100644 tests/baselines/reference/anyMappedTypesError.symbols create mode 100644 tests/baselines/reference/anyMappedTypesError.types create mode 100644 tests/cases/compiler/anyMappedTypesError.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 16bfd7fa7e2..540f3722f92 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11281,6 +11281,9 @@ namespace ts { } diagnostic = Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type; break; + case SyntaxKind.MappedType: + error(declaration, Diagnostics.Mapped_object_type_implicitly_has_an_any_template_type); + return; default: diagnostic = Diagnostics.Variable_0_implicitly_has_an_1_type; } @@ -20312,6 +20315,11 @@ namespace ts { function checkMappedType(node: MappedTypeNode) { checkSourceElement(node.typeParameter); checkSourceElement(node.type); + + if (noImplicitAny && !node.type) { + reportImplicitAnyError(node, anyType); + } + const type = getTypeFromMappedTypeNode(node); const constraintType = getConstraintTypeFromMappedType(type); checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 96be3e99fdc..4c091673137 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3571,7 +3571,10 @@ "category": "Error", "code": 7038 }, - + "Mapped object type implicitly has an 'any' template type.": { + "category": "Error", + "code": 7039 + }, "You cannot rename this element.": { "category": "Error", "code": 8000 diff --git a/tests/baselines/reference/anyMappedTypesError.errors.txt b/tests/baselines/reference/anyMappedTypesError.errors.txt new file mode 100644 index 00000000000..e1442c15723 --- /dev/null +++ b/tests/baselines/reference/anyMappedTypesError.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/anyMappedTypesError.ts(1,12): error TS7039: Mapped object type implicitly has an 'any' template type. + + +==== tests/cases/compiler/anyMappedTypesError.ts (1 errors) ==== + type Foo = {[P in "bar"]}; + ~~~~~~~~~~~~~~ +!!! error TS7039: Mapped object type implicitly has an 'any' template type. \ No newline at end of file diff --git a/tests/baselines/reference/anyMappedTypesError.js b/tests/baselines/reference/anyMappedTypesError.js new file mode 100644 index 00000000000..8797d2cfc0e --- /dev/null +++ b/tests/baselines/reference/anyMappedTypesError.js @@ -0,0 +1,4 @@ +//// [anyMappedTypesError.ts] +type Foo = {[P in "bar"]}; + +//// [anyMappedTypesError.js] diff --git a/tests/baselines/reference/anyMappedTypesError.symbols b/tests/baselines/reference/anyMappedTypesError.symbols new file mode 100644 index 00000000000..0e9a425aad3 --- /dev/null +++ b/tests/baselines/reference/anyMappedTypesError.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/anyMappedTypesError.ts === +type Foo = {[P in "bar"]}; +>Foo : Symbol(Foo, Decl(anyMappedTypesError.ts, 0, 0)) +>P : Symbol(P, Decl(anyMappedTypesError.ts, 0, 13)) + diff --git a/tests/baselines/reference/anyMappedTypesError.types b/tests/baselines/reference/anyMappedTypesError.types new file mode 100644 index 00000000000..290ea6883b1 --- /dev/null +++ b/tests/baselines/reference/anyMappedTypesError.types @@ -0,0 +1,5 @@ +=== tests/cases/compiler/anyMappedTypesError.ts === +type Foo = {[P in "bar"]}; +>Foo : Foo +>P : P + diff --git a/tests/cases/compiler/anyMappedTypesError.ts b/tests/cases/compiler/anyMappedTypesError.ts new file mode 100644 index 00000000000..6b37b286046 --- /dev/null +++ b/tests/cases/compiler/anyMappedTypesError.ts @@ -0,0 +1,3 @@ +// @noImplicitAny: true + +type Foo = {[P in "bar"]}; \ No newline at end of file From c0bdd12c4c730291aa6470762fc953639c754498 Mon Sep 17 00:00:00 2001 From: Sharon Rolel Date: Tue, 9 Jan 2018 20:15:08 -0500 Subject: [PATCH 06/13] add fixAwaitInSyncFunction code fix (#21069) * add fixAwaitInSyncFunction code fix * Just insert the keyword * only one codefix * remove comment * Change explicit return type T to Promise * Review changes * Change codefix message --- src/compiler/diagnosticMessages.json | 4 + .../codefixes/fixAwaitInSyncFunction.ts | 74 +++++++++++++++++++ src/services/codefixes/fixes.ts | 1 + src/services/textChanges.ts | 5 ++ .../fourslash/codeFixAwaitInSyncFunction1.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction10.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction11.ts | 14 ++++ .../fourslash/codeFixAwaitInSyncFunction12.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction13.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction14.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction15.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction2.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction3.ts | 12 +++ .../fourslash/codeFixAwaitInSyncFunction4.ts | 9 +++ .../fourslash/codeFixAwaitInSyncFunction5.ts | 17 +++++ .../codeFixAwaitInSyncFunction6.5.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction6.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction7.ts | 17 +++++ .../fourslash/codeFixAwaitInSyncFunction8.ts | 13 ++++ .../fourslash/codeFixAwaitInSyncFunction9.ts | 17 +++++ .../codeFixAwaitInSyncFunction_all.ts | 21 ++++++ 21 files changed, 321 insertions(+) create mode 100644 src/services/codefixes/fixAwaitInSyncFunction.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction1.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction12.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction13.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction14.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction15.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction2.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction3.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction4.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction5.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction6.5.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction6.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction7.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction8.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction9.ts create mode 100644 tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4c091673137..cf5ccb1397d 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3877,6 +3877,10 @@ "category": "Message", "code": 90028 }, + "Add async modifier to containing function": { + "category": "Message", + "code": 90029 + }, "Convert function to an ES2015 class": { "category": "Message", "code": 95001 diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts new file mode 100644 index 00000000000..883993e7b51 --- /dev/null +++ b/src/services/codefixes/fixAwaitInSyncFunction.ts @@ -0,0 +1,74 @@ +/* @internal */ +namespace ts.codefix { + const fixId = "fixAwaitInSyncFunction"; + const errorCodes = [ + Diagnostics.await_expression_is_only_allowed_within_an_async_function.code, + Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator.code, + ]; + registerCodeFix({ + errorCodes, + getCodeActions(context) { + const { sourceFile, span } = context; + const nodes = getNodes(sourceFile, span.start); + if (!nodes) return undefined; + const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, nodes)); + return [{ description: getLocaleSpecificMessage(Diagnostics.Add_async_modifier_to_containing_function), changes, fixId }]; + }, + fixIds: [fixId], + getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { + const nodes = getNodes(diag.file, diag.start); + if (!nodes) return; + doChange(changes, context.sourceFile, nodes); + }), + }); + + function getReturnType(expr: FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction) { + if (expr.type) { + return expr.type; + } + if (isVariableDeclaration(expr.parent) && + expr.parent.type && + isFunctionTypeNode(expr.parent.type)) { + return expr.parent.type.type; + } + } + + function getNodes(sourceFile: SourceFile, start: number): { insertBefore: Node, returnType: TypeNode | undefined } | undefined { + const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); + const containingFunction = getContainingFunction(token); + let insertBefore: Node | undefined; + switch (containingFunction.kind) { + case SyntaxKind.MethodDeclaration: + insertBefore = containingFunction.name; + break; + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + insertBefore = findChildOfKind(containingFunction, SyntaxKind.FunctionKeyword, sourceFile); + break; + case SyntaxKind.ArrowFunction: + insertBefore = findChildOfKind(containingFunction, SyntaxKind.OpenParenToken, sourceFile) || first(containingFunction.parameters); + break; + default: + return; + } + + return { + insertBefore, + returnType: getReturnType(containingFunction) + }; + } + + function doChange( + changes: textChanges.ChangeTracker, + sourceFile: SourceFile, + { insertBefore, returnType }: { insertBefore: Node | undefined, returnType: TypeNode | undefined }): void { + + if (returnType) { + const entityName = getEntityNameFromTypeNode(returnType); + if (!entityName || entityName.kind !== SyntaxKind.Identifier || entityName.text !== "Promise") { + changes.replaceNode(sourceFile, returnType, createTypeReferenceNode("Promise", createNodeArray([returnType]))); + } + } + changes.insertModifierBefore(sourceFile, SyntaxKind.AsyncKeyword, insertBefore); + } +} diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts index bdbd8311a76..317c65b15ee 100644 --- a/src/services/codefixes/fixes.ts +++ b/src/services/codefixes/fixes.ts @@ -11,6 +11,7 @@ /// /// /// +/// /// /// /// diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index e73c639ba79..b0efef44642 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -345,6 +345,11 @@ namespace ts.textChanges { return this.replaceWithSingle(sourceFile, startPosition, startPosition, newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween)); } + public insertModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void { + const pos = before.getStart(sourceFile); + this.replaceWithSingle(sourceFile, pos, pos, createToken(modifier), { suffix: " " }); + } + public changeIdentifierToPropertyAccess(sourceFile: SourceFile, prefix: string, node: Identifier): void { const startPosition = getAdjustedStartPosition(sourceFile, node, {}, Position.Start); this.replaceWithSingle(sourceFile, startPosition, startPosition, createPropertyAccess(createIdentifier(prefix), ""), {}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction1.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction1.ts new file mode 100644 index 00000000000..e64d4072757 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction1.ts @@ -0,0 +1,13 @@ +/// + +////function f() { +//// await Promise.resolve(); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`async function f() { + await Promise.resolve(); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts new file mode 100644 index 00000000000..42e0bc5be78 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts @@ -0,0 +1,13 @@ +/// + +////const f: () => number | string = () => { +//// await Promise.resolve('foo'); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f: () => Promise = async () => { + await Promise.resolve('foo'); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts new file mode 100644 index 00000000000..bc7b17f8db5 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts @@ -0,0 +1,14 @@ +/// + +////const f: string = () => { +//// await Promise.resolve('foo'); +////} + +// should not change type if it's incorrectly set +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f: string = async () => { + await Promise.resolve('foo'); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction12.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction12.ts new file mode 100644 index 00000000000..ee694a80e9f --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction12.ts @@ -0,0 +1,13 @@ +/// + +////const f: () => Array = function() { +//// await Promise.resolve([]); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f: () => Promise> = async function() { + await Promise.resolve([]); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction13.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction13.ts new file mode 100644 index 00000000000..06f54d29eeb --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction13.ts @@ -0,0 +1,13 @@ +/// + +////const f: () => Promise = () => { +//// await Promise.resolve('foo'); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f: () => Promise = async () => { + await Promise.resolve('foo'); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction14.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction14.ts new file mode 100644 index 00000000000..c798af5f5ab --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction14.ts @@ -0,0 +1,13 @@ +/// + +////const f = function(): number { +//// await Promise.resolve(1); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async function(): Promise { + await Promise.resolve(1); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction15.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction15.ts new file mode 100644 index 00000000000..a2c6f7dcb1a --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction15.ts @@ -0,0 +1,13 @@ +/// + +////const f = (): number[] => { +//// await Promise.resolve([1]); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async (): Promise => { + await Promise.resolve([1]); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction2.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction2.ts new file mode 100644 index 00000000000..e8da351af5d --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction2.ts @@ -0,0 +1,13 @@ +/// + +////const f = function() { +//// await Promise.resolve(); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async function() { + await Promise.resolve(); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction3.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction3.ts new file mode 100644 index 00000000000..54d0aba103b --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction3.ts @@ -0,0 +1,12 @@ +/// + +////const f = { +//// get a() { +//// return await Promise.resolve(); +//// }, +//// get a() { +//// await Promise.resolve(); +//// }, +////} + +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction4.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction4.ts new file mode 100644 index 00000000000..dd123e25d0b --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction4.ts @@ -0,0 +1,9 @@ +/// + +////class Foo { +//// constructor { +//// await Promise.resolve(); +//// } +////} + +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction5.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction5.ts new file mode 100644 index 00000000000..a1c58b53831 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction5.ts @@ -0,0 +1,17 @@ +/// + +////class Foo { +//// bar() { +//// await Promise.resolve(); +//// } +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`class Foo { + async bar() { + await Promise.resolve(); + } +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction6.5.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction6.5.ts new file mode 100644 index 00000000000..c1b06811113 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction6.5.ts @@ -0,0 +1,13 @@ +/// + +////const f = promise => { +//// await promise; +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async promise => { + await promise; +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction6.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction6.ts new file mode 100644 index 00000000000..0b0aa098164 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction6.ts @@ -0,0 +1,13 @@ +/// + +////const f = (promise) => { +//// await promise; +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async (promise) => { + await promise; +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction7.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction7.ts new file mode 100644 index 00000000000..a467e9ee0ce --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction7.ts @@ -0,0 +1,17 @@ +/// + +////function f() { +//// for await (const x of g()) { +//// console.log(x); +//// } +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`async function f() { + for await (const x of g()) { + console.log(x); + } +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction8.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction8.ts new file mode 100644 index 00000000000..7c43add3edd --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction8.ts @@ -0,0 +1,13 @@ +/// + +////function f(): number | string { +//// await Promise.resolve(8); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`async function f(): Promise { + await Promise.resolve(8); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction9.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction9.ts new file mode 100644 index 00000000000..f93603e69c4 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction9.ts @@ -0,0 +1,17 @@ +/// + +////class Foo { +//// bar(): string { +//// await Promise.resolve('baz'); +//// } +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`class Foo { + async bar(): Promise { + await Promise.resolve('baz'); + } +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts new file mode 100644 index 00000000000..e6314a3a5f0 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts @@ -0,0 +1,21 @@ +/// + +////function f() { +//// await Promise.resolve(); +////} +//// +////const g = () => { +//// await f(); +////} + +verify.codeFixAll({ + fixId: "fixAwaitInSyncFunction", + newFileContent: +`async function f() { + await Promise.resolve(); +} + +const g = async () => { + await f(); +}`, +}); From c9ef52b9d818f1192ac3146385bbaddb599d5afe Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 9 Jan 2018 17:22:19 -0800 Subject: [PATCH 07/13] Do not always instantiate jsx signatures (#21108) --- src/compiler/checker.ts | 35 +++++++++++-------- .../baselines/reference/jsxHasLiteralType.js | 32 +++++++++++++++++ .../reference/jsxHasLiteralType.symbols | 25 +++++++++++++ .../reference/jsxHasLiteralType.types | 26 ++++++++++++++ tests/cases/compiler/jsxHasLiteralType.tsx | 11 ++++++ 5 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 tests/baselines/reference/jsxHasLiteralType.js create mode 100644 tests/baselines/reference/jsxHasLiteralType.symbols create mode 100644 tests/baselines/reference/jsxHasLiteralType.types create mode 100644 tests/cases/compiler/jsxHasLiteralType.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 540f3722f92..5e247c1ce2c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15162,7 +15162,7 @@ namespace ts { * element is not a class element, or the class element type cannot be determined, returns 'undefined'. * For example, in the element , the element instance type is `MyClass` (not `typeof MyClass`). */ - function getJsxElementInstanceType(node: JsxOpeningLikeElement, valueType: Type, sourceAttributesType: Type) { + function getJsxElementInstanceType(node: JsxOpeningLikeElement, valueType: Type, sourceAttributesType: Type | undefined) { Debug.assert(!(valueType.flags & TypeFlags.Union)); if (isTypeAny(valueType)) { // Short-circuit if the class tag is using an element type 'any' @@ -15181,20 +15181,27 @@ namespace ts { } } - const instantiatedSignatures = []; - for (const signature of signatures) { - if (signature.typeParameters) { - const isJavascript = isInJavaScriptFile(node); - const inferenceContext = createInferenceContext(signature, /*flags*/ isJavascript ? InferenceFlags.AnyDefault : 0); - const typeArguments = inferJsxTypeArguments(signature, sourceAttributesType, inferenceContext); - instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript)); + if (sourceAttributesType) { + // Instantiate in context of source type + const instantiatedSignatures = []; + for (const signature of signatures) { + if (signature.typeParameters) { + const isJavascript = isInJavaScriptFile(node); + const inferenceContext = createInferenceContext(signature, /*flags*/ isJavascript ? InferenceFlags.AnyDefault : 0); + const typeArguments = inferJsxTypeArguments(signature, sourceAttributesType, inferenceContext); + instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript)); + } + else { + instantiatedSignatures.push(signature); + } } - else { - instantiatedSignatures.push(signature); - } - } - return getUnionType(map(instantiatedSignatures, getReturnTypeOfSignature), UnionReduction.Subtype); + return getUnionType(map(instantiatedSignatures, getReturnTypeOfSignature), UnionReduction.Subtype); + } + else { + // Do not instantiate if no source type is provided - type parameters and their constraints will be used by contextual typing + return getUnionType(map(signatures, getReturnTypeOfSignature), UnionReduction.Subtype); + } } /** @@ -15418,7 +15425,7 @@ namespace ts { } // Get the element instance type (the result of newing or invoking this tag) - const elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType, sourceAttributesType || emptyObjectType); + const elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType, sourceAttributesType); // If we should include all stateless attributes type, then get all attributes type from all stateless function signature. // Otherwise get only attributes type from the signature picked by choose-overload logic. diff --git a/tests/baselines/reference/jsxHasLiteralType.js b/tests/baselines/reference/jsxHasLiteralType.js new file mode 100644 index 00000000000..491f58eebb1 --- /dev/null +++ b/tests/baselines/reference/jsxHasLiteralType.js @@ -0,0 +1,32 @@ +//// [jsxHasLiteralType.tsx] +import * as React from "react"; + +interface Props { + x?: "a" | "b"; +} +class MyComponent

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

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

extends React.Component {} +>MyComponent : MyComponent

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

extends React.Component {} +const m = From da593ca7a81611d37a8ea29b9668e5bb6da51ba5 Mon Sep 17 00:00:00 2001 From: falsandtru Date: Wed, 10 Jan 2018 15:06:06 +0900 Subject: [PATCH 08/13] Fix WeakSet interface (#19756) --- src/lib/es2015.collection.d.ts | 2 +- src/lib/es2015.iterable.d.ts | 2 +- src/lib/es2015.symbol.wellknown.d.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/es2015.collection.d.ts b/src/lib/es2015.collection.d.ts index f6087eb4405..74759107851 100644 --- a/src/lib/es2015.collection.d.ts +++ b/src/lib/es2015.collection.d.ts @@ -58,7 +58,7 @@ interface ReadonlySet { readonly size: number; } -interface WeakSet { +interface WeakSet { add(value: T): this; delete(value: T): boolean; has(value: T): boolean; diff --git a/src/lib/es2015.iterable.d.ts b/src/lib/es2015.iterable.d.ts index 26722b5ab2f..ccb7df6be69 100644 --- a/src/lib/es2015.iterable.d.ts +++ b/src/lib/es2015.iterable.d.ts @@ -180,7 +180,7 @@ interface SetConstructor { new (iterable: Iterable): Set; } -interface WeakSet { } +interface WeakSet { } interface WeakSetConstructor { new (iterable: Iterable): WeakSet; diff --git a/src/lib/es2015.symbol.wellknown.d.ts b/src/lib/es2015.symbol.wellknown.d.ts index 23d836c6515..681b6e8edfa 100644 --- a/src/lib/es2015.symbol.wellknown.d.ts +++ b/src/lib/es2015.symbol.wellknown.d.ts @@ -118,7 +118,7 @@ interface Set { readonly [Symbol.toStringTag]: "Set"; } -interface WeakSet { +interface WeakSet { readonly [Symbol.toStringTag]: "WeakSet"; } From 743d8dbe0a82c4db828bc657b8c3b2e34548249d Mon Sep 17 00:00:00 2001 From: Priyantha Lankapura <403912+lankaapura@users.noreply.github.com> Date: Wed, 10 Jan 2018 23:00:35 +0530 Subject: [PATCH 09/13] Fix to remove extra space between function and array index. (#21113) https://github.com/Microsoft/TypeScript/issues/21111 --- src/services/formatting/rules.ts | 14 +++++++------- ...formatSpaceBetweenFunctionAndArrayIndex.ts | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 tests/cases/fourslash/server/formatSpaceBetweenFunctionAndArrayIndex.ts diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 04f599039da..16270eda479 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -11,8 +11,8 @@ namespace ts.formatting { for (let token = SyntaxKind.FirstToken; token <= SyntaxKind.LastToken; token++) { allTokens.push(token); } - function anyTokenExcept(token: SyntaxKind): TokenRange { - return { tokens: allTokens.filter(t => t !== token), isSpecific: false }; + function anyTokenExcept(...tokens: SyntaxKind[]): TokenRange { + return { tokens: allTokens.filter(t => !tokens.some(t2 => t2 === t)), isSpecific: false }; } const anyToken: TokenRange = { tokens: allTokens, isSpecific: false }; @@ -316,6 +316,11 @@ namespace ts.formatting { rule("NoSpaceBeforeComma", anyToken, SyntaxKind.CommaToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + // No space before and after indexer `x[]` + rule("NoSpaceBeforeOpenBracket", anyTokenExcept(SyntaxKind.AsyncKeyword, SyntaxKind.CaseKeyword), SyntaxKind.OpenBracketToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceAfterCloseBracket", SyntaxKind.CloseBracketToken, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], RuleAction.Delete), + rule("SpaceAfterSemicolon", SyntaxKind.SemicolonToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space), + // Add a space between statements. All keywords except (do,else,case) has open/close parens after them. // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any] rule( @@ -326,11 +331,6 @@ namespace ts.formatting { RuleAction.Space), // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter. rule("SpaceAfterTryFinally", [SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword], SyntaxKind.OpenBraceToken, [isNonJsxSameLineTokenContext], RuleAction.Space), - - // No space before and after indexer `x[]` - rule("NoSpaceBeforeOpenBracket", anyTokenExcept(SyntaxKind.AsyncKeyword), SyntaxKind.OpenBracketToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), - rule("NoSpaceAfterCloseBracket", SyntaxKind.CloseBracketToken, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], RuleAction.Delete), - rule("SpaceAfterSemicolon", SyntaxKind.SemicolonToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space), ]; return [ diff --git a/tests/cases/fourslash/server/formatSpaceBetweenFunctionAndArrayIndex.ts b/tests/cases/fourslash/server/formatSpaceBetweenFunctionAndArrayIndex.ts new file mode 100644 index 00000000000..7f2cbb8148f --- /dev/null +++ b/tests/cases/fourslash/server/formatSpaceBetweenFunctionAndArrayIndex.ts @@ -0,0 +1,19 @@ +/// + +//// +////function test() { +//// return []; +////} +//// +////test() [0] +//// + +format.document(); +verify.currentFileContentIs( +` +function test() { + return []; +} + +test()[0] +`); From ddd8e759c1a166e6dbc7de2be669791fda24ba64 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 10 Jan 2018 11:13:47 -0800 Subject: [PATCH 10/13] Use 'append' helper (#21101) --- src/compiler/parser.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index bae9f0594ed..0e2118af52a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -786,15 +786,7 @@ namespace ts { const comments = getJSDocCommentRanges(node, sourceFile.text); if (comments) { for (const comment of comments) { - const jsDoc = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); - if (jsDoc) { - if (!node.jsDoc) { - node.jsDoc = [jsDoc]; - } - else { - node.jsDoc.push(jsDoc); - } - } + node.jsDoc = append(node.jsDoc, JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos)); } } From 102368332eb43682c2c964af08d49ffa3e3f6da4 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 10 Jan 2018 11:31:13 -0800 Subject: [PATCH 11/13] Use 'append' helper more (#21125) --- src/compiler/parser.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 0e2118af52a..f0685b7372e 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6603,10 +6603,7 @@ namespace ts { const start = scanner.getStartPos(); let children: JSDocParameterTag[]; while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.Parameter, name))) { - if (!children) { - children = []; - } - children.push(child); + children = append(children, child); } if (children) { jsdocTypeLiteral = createNode(SyntaxKind.JSDocTypeLiteral, start); @@ -6723,10 +6720,7 @@ namespace ts { } } else { - if (!jsdocTypeLiteral.jsDocPropertyTags) { - jsdocTypeLiteral.jsDocPropertyTags = [] as MutableNodeArray; - } - (jsdocTypeLiteral.jsDocPropertyTags as MutableNodeArray).push(child); + jsdocTypeLiteral.jsDocPropertyTags = append(jsdocTypeLiteral.jsDocPropertyTags as MutableNodeArray, child); } } if (jsdocTypeLiteral) { From ee87cf409b52a9e51ee66dbb2b86204ed66fc8df Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 10 Jan 2018 11:41:14 -0800 Subject: [PATCH 12/13] Print the correct type in the top level chain as the message indicates (#21127) --- src/compiler/checker.ts | 2 +- .../abstractPropertyNegative.errors.txt | 12 ++--- .../apparentTypeSubtyping.errors.txt | 4 +- .../apparentTypeSupertype.errors.txt | 4 +- ...baseClassImprovedMismatchErrors.errors.txt | 16 +++---- .../classIsSubtypeOfBaseType.errors.txt | 4 +- ...ctionOverridesBaseClassAccessor.errors.txt | 4 +- ...tructuringParameterDeclaration2.errors.txt | 4 +- .../reference/elaboratedErrors.errors.txt | 4 +- .../reference/genericImplements.errors.txt | 4 +- .../genericSpecializations1.errors.txt | 8 ++-- .../genericSpecializations2.errors.txt | 8 ++-- .../genericSpecializations3.errors.txt | 4 +- ...cTypeWithNonGenericBaseMisMatch.errors.txt | 4 +- ...ementGenericWithMismatchedTypes.errors.txt | 8 ++-- ...mplementsIncorrectlyNoAssertion.errors.txt | 4 +- .../reference/incompatibleTypes.errors.txt | 16 +++---- .../reference/inheritance.errors.txt | 4 +- ...eMemberAccessorOverridingMethod.errors.txt | 8 ++-- ...nceMemberFuncOverridingAccessor.errors.txt | 4 +- .../instanceSubtypeCheck2.errors.txt | 4 +- .../interfaceDeclaration3.errors.txt | 8 ++-- ...terfaceExtendsClassWithPrivate2.errors.txt | 11 +++-- ...ExtendsObjectIntersectionErrors.errors.txt | 20 ++++---- .../interfaceImplementation7.errors.txt | 4 +- .../mismatchedGenericArguments1.errors.txt | 8 ++-- .../reference/multipleInheritance.errors.txt | 4 +- .../requiredInitializedParameter2.errors.txt | 4 +- .../subtypesOfTypeParameter.errors.txt | 4 +- ...sOfTypeParameterWithConstraints.errors.txt | 40 ++++++++-------- ...OfTypeParameterWithConstraints4.errors.txt | 20 ++++---- ...rameterWithRecursiveConstraints.errors.txt | 48 +++++++++---------- .../subtypingWithObjectMembers.errors.txt | 24 +++++----- 33 files changed, 165 insertions(+), 160 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5e247c1ce2c..fd6a033653a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23005,7 +23005,7 @@ namespace ts { Diagnostics.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2, unescapeLeadingUnderscores(declaredProp.escapedName), typeToString(typeWithThis), - typeToString(getTypeOfSymbol(baseProp)) + typeToString(baseWithThis) ); if (!checkTypeAssignableTo(getTypeOfSymbol(prop), getTypeOfSymbol(baseProp), member.name || member, /*message*/ undefined, rootChain)) { issuedMemberError = true; diff --git a/tests/baselines/reference/abstractPropertyNegative.errors.txt b/tests/baselines/reference/abstractPropertyNegative.errors.txt index 6e4cae81db9..be1c85374fb 100644 --- a/tests/baselines/reference/abstractPropertyNegative.errors.txt +++ b/tests/baselines/reference/abstractPropertyNegative.errors.txt @@ -7,11 +7,11 @@ tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS2515: Non-abstra tests/cases/compiler/abstractPropertyNegative.ts(15,5): error TS1244: Abstract methods can only appear within an abstract class. tests/cases/compiler/abstractPropertyNegative.ts(16,37): error TS1005: '{' expected. tests/cases/compiler/abstractPropertyNegative.ts(19,3): error TS2540: Cannot assign to 'ro' because it is a constant or a read-only property. -tests/cases/compiler/abstractPropertyNegative.ts(25,5): error TS2416: Property 'num' in type 'WrongTypePropertyImpl' is not assignable to the same property in base type 'number'. +tests/cases/compiler/abstractPropertyNegative.ts(25,5): error TS2416: Property 'num' in type 'WrongTypePropertyImpl' is not assignable to the same property in base type 'WrongTypeProperty'. Type 'string' is not assignable to type 'number'. -tests/cases/compiler/abstractPropertyNegative.ts(31,9): error TS2416: Property 'num' in type 'WrongTypeAccessorImpl' is not assignable to the same property in base type 'number'. +tests/cases/compiler/abstractPropertyNegative.ts(31,9): error TS2416: Property 'num' in type 'WrongTypeAccessorImpl' is not assignable to the same property in base type 'WrongTypeAccessor'. Type 'string' is not assignable to type 'number'. -tests/cases/compiler/abstractPropertyNegative.ts(34,5): error TS2416: Property 'num' in type 'WrongTypeAccessorImpl2' is not assignable to the same property in base type 'number'. +tests/cases/compiler/abstractPropertyNegative.ts(34,5): error TS2416: Property 'num' in type 'WrongTypeAccessorImpl2' is not assignable to the same property in base type 'WrongTypeAccessor'. Type 'string' is not assignable to type 'number'. tests/cases/compiler/abstractPropertyNegative.ts(38,18): error TS2676: Accessors must both be abstract or non-abstract. tests/cases/compiler/abstractPropertyNegative.ts(39,9): error TS2676: Accessors must both be abstract or non-abstract. @@ -64,7 +64,7 @@ tests/cases/compiler/abstractPropertyNegative.ts(41,18): error TS2676: Accessors class WrongTypePropertyImpl extends WrongTypeProperty { num = "nope, wrong"; ~~~ -!!! error TS2416: Property 'num' in type 'WrongTypePropertyImpl' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'num' in type 'WrongTypePropertyImpl' is not assignable to the same property in base type 'WrongTypeProperty'. !!! error TS2416: Type 'string' is not assignable to type 'number'. } abstract class WrongTypeAccessor { @@ -73,13 +73,13 @@ tests/cases/compiler/abstractPropertyNegative.ts(41,18): error TS2676: Accessors class WrongTypeAccessorImpl extends WrongTypeAccessor { get num() { return "nope, wrong"; } ~~~ -!!! error TS2416: Property 'num' in type 'WrongTypeAccessorImpl' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'num' in type 'WrongTypeAccessorImpl' is not assignable to the same property in base type 'WrongTypeAccessor'. !!! error TS2416: Type 'string' is not assignable to type 'number'. } class WrongTypeAccessorImpl2 extends WrongTypeAccessor { num = "nope, wrong"; ~~~ -!!! error TS2416: Property 'num' in type 'WrongTypeAccessorImpl2' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'num' in type 'WrongTypeAccessorImpl2' is not assignable to the same property in base type 'WrongTypeAccessor'. !!! error TS2416: Type 'string' is not assignable to type 'number'. } diff --git a/tests/baselines/reference/apparentTypeSubtyping.errors.txt b/tests/baselines/reference/apparentTypeSubtyping.errors.txt index cde65657778..ca2f0765d62 100644 --- a/tests/baselines/reference/apparentTypeSubtyping.errors.txt +++ b/tests/baselines/reference/apparentTypeSubtyping.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts(10,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'string'. +tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts(10,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. Type 'String' is not assignable to type 'string'. 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. @@ -15,7 +15,7 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtypi class Derived extends Base { // error x: String; ~ -!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'String' is not assignable to type 'string'. !!! error TS2416: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. } diff --git a/tests/baselines/reference/apparentTypeSupertype.errors.txt b/tests/baselines/reference/apparentTypeSupertype.errors.txt index 066d0be2710..a4a8ccc0a8b 100644 --- a/tests/baselines/reference/apparentTypeSupertype.errors.txt +++ b/tests/baselines/reference/apparentTypeSupertype.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts(10,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'string'. +tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts(10,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. Type 'U' is not assignable to type 'string'. Type 'String' is not assignable to type 'string'. 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. @@ -16,7 +16,7 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSuperty class Derived extends Base { // error x: U; ~ -!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'U' is not assignable to type 'string'. !!! error TS2416: Type 'String' is not assignable to type 'string'. !!! error TS2416: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. diff --git a/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt b/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt index 585c929d9a4..031fe183754 100644 --- a/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt +++ b/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/baseClassImprovedMismatchErrors.ts(8,5): error TS2416: Property 'n' in type 'Derived' is not assignable to the same property in base type 'string | Base'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(8,5): error TS2416: Property 'n' in type 'Derived' is not assignable to the same property in base type 'Base'. Type 'string | Derived' is not assignable to type 'string | Base'. Type 'Derived' is not assignable to type 'string | Base'. Type 'Derived' is not assignable to type 'Base'. @@ -6,11 +6,11 @@ tests/cases/compiler/baseClassImprovedMismatchErrors.ts(8,5): error TS2416: Prop Type 'string | Derived' is not assignable to type 'string | Base'. Type 'Derived' is not assignable to type 'string | Base'. Type 'Derived' is not assignable to type 'Base'. -tests/cases/compiler/baseClassImprovedMismatchErrors.ts(9,5): error TS2416: Property 'fn' in type 'Derived' is not assignable to the same property in base type '() => number'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(9,5): error TS2416: Property 'fn' in type 'Derived' is not assignable to the same property in base type 'Base'. Type '() => string | number' is not assignable to type '() => number'. Type 'string | number' is not assignable to type 'number'. Type 'string' is not assignable to type 'number'. -tests/cases/compiler/baseClassImprovedMismatchErrors.ts(14,5): error TS2416: Property 'n' in type 'DerivedInterface' is not assignable to the same property in base type 'string | Base'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(14,5): error TS2416: Property 'n' in type 'DerivedInterface' is not assignable to the same property in base type 'Base'. Type 'string | DerivedInterface' is not assignable to type 'string | Base'. Type 'DerivedInterface' is not assignable to type 'string | Base'. Type 'DerivedInterface' is not assignable to type 'Base'. @@ -18,7 +18,7 @@ tests/cases/compiler/baseClassImprovedMismatchErrors.ts(14,5): error TS2416: Pro Type 'string | DerivedInterface' is not assignable to type 'string | Base'. Type 'DerivedInterface' is not assignable to type 'string | Base'. Type 'DerivedInterface' is not assignable to type 'Base'. -tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Property 'fn' in type 'DerivedInterface' is not assignable to the same property in base type '() => number'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Property 'fn' in type 'DerivedInterface' is not assignable to the same property in base type 'Base'. Type '() => string | number' is not assignable to type '() => number'. Type 'string | number' is not assignable to type 'number'. Type 'string' is not assignable to type 'number'. @@ -34,7 +34,7 @@ tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Pro class Derived extends Base { n: Derived | string; ~ -!!! error TS2416: Property 'n' in type 'Derived' is not assignable to the same property in base type 'string | Base'. +!!! error TS2416: Property 'n' in type 'Derived' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'string | Derived' is not assignable to type 'string | Base'. !!! error TS2416: Type 'Derived' is not assignable to type 'string | Base'. !!! error TS2416: Type 'Derived' is not assignable to type 'Base'. @@ -44,7 +44,7 @@ tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Pro !!! error TS2416: Type 'Derived' is not assignable to type 'Base'. fn() { ~~ -!!! error TS2416: Property 'fn' in type 'Derived' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Property 'fn' in type 'Derived' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type '() => string | number' is not assignable to type '() => number'. !!! error TS2416: Type 'string | number' is not assignable to type 'number'. !!! error TS2416: Type 'string' is not assignable to type 'number'. @@ -54,7 +54,7 @@ tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Pro class DerivedInterface implements Base { n: DerivedInterface | string; ~ -!!! error TS2416: Property 'n' in type 'DerivedInterface' is not assignable to the same property in base type 'string | Base'. +!!! error TS2416: Property 'n' in type 'DerivedInterface' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'string | DerivedInterface' is not assignable to type 'string | Base'. !!! error TS2416: Type 'DerivedInterface' is not assignable to type 'string | Base'. !!! error TS2416: Type 'DerivedInterface' is not assignable to type 'Base'. @@ -64,7 +64,7 @@ tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Pro !!! error TS2416: Type 'DerivedInterface' is not assignable to type 'Base'. fn() { ~~ -!!! error TS2416: Property 'fn' in type 'DerivedInterface' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Property 'fn' in type 'DerivedInterface' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type '() => string | number' is not assignable to type '() => number'. !!! error TS2416: Type 'string | number' is not assignable to type 'number'. !!! error TS2416: Type 'string' is not assignable to type 'number'. diff --git a/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt b/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt index 3070a041748..8b84602b807 100644 --- a/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt +++ b/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classIsSubtypeOfBaseType.ts(12,5): error TS2416: Property 'foo' in type 'Derived2' is not assignable to the same property in base type '{ bar: string; }'. +tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classIsSubtypeOfBaseType.ts(12,5): error TS2416: Property 'foo' in type 'Derived2' is not assignable to the same property in base type 'Base<{ bar: string; }>'. Type '{ bar?: string; }' is not assignable to type '{ bar: string; }'. Property 'bar' is optional in type '{ bar?: string; }' but required in type '{ bar: string; }'. @@ -17,7 +17,7 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla class Derived2 extends Base<{ bar: string; }> { foo: { ~~~ -!!! error TS2416: Property 'foo' in type 'Derived2' is not assignable to the same property in base type '{ bar: string; }'. +!!! error TS2416: Property 'foo' in type 'Derived2' is not assignable to the same property in base type 'Base<{ bar: string; }>'. !!! error TS2416: Type '{ bar?: string; }' is not assignable to type '{ bar: string; }'. !!! error TS2416: Property 'bar' is optional in type '{ bar?: string; }' but required in type '{ bar: string; }'. bar?: string; // error diff --git a/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt b/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt index ca154600c9f..fa8c7f2bc7a 100644 --- a/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt +++ b/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(2,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(5,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(11,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'number'. +tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(11,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. Type '() => number' is not assignable to type 'number'. tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(11,5): error TS2426: Class 'Base' defines instance member accessor 'x', but extended class 'Derived' defines it as instance member function. @@ -22,7 +22,7 @@ tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFun class Derived extends Base { x() { ~ -!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type '() => number' is not assignable to type 'number'. ~ !!! error TS2426: Class 'Base' defines instance member accessor 'x', but extended class 'Derived' defines it as instance member function. diff --git a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt index 9cc122c7588..46a816af349 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt @@ -35,7 +35,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(46,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(47,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(56,8): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(57,5): error TS2416: Property 'd4' in type 'C4' is not assignable to the same property in base type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(57,5): error TS2416: Property 'd4' in type 'C4' is not assignable to the same property in base type 'F2'. Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. Types of parameters '__0' and '__0' are incompatible. Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'. @@ -159,7 +159,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( !!! error TS2463: A binding pattern parameter cannot be optional in an implementation signature. d4({x, y, c}) { } ~~ -!!! error TS2416: Property 'd4' in type 'C4' is not assignable to the same property in base type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. +!!! error TS2416: Property 'd4' in type 'C4' is not assignable to the same property in base type 'F2'. !!! error TS2416: Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. !!! error TS2416: Types of parameters '__0' and '__0' are incompatible. !!! error TS2416: Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'. diff --git a/tests/baselines/reference/elaboratedErrors.errors.txt b/tests/baselines/reference/elaboratedErrors.errors.txt index 9a05bdc1d1b..a9060282404 100644 --- a/tests/baselines/reference/elaboratedErrors.errors.txt +++ b/tests/baselines/reference/elaboratedErrors.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/elaboratedErrors.ts(11,3): error TS2416: Property 'read' in type 'WorkerFS' is not assignable to the same property in base type 'number'. +tests/cases/compiler/elaboratedErrors.ts(11,3): error TS2416: Property 'read' in type 'WorkerFS' is not assignable to the same property in base type 'FileSystem'. Type 'string' is not assignable to type 'number'. tests/cases/compiler/elaboratedErrors.ts(20,1): error TS2322: Type 'Beta' is not assignable to type 'Alpha'. Property 'x' is missing in type 'Beta'. @@ -21,7 +21,7 @@ tests/cases/compiler/elaboratedErrors.ts(25,1): error TS2322: Type 'Alpha' is no class WorkerFS implements FileSystem { read: string; ~~~~ -!!! error TS2416: Property 'read' in type 'WorkerFS' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'read' in type 'WorkerFS' is not assignable to the same property in base type 'FileSystem'. !!! error TS2416: Type 'string' is not assignable to type 'number'. } diff --git a/tests/baselines/reference/genericImplements.errors.txt b/tests/baselines/reference/genericImplements.errors.txt index 04ae8d0f0cb..fff51884f10 100644 --- a/tests/baselines/reference/genericImplements.errors.txt +++ b/tests/baselines/reference/genericImplements.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/genericImplements.ts(9,5): error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type '() => T'. +tests/cases/compiler/genericImplements.ts(9,5): error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type 'I'. Type '() => T' is not assignable to type '() => T'. Type 'B' is not assignable to type 'T'. @@ -14,7 +14,7 @@ tests/cases/compiler/genericImplements.ts(9,5): error TS2416: Property 'f' in ty class X implements I { f(): T { return undefined; } ~ -!!! error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type '() => T'. +!!! error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type 'I'. !!! error TS2416: Type '() => T' is not assignable to type '() => T'. !!! error TS2416: Type 'B' is not assignable to type 'T'. } // { f: () => { b; } } diff --git a/tests/baselines/reference/genericSpecializations1.errors.txt b/tests/baselines/reference/genericSpecializations1.errors.txt index b56cc0d7865..83015cef259 100644 --- a/tests/baselines/reference/genericSpecializations1.errors.txt +++ b/tests/baselines/reference/genericSpecializations1.errors.txt @@ -1,8 +1,8 @@ -tests/cases/compiler/genericSpecializations1.ts(6,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/genericSpecializations1.ts(6,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => string' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. -tests/cases/compiler/genericSpecializations1.ts(10,5): error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/genericSpecializations1.ts(10,5): error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => string' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. @@ -16,7 +16,7 @@ tests/cases/compiler/genericSpecializations1.ts(10,5): error TS2416: Property 'f class IntFooBad implements IFoo { foo(x: string): string { return null; } ~~~ -!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. @@ -25,7 +25,7 @@ tests/cases/compiler/genericSpecializations1.ts(10,5): error TS2416: Property 'f class StringFoo2 implements IFoo { foo(x: string): string { return null; } ~~~ -!!! error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. diff --git a/tests/baselines/reference/genericSpecializations2.errors.txt b/tests/baselines/reference/genericSpecializations2.errors.txt index dc59c200d4f..1088d7b8956 100644 --- a/tests/baselines/reference/genericSpecializations2.errors.txt +++ b/tests/baselines/reference/genericSpecializations2.errors.txt @@ -1,9 +1,9 @@ -tests/cases/compiler/genericSpecializations2.ts(8,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/genericSpecializations2.ts(8,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => string' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. tests/cases/compiler/genericSpecializations2.ts(8,9): error TS2368: Type parameter name cannot be 'string'. -tests/cases/compiler/genericSpecializations2.ts(12,5): error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/genericSpecializations2.ts(12,5): error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => string' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. @@ -20,7 +20,7 @@ tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parame class IntFooBad implements IFoo { foo(x: string): string { return null; } ~~~ -!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. @@ -31,7 +31,7 @@ tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parame class StringFoo2 implements IFoo { foo(x: string): string { return null; } ~~~ -!!! error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. diff --git a/tests/baselines/reference/genericSpecializations3.errors.txt b/tests/baselines/reference/genericSpecializations3.errors.txt index f99872539a9..eaa7f094bdb 100644 --- a/tests/baselines/reference/genericSpecializations3.errors.txt +++ b/tests/baselines/reference/genericSpecializations3.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/genericSpecializations3.ts(9,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: number) => number'. +tests/cases/compiler/genericSpecializations3.ts(9,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => string' is not assignable to type '(x: number) => number'. Types of parameters 'x' and 'x' are incompatible. Type 'number' is not assignable to type 'string'. @@ -25,7 +25,7 @@ tests/cases/compiler/genericSpecializations3.ts(29,1): error TS2322: Type 'IntFo class IntFooBad implements IFoo { // error foo(x: string): string { return null; } ~~~ -!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type '(x: number) => number'. +!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: number) => number'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'number' is not assignable to type 'string'. diff --git a/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt b/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt index d91eb2b864e..a7a96c2abd8 100644 --- a/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt +++ b/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(5,2): error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type '(a: { a: number; }) => void'. +tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(5,2): error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type 'I'. Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. Types of parameters 'a' and 'a' are incompatible. Type '{ a: number; }' is not assignable to type 'T'. @@ -18,7 +18,7 @@ tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(8,5): error TS2322 class X implements I { f(a: T): void { } ~ -!!! error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type '(a: { a: number; }) => void'. +!!! error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type 'I'. !!! error TS2416: Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. !!! error TS2416: Types of parameters 'a' and 'a' are incompatible. !!! error TS2416: Type '{ a: number; }' is not assignable to type 'T'. diff --git a/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt b/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt index 994174eb84c..576013f43c5 100644 --- a/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt +++ b/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt @@ -1,8 +1,8 @@ -tests/cases/compiler/implementGenericWithMismatchedTypes.ts(8,5): error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/implementGenericWithMismatchedTypes.ts(8,5): error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => number' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. -tests/cases/compiler/implementGenericWithMismatchedTypes.ts(17,5): error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/implementGenericWithMismatchedTypes.ts(17,5): error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type 'IFoo2'. Type '(x: Tstring) => number' is not assignable to type '(x: T) => T'. Type 'number' is not assignable to type 'T'. @@ -17,7 +17,7 @@ tests/cases/compiler/implementGenericWithMismatchedTypes.ts(17,5): error TS2416: class C implements IFoo { // error foo(x: string): number { ~~~ -!!! error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => number' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. @@ -31,7 +31,7 @@ tests/cases/compiler/implementGenericWithMismatchedTypes.ts(17,5): error TS2416: class C2 implements IFoo2 { // error foo(x: Tstring): number { ~~~ -!!! error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type 'IFoo2'. !!! error TS2416: Type '(x: Tstring) => number' is not assignable to type '(x: T) => T'. !!! error TS2416: Type 'number' is not assignable to type 'T'. return null; diff --git a/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt b/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt index 7b717545e77..f56da547126 100644 --- a/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt +++ b/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/implementsIncorrectlyNoAssertion.ts(9,5): error TS2416: Property 'x' in type 'Baz' is not assignable to the same property in base type 'string'. +tests/cases/compiler/implementsIncorrectlyNoAssertion.ts(9,5): error TS2416: Property 'x' in type 'Baz' is not assignable to the same property in base type 'Foo & Bar'. Type 'number' is not assignable to type 'string'. @@ -13,7 +13,7 @@ tests/cases/compiler/implementsIncorrectlyNoAssertion.ts(9,5): error TS2416: Pro class Baz implements Wrapper { x: number; ~ -!!! error TS2416: Property 'x' in type 'Baz' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'x' in type 'Baz' is not assignable to the same property in base type 'Foo & Bar'. !!! error TS2416: Type 'number' is not assignable to type 'string'. y: string; } diff --git a/tests/baselines/reference/incompatibleTypes.errors.txt b/tests/baselines/reference/incompatibleTypes.errors.txt index 1feed1a3fb6..1951e363eec 100644 --- a/tests/baselines/reference/incompatibleTypes.errors.txt +++ b/tests/baselines/reference/incompatibleTypes.errors.txt @@ -1,13 +1,13 @@ -tests/cases/compiler/incompatibleTypes.ts(6,12): error TS2416: Property 'p1' in type 'C1' is not assignable to the same property in base type '() => number'. +tests/cases/compiler/incompatibleTypes.ts(6,12): error TS2416: Property 'p1' in type 'C1' is not assignable to the same property in base type 'IFoo1'. Type '() => string' is not assignable to type '() => number'. Type 'string' is not assignable to type 'number'. -tests/cases/compiler/incompatibleTypes.ts(16,12): error TS2416: Property 'p1' in type 'C2' is not assignable to the same property in base type '(s: string) => number'. +tests/cases/compiler/incompatibleTypes.ts(16,12): error TS2416: Property 'p1' in type 'C2' is not assignable to the same property in base type 'IFoo2'. Type '(n: number) => number' is not assignable to type '(s: string) => number'. Types of parameters 'n' and 's' are incompatible. Type 'string' is not assignable to type 'number'. -tests/cases/compiler/incompatibleTypes.ts(26,12): error TS2416: Property 'p1' in type 'C3' is not assignable to the same property in base type 'string'. +tests/cases/compiler/incompatibleTypes.ts(26,12): error TS2416: Property 'p1' in type 'C3' is not assignable to the same property in base type 'IFoo3'. Type 'number' is not assignable to type 'string'. -tests/cases/compiler/incompatibleTypes.ts(34,12): error TS2416: Property 'p1' in type 'C4' is not assignable to the same property in base type '{ a: { a: string; }; b: string; }'. +tests/cases/compiler/incompatibleTypes.ts(34,12): error TS2416: Property 'p1' in type 'C4' is not assignable to the same property in base type 'IFoo4'. Type '{ c: { b: string; }; d: string; }' is not assignable to type '{ a: { a: string; }; b: string; }'. Property 'a' is missing in type '{ c: { b: string; }; d: string; }'. tests/cases/compiler/incompatibleTypes.ts(42,5): error TS2345: Argument of type 'C1' is not assignable to parameter of type 'IFoo2'. @@ -30,7 +30,7 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => class C1 implements IFoo1 { // incompatible on the return type public p1() { ~~ -!!! error TS2416: Property 'p1' in type 'C1' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Property 'p1' in type 'C1' is not assignable to the same property in base type 'IFoo1'. !!! error TS2416: Type '() => string' is not assignable to type '() => number'. !!! error TS2416: Type 'string' is not assignable to type 'number'. return "s"; @@ -44,7 +44,7 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => class C2 implements IFoo2 { // incompatible on the param type public p1(n:number) { ~~ -!!! error TS2416: Property 'p1' in type 'C2' is not assignable to the same property in base type '(s: string) => number'. +!!! error TS2416: Property 'p1' in type 'C2' is not assignable to the same property in base type 'IFoo2'. !!! error TS2416: Type '(n: number) => number' is not assignable to type '(s: string) => number'. !!! error TS2416: Types of parameters 'n' and 's' are incompatible. !!! error TS2416: Type 'string' is not assignable to type 'number'. @@ -59,7 +59,7 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => class C3 implements IFoo3 { // incompatible on the property type public p1: number; ~~ -!!! error TS2416: Property 'p1' in type 'C3' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'p1' in type 'C3' is not assignable to the same property in base type 'IFoo3'. !!! error TS2416: Type 'number' is not assignable to type 'string'. } @@ -70,7 +70,7 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => class C4 implements IFoo4 { // incompatible on the property type public p1: { c: { b: string; }; d: string; }; ~~ -!!! error TS2416: Property 'p1' in type 'C4' is not assignable to the same property in base type '{ a: { a: string; }; b: string; }'. +!!! error TS2416: Property 'p1' in type 'C4' is not assignable to the same property in base type 'IFoo4'. !!! error TS2416: Type '{ c: { b: string; }; d: string; }' is not assignable to type '{ a: { a: string; }; b: string; }'. !!! error TS2416: Property 'a' is missing in type '{ c: { b: string; }; d: string; }'. } diff --git a/tests/baselines/reference/inheritance.errors.txt b/tests/baselines/reference/inheritance.errors.txt index 429eb2674df..b476f1399b4 100644 --- a/tests/baselines/reference/inheritance.errors.txt +++ b/tests/baselines/reference/inheritance.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/inheritance.ts(31,12): error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. -tests/cases/compiler/inheritance.ts(32,12): error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type '() => number'. +tests/cases/compiler/inheritance.ts(32,12): error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type 'Good'. Type '(n: number) => number' is not assignable to type '() => number'. @@ -39,7 +39,7 @@ tests/cases/compiler/inheritance.ts(32,12): error TS2416: Property 'g' in type ' !!! error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. public g(n: number) { return 0; } ~ -!!! error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type 'Good'. !!! error TS2416: Type '(n: number) => number' is not assignable to type '() => number'. } \ No newline at end of file diff --git a/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt b/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt index a0c20277333..66d955324c8 100644 --- a/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt +++ b/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt @@ -1,9 +1,9 @@ tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type '() => string'. +tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. Type 'string' is not assignable to type '() => string'. tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS2423: Class 'a' defines instance member function 'x', but extended class 'b' defines it as instance member accessor. tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type '() => string'. +tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. Type 'string' is not assignable to type '() => string'. @@ -19,7 +19,7 @@ tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error T ~ !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. ~ -!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type '() => string'. +!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. !!! error TS2416: Type 'string' is not assignable to type '() => string'. ~ !!! error TS2423: Class 'a' defines instance member function 'x', but extended class 'b' defines it as instance member accessor. @@ -29,7 +29,7 @@ tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error T ~ !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. ~ -!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type '() => string'. +!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. !!! error TS2416: Type 'string' is not assignable to type '() => string'. } diff --git a/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt b/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt index b31d5d12ec6..38a390d5063 100644 --- a/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt +++ b/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(2,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(5,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'string'. +tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. Type '() => string' is not assignable to type 'string'. tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2426: Class 'a' defines instance member accessor 'x', but extended class 'b' defines it as instance member function. @@ -22,7 +22,7 @@ tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2 class b extends a { x() { ~ -!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. !!! error TS2416: Type '() => string' is not assignable to type 'string'. ~ !!! error TS2426: Class 'a' defines instance member accessor 'x', but extended class 'b' defines it as instance member function. diff --git a/tests/baselines/reference/instanceSubtypeCheck2.errors.txt b/tests/baselines/reference/instanceSubtypeCheck2.errors.txt index b1d0f33af08..84b454d7ea0 100644 --- a/tests/baselines/reference/instanceSubtypeCheck2.errors.txt +++ b/tests/baselines/reference/instanceSubtypeCheck2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/instanceSubtypeCheck2.ts(6,5): error TS2416: Property 'x' in type 'C2' is not assignable to the same property in base type 'C2'. +tests/cases/compiler/instanceSubtypeCheck2.ts(6,5): error TS2416: Property 'x' in type 'C2' is not assignable to the same property in base type 'C1'. Type 'string' is not assignable to type 'C2'. @@ -10,6 +10,6 @@ tests/cases/compiler/instanceSubtypeCheck2.ts(6,5): error TS2416: Property 'x' i class C2 extends C1 { x: string ~ -!!! error TS2416: Property 'x' in type 'C2' is not assignable to the same property in base type 'C2'. +!!! error TS2416: Property 'x' in type 'C2' is not assignable to the same property in base type 'C1'. !!! error TS2416: Type 'string' is not assignable to type 'C2'. } \ No newline at end of file diff --git a/tests/baselines/reference/interfaceDeclaration3.errors.txt b/tests/baselines/reference/interfaceDeclaration3.errors.txt index 2c29b6a86f2..2ea419aaa52 100644 --- a/tests/baselines/reference/interfaceDeclaration3.errors.txt +++ b/tests/baselines/reference/interfaceDeclaration3.errors.txt @@ -1,6 +1,6 @@ -tests/cases/compiler/interfaceDeclaration3.ts(7,16): error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'string'. +tests/cases/compiler/interfaceDeclaration3.ts(7,16): error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'I1'. Type 'number' is not assignable to type 'string'. -tests/cases/compiler/interfaceDeclaration3.ts(32,16): error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'string'. +tests/cases/compiler/interfaceDeclaration3.ts(32,16): error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'I1'. Type 'number' is not assignable to type 'string'. tests/cases/compiler/interfaceDeclaration3.ts(54,11): error TS2430: Interface 'I2' incorrectly extends interface 'I1'. Types of property 'item' are incompatible. @@ -16,7 +16,7 @@ tests/cases/compiler/interfaceDeclaration3.ts(54,11): error TS2430: Interface 'I class C1 implements I1 { public item:number; ~~~~ -!!! error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'I1'. !!! error TS2416: Type 'number' is not assignable to type 'string'. } class C2 implements I1 { @@ -44,7 +44,7 @@ tests/cases/compiler/interfaceDeclaration3.ts(54,11): error TS2430: Interface 'I class C1 implements I1 { public item:number; ~~~~ -!!! error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'I1'. !!! error TS2416: Type 'number' is not assignable to type 'string'. } class C2 implements I1 { diff --git a/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt b/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt index cac4ba6def7..d6af9ce44dd 100644 --- a/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt +++ b/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt @@ -2,11 +2,13 @@ tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(10,7): error TS2415: C Types have separate declarations of a private property 'x'. tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(10,7): error TS2420: Class 'D' incorrectly implements interface 'I'. Types have separate declarations of a private property 'x'. -tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(20,13): error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'number'. +tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(20,13): error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'C'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(20,13): error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'I'. Type 'string' is not assignable to type 'number'. -==== tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts (3 errors) ==== +==== tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts (4 errors) ==== class C { public foo(x: any) { return x; } private x = 1; @@ -34,7 +36,10 @@ tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(20,13): error TS2416: public foo(x: any) { return x; } private x = ""; ~ -!!! error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'C'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. + ~ +!!! error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'I'. !!! error TS2416: Type 'string' is not assignable to type 'number'. other(x: any) { return x; } bar() { } diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt index 6a53fc01c0d..87faadeb4a6 100644 --- a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt +++ b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt @@ -14,15 +14,15 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectI tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(11,11): error TS2430: Interface 'I5' incorrectly extends interface 'T5'. Types of property 'c' are incompatible. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(16,38): error TS2416: Property 'a' in type 'C1' is not assignable to the same property in base type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(16,38): error TS2416: Property 'a' in type 'C1' is not assignable to the same property in base type 'T1'. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(17,38): error TS2416: Property 'b' in type 'C2' is not assignable to the same property in base type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(17,38): error TS2416: Property 'b' in type 'C2' is not assignable to the same property in base type 'T2'. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(18,38): error TS2416: Property 'length' in type 'C3' is not assignable to the same property in base type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(18,38): error TS2416: Property 'length' in type 'C3' is not assignable to the same property in base type 'number[]'. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(19,38): error TS2416: Property '0' in type 'C4' is not assignable to the same property in base type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(19,38): error TS2416: Property '0' in type 'C4' is not assignable to the same property in base type '[string, number]'. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(20,38): error TS2416: Property 'c' in type 'C5' is not assignable to the same property in base type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(20,38): error TS2416: Property 'c' in type 'C5' is not assignable to the same property in base type 'T5'. Type 'number' is not assignable to type 'string'. tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(30,11): error TS2430: Interface 'I10' incorrectly extends interface 'typeof CX'. Types of property 'a' are incompatible. @@ -94,23 +94,23 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectI class C1 extends Constructor() { a: string } ~ -!!! error TS2416: Property 'a' in type 'C1' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'a' in type 'C1' is not assignable to the same property in base type 'T1'. !!! error TS2416: Type 'string' is not assignable to type 'number'. class C2 extends Constructor() { b: string } ~ -!!! error TS2416: Property 'b' in type 'C2' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'b' in type 'C2' is not assignable to the same property in base type 'T2'. !!! error TS2416: Type 'string' is not assignable to type 'number'. class C3 extends Constructor() { length: string } ~~~~~~ -!!! error TS2416: Property 'length' in type 'C3' is not assignable to the same property in base type 'number'. +!!! error TS2416: Property 'length' in type 'C3' is not assignable to the same property in base type 'number[]'. !!! error TS2416: Type 'string' is not assignable to type 'number'. class C4 extends Constructor() { 0: number } ~ -!!! error TS2416: Property '0' in type 'C4' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property '0' in type 'C4' is not assignable to the same property in base type '[string, number]'. !!! error TS2416: Type 'number' is not assignable to type 'string'. class C5 extends Constructor() { c: number } ~ -!!! error TS2416: Property 'c' in type 'C5' is not assignable to the same property in base type 'string'. +!!! error TS2416: Property 'c' in type 'C5' is not assignable to the same property in base type 'T5'. !!! error TS2416: Type 'number' is not assignable to type 'string'. declare class CX { static a: string } diff --git a/tests/baselines/reference/interfaceImplementation7.errors.txt b/tests/baselines/reference/interfaceImplementation7.errors.txt index de9bbdae835..a275090b199 100644 --- a/tests/baselines/reference/interfaceImplementation7.errors.txt +++ b/tests/baselines/reference/interfaceImplementation7.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/interfaceImplementation7.ts(4,11): error TS2320: Interface 'i3' cannot simultaneously extend types 'i1' and 'i2'. Named property 'name' of types 'i1' and 'i2' are not identical. -tests/cases/compiler/interfaceImplementation7.ts(8,12): error TS2416: Property 'name' in type 'C1' is not assignable to the same property in base type '() => { s: string; n: number; }'. +tests/cases/compiler/interfaceImplementation7.ts(8,12): error TS2416: Property 'name' in type 'C1' is not assignable to the same property in base type 'i4'. Type '() => string' is not assignable to type '() => { s: string; n: number; }'. Type 'string' is not assignable to type '{ s: string; n: number; }'. @@ -18,7 +18,7 @@ tests/cases/compiler/interfaceImplementation7.ts(8,12): error TS2416: Property ' class C1 implements i4 { public name(): string { return ""; } ~~~~ -!!! error TS2416: Property 'name' in type 'C1' is not assignable to the same property in base type '() => { s: string; n: number; }'. +!!! error TS2416: Property 'name' in type 'C1' is not assignable to the same property in base type 'i4'. !!! error TS2416: Type '() => string' is not assignable to type '() => { s: string; n: number; }'. !!! error TS2416: Type 'string' is not assignable to type '{ s: string; n: number; }'. } diff --git a/tests/baselines/reference/mismatchedGenericArguments1.errors.txt b/tests/baselines/reference/mismatchedGenericArguments1.errors.txt index 4b2d13986ce..8c95aa78fb7 100644 --- a/tests/baselines/reference/mismatchedGenericArguments1.errors.txt +++ b/tests/baselines/reference/mismatchedGenericArguments1.errors.txt @@ -1,8 +1,8 @@ -tests/cases/compiler/mismatchedGenericArguments1.ts(5,4): error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/mismatchedGenericArguments1.ts(5,4): error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => number' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. -tests/cases/compiler/mismatchedGenericArguments1.ts(11,4): error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type '(x: T) => T'. +tests/cases/compiler/mismatchedGenericArguments1.ts(11,4): error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type 'IFoo'. Type '(x: string) => number' is not assignable to type '(x: T) => T'. Types of parameters 'x' and 'x' are incompatible. Type 'T' is not assignable to type 'string'. @@ -15,7 +15,7 @@ tests/cases/compiler/mismatchedGenericArguments1.ts(11,4): error TS2416: Propert class C implements IFoo { foo(x: string): number { ~~~ -!!! error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => number' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. @@ -26,7 +26,7 @@ tests/cases/compiler/mismatchedGenericArguments1.ts(11,4): error TS2416: Propert class C2 implements IFoo { foo(x: string): number { ~~~ -!!! error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type '(x: T) => T'. +!!! error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type 'IFoo'. !!! error TS2416: Type '(x: string) => number' is not assignable to type '(x: T) => T'. !!! error TS2416: Types of parameters 'x' and 'x' are incompatible. !!! error TS2416: Type 'T' is not assignable to type 'string'. diff --git a/tests/baselines/reference/multipleInheritance.errors.txt b/tests/baselines/reference/multipleInheritance.errors.txt index 72e44dc999c..c4a440d9a0e 100644 --- a/tests/baselines/reference/multipleInheritance.errors.txt +++ b/tests/baselines/reference/multipleInheritance.errors.txt @@ -1,7 +1,7 @@ tests/cases/compiler/multipleInheritance.ts(9,21): error TS1174: Classes can only extend a single class. tests/cases/compiler/multipleInheritance.ts(18,21): error TS1174: Classes can only extend a single class. tests/cases/compiler/multipleInheritance.ts(35,12): error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. -tests/cases/compiler/multipleInheritance.ts(36,12): error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type '() => number'. +tests/cases/compiler/multipleInheritance.ts(36,12): error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type 'Good'. Type '(n: number) => number' is not assignable to type '() => number'. @@ -49,7 +49,7 @@ tests/cases/compiler/multipleInheritance.ts(36,12): error TS2416: Property 'g' i !!! error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. public g(n:number) { return 0; } ~ -!!! error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type '() => number'. +!!! error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type 'Good'. !!! error TS2416: Type '(n: number) => number' is not assignable to type '() => number'. } \ No newline at end of file diff --git a/tests/baselines/reference/requiredInitializedParameter2.errors.txt b/tests/baselines/reference/requiredInitializedParameter2.errors.txt index cdb659f251a..278d5c0f359 100644 --- a/tests/baselines/reference/requiredInitializedParameter2.errors.txt +++ b/tests/baselines/reference/requiredInitializedParameter2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/requiredInitializedParameter2.ts(6,5): error TS2416: Property 'method' in type 'C1' is not assignable to the same property in base type '() => any'. +tests/cases/compiler/requiredInitializedParameter2.ts(6,5): error TS2416: Property 'method' in type 'C1' is not assignable to the same property in base type 'I1'. Type '(a: number, b: any) => void' is not assignable to type '() => any'. @@ -10,6 +10,6 @@ tests/cases/compiler/requiredInitializedParameter2.ts(6,5): error TS2416: Proper class C1 implements I1 { method(a = 0, b) { } ~~~~~~ -!!! error TS2416: Property 'method' in type 'C1' is not assignable to the same property in base type '() => any'. +!!! error TS2416: Property 'method' in type 'C1' is not assignable to the same property in base type 'I1'. !!! error TS2416: Type '(a: number, b: any) => void' is not assignable to type '() => any'. } \ No newline at end of file diff --git a/tests/baselines/reference/subtypesOfTypeParameter.errors.txt b/tests/baselines/reference/subtypesOfTypeParameter.errors.txt index f0bed548c97..8983c26e153 100644 --- a/tests/baselines/reference/subtypesOfTypeParameter.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameter.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameter.ts(8,5): error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameter.ts(8,5): error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'C3'. Type 'U' is not assignable to type 'T'. @@ -12,7 +12,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf class D1 extends C3 { foo: U; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'U' is not assignable to type 'T'. } diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt index 7019967d204..cff11049787 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt @@ -1,36 +1,36 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(19,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(19,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'C3'. Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(19,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'C3'. Type 'U' is not assignable to type 'T'. Type 'V' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(67,5): error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(67,5): error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'C3'. Type 'V' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(67,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(72,5): error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(72,5): error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'C3'. Type 'V' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(72,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'C3'. Type 'U' is not assignable to type 'T'. Type 'V' is not assignable to type 'T'. Type 'Date' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'C3'. Type 'V' is not assignable to type 'T'. Type 'Date' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'C3'. Type 'V' is not assignable to type 'U'. Type 'Date' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'C3'. Type 'Date' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(161,5): error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(161,5): error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'C3'. Type 'Date' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(161,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(166,5): error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(166,5): error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'C3'. Type 'Date' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(166,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'V'. @@ -56,7 +56,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'U' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. @@ -92,7 +92,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'U' is not assignable to type 'T'. !!! error TS2416: Type 'V' is not assignable to type 'T'. ~~~~~~~ @@ -115,7 +115,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'V' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. @@ -125,7 +125,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'V' is not assignable to type 'U'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. @@ -170,7 +170,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'U' is not assignable to type 'T'. !!! error TS2416: Type 'V' is not assignable to type 'T'. !!! error TS2416: Type 'Date' is not assignable to type 'T'. @@ -199,7 +199,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'V' is not assignable to type 'T'. !!! error TS2416: Type 'Date' is not assignable to type 'T'. ~~~~~~~ @@ -210,7 +210,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'V' is not assignable to type 'U'. !!! error TS2416: Type 'Date' is not assignable to type 'U'. ~~~~~~~ @@ -233,7 +233,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: Date; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'Date' is not assignable to type 'T'. ~~~~~~~~~~ !!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'T'. @@ -243,7 +243,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: Date; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'Date' is not assignable to type 'U'. ~~~~~~~~~~ !!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'U'. @@ -253,7 +253,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: Date; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'V'. +!!! error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'Date' is not assignable to type 'V'. ~~~~~~~~~~ !!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'V'. diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt index 5b1cd0dffa3..ad85188fb4d 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt @@ -1,18 +1,18 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'B1'. Type 'V' is not assignable to type 'Foo'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'Foo'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'B1'. Type 'U' is not assignable to type 'T'. Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(62,5): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(62,5): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'B1'. Type 'V' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(62,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'B1'. Type 'T' is not assignable to type 'U'. Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(77,5): error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(77,5): error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'B1'. Type 'V' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(77,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. @@ -66,7 +66,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: Foo; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'V' is not assignable to type 'Foo'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'Foo'. @@ -81,7 +81,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'U' is not assignable to type 'T'. !!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~~ @@ -92,7 +92,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'V' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. @@ -102,7 +102,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: T; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'T' is not assignable to type 'U'. !!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~~ @@ -118,7 +118,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V; // error ~~~ -!!! error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'V' is not assignable to type 'U'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt index 35c086e52a2..c5adf758728 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt @@ -1,58 +1,58 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(68,9): error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(68,9): error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'Base'. Type 'U' is not assignable to type 'T'. Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(68,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(73,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(73,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base'. Type 'V' is not assignable to type 'T'. Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(73,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(78,9): error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(78,9): error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'Base'. Type 'T' is not assignable to type 'U'. Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(78,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(88,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(88,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base'. Type 'V' is not assignable to type 'U'. Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(88,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(93,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(93,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base'. Type 'T' is not assignable to type 'V'. Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(93,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(98,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(98,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base'. Type 'U' is not assignable to type 'V'. Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(98,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(115,9): error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(115,9): error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'Base2'. Type 'T' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'U' is not assignable to type 'T'. Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(120,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(125,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(125,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base2'. Type 'V' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'V' is not assignable to type 'T'. Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(125,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(130,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(135,9): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(135,9): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'Base2'. Type 'U' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'T' is not assignable to type 'U'. Type 'Foo' is not assignable to type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(140,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(140,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base2'. Type 'V' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'V' is not assignable to type 'U'. Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(140,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(145,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(145,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base2'. Type 'T' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'U' is not assignable to type 'V'. Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(145,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(150,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(150,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base2'. Type 'U' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'T' is not assignable to type 'V'. @@ -130,7 +130,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U ~~~ -!!! error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'U' is not assignable to type 'T'. !!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~ @@ -141,7 +141,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V ~~~ -!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'T'. +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'V' is not assignable to type 'T'. !!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~ @@ -152,7 +152,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: T ~~~ -!!! error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'T' is not assignable to type 'U'. !!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~ @@ -168,7 +168,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V ~~~ -!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'U'. +!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'V' is not assignable to type 'U'. !!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~ @@ -179,7 +179,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: T ~~~ -!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'V'. +!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'T' is not assignable to type 'V'. !!! error TS2416: Type 'Foo' is not assignable to type 'V'. ~~~~~~ @@ -190,7 +190,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: U ~~~ -!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'V'. +!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'U' is not assignable to type 'V'. !!! error TS2416: Type 'Foo' is not assignable to type 'V'. ~~~~~~ @@ -213,7 +213,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: T ~~~ -!!! error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'T' is not assignable to type 'Foo'. !!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. !!! error TS2416: Type 'U' is not assignable to type 'T'. @@ -231,7 +231,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V ~~~ -!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'V' is not assignable to type 'Foo'. !!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. !!! error TS2416: Type 'V' is not assignable to type 'T'. @@ -251,7 +251,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: U ~~~ -!!! error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'U' is not assignable to type 'Foo'. !!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. !!! error TS2416: Type 'T' is not assignable to type 'U'. @@ -262,7 +262,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V ~~~ -!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'V' is not assignable to type 'Foo'. !!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. !!! error TS2416: Type 'V' is not assignable to type 'U'. @@ -275,7 +275,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: T ~~~ -!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'T' is not assignable to type 'Foo'. !!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. !!! error TS2416: Type 'U' is not assignable to type 'V'. @@ -288,7 +288,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: U ~~~ -!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Foo'. +!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'U' is not assignable to type 'Foo'. !!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. !!! error TS2416: Type 'T' is not assignable to type 'V'. diff --git a/tests/baselines/reference/subtypingWithObjectMembers.errors.txt b/tests/baselines/reference/subtypingWithObjectMembers.errors.txt index 2be672f5c03..044e4ee0f2b 100644 --- a/tests/baselines/reference/subtypingWithObjectMembers.errors.txt +++ b/tests/baselines/reference/subtypingWithObjectMembers.errors.txt @@ -1,14 +1,14 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(14,5): error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(14,5): error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'A'. Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(24,5): error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(24,5): error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'A2'. Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(34,5): error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(34,5): error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'A3'. Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(45,9): error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(45,9): error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'A'. Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(55,9): error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(55,9): error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'A2'. Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(65,9): error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(65,9): error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'A3'. Type 'string' is not assignable to type 'Base'. @@ -28,7 +28,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW foo: Derived; // ok bar: string; // error ~~~ -!!! error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'A'. !!! error TS2416: Type 'string' is not assignable to type 'Base'. } @@ -41,7 +41,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW 1: Derived; // ok 2: string; // error ~ -!!! error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'A2'. !!! error TS2416: Type 'string' is not assignable to type 'Base'. } @@ -54,7 +54,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW '1': Derived; // ok '2.0': string; // error ~~~~~ -!!! error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'A3'. !!! error TS2416: Type 'string' is not assignable to type 'Base'. } @@ -68,7 +68,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW foo: Derived2; // ok bar: string; // error ~~~ -!!! error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'A'. !!! error TS2416: Type 'string' is not assignable to type 'Base'. } @@ -81,7 +81,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW 1: Derived2; // ok 2: string; // error ~ -!!! error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'A2'. !!! error TS2416: Type 'string' is not assignable to type 'Base'. } @@ -94,7 +94,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW '1': Derived2; // ok '2.0': string; // error ~~~~~ -!!! error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'A3'. !!! error TS2416: Type 'string' is not assignable to type 'Base'. } } \ No newline at end of file From 7a1deae6aa9a6b36c8364556aa9f8fc8225f01ed Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 10 Jan 2018 12:52:35 -0800 Subject: [PATCH 13/13] AsteriskToken should always have length 1 (#21126) --- src/compiler/parser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index f0685b7372e..2797fe557c7 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6491,7 +6491,7 @@ namespace ts { if (state === JSDocState.BeginningOfLine) { // leading asterisks start recording on the *next* (non-whitespace) token state = JSDocState.SawAsterisk; - indent += scanner.getTokenText().length; + indent += 1; break; } // record the * as a comment