Fix renaming an ExportSpecifier name when propertyName is present (#36790)

* Fix renaming exportSpecifier name when propertyName is present

* Add baseline test for name without propertyName too
This commit is contained in:
Andrew Branch
2020-02-13 16:55:52 -08:00
committed by GitHub
parent 888cd4db20
commit 950b36192a
8 changed files with 89 additions and 4 deletions
+31
View File
@@ -1319,6 +1319,37 @@ namespace FourSlash {
}
}
public baselineRename(marker: string, options: FourSlashInterface.RenameOptions) {
const position = this.getMarkerByName(marker).position;
const locations = this.languageService.findRenameLocations(
this.activeFile.fileName,
position,
options.findInStrings ?? false,
options.findInComments ?? false,
options.providePrefixAndSuffixTextForRename);
if (!locations) {
this.raiseError(`baselineRename failed. Could not rename at the provided position.`);
}
const renamesByFile = ts.group(locations, l => l.fileName);
const baselineContent = renamesByFile.map(renames => {
const { fileName } = renames[0];
const sortedRenames = ts.sort(renames, (a, b) => b.textSpan.start - a.textSpan.start);
let baselineFileContent = this.getFileContent(fileName);
for (const { textSpan } of sortedRenames) {
const isOriginalSpan = fileName === this.activeFile.fileName && ts.textSpanIntersectsWithPosition(textSpan, position);
baselineFileContent =
baselineFileContent.slice(0, textSpan.start) +
(isOriginalSpan ? "[|RENAME|]" : "RENAME") +
baselineFileContent.slice(textSpan.start + textSpan.length);
}
return `/*====== ${fileName} ======*/\n\n${baselineFileContent}`;
}).join("\n\n") + "\n";
Harness.Baseline.runBaseline(this.getBaselineFileNameForContainingTestFile(), baselineContent);
}
public verifyQuickInfoExists(negative: boolean) {
const actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition);
if (negative) {
+9
View File
@@ -516,6 +516,10 @@ namespace FourSlashInterface {
this.state.verifyRenameLocations(startRanges, options);
}
public baselineRename(marker: string, options: RenameOptions) {
this.state.baselineRename(marker, options);
}
public verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: FourSlash.TextSpan,
displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[], tags: ts.JSDocTagInfo[]) {
this.state.verifyQuickInfoDisplayParts(kind, kindModifiers, textSpan, displayParts, documentation, tags);
@@ -1623,4 +1627,9 @@ namespace FourSlashInterface {
template: string
};
export type RenameLocationOptions = FourSlash.Range | { readonly range: FourSlash.Range, readonly prefixText?: string, readonly suffixText?: string };
export interface RenameOptions {
readonly findInStrings?: boolean;
readonly findInComments?: boolean;
readonly providePrefixAndSuffixTextForRename?: boolean;
};
}
+6 -4
View File
@@ -1927,10 +1927,12 @@ namespace ts.FindAllReferences {
}
const exportSpecifier = getDeclarationOfKind<ExportSpecifier>(symbol, SyntaxKind.ExportSpecifier);
const localSymbol = exportSpecifier && checker.getExportSpecifierLocalTargetSymbol(exportSpecifier);
if (localSymbol) {
const res = cbSymbol(localSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.Node);
if (res) return res;
if (!isForRenamePopulateSearchSymbolSet || exportSpecifier && !exportSpecifier.propertyName) {
const localSymbol = exportSpecifier && checker.getExportSpecifierLocalTargetSymbol(exportSpecifier);
if (localSymbol) {
const res = cbSymbol(localSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.Node);
if (res) return res;
}
}
// symbolAtLocation for a binding element is the local symbol. See if the search symbol is the property.
@@ -0,0 +1,9 @@
/*====== /tests/cases/fourslash/a.ts ======*/
const name = {};
export { name as [|RENAME|] };
/*====== /tests/cases/fourslash/b.ts ======*/
import { RENAME } from './a';
const x = RENAME.toString();
@@ -0,0 +1,9 @@
/*====== /tests/cases/fourslash/a.ts ======*/
const RENAME = {};
export { [|RENAME|] };
/*====== /tests/cases/fourslash/b.ts ======*/
import { RENAME } from './a';
const x = RENAME.toString();
+3
View File
@@ -359,6 +359,7 @@ declare namespace FourSlashInterface {
renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string, fileToRename?: string, range?: Range, allowRenameOfImportPath?: boolean): void;
renameInfoFailed(message?: string, allowRenameOfImportPath?: boolean): void;
renameLocations(startRanges: ArrayOrSingle<Range>, options: RenameLocationsOptions): void;
baselineRename(marker: string, options: RenameOptions): void;
/** Verify the quick info available at the current marker. */
quickInfoIs(expectedText: string, expectedDocumentation?: string): void;
@@ -723,6 +724,8 @@ declare namespace FourSlashInterface {
readonly ranges: ReadonlyArray<RenameLocationOptions>;
readonly providePrefixAndSuffixTextForRename?: boolean;
};
type RenameOptions = { readonly findInStrings?: boolean, readonly findInComments?: boolean, readonly providePrefixAndSuffixTextForRename?: boolean };
type RenameLocationOptions = Range | { readonly range: Range, readonly prefixText?: string, readonly suffixText?: string };
type DiagnosticIgnoredInterpolations = { template: string }
}
@@ -0,0 +1,11 @@
/// <reference path="fourslash.ts" />
// @Filename: a.ts
////const name = {};
////export { name as name/**/ };
// @Filename: b.ts
////import { name } from './a';
////const x = name.toString();
verify.baselineRename("", { providePrefixAndSuffixTextForRename: false });
@@ -0,0 +1,11 @@
/// <reference path="fourslash.ts" />
// @Filename: a.ts
////const name = {};
////export { name/**/ };
// @Filename: b.ts
////import { name } from './a';
////const x = name.toString();
verify.baselineRename("", { providePrefixAndSuffixTextForRename: false });