Skip to content

Add 'fileToRename' property to RenameInfo #24702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
4 commits merged into from
Sep 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/harness/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ namespace ts.server {

return this.lastRenameEntry = {
canRename: body.info.canRename,
fileToRename: body.info.fileToRename,
displayName: body.info.displayName,
fullDisplayName: body.info.fullDisplayName,
kind: body.info.kind,
Expand Down
21 changes: 12 additions & 9 deletions src/harness/fourslash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,12 +420,12 @@ namespace FourSlash {
}
}

public goToEachRange(action: () => void) {
public goToEachRange(action: (range: Range) => void) {
const ranges = this.getRanges();
assert(ranges.length);
for (const range of ranges) {
this.selectRange(range);
action();
action(range);
}
}

Expand Down Expand Up @@ -1525,7 +1525,7 @@ Actual: ${stringify(fullActual)}`);
}
}

public verifyRenameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) {
public verifyRenameInfoSucceeded(displayName: string | undefined, fullDisplayName: string | undefined, kind: string | undefined, kindModifiers: string | undefined, fileToRename: string | undefined, expectedRange: Range | undefined): void {
const renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
if (!renameInfo.canRename) {
this.raiseError("Rename did not succeed");
Expand All @@ -1535,12 +1535,15 @@ Actual: ${stringify(fullActual)}`);
this.validate("fullDisplayName", fullDisplayName, renameInfo.fullDisplayName);
this.validate("kind", kind, renameInfo.kind);
this.validate("kindModifiers", kindModifiers, renameInfo.kindModifiers);
this.validate("fileToRename", fileToRename, renameInfo.fileToRename);

if (this.getRanges().length !== 1) {
this.raiseError("Expected a single range to be selected in the test file.");
if (!expectedRange) {
if (this.getRanges().length !== 1) {
this.raiseError("Expected a single range to be selected in the test file.");
}
expectedRange = this.getRanges()[0];
}

const expectedRange = this.getRanges()[0];
if (renameInfo.triggerSpan.start !== expectedRange.pos ||
ts.textSpanEnd(renameInfo.triggerSpan) !== expectedRange.end) {
this.raiseError("Expected triggerSpan [" + expectedRange.pos + "," + expectedRange.end + "). Got [" +
Expand Down Expand Up @@ -3977,7 +3980,7 @@ namespace FourSlashInterface {
this.state.goToRangeStart(range);
}

public eachRange(action: () => void) {
public eachRange(action: (range: FourSlash.Range) => void) {
this.state.goToEachRange(action);
}

Expand Down Expand Up @@ -4456,8 +4459,8 @@ namespace FourSlashInterface {
this.state.verifySemanticClassifications(classifications);
}

public renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) {
this.state.verifyRenameInfoSucceeded(displayName, fullDisplayName, kind, kindModifiers);
public renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string, fileToRename?: string, expectedRange?: FourSlash.Range) {
this.state.verifyRenameInfoSucceeded(displayName, fullDisplayName, kind, kindModifiers, fileToRename, expectedRange);
}

public renameInfoFailed(message?: string) {
Expand Down
6 changes: 6 additions & 0 deletions src/server/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,12 @@ namespace ts.server.protocol {
*/
canRename: boolean;

/**
* File or directory to rename.
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
*/
fileToRename?: string;

/**
* Error message if item can not be renamed.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/server/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1096,7 +1096,7 @@ namespace ts.server {
return projectInfo;
}

private getRenameInfo(args: protocol.FileLocationRequestArgs) {
private getRenameInfo(args: protocol.FileLocationRequestArgs): RenameInfo {
const { file, project } = this.getFileAndProject(args);
const position = this.getPositionInFile(args, file);
return project.getLanguageService().getRenameInfo(file, position);
Expand Down
24 changes: 22 additions & 2 deletions src/services/rename.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ namespace ts.Rename {
return undefined;
}

// Can't rename a module name.
if (isStringLiteralLike(node) && tryGetImportFromModuleSpecifier(node)) return undefined;
if (isStringLiteralLike(node) && tryGetImportFromModuleSpecifier(node)) {
return getRenameInfoForModule(node, sourceFile, symbol);
}

const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node);
const specifierName = (isImportOrExportSpecifierName(node) || isStringOrNumericLiteralLike(node) && node.parent.kind === SyntaxKind.ComputedPropertyName)
Expand All @@ -37,9 +38,28 @@ namespace ts.Rename {
return getRenameInfoSuccess(displayName, fullDisplayName, kind, SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile);
}

function getRenameInfoForModule(node: StringLiteralLike, sourceFile: SourceFile, moduleSymbol: Symbol): RenameInfo | undefined {
const moduleSourceFile = find(moduleSymbol.declarations, isSourceFile);
if (!moduleSourceFile) return undefined;
const withoutIndex = node.text.endsWith("/index") || node.text.endsWith("/index.js") ? undefined : tryRemoveSuffix(removeFileExtension(moduleSourceFile.fileName), "/index");
const name = withoutIndex === undefined ? moduleSourceFile.fileName : withoutIndex;
const kind = withoutIndex === undefined ? ScriptElementKind.moduleElement : ScriptElementKind.directory;
return {
canRename: true,
fileToRename: name,
kind,
displayName: name,
localizedErrorMessage: undefined,
fullDisplayName: name,
kindModifiers: ScriptElementKindModifier.none,
triggerSpan: createTriggerSpanForNode(node, sourceFile),
};
}

function getRenameInfoSuccess(displayName: string, fullDisplayName: string, kind: ScriptElementKind, kindModifiers: string, node: Node, sourceFile: SourceFile): RenameInfo {
return {
canRename: true,
fileToRename: undefined,
kind,
displayName,
localizedErrorMessage: undefined,
Expand Down
5 changes: 5 additions & 0 deletions src/services/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,11 @@ namespace ts {

export interface RenameInfo {
canRename: boolean;
/**
* File or directory to rename.
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
*/
fileToRename?: string;
localizedErrorMessage?: string;
displayName: string;
fullDisplayName: string;
Expand Down
10 changes: 10 additions & 0 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5101,6 +5101,11 @@ declare namespace ts {
}
interface RenameInfo {
canRename: boolean;
/**
* File or directory to rename.
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
*/
fileToRename?: string;
localizedErrorMessage?: string;
displayName: string;
fullDisplayName: string;
Expand Down Expand Up @@ -6422,6 +6427,11 @@ declare namespace ts.server.protocol {
* True if item can be renamed.
*/
canRename: boolean;
/**
* File or directory to rename.
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
*/
fileToRename?: string;
/**
* Error message if item can not be renamed.
*/
Expand Down
5 changes: 5 additions & 0 deletions tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5101,6 +5101,11 @@ declare namespace ts {
}
interface RenameInfo {
canRename: boolean;
/**
* File or directory to rename.
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
*/
fileToRename?: string;
localizedErrorMessage?: string;
displayName: string;
fullDisplayName: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ verify.renameLocations(r1, [r1, r2]);
verify.renameLocations(r2, [r0, r1, r2]);
for (const range of [r3, r4]) {
goTo.rangeStart(range);
verify.renameInfoFailed();
verify.renameInfoSucceeded(/*displayName*/ "/a.ts", /*fullDisplayName*/ "/a.ts", /*kind*/ "module", /*kindModifiers*/ "", /*fileToRename*/ "/a.ts", range);
}
4 changes: 2 additions & 2 deletions tests/cases/fourslash/fourslash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ declare namespace FourSlashInterface {
eachMarker(markers: ReadonlyArray<string>, action: (marker: Marker, index: number) => void): void;
eachMarker(action: (marker: Marker, index: number) => void): void;
rangeStart(range: Range): void;
eachRange(action: () => void): void;
eachRange(action: (range: Range) => void): void;
bof(): void;
eof(): void;
implementation(): void;
Expand Down Expand Up @@ -315,7 +315,7 @@ declare namespace FourSlashInterface {
text: string;
textSpan?: TextSpan;
}[]): void;
renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string): void;
renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string, fileToRename?: string, range?: Range): void;
renameInfoFailed(message?: string): void;
renameLocations(startRanges: ArrayOrSingle<Range>, options: Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges: Range[] }): void;

Expand Down
14 changes: 12 additions & 2 deletions tests/cases/fourslash/renameImport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,22 @@
// @Filename: /a.ts
////export const x = 0;

// @Filename: /dir/index.ts
////export const x = 0;

// @Filename: /b.ts
////import * as a from "[|./a|]";
////import a2 = require("[|./a"|]);
////import a2 = require("[|./a|]");
////import * as dir from "[|{| "target": "dir" |}./dir|]";
////import * as dir2 from "[|{| "target": "dir/index" |}./dir/index|]";

// @Filename: /c.js
////const a = require("[|./a|]");

verify.noErrors();
goTo.eachRange(() => { verify.renameInfoFailed(); });
goTo.eachRange(range => {
const target = range.marker && range.marker.data && range.marker.data.target;
const name = target === "dir" ? "/dir" : target === "dir/index" ? "/dir/index.ts" : "/a.ts";
const kind = target === "dir" ? "directory" : "module";
verify.renameInfoSucceeded(/*displayName*/ name, /*fullDisplayName*/ name, /*kind*/ kind, /*kindModifiers*/ "", /*fileToRename*/ name, range);
});