diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 796c960342..28193535ce 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -230,6 +230,10 @@ namespace ts { // Should not be called on a declaration with a computed property name, // unless it is a well known Symbol. function getDeclarationName(node: Declaration): __String { + if (node.kind === SyntaxKind.ExportAssignment) { + return (node).isExportEquals ? InternalSymbolName.ExportEquals : InternalSymbolName.Default; + } + const name = getNameOfDeclaration(node); if (name) { if (isAmbientModule(node)) { @@ -261,8 +265,6 @@ namespace ts { return InternalSymbolName.Index; case SyntaxKind.ExportDeclaration: return InternalSymbolName.ExportStar; - case SyntaxKind.ExportAssignment: - return (node).isExportEquals ? InternalSymbolName.ExportEquals : InternalSymbolName.Default; case SyntaxKind.BinaryExpression: if (getSpecialPropertyAssignmentKind(node as BinaryExpression) === SpecialPropertyAssignmentKind.ModuleExports) { // module.exports = ... diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f0eb394adb..ce209cbd81 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4112,27 +4112,35 @@ namespace ts { if (!declaration) { return undefined; } - if (isJSDocPropertyLikeTag(declaration) && declaration.name.kind === SyntaxKind.QualifiedName) { - return declaration.name.right; - } - if (declaration.kind === SyntaxKind.BinaryExpression) { - const expr = declaration as BinaryExpression; - switch (getSpecialPropertyAssignmentKind(expr)) { - case SpecialPropertyAssignmentKind.ExportsProperty: - case SpecialPropertyAssignmentKind.ThisProperty: - case SpecialPropertyAssignmentKind.Property: - case SpecialPropertyAssignmentKind.PrototypeProperty: - return (expr.left as PropertyAccessExpression).name; - default: - return undefined; + switch (declaration.kind) { + case SyntaxKind.JSDocPropertyTag: + case SyntaxKind.JSDocParameterTag: { + const { name } = declaration as JSDocPropertyLikeTag; + if (name.kind === SyntaxKind.QualifiedName) { + return name.right; + } + break; + } + case SyntaxKind.BinaryExpression: { + const expr = declaration as BinaryExpression; + switch (getSpecialPropertyAssignmentKind(expr)) { + case SpecialPropertyAssignmentKind.ExportsProperty: + case SpecialPropertyAssignmentKind.ThisProperty: + case SpecialPropertyAssignmentKind.Property: + case SpecialPropertyAssignmentKind.PrototypeProperty: + return (expr.left as PropertyAccessExpression).name; + default: + return undefined; + } + } + case SyntaxKind.JSDocTypedefTag: + return getNameOfJSDocTypedef(declaration as JSDocTypedefTag); + case SyntaxKind.ExportAssignment: { + const { expression } = declaration as ExportAssignment; + return isIdentifier(expression) ? expression : undefined; } } - else if (declaration.kind === SyntaxKind.JSDocTypedefTag) { - return getNameOfJSDocTypedef(declaration as JSDocTypedefTag); - } - else { - return (declaration as NamedDeclaration).name; - } + return (declaration as NamedDeclaration).name; } /** diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index d4e660295a..e43a2cbfd8 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -482,7 +482,10 @@ namespace ts.FindAllReferences.Core { /** @param allSearchSymbols set of additinal symbols for use by `includes`. */ createSearch(location: Node, symbol: Symbol, comingFrom: ImportExport | undefined, searchOptions: { text?: string, allSearchSymbols?: Symbol[] } = {}): Search { // Note: if this is an external module symbol, the name doesn't include quotes. - const { text = stripQuotes(getDeclaredName(this.checker, symbol, location)), allSearchSymbols = undefined } = searchOptions; + const { + text = stripQuotes(unescapeLeadingUnderscores((getLocalSymbolForExportDefault(symbol) || symbol).escapedName)), + allSearchSymbols = undefined, + } = searchOptions; const escapedText = escapeLeadingUnderscores(text); const parents = this.options.implementations && getParentSymbolsOfPropertyAccess(location, symbol, this.checker); return { diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index a615223021..f12df4613c 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -609,9 +609,6 @@ namespace ts.FindAllReferences { } return forEach(symbol.declarations, decl => { - if (isExportAssignment(decl)) { - return isIdentifier(decl.expression) ? decl.expression.escapedText : undefined; - } const name = getNameOfDeclaration(decl); return name && name.kind === SyntaxKind.Identifier && name.escapedText; }); diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index a399610d82..d38d21f109 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -341,13 +341,19 @@ namespace ts.SymbolDisplay { } if (symbolFlags & SymbolFlags.Alias) { addNewLineIfDisplayPartsExist(); - if (symbol.declarations[0].kind === SyntaxKind.NamespaceExportDeclaration) { - displayParts.push(keywordPart(SyntaxKind.ExportKeyword)); - displayParts.push(spacePart()); - displayParts.push(keywordPart(SyntaxKind.NamespaceKeyword)); - } - else { - displayParts.push(keywordPart(SyntaxKind.ImportKeyword)); + switch (symbol.declarations[0].kind) { + case SyntaxKind.NamespaceExportDeclaration: + displayParts.push(keywordPart(SyntaxKind.ExportKeyword)); + displayParts.push(spacePart()); + displayParts.push(keywordPart(SyntaxKind.NamespaceKeyword)); + break; + case SyntaxKind.ExportAssignment: + displayParts.push(keywordPart(SyntaxKind.ExportKeyword)); + displayParts.push(spacePart()); + displayParts.push(keywordPart((symbol.declarations[0] as ExportAssignment).isExportEquals ? SyntaxKind.EqualsToken : SyntaxKind.DefaultKeyword)); + break; + default: + displayParts.push(keywordPart(SyntaxKind.ImportKeyword)); } displayParts.push(spacePart()); addFullSymbolName(symbol); diff --git a/tests/baselines/reference/duplicateExportAssignments.errors.txt b/tests/baselines/reference/duplicateExportAssignments.errors.txt index 17ad0a3984..0ad9507c9a 100644 --- a/tests/baselines/reference/duplicateExportAssignments.errors.txt +++ b/tests/baselines/reference/duplicateExportAssignments.errors.txt @@ -1,34 +1,34 @@ -tests/cases/conformance/externalModules/foo1.ts(3,1): error TS2300: Duplicate identifier 'export='. -tests/cases/conformance/externalModules/foo1.ts(4,1): error TS2300: Duplicate identifier 'export='. -tests/cases/conformance/externalModules/foo2.ts(3,1): error TS2300: Duplicate identifier 'export='. -tests/cases/conformance/externalModules/foo2.ts(4,1): error TS2300: Duplicate identifier 'export='. -tests/cases/conformance/externalModules/foo3.ts(7,1): error TS2300: Duplicate identifier 'export='. -tests/cases/conformance/externalModules/foo3.ts(8,1): error TS2300: Duplicate identifier 'export='. -tests/cases/conformance/externalModules/foo4.ts(1,1): error TS2300: Duplicate identifier 'export='. -tests/cases/conformance/externalModules/foo4.ts(8,1): error TS2300: Duplicate identifier 'export='. -tests/cases/conformance/externalModules/foo5.ts(4,1): error TS2300: Duplicate identifier 'export='. -tests/cases/conformance/externalModules/foo5.ts(5,1): error TS2300: Duplicate identifier 'export='. -tests/cases/conformance/externalModules/foo5.ts(6,1): error TS2300: Duplicate identifier 'export='. +tests/cases/conformance/externalModules/foo1.ts(3,10): error TS2300: Duplicate identifier 'export='. +tests/cases/conformance/externalModules/foo1.ts(4,10): error TS2300: Duplicate identifier 'export='. +tests/cases/conformance/externalModules/foo2.ts(3,10): error TS2300: Duplicate identifier 'export='. +tests/cases/conformance/externalModules/foo2.ts(4,10): error TS2300: Duplicate identifier 'export='. +tests/cases/conformance/externalModules/foo3.ts(7,10): error TS2300: Duplicate identifier 'export='. +tests/cases/conformance/externalModules/foo3.ts(8,10): error TS2300: Duplicate identifier 'export='. +tests/cases/conformance/externalModules/foo4.ts(1,10): error TS2300: Duplicate identifier 'export='. +tests/cases/conformance/externalModules/foo4.ts(8,10): error TS2300: Duplicate identifier 'export='. +tests/cases/conformance/externalModules/foo5.ts(4,10): error TS2300: Duplicate identifier 'export='. +tests/cases/conformance/externalModules/foo5.ts(5,10): error TS2300: Duplicate identifier 'export='. +tests/cases/conformance/externalModules/foo5.ts(6,10): error TS2300: Duplicate identifier 'export='. ==== tests/cases/conformance/externalModules/foo1.ts (2 errors) ==== var x = 10; var y = 20; export = x; - ~~~~~~~~~~~ + ~ !!! error TS2300: Duplicate identifier 'export='. export = y; - ~~~~~~~~~~~ + ~ !!! error TS2300: Duplicate identifier 'export='. ==== tests/cases/conformance/externalModules/foo2.ts (2 errors) ==== var x = 10; class y {}; export = x; - ~~~~~~~~~~~ + ~ !!! error TS2300: Duplicate identifier 'export='. export = y; - ~~~~~~~~~~~ + ~ !!! error TS2300: Duplicate identifier 'export='. ==== tests/cases/conformance/externalModules/foo3.ts (2 errors) ==== @@ -39,15 +39,15 @@ tests/cases/conformance/externalModules/foo5.ts(6,1): error TS2300: Duplicate id y: number; } export = x; - ~~~~~~~~~~~ + ~ !!! error TS2300: Duplicate identifier 'export='. export = y; - ~~~~~~~~~~~ + ~ !!! error TS2300: Duplicate identifier 'export='. ==== tests/cases/conformance/externalModules/foo4.ts (2 errors) ==== export = x; - ~~~~~~~~~~~ + ~ !!! error TS2300: Duplicate identifier 'export='. function x(){ return 42; @@ -56,7 +56,7 @@ tests/cases/conformance/externalModules/foo5.ts(6,1): error TS2300: Duplicate id return 42; } export = y; - ~~~~~~~~~~~ + ~ !!! error TS2300: Duplicate identifier 'export='. ==== tests/cases/conformance/externalModules/foo5.ts (3 errors) ==== @@ -64,12 +64,12 @@ tests/cases/conformance/externalModules/foo5.ts(6,1): error TS2300: Duplicate id var y = "test"; var z = {}; export = x; - ~~~~~~~~~~~ + ~ !!! error TS2300: Duplicate identifier 'export='. export = y; - ~~~~~~~~~~~ + ~ !!! error TS2300: Duplicate identifier 'export='. export = z; - ~~~~~~~~~~~ + ~ !!! error TS2300: Duplicate identifier 'export='. \ No newline at end of file diff --git a/tests/baselines/reference/es5-commonjs7.symbols b/tests/baselines/reference/es5-commonjs7.symbols index ed8247a687..eb6dc06257 100644 --- a/tests/baselines/reference/es5-commonjs7.symbols +++ b/tests/baselines/reference/es5-commonjs7.symbols @@ -1,6 +1,6 @@ === tests/cases/compiler/test.d.ts === export default undefined; ->undefined : Symbol(default) +>undefined : Symbol(undefined) export var __esModule; >__esModule : Symbol(__esModule, Decl(test.d.ts, 1, 10)) diff --git a/tests/baselines/reference/exportDefaultVariable.symbols b/tests/baselines/reference/exportDefaultVariable.symbols index cd7ebed926..9c924c32f4 100644 --- a/tests/baselines/reference/exportDefaultVariable.symbols +++ b/tests/baselines/reference/exportDefaultVariable.symbols @@ -6,6 +6,6 @@ declare var io: any; declare module 'module' { export default io; ->io : Symbol(default, Decl(exportDefaultVariable.ts, 2, 11)) +>io : Symbol(io, Decl(exportDefaultVariable.ts, 2, 11)) } diff --git a/tests/baselines/reference/jsFileCompilationBindMultipleDefaultExports.errors.txt b/tests/baselines/reference/jsFileCompilationBindMultipleDefaultExports.errors.txt index 9a9a7a12db..246b8f20ca 100644 --- a/tests/baselines/reference/jsFileCompilationBindMultipleDefaultExports.errors.txt +++ b/tests/baselines/reference/jsFileCompilationBindMultipleDefaultExports.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/a.js(1,22): error TS2528: A module cannot have multiple default exports. tests/cases/compiler/a.js(1,22): error TS2652: Merged declaration 'a' cannot include a default export declaration. Consider adding a separate 'export default a' declaration instead. -tests/cases/compiler/a.js(3,1): error TS2528: A module cannot have multiple default exports. +tests/cases/compiler/a.js(3,15): error TS2528: A module cannot have multiple default exports. tests/cases/compiler/a.js(3,16): error TS1109: Expression expected. tests/cases/compiler/a.js(3,20): error TS2652: Merged declaration 'a' cannot include a default export declaration. Consider adding a separate 'export default a' declaration instead. @@ -13,7 +13,7 @@ tests/cases/compiler/a.js(3,20): error TS2652: Merged declaration 'a' cannot inc !!! error TS2652: Merged declaration 'a' cannot include a default export declaration. Consider adding a separate 'export default a' declaration instead. } export default var a = 10; - ~~~~~~~~~~~~~~ + !!! error TS2528: A module cannot have multiple default exports. ~~~ !!! error TS1109: Expression expected. diff --git a/tests/baselines/reference/multipleDefaultExports01.errors.txt b/tests/baselines/reference/multipleDefaultExports01.errors.txt index b53d4113de..eff0203387 100644 --- a/tests/baselines/reference/multipleDefaultExports01.errors.txt +++ b/tests/baselines/reference/multipleDefaultExports01.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/es6/modules/m1.ts(1,22): error TS2528: A module cannot have multiple default exports. tests/cases/conformance/es6/modules/m1.ts(5,25): error TS2528: A module cannot have multiple default exports. -tests/cases/conformance/es6/modules/m1.ts(10,1): error TS2528: A module cannot have multiple default exports. +tests/cases/conformance/es6/modules/m1.ts(10,16): error TS2528: A module cannot have multiple default exports. tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typeof foo' is not callable. Did you mean to include 'new'? @@ -19,7 +19,7 @@ tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typ var x = 10; export default x; - ~~~~~~~~~~~~~~~~~ + ~ !!! error TS2528: A module cannot have multiple default exports. ==== tests/cases/conformance/es6/modules/m2.ts (1 errors) ==== diff --git a/tests/baselines/reference/multipleExportAssignments.errors.txt b/tests/baselines/reference/multipleExportAssignments.errors.txt index 5fbabc2b4d..c9f5eb7cf7 100644 --- a/tests/baselines/reference/multipleExportAssignments.errors.txt +++ b/tests/baselines/reference/multipleExportAssignments.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/multipleExportAssignments.ts(13,1): error TS2300: Duplicate identifier 'export='. -tests/cases/compiler/multipleExportAssignments.ts(14,1): error TS2300: Duplicate identifier 'export='. +tests/cases/compiler/multipleExportAssignments.ts(13,10): error TS2300: Duplicate identifier 'export='. +tests/cases/compiler/multipleExportAssignments.ts(14,10): error TS2300: Duplicate identifier 'export='. ==== tests/cases/compiler/multipleExportAssignments.ts (2 errors) ==== @@ -16,10 +16,10 @@ tests/cases/compiler/multipleExportAssignments.ts(14,1): error TS2300: Duplicate test2(): connectModule; }; export = server; - ~~~~~~~~~~~~~~~~ + ~~~~~~ !!! error TS2300: Duplicate identifier 'export='. export = connectExport; - ~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~ !!! error TS2300: Duplicate identifier 'export='. \ No newline at end of file diff --git a/tests/baselines/reference/multipleExportAssignmentsInAmbientDeclaration.errors.txt b/tests/baselines/reference/multipleExportAssignmentsInAmbientDeclaration.errors.txt index c6427a5cc2..792e2dd596 100644 --- a/tests/baselines/reference/multipleExportAssignmentsInAmbientDeclaration.errors.txt +++ b/tests/baselines/reference/multipleExportAssignmentsInAmbientDeclaration.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/multipleExportAssignmentsInAmbientDeclaration.ts(4,5): error TS2300: Duplicate identifier 'export='. -tests/cases/compiler/multipleExportAssignmentsInAmbientDeclaration.ts(5,5): error TS2300: Duplicate identifier 'export='. +tests/cases/compiler/multipleExportAssignmentsInAmbientDeclaration.ts(4,14): error TS2300: Duplicate identifier 'export='. +tests/cases/compiler/multipleExportAssignmentsInAmbientDeclaration.ts(5,14): error TS2300: Duplicate identifier 'export='. ==== tests/cases/compiler/multipleExportAssignmentsInAmbientDeclaration.ts (2 errors) ==== @@ -7,9 +7,9 @@ tests/cases/compiler/multipleExportAssignmentsInAmbientDeclaration.ts(5,5): erro var a: number var b: number; export = a; - ~~~~~~~~~~~ + ~ !!! error TS2300: Duplicate identifier 'export='. export = b; - ~~~~~~~~~~~ + ~ !!! error TS2300: Duplicate identifier 'export='. } \ No newline at end of file diff --git a/tests/baselines/reference/typeAliasExport.symbols b/tests/baselines/reference/typeAliasExport.symbols index e019ca7a10..5ffe181ca7 100644 --- a/tests/baselines/reference/typeAliasExport.symbols +++ b/tests/baselines/reference/typeAliasExport.symbols @@ -1,7 +1,7 @@ === tests/cases/compiler/typeAliasExport.ts === declare module "a" { export default undefined ->undefined : Symbol(default) +>undefined : Symbol(undefined) export var a; >a : Symbol(a, Decl(typeAliasExport.ts, 2, 12), Decl(typeAliasExport.ts, 2, 15)) diff --git a/tests/cases/fourslash/findAllRefsDefaultImportThroughNamespace.ts b/tests/cases/fourslash/findAllRefsDefaultImportThroughNamespace.ts index e5f7763132..1411a106c8 100644 --- a/tests/cases/fourslash/findAllRefsDefaultImportThroughNamespace.ts +++ b/tests/cases/fourslash/findAllRefsDefaultImportThroughNamespace.ts @@ -1,7 +1,7 @@ /// // @Filename: /a.ts -////export default function [|{| "isWriteAccess": true, "isDefinition": true |}f|]() {} +////export [|{| "isWriteAccess": true, "isDefinition": true |}default|] function [|{| "isWriteAccess": true, "isDefinition": true |}f|]() {} // @Filename: /b.ts ////export import a = require("./a"); @@ -13,16 +13,17 @@ ////declare const x: { [|{| "isWriteAccess": true, "isDefinition": true |}default|]: number }; ////x.[|default|]; -const [r0, r1, r2, r3] = test.ranges(); +const [r0, r1, r2, r3, r4] = test.ranges(); -verify.singleReferenceGroup("function f(): void", [r0, r1]); -verify.singleReferenceGroup("(property) default: number", [r2, r3]); +verify.referenceGroups([r0], [{ definition: "function f(): void", ranges: [r1, r2] }]); +verify.singleReferenceGroup("function f(): void", [r1, r2]); +verify.singleReferenceGroup("(property) default: number", [r3, r4]); -verify.rangesAreRenameLocations([r0]); +verify.rangesAreRenameLocations([r1]); // Can't rename a default import. -goTo.rangeStart(r1); +goTo.rangeStart(r2); verify.renameInfoFailed(); // Can rename a default property. -verify.rangesAreRenameLocations([r2, r3]); +verify.rangesAreRenameLocations([r3, r4]); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport04.ts b/tests/cases/fourslash/findAllRefsForDefaultExport04.ts index 1b5eb7a282..093910d1cb 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport04.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport04.ts @@ -14,12 +14,10 @@ verify.referenceGroups([r0, r2], [ { definition: "import a", ranges: [r3, r4] } ]); verify.referenceGroups(r1, [ - // TODO:GH#17990 - { definition: "import default", ranges: [r1] }, + { definition: "export default a", ranges: [r1] }, { definition: "import a", ranges: [r3, r4] }, ]); verify.referenceGroups([r3, r4], [ { definition: "import a", ranges: [r3, r4] }, - // TODO:GH#17990 - { definition: "import default", ranges: [r1] }, + { definition: "export default a", ranges: [r1] }, ]); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts index 7d6cb0a48a..329a72c30f 100644 --- a/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts @@ -6,4 +6,8 @@ const ranges = test.ranges(); const [r0, r1, r2] = ranges; verify.referenceGroups(r0, [{ definition: '(property) ["foo"]: number', ranges }]); -verify.referenceGroups([r1, r2], undefined); // TODO: fix +verify.referenceGroups([r1, r2], [ + // TODO: these are the same thing, should be in the same group. + { definition: "(property) [\"foo\"]: number", ranges: [r0] }, + { definition: "(property) [\"foo\"]: number", ranges: [r1, r2] }, +]);