From a70c773e167ad4298998e7495022d59da84b1c49 Mon Sep 17 00:00:00 2001 From: NamHaiBui Date: Tue, 4 Mar 2025 21:04:12 -0500 Subject: [PATCH 1/4] Fixes 57026 --- src/services/findAllReferences.ts | 18 +++++++++++++----- .../renameStringLiteralTypes5.baseline.jsonc | 10 ++++++---- .../renameStringLiteralTypes6.baseline.jsonc | 9 +++++++++ .../fourslash/renameStringLiteralTypes5.ts | 10 ++++++---- .../fourslash/renameStringLiteralTypes6.ts | 12 ++++++++++++ 5 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 tests/baselines/reference/renameStringLiteralTypes6.baseline.jsonc create mode 100644 tests/cases/fourslash/renameStringLiteralTypes6.ts diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 522577f9d8f87..4ab27ea2167e5 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1013,9 +1013,8 @@ export namespace Core { const checker = program.getTypeChecker(); // constructors should use the class symbol, detected by name, if present const symbol = checker.getSymbolAtLocation(isConstructorDeclaration(node) && node.parent.name || node); - // Could not find a symbol e.g. unknown identifier - if (!symbol) { + if (!symbol || (isStringLiteralLike(node) && isStringLiteralPropertyReference(node, checker))) { // String literal might be a property (and thus have a symbol), so do this here rather than in getReferencedSymbolsSpecial. if (!options.implementations && isStringLiteralLike(node)) { if (isModuleSpecifierLike(node)) { @@ -1389,7 +1388,8 @@ export namespace Core { /** Only set if `options.implementations` is true. These are the symbols checked to get the implementations of a property access. */ readonly parents: readonly Symbol[] | undefined; readonly allSearchSymbols: readonly Symbol[]; - + /** The node that we are searching for. This is used for searching. */ + readonly node: Node | undefined; /** * Whether a symbol is in the search set. * Do not compare directly to `symbol` because there may be related symbols to search for. See `populateSearchSymbolSet`. @@ -1474,7 +1474,7 @@ export namespace Core { } = searchOptions; const escapedText = escapeLeadingUnderscores(text); const parents = this.options.implementations && location ? getParentSymbolsOfPropertyAccess(location, symbol, this.checker) : undefined; - return { symbol, comingFrom, text, escapedText, parents, allSearchSymbols, includes: sym => contains(allSearchSymbols, sym) }; + return { symbol, comingFrom, text, escapedText, parents, allSearchSymbols, node: location, includes: sym => contains(allSearchSymbols, sym) }; } private readonly symbolIdToReferences: Entry[][] = []; @@ -1921,7 +1921,15 @@ export namespace Core { // 'FindReferences' will just filter out these results. state.addStringOrCommentReference(sourceFile.fileName, createTextSpan(position, search.text.length)); } - + // if ( search.node &&!state.checker.getSymbolAtLocation(referenceLocation) && !state.options.implementations && isStringLiteralLike(search.node) && isStringLiteralLike(referenceLocation) ) + // { + // const type = getContextualTypeFromParentOrAncestorTypeNode(search.node, state.checker) + // const refType = getContextualTypeFromParentOrAncestorTypeNode(referenceLocation, state.checker) + // if (type !== state.checker.getStringType() && type === refType) + // { + // addReference(referenceLocation, referenceLocation.symbol, state); + // } + // } return; } diff --git a/tests/baselines/reference/renameStringLiteralTypes5.baseline.jsonc b/tests/baselines/reference/renameStringLiteralTypes5.baseline.jsonc index 3cb3e208e34b1..a9475604e6c96 100644 --- a/tests/baselines/reference/renameStringLiteralTypes5.baseline.jsonc +++ b/tests/baselines/reference/renameStringLiteralTypes5.baseline.jsonc @@ -1,9 +1,11 @@ // === findRenameLocations === // === /tests/cases/fourslash/renameStringLiteralTypes5.ts === -// type T = { -// <|"[|Prop 1RENAME|]": string;|> +// declare const Att_1: "[|Att 2RENAME|]"/*RENAME*/ +// +// interface Case_1 { +// [Att_1]: string // } // -// declare const fn: (p: K) => void +// declare const fnc_1: (p: K) => void // -// fn("[|Prop 1RENAME|]"/*RENAME*/) \ No newline at end of file +// fnc_1("[|Att 2RENAME|]") \ No newline at end of file diff --git a/tests/baselines/reference/renameStringLiteralTypes6.baseline.jsonc b/tests/baselines/reference/renameStringLiteralTypes6.baseline.jsonc new file mode 100644 index 0000000000000..e34b4a0bbf388 --- /dev/null +++ b/tests/baselines/reference/renameStringLiteralTypes6.baseline.jsonc @@ -0,0 +1,9 @@ +// === findRenameLocations === +// === /tests/cases/fourslash/renameStringLiteralTypes6.ts === +// interface Case_1 { +// <|"[|Att 2RENAME|]"/*RENAME*/: string|> +// } +// +// declare const fnc_1: (p: K) => void +// +// fnc_1("[|Att 2RENAME|]") \ No newline at end of file diff --git a/tests/cases/fourslash/renameStringLiteralTypes5.ts b/tests/cases/fourslash/renameStringLiteralTypes5.ts index aa40b656e57e3..a3fdd564668ed 100644 --- a/tests/cases/fourslash/renameStringLiteralTypes5.ts +++ b/tests/cases/fourslash/renameStringLiteralTypes5.ts @@ -1,11 +1,13 @@ /// -////type T = { -//// "Prop 1": string; +////declare const Att_1: "Att 2"/**/ +//// +////interface Case_1 { +//// [Att_1]: string ////} //// -////declare const fn: (p: K) => void +////declare const fnc_1: (p: K) => void //// -////fn("Prop 1"/**/) +////fnc_1("Att 2") verify.baselineRename("", {}); diff --git a/tests/cases/fourslash/renameStringLiteralTypes6.ts b/tests/cases/fourslash/renameStringLiteralTypes6.ts new file mode 100644 index 0000000000000..7e8b9b68ce6fe --- /dev/null +++ b/tests/cases/fourslash/renameStringLiteralTypes6.ts @@ -0,0 +1,12 @@ +/// + + +////interface Case_1 { +//// "Att 2"/**/: string +////} +//// +////declare const fnc_1: (p: K) => void +//// +////fnc_1("Att 2") + +verify.baselineRename("", {}); From e59e21367f72cf1304f4910eb04f7f45b3f2b360 Mon Sep 17 00:00:00 2001 From: NamHaiBui Date: Tue, 4 Mar 2025 21:33:37 -0500 Subject: [PATCH 2/4] Remove unnecessary comment --- src/services/findAllReferences.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 4ab27ea2167e5..3ee9893144c1c 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1921,15 +1921,7 @@ export namespace Core { // 'FindReferences' will just filter out these results. state.addStringOrCommentReference(sourceFile.fileName, createTextSpan(position, search.text.length)); } - // if ( search.node &&!state.checker.getSymbolAtLocation(referenceLocation) && !state.options.implementations && isStringLiteralLike(search.node) && isStringLiteralLike(referenceLocation) ) - // { - // const type = getContextualTypeFromParentOrAncestorTypeNode(search.node, state.checker) - // const refType = getContextualTypeFromParentOrAncestorTypeNode(referenceLocation, state.checker) - // if (type !== state.checker.getStringType() && type === refType) - // { - // addReference(referenceLocation, referenceLocation.symbol, state); - // } - // } + return; } From eaa8990f44bfd084985c929610ba1f87660ac242 Mon Sep 17 00:00:00 2001 From: NamHaiBui Date: Tue, 4 Mar 2025 23:08:48 -0500 Subject: [PATCH 3/4] Remove unneccessary code and finalized --- src/services/findAllReferences.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 3ee9893144c1c..c1674a5ac4d86 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1388,8 +1388,6 @@ export namespace Core { /** Only set if `options.implementations` is true. These are the symbols checked to get the implementations of a property access. */ readonly parents: readonly Symbol[] | undefined; readonly allSearchSymbols: readonly Symbol[]; - /** The node that we are searching for. This is used for searching. */ - readonly node: Node | undefined; /** * Whether a symbol is in the search set. * Do not compare directly to `symbol` because there may be related symbols to search for. See `populateSearchSymbolSet`. @@ -1474,7 +1472,7 @@ export namespace Core { } = searchOptions; const escapedText = escapeLeadingUnderscores(text); const parents = this.options.implementations && location ? getParentSymbolsOfPropertyAccess(location, symbol, this.checker) : undefined; - return { symbol, comingFrom, text, escapedText, parents, allSearchSymbols, node: location, includes: sym => contains(allSearchSymbols, sym) }; + return { symbol, comingFrom, text, escapedText, parents, allSearchSymbols, includes: sym => contains(allSearchSymbols, sym) }; } private readonly symbolIdToReferences: Entry[][] = []; From ea220c108bdb5272d2f1cfdd277f86d672a4b61e Mon Sep 17 00:00:00 2001 From: NamHaiBui Date: Tue, 15 Apr 2025 16:00:02 -0400 Subject: [PATCH 4/4] Adding tests and changed property checking --- src/services/findAllReferences.ts | 2 +- .../renameStringLiteralTypes5.baseline.jsonc | 10 ++++------ .../renameStringLiteralTypes7.baseline.jsonc | 11 +++++++++++ .../renameStringLiteralTypes8.baseline.jsonc | 9 +++++++++ tests/cases/fourslash/renameStringLiteralTypes5.ts | 14 +++++--------- tests/cases/fourslash/renameStringLiteralTypes7.ts | 13 +++++++++++++ tests/cases/fourslash/renameStringLiteralTypes8.ts | 9 +++++++++ 7 files changed, 52 insertions(+), 16 deletions(-) create mode 100644 tests/baselines/reference/renameStringLiteralTypes7.baseline.jsonc create mode 100644 tests/baselines/reference/renameStringLiteralTypes8.baseline.jsonc create mode 100644 tests/cases/fourslash/renameStringLiteralTypes7.ts create mode 100644 tests/cases/fourslash/renameStringLiteralTypes8.ts diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index c1674a5ac4d86..364e150b5a7af 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -2478,7 +2478,7 @@ export namespace Core { cancellationToken.throwIfCancellationRequested(); return mapDefined(getPossibleSymbolReferenceNodes(sourceFile, node.text), ref => { if (isStringLiteralLike(ref) && ref.text === node.text) { - if (type) { + if (type && !isStringLiteralPropertyReference(node, checker)) { const refType = getContextualTypeFromParentOrAncestorTypeNode(ref, checker); if (type !== checker.getStringType() && (type === refType || isStringLiteralPropertyReference(ref, checker))) { return nodeEntry(ref, EntryKind.StringLiteral); diff --git a/tests/baselines/reference/renameStringLiteralTypes5.baseline.jsonc b/tests/baselines/reference/renameStringLiteralTypes5.baseline.jsonc index a9475604e6c96..3cb3e208e34b1 100644 --- a/tests/baselines/reference/renameStringLiteralTypes5.baseline.jsonc +++ b/tests/baselines/reference/renameStringLiteralTypes5.baseline.jsonc @@ -1,11 +1,9 @@ // === findRenameLocations === // === /tests/cases/fourslash/renameStringLiteralTypes5.ts === -// declare const Att_1: "[|Att 2RENAME|]"/*RENAME*/ -// -// interface Case_1 { -// [Att_1]: string +// type T = { +// <|"[|Prop 1RENAME|]": string;|> // } // -// declare const fnc_1: (p: K) => void +// declare const fn: (p: K) => void // -// fnc_1("[|Att 2RENAME|]") \ No newline at end of file +// fn("[|Prop 1RENAME|]"/*RENAME*/) \ No newline at end of file diff --git a/tests/baselines/reference/renameStringLiteralTypes7.baseline.jsonc b/tests/baselines/reference/renameStringLiteralTypes7.baseline.jsonc new file mode 100644 index 0000000000000..bf5d7d29e9994 --- /dev/null +++ b/tests/baselines/reference/renameStringLiteralTypes7.baseline.jsonc @@ -0,0 +1,11 @@ +// === findRenameLocations === +// === /tests/cases/fourslash/renameStringLiteralTypes7.ts === +// declare const Att_1: "[|Att 2RENAME|]"/*RENAME*/ +// +// interface Case_1 { +// [Att_1]: string +// } +// +// declare const fnc_1: (p: K) => void +// +// fnc_1("[|Att 2RENAME|]") \ No newline at end of file diff --git a/tests/baselines/reference/renameStringLiteralTypes8.baseline.jsonc b/tests/baselines/reference/renameStringLiteralTypes8.baseline.jsonc new file mode 100644 index 0000000000000..a608bbdf3b75f --- /dev/null +++ b/tests/baselines/reference/renameStringLiteralTypes8.baseline.jsonc @@ -0,0 +1,9 @@ +// === findRenameLocations === +// === /tests/cases/fourslash/renameStringLiteralTypes8.ts === +// type T = { +// <|"[|Prop 1RENAME|]"/*RENAME*/: string;|> +// } +// +// declare const fn: (p: K) => void +// +// fn("[|Prop 1RENAME|]") \ No newline at end of file diff --git a/tests/cases/fourslash/renameStringLiteralTypes5.ts b/tests/cases/fourslash/renameStringLiteralTypes5.ts index a3fdd564668ed..44e809b3b94e5 100644 --- a/tests/cases/fourslash/renameStringLiteralTypes5.ts +++ b/tests/cases/fourslash/renameStringLiteralTypes5.ts @@ -1,13 +1,9 @@ /// - -////declare const Att_1: "Att 2"/**/ -//// -////interface Case_1 { -//// [Att_1]: string +////type T = { +//// "Prop 1": string; ////} //// -////declare const fnc_1: (p: K) => void +////declare const fn: (p: K) => void //// -////fnc_1("Att 2") - -verify.baselineRename("", {}); +////fn("Prop 1"/**/) +verify.baselineRename("", {}); \ No newline at end of file diff --git a/tests/cases/fourslash/renameStringLiteralTypes7.ts b/tests/cases/fourslash/renameStringLiteralTypes7.ts new file mode 100644 index 0000000000000..76280e63838d6 --- /dev/null +++ b/tests/cases/fourslash/renameStringLiteralTypes7.ts @@ -0,0 +1,13 @@ +/// + +////declare const Att_1: "Att 2"/**/ +//// +////interface Case_1 { +//// [Att_1]: string +////} +//// +////declare const fnc_1: (p: K) => void +//// +////fnc_1("Att 2") + +verify.baselineRename("", {}); diff --git a/tests/cases/fourslash/renameStringLiteralTypes8.ts b/tests/cases/fourslash/renameStringLiteralTypes8.ts new file mode 100644 index 0000000000000..0273d1c1dc95b --- /dev/null +++ b/tests/cases/fourslash/renameStringLiteralTypes8.ts @@ -0,0 +1,9 @@ +/// +////type T = { +//// "Prop 1"/**/: string; +////} +//// +////declare const fn: (p: K) => void +//// +////fn("Prop 1") +verify.baselineRename("", {}); \ No newline at end of file