Skip to content

Commit f08ff9d

Browse files
committed
Fix renaming an ExportSpecifier name when propertyName is present (microsoft#36790)
* Fix renaming exportSpecifier name when propertyName is present * Add baseline test for name without propertyName too
1 parent e7fec6d commit f08ff9d

8 files changed

+89
-4
lines changed

src/harness/fourslashImpl.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,37 @@ namespace FourSlash {
13191319
}
13201320
}
13211321

1322+
public baselineRename(marker: string, options: FourSlashInterface.RenameOptions) {
1323+
const position = this.getMarkerByName(marker).position;
1324+
const locations = this.languageService.findRenameLocations(
1325+
this.activeFile.fileName,
1326+
position,
1327+
options.findInStrings ?? false,
1328+
options.findInComments ?? false,
1329+
options.providePrefixAndSuffixTextForRename);
1330+
1331+
if (!locations) {
1332+
this.raiseError(`baselineRename failed. Could not rename at the provided position.`);
1333+
}
1334+
1335+
const renamesByFile = ts.group(locations, l => l.fileName);
1336+
const baselineContent = renamesByFile.map(renames => {
1337+
const { fileName } = renames[0];
1338+
const sortedRenames = ts.sort(renames, (a, b) => b.textSpan.start - a.textSpan.start);
1339+
let baselineFileContent = this.getFileContent(fileName);
1340+
for (const { textSpan } of sortedRenames) {
1341+
const isOriginalSpan = fileName === this.activeFile.fileName && ts.textSpanIntersectsWithPosition(textSpan, position);
1342+
baselineFileContent =
1343+
baselineFileContent.slice(0, textSpan.start) +
1344+
(isOriginalSpan ? "[|RENAME|]" : "RENAME") +
1345+
baselineFileContent.slice(textSpan.start + textSpan.length);
1346+
}
1347+
return `/*====== ${fileName} ======*/\n\n${baselineFileContent}`;
1348+
}).join("\n\n") + "\n";
1349+
1350+
Harness.Baseline.runBaseline(this.getBaselineFileNameForContainingTestFile(), baselineContent);
1351+
}
1352+
13221353
public verifyQuickInfoExists(negative: boolean) {
13231354
const actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition);
13241355
if (negative) {

src/harness/fourslashInterfaceImpl.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,10 @@ namespace FourSlashInterface {
516516
this.state.verifyRenameLocations(startRanges, options);
517517
}
518518

519+
public baselineRename(marker: string, options: RenameOptions) {
520+
this.state.baselineRename(marker, options);
521+
}
522+
519523
public verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: FourSlash.TextSpan,
520524
displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[], tags: ts.JSDocTagInfo[]) {
521525
this.state.verifyQuickInfoDisplayParts(kind, kindModifiers, textSpan, displayParts, documentation, tags);
@@ -1623,4 +1627,9 @@ namespace FourSlashInterface {
16231627
template: string
16241628
};
16251629
export type RenameLocationOptions = FourSlash.Range | { readonly range: FourSlash.Range, readonly prefixText?: string, readonly suffixText?: string };
1630+
export interface RenameOptions {
1631+
readonly findInStrings?: boolean;
1632+
readonly findInComments?: boolean;
1633+
readonly providePrefixAndSuffixTextForRename?: boolean;
1634+
};
16261635
}

src/services/findAllReferences.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,10 +1927,12 @@ namespace ts.FindAllReferences {
19271927
}
19281928

19291929
const exportSpecifier = getDeclarationOfKind<ExportSpecifier>(symbol, SyntaxKind.ExportSpecifier);
1930-
const localSymbol = exportSpecifier && checker.getExportSpecifierLocalTargetSymbol(exportSpecifier);
1931-
if (localSymbol) {
1932-
const res = cbSymbol(localSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.Node);
1933-
if (res) return res;
1930+
if (!isForRenamePopulateSearchSymbolSet || exportSpecifier && !exportSpecifier.propertyName) {
1931+
const localSymbol = exportSpecifier && checker.getExportSpecifierLocalTargetSymbol(exportSpecifier);
1932+
if (localSymbol) {
1933+
const res = cbSymbol(localSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.Node);
1934+
if (res) return res;
1935+
}
19341936
}
19351937

19361938
// symbolAtLocation for a binding element is the local symbol. See if the search symbol is the property.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*====== /tests/cases/fourslash/a.ts ======*/
2+
3+
const name = {};
4+
export { name as [|RENAME|] };
5+
6+
/*====== /tests/cases/fourslash/b.ts ======*/
7+
8+
import { RENAME } from './a';
9+
const x = RENAME.toString();
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*====== /tests/cases/fourslash/a.ts ======*/
2+
3+
const RENAME = {};
4+
export { [|RENAME|] };
5+
6+
/*====== /tests/cases/fourslash/b.ts ======*/
7+
8+
import { RENAME } from './a';
9+
const x = RENAME.toString();

tests/cases/fourslash/fourslash.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ declare namespace FourSlashInterface {
359359
renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string, fileToRename?: string, range?: Range, allowRenameOfImportPath?: boolean): void;
360360
renameInfoFailed(message?: string, allowRenameOfImportPath?: boolean): void;
361361
renameLocations(startRanges: ArrayOrSingle<Range>, options: RenameLocationsOptions): void;
362+
baselineRename(marker: string, options: RenameOptions): void;
362363

363364
/** Verify the quick info available at the current marker. */
364365
quickInfoIs(expectedText: string, expectedDocumentation?: string): void;
@@ -723,6 +724,8 @@ declare namespace FourSlashInterface {
723724
readonly ranges: ReadonlyArray<RenameLocationOptions>;
724725
readonly providePrefixAndSuffixTextForRename?: boolean;
725726
};
727+
728+
type RenameOptions = { readonly findInStrings?: boolean, readonly findInComments?: boolean, readonly providePrefixAndSuffixTextForRename?: boolean };
726729
type RenameLocationOptions = Range | { readonly range: Range, readonly prefixText?: string, readonly suffixText?: string };
727730
type DiagnosticIgnoredInterpolations = { template: string }
728731
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: a.ts
4+
////const name = {};
5+
////export { name as name/**/ };
6+
7+
// @Filename: b.ts
8+
////import { name } from './a';
9+
////const x = name.toString();
10+
11+
verify.baselineRename("", { providePrefixAndSuffixTextForRename: false });
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: a.ts
4+
////const name = {};
5+
////export { name/**/ };
6+
7+
// @Filename: b.ts
8+
////import { name } from './a';
9+
////const x = name.toString();
10+
11+
verify.baselineRename("", { providePrefixAndSuffixTextForRename: false });

0 commit comments

Comments
 (0)