mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 20:25:23 -06:00
99 lines
4.7 KiB
TypeScript
99 lines
4.7 KiB
TypeScript
/* @internal */
|
|
namespace ts.Rename {
|
|
export function getRenameInfo(typeChecker: TypeChecker, defaultLibFileName: string, getCanonicalFileName: (fileName: string) => string, sourceFile: SourceFile, position: number): RenameInfo {
|
|
const canonicalDefaultLibName = getCanonicalFileName(ts.normalizePath(defaultLibFileName));
|
|
|
|
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
|
|
|
|
if (node) {
|
|
if (node.kind === SyntaxKind.Identifier ||
|
|
node.kind === SyntaxKind.StringLiteral ||
|
|
isLiteralNameOfPropertyDeclarationOrIndexAccess(node) ||
|
|
isThis(node)) {
|
|
const symbol = typeChecker.getSymbolAtLocation(node);
|
|
|
|
// Only allow a symbol to be renamed if it actually has at least one declaration.
|
|
if (symbol) {
|
|
const declarations = symbol.getDeclarations();
|
|
if (declarations && declarations.length > 0) {
|
|
// Disallow rename for elements that are defined in the standard TypeScript library.
|
|
if (forEach(declarations, isDefinedInLibraryFile)) {
|
|
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library));
|
|
}
|
|
|
|
const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node));
|
|
const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node);
|
|
if (kind) {
|
|
return {
|
|
canRename: true,
|
|
kind,
|
|
displayName,
|
|
localizedErrorMessage: undefined,
|
|
fullDisplayName: typeChecker.getFullyQualifiedName(symbol),
|
|
kindModifiers: SymbolDisplay.getSymbolModifiers(symbol),
|
|
triggerSpan: createTriggerSpanForNode(node, sourceFile)
|
|
};
|
|
}
|
|
}
|
|
}
|
|
else if (node.kind === SyntaxKind.StringLiteral) {
|
|
const type = getStringLiteralTypeForNode(<StringLiteral>node, typeChecker);
|
|
if (type) {
|
|
if (isDefinedInLibraryFile(node)) {
|
|
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library));
|
|
}
|
|
else {
|
|
const displayName = stripQuotes(type.text);
|
|
return {
|
|
canRename: true,
|
|
kind: ScriptElementKind.variableElement,
|
|
displayName,
|
|
localizedErrorMessage: undefined,
|
|
fullDisplayName: displayName,
|
|
kindModifiers: ScriptElementKindModifier.none,
|
|
triggerSpan: createTriggerSpanForNode(node, sourceFile)
|
|
};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element));
|
|
|
|
function getRenameInfoError(localizedErrorMessage: string): RenameInfo {
|
|
return {
|
|
canRename: false,
|
|
localizedErrorMessage: localizedErrorMessage,
|
|
displayName: undefined,
|
|
fullDisplayName: undefined,
|
|
kind: undefined,
|
|
kindModifiers: undefined,
|
|
triggerSpan: undefined
|
|
};
|
|
}
|
|
|
|
function isDefinedInLibraryFile(declaration: Node) {
|
|
if (defaultLibFileName) {
|
|
const sourceFile = declaration.getSourceFile();
|
|
const canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName));
|
|
if (canonicalName === canonicalDefaultLibName) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function createTriggerSpanForNode(node: Node, sourceFile: SourceFile) {
|
|
let start = node.getStart(sourceFile);
|
|
let width = node.getWidth(sourceFile);
|
|
if (node.kind === SyntaxKind.StringLiteral) {
|
|
// Exclude the quotes
|
|
start += 1;
|
|
width -= 2;
|
|
}
|
|
return createTextSpan(start, width);
|
|
}
|
|
}
|
|
}
|