Skip to content

Commit 8144c89

Browse files
author
Andy
authored
Merge pull request microsoft#13660 from Microsoft/rename
Simplify code in 'rename'
2 parents c55b9ff + 33b8677 commit 8144c89

File tree

1 file changed

+74
-80
lines changed

1 file changed

+74
-80
lines changed

src/services/rename.ts

Lines changed: 74 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,92 @@
11
/* @internal */
22
namespace ts.Rename {
33
export function getRenameInfo(typeChecker: TypeChecker, defaultLibFileName: string, getCanonicalFileName: (fileName: string) => string, sourceFile: SourceFile, position: number): RenameInfo {
4-
const canonicalDefaultLibName = getCanonicalFileName(ts.normalizePath(defaultLibFileName));
5-
4+
const getCanonicalDefaultLibName = memoize(() => getCanonicalFileName(ts.normalizePath(defaultLibFileName)));
65
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
6+
const renameInfo = node && nodeIsEligibleForRename(node)
7+
? getRenameInfoForNode(node, typeChecker, sourceFile, isDefinedInLibraryFile)
8+
: undefined;
9+
return renameInfo || getRenameInfoError(Diagnostics.You_cannot_rename_this_element);
710

8-
if (node) {
9-
if (node.kind === SyntaxKind.Identifier ||
10-
node.kind === SyntaxKind.StringLiteral ||
11-
isLiteralNameOfPropertyDeclarationOrIndexAccess(node) ||
12-
isThis(node)) {
13-
const symbol = typeChecker.getSymbolAtLocation(node);
11+
function isDefinedInLibraryFile(declaration: Node) {
12+
if (!defaultLibFileName) {
13+
return false;
14+
}
15+
16+
const sourceFile = declaration.getSourceFile();
17+
const canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName));
18+
return canonicalName === getCanonicalDefaultLibName();
19+
}
20+
}
1421

15-
// Only allow a symbol to be renamed if it actually has at least one declaration.
16-
if (symbol) {
17-
const declarations = symbol.getDeclarations();
18-
if (declarations && declarations.length > 0) {
19-
// Disallow rename for elements that are defined in the standard TypeScript library.
20-
if (forEach(declarations, isDefinedInLibraryFile)) {
21-
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library));
22-
}
22+
function getRenameInfoForNode(node: Node, typeChecker: TypeChecker, sourceFile: SourceFile, isDefinedInLibraryFile: (declaration: Node) => boolean): RenameInfo | undefined {
23+
const symbol = typeChecker.getSymbolAtLocation(node);
2324

24-
const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node));
25-
const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node);
26-
if (kind) {
27-
return {
28-
canRename: true,
29-
kind,
30-
displayName,
31-
localizedErrorMessage: undefined,
32-
fullDisplayName: typeChecker.getFullyQualifiedName(symbol),
33-
kindModifiers: SymbolDisplay.getSymbolModifiers(symbol),
34-
triggerSpan: createTriggerSpanForNode(node, sourceFile)
35-
};
36-
}
37-
}
25+
// Only allow a symbol to be renamed if it actually has at least one declaration.
26+
if (symbol) {
27+
const declarations = symbol.getDeclarations();
28+
if (declarations && declarations.length > 0) {
29+
// Disallow rename for elements that are defined in the standard TypeScript library.
30+
if (some(declarations, isDefinedInLibraryFile)) {
31+
return getRenameInfoError(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library);
3832
}
39-
else if (node.kind === SyntaxKind.StringLiteral) {
40-
const type = getStringLiteralTypeForNode(<StringLiteral>node, typeChecker);
41-
if (type) {
42-
if (isDefinedInLibraryFile(node)) {
43-
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library));
44-
}
45-
else {
46-
const displayName = stripQuotes(type.text);
47-
return {
48-
canRename: true,
49-
kind: ScriptElementKind.variableElement,
50-
displayName,
51-
localizedErrorMessage: undefined,
52-
fullDisplayName: displayName,
53-
kindModifiers: ScriptElementKindModifier.none,
54-
triggerSpan: createTriggerSpanForNode(node, sourceFile)
55-
};
56-
}
57-
}
33+
34+
const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node));
35+
const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node);
36+
return kind ? getRenameInfoSuccess(displayName, typeChecker.getFullyQualifiedName(symbol), kind, SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile) : undefined;
37+
}
38+
}
39+
else if (node.kind === SyntaxKind.StringLiteral) {
40+
const type = getStringLiteralTypeForNode(<StringLiteral>node, typeChecker);
41+
if (type) {
42+
if (isDefinedInLibraryFile(node)) {
43+
return getRenameInfoError(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library);
5844
}
45+
46+
const displayName = stripQuotes(type.text);
47+
return getRenameInfoSuccess(displayName, displayName, ScriptElementKind.variableElement, ScriptElementKindModifier.none, node, sourceFile);
5948
}
6049
}
50+
}
6151

62-
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element));
52+
function getRenameInfoSuccess(displayName: string, fullDisplayName: string, kind: string, kindModifiers: string, node: Node, sourceFile: SourceFile): RenameInfo {
53+
return {
54+
canRename: true,
55+
kind,
56+
displayName,
57+
localizedErrorMessage: undefined,
58+
fullDisplayName,
59+
kindModifiers,
60+
triggerSpan: createTriggerSpanForNode(node, sourceFile)
61+
};
62+
}
6363

64-
function getRenameInfoError(localizedErrorMessage: string): RenameInfo {
65-
return {
66-
canRename: false,
67-
localizedErrorMessage: localizedErrorMessage,
68-
displayName: undefined,
69-
fullDisplayName: undefined,
70-
kind: undefined,
71-
kindModifiers: undefined,
72-
triggerSpan: undefined
73-
};
74-
}
64+
function getRenameInfoError(diagnostic: DiagnosticMessage): RenameInfo {
65+
return {
66+
canRename: false,
67+
localizedErrorMessage: getLocaleSpecificMessage(diagnostic),
68+
displayName: undefined,
69+
fullDisplayName: undefined,
70+
kind: undefined,
71+
kindModifiers: undefined,
72+
triggerSpan: undefined
73+
};
74+
}
7575

76-
function isDefinedInLibraryFile(declaration: Node) {
77-
if (defaultLibFileName) {
78-
const sourceFile = declaration.getSourceFile();
79-
const canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName));
80-
if (canonicalName === canonicalDefaultLibName) {
81-
return true;
82-
}
83-
}
84-
return false;
76+
function createTriggerSpanForNode(node: Node, sourceFile: SourceFile) {
77+
let start = node.getStart(sourceFile);
78+
let width = node.getWidth(sourceFile);
79+
if (node.kind === SyntaxKind.StringLiteral) {
80+
// Exclude the quotes
81+
start += 1;
82+
width -= 2;
8583
}
84+
return createTextSpan(start, width);
85+
}
8686

87-
function createTriggerSpanForNode(node: Node, sourceFile: SourceFile) {
88-
let start = node.getStart(sourceFile);
89-
let width = node.getWidth(sourceFile);
90-
if (node.kind === SyntaxKind.StringLiteral) {
91-
// Exclude the quotes
92-
start += 1;
93-
width -= 2;
94-
}
95-
return createTextSpan(start, width);
96-
}
87+
function nodeIsEligibleForRename(node: Node) {
88+
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.StringLiteral ||
89+
isLiteralNameOfPropertyDeclarationOrIndexAccess(node) ||
90+
isThis(node);
9791
}
9892
}

0 commit comments

Comments
 (0)