Skip to content

Commit a478bfd

Browse files
author
Andy Hanson
committed
Simplify code in 'rename'
1 parent ceb5fac commit a478bfd

File tree

1 file changed

+76
-80
lines changed

1 file changed

+76
-80
lines changed

src/services/rename.ts

Lines changed: 76 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,94 @@
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-
64
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
5+
const renameInfo = node && nodeIsEligibleForRename(node)
6+
? getRenameInfoForNode(node, typeChecker, sourceFile, getIsDefinedInLibraryFile(defaultLibFileName, getCanonicalFileName))
7+
: undefined;
8+
return renameInfo || getRenameInfoError(Diagnostics.You_cannot_rename_this_element);
9+
}
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 getIsDefinedInLibraryFile(defaultLibFileName: string, getCanonicalFileName: (fileName: string) => string): (declaration: Node) => boolean {
12+
if (!defaultLibFileName) {
13+
return () => false;
14+
}
1415

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-
}
16+
const canonicalDefaultLibName = getCanonicalFileName(ts.normalizePath(defaultLibFileName));
17+
return declaration => {
18+
const sourceFile = declaration.getSourceFile();
19+
const canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName));
20+
return canonicalName === canonicalDefaultLibName;
21+
}
22+
}
23+
24+
function getRenameInfoForNode(node: Node, typeChecker: TypeChecker, sourceFile: SourceFile, isDefinedInLibraryFile: (declaration: Node) => boolean): RenameInfo | undefined {
25+
const symbol = typeChecker.getSymbolAtLocation(node);
2326

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-
}
27+
// Only allow a symbol to be renamed if it actually has at least one declaration.
28+
if (symbol) {
29+
const declarations = symbol.getDeclarations();
30+
if (declarations && declarations.length > 0) {
31+
// Disallow rename for elements that are defined in the standard TypeScript library.
32+
if (some(declarations, isDefinedInLibraryFile)) {
33+
return getRenameInfoError(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library);
3834
}
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-
}
35+
36+
const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node));
37+
const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node);
38+
return kind ? getRenameInfoSuccess(displayName, typeChecker.getFullyQualifiedName(symbol), kind, SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile) : undefined;
39+
}
40+
}
41+
else if (node.kind === SyntaxKind.StringLiteral) {
42+
const type = getStringLiteralTypeForNode(<StringLiteral>node, typeChecker);
43+
if (type) {
44+
if (isDefinedInLibraryFile(node)) {
45+
return getRenameInfoError(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library);
5846
}
47+
48+
const displayName = stripQuotes(type.text);
49+
return getRenameInfoSuccess(displayName, displayName, ScriptElementKind.variableElement, ScriptElementKindModifier.none, node, sourceFile);
5950
}
6051
}
52+
}
6153

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

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-
}
66+
function getRenameInfoError(diagnostic: DiagnosticMessage): RenameInfo {
67+
return {
68+
canRename: false,
69+
localizedErrorMessage: getLocaleSpecificMessage(diagnostic),
70+
displayName: undefined,
71+
fullDisplayName: undefined,
72+
kind: undefined,
73+
kindModifiers: undefined,
74+
triggerSpan: undefined
75+
};
76+
}
7577

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;
78+
function createTriggerSpanForNode(node: Node, sourceFile: SourceFile) {
79+
let start = node.getStart(sourceFile);
80+
let width = node.getWidth(sourceFile);
81+
if (node.kind === SyntaxKind.StringLiteral) {
82+
// Exclude the quotes
83+
start += 1;
84+
width -= 2;
8585
}
86+
return createTextSpan(start, width);
87+
}
8688

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-
}
89+
function nodeIsEligibleForRename(node: Node) {
90+
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.StringLiteral ||
91+
isLiteralNameOfPropertyDeclarationOrIndexAccess(node) ||
92+
isThis(node);
9793
}
9894
}

0 commit comments

Comments
 (0)