Merge pull request #682 from Microsoft/getRenameInfo

Implement the getRenameInfo language service entrypoint.
This commit is contained in:
CyrusNajmabadi 2014-09-17 15:52:12 -07:00
commit d867cecf74
7 changed files with 92 additions and 2 deletions

View File

@ -65,7 +65,8 @@ module ts {
symbolToString: symbolToString,
getAugmentedPropertiesOfApparentType: getAugmentedPropertiesOfApparentType,
getRootSymbol: getRootSymbol,
getContextualType: getContextualType
getContextualType: getContextualType,
getFullyQualifiedName: getFullyQualifiedName
};
var undefinedSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "undefined");

View File

@ -634,6 +634,7 @@ module ts {
getApparentType(type: Type): ApparentType;
typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string;
symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string;
getFullyQualifiedName(symbol: Symbol): string;
getAugmentedPropertiesOfApparentType(type: Type): Symbol[];
getRootSymbol(symbol: Symbol): Symbol;
getContextualType(node: Node): Type;

View File

@ -898,6 +898,44 @@ module FourSlash {
}
}
private validate(name: string, expected: string, actual: string) {
if (expected && expected !== actual) {
throw new Error("Expected " + name + " '" + expected + "'. Got '" + actual + "' instead.");
}
}
public verifyRenameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) {
var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
if (!renameInfo.canRename) {
throw new Error("Rename did not succeed");
}
this.validate("displayName", displayName, renameInfo.displayName);
this.validate("fullDisplayName", fullDisplayName, renameInfo.fullDisplayName);
this.validate("kind", kind, renameInfo.kind);
this.validate("kindModifiers", kindModifiers, renameInfo.kindModifiers);
if (this.getRanges().length !== 1) {
throw new Error("Expected a single range to be selected in the test file.");
}
var expectedRange = this.getRanges()[0];
if (renameInfo.triggerSpan.start() !== expectedRange.start ||
renameInfo.triggerSpan.end() !== expectedRange.end) {
throw new Error("Expected triggerSpan [" + expectedRange.start + "," + expectedRange.end + "). Got [" +
renameInfo.triggerSpan.start() + "," + renameInfo.triggerSpan.end() + ") instead.");
}
}
public verifyRenameInfoFailed(message?: string) {
var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
if (renameInfo.canRename) {
throw new Error("Rename was expected to fail");
}
this.validate("error", message, renameInfo.localizedErrorMessage);
}
//private getFormalParameter() {
// var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition);
// return help.formal;

View File

@ -3896,6 +3896,32 @@ module ts {
return null;
}
function getRenameInfo(fileName: string, position: number): RenameInfo {
synchronizeHostData();
fileName = TypeScript.switchToForwardSlashes(fileName);
var sourceFile = getSourceFile(fileName);
var node = getNodeAtPosition(sourceFile, position);
// Can only rename an identifier.
if (node && node.kind === SyntaxKind.Identifier) {
var symbol = typeInfoResolver.getSymbolInfo(node);
// Only allow a symbol to be renamed if it actually has at least one declaration.
if (symbol && symbol.getDeclarations() && symbol.getDeclarations().length > 0) {
var kind = getSymbolKind(symbol);
if (kind) {
return RenameInfo.Create(symbol.name, typeInfoResolver.getFullyQualifiedName(symbol), kind,
getNodeModifiers(symbol.getDeclarations()[0]),
new TypeScript.TextSpan(node.getStart(), node.getWidth()));
}
}
}
return RenameInfo.CreateError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element.key));
}
return {
dispose: dispose,
cleanupSemanticCache: cleanupSemanticCache,
@ -3916,7 +3942,7 @@ module ts {
getNameOrDottedNameSpan: getNameOrDottedNameSpan,
getBreakpointStatementAtPosition: getBreakpointStatementAtPosition,
getNavigateToItems: getNavigateToItems,
getRenameInfo: (fileName, position): RenameInfo => RenameInfo.CreateError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element.key)),
getRenameInfo: getRenameInfo,
getNavigationBarItems: getNavigationBarItems,
getOutliningSpans: getOutliningSpans,
getTodoComments: getTodoComments,

View File

@ -404,6 +404,14 @@ module FourSlashInterface {
public semanticClassificationsAre(...classifications: { classificationType: string; text: string }[]) {
FourSlash.currentTestState.verifySemanticClassifications(classifications);
}
public renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) {
FourSlash.currentTestState.verifyRenameInfoSucceeded(displayName, fullDisplayName, kind, kindModifiers)
}
public renameInfoFailed(message?: string) {
FourSlash.currentTestState.verifyRenameInfoFailed(message)
}
}
export class edit {

View File

@ -0,0 +1,8 @@
/// <reference path="fourslash.ts"/>
////class [|/**/C|] {
////
////}
goTo.marker("");
verify.renameInfoSucceeded("C");

View File

@ -0,0 +1,8 @@
/// <reference path="fourslash.ts"/>
/////**/class C {
////
////}
goTo.marker("");
verify.renameInfoFailed();