Skip to content

Commit d867cec

Browse files
Merge pull request #682 from Microsoft/getRenameInfo
Implement the getRenameInfo language service entrypoint.
2 parents b1f243d + 2eb14aa commit d867cec

File tree

7 files changed

+92
-2
lines changed

7 files changed

+92
-2
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ module ts {
6565
symbolToString: symbolToString,
6666
getAugmentedPropertiesOfApparentType: getAugmentedPropertiesOfApparentType,
6767
getRootSymbol: getRootSymbol,
68-
getContextualType: getContextualType
68+
getContextualType: getContextualType,
69+
getFullyQualifiedName: getFullyQualifiedName
6970
};
7071

7172
var undefinedSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "undefined");

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,7 @@ module ts {
634634
getApparentType(type: Type): ApparentType;
635635
typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string;
636636
symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string;
637+
getFullyQualifiedName(symbol: Symbol): string;
637638
getAugmentedPropertiesOfApparentType(type: Type): Symbol[];
638639
getRootSymbol(symbol: Symbol): Symbol;
639640
getContextualType(node: Node): Type;

src/harness/fourslash.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,44 @@ module FourSlash {
898898
}
899899
}
900900

901+
private validate(name: string, expected: string, actual: string) {
902+
if (expected && expected !== actual) {
903+
throw new Error("Expected " + name + " '" + expected + "'. Got '" + actual + "' instead.");
904+
}
905+
}
906+
907+
public verifyRenameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) {
908+
var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
909+
if (!renameInfo.canRename) {
910+
throw new Error("Rename did not succeed");
911+
}
912+
913+
this.validate("displayName", displayName, renameInfo.displayName);
914+
this.validate("fullDisplayName", fullDisplayName, renameInfo.fullDisplayName);
915+
this.validate("kind", kind, renameInfo.kind);
916+
this.validate("kindModifiers", kindModifiers, renameInfo.kindModifiers);
917+
918+
if (this.getRanges().length !== 1) {
919+
throw new Error("Expected a single range to be selected in the test file.");
920+
}
921+
922+
var expectedRange = this.getRanges()[0];
923+
if (renameInfo.triggerSpan.start() !== expectedRange.start ||
924+
renameInfo.triggerSpan.end() !== expectedRange.end) {
925+
throw new Error("Expected triggerSpan [" + expectedRange.start + "," + expectedRange.end + "). Got [" +
926+
renameInfo.triggerSpan.start() + "," + renameInfo.triggerSpan.end() + ") instead.");
927+
}
928+
}
929+
930+
public verifyRenameInfoFailed(message?: string) {
931+
var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
932+
if (renameInfo.canRename) {
933+
throw new Error("Rename was expected to fail");
934+
}
935+
936+
this.validate("error", message, renameInfo.localizedErrorMessage);
937+
}
938+
901939
//private getFormalParameter() {
902940
// var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition);
903941
// return help.formal;

src/services/services.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3896,6 +3896,32 @@ module ts {
38963896
return null;
38973897
}
38983898

3899+
function getRenameInfo(fileName: string, position: number): RenameInfo {
3900+
synchronizeHostData();
3901+
3902+
fileName = TypeScript.switchToForwardSlashes(fileName);
3903+
var sourceFile = getSourceFile(fileName);
3904+
3905+
var node = getNodeAtPosition(sourceFile, position);
3906+
3907+
// Can only rename an identifier.
3908+
if (node && node.kind === SyntaxKind.Identifier) {
3909+
var symbol = typeInfoResolver.getSymbolInfo(node);
3910+
3911+
// Only allow a symbol to be renamed if it actually has at least one declaration.
3912+
if (symbol && symbol.getDeclarations() && symbol.getDeclarations().length > 0) {
3913+
var kind = getSymbolKind(symbol);
3914+
if (kind) {
3915+
return RenameInfo.Create(symbol.name, typeInfoResolver.getFullyQualifiedName(symbol), kind,
3916+
getNodeModifiers(symbol.getDeclarations()[0]),
3917+
new TypeScript.TextSpan(node.getStart(), node.getWidth()));
3918+
}
3919+
}
3920+
}
3921+
3922+
return RenameInfo.CreateError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element.key));
3923+
}
3924+
38993925
return {
39003926
dispose: dispose,
39013927
cleanupSemanticCache: cleanupSemanticCache,
@@ -3916,7 +3942,7 @@ module ts {
39163942
getNameOrDottedNameSpan: getNameOrDottedNameSpan,
39173943
getBreakpointStatementAtPosition: getBreakpointStatementAtPosition,
39183944
getNavigateToItems: getNavigateToItems,
3919-
getRenameInfo: (fileName, position): RenameInfo => RenameInfo.CreateError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element.key)),
3945+
getRenameInfo: getRenameInfo,
39203946
getNavigationBarItems: getNavigationBarItems,
39213947
getOutliningSpans: getOutliningSpans,
39223948
getTodoComments: getTodoComments,

tests/cases/fourslash/fourslash.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,14 @@ module FourSlashInterface {
404404
public semanticClassificationsAre(...classifications: { classificationType: string; text: string }[]) {
405405
FourSlash.currentTestState.verifySemanticClassifications(classifications);
406406
}
407+
408+
public renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) {
409+
FourSlash.currentTestState.verifyRenameInfoSucceeded(displayName, fullDisplayName, kind, kindModifiers)
410+
}
411+
412+
public renameInfoFailed(message?: string) {
413+
FourSlash.currentTestState.verifyRenameInfoFailed(message)
414+
}
407415
}
408416

409417
export class edit {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
////class [|/**/C|] {
4+
////
5+
////}
6+
7+
goTo.marker("");
8+
verify.renameInfoSucceeded("C");
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
/////**/class C {
4+
////
5+
////}
6+
7+
goTo.marker("");
8+
verify.renameInfoFailed();

0 commit comments

Comments
 (0)