Skip to content

Commit 69b0b56

Browse files
author
Andy Hanson
committed
Factor out getRenameInfo
1 parent 2d64a23 commit 69b0b56

File tree

5 files changed

+109
-105
lines changed

5 files changed

+109
-105
lines changed

src/services/findAllReferences.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,4 +1114,12 @@ namespace ts.FindAllReferences {
11141114
function tryGetClassByExtendingIdentifier(node: Node): ClassLikeDeclaration | undefined {
11151115
return tryGetClassExtendingExpressionWithTypeArguments(climbPastPropertyAccess(node).parent);
11161116
}
1117+
1118+
function isNameOfExternalModuleImportOrDeclaration(node: Node): boolean {
1119+
if (node.kind === SyntaxKind.StringLiteral) {
1120+
return isNameOfModuleDeclaration(node) || isExpressionOfExternalModuleImportEqualsDeclaration(node);
1121+
}
1122+
1123+
return false;
1124+
}
11171125
}

src/services/rename.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/* @internal */
2+
namespace ts.Rename {
3+
export function getRenameInfo(typeChecker: TypeChecker, defaultLibFileName: string, getCanonicalFileName: (fileName: string) => string, sourceFile: SourceFile, position: number): RenameInfo {
4+
const canonicalDefaultLibName = getCanonicalFileName(ts.normalizePath(defaultLibFileName));
5+
6+
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
7+
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);
14+
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+
}
23+
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+
}
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(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+
}
58+
}
59+
}
60+
}
61+
62+
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element));
63+
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+
}
75+
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;
85+
}
86+
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+
}
97+
}
98+
}

src/services/services.ts

Lines changed: 2 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
/// <reference path='outliningElementsCollector.ts' />
1919
/// <reference path='patternMatcher.ts' />
2020
/// <reference path='preProcess.ts' />
21+
/// <reference path='rename.ts' />
2122
/// <reference path='signatureHelp.ts' />
2223
/// <reference path='symbolDisplay.ts' />
2324
/// <reference path='formatting\formatting.ts' />
@@ -1419,104 +1420,8 @@ namespace ts {
14191420

14201421
function getRenameInfo(fileName: string, position: number): RenameInfo {
14211422
synchronizeHostData();
1422-
1423-
const sourceFile = getValidSourceFile(fileName);
1424-
const typeChecker = program.getTypeChecker();
1425-
14261423
const defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings());
1427-
const canonicalDefaultLibName = getCanonicalFileName(ts.normalizePath(defaultLibFileName));
1428-
1429-
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
1430-
1431-
if (node) {
1432-
if (node.kind === SyntaxKind.Identifier ||
1433-
node.kind === SyntaxKind.StringLiteral ||
1434-
isLiteralNameOfPropertyDeclarationOrIndexAccess(node) ||
1435-
isThis(node)) {
1436-
const symbol = typeChecker.getSymbolAtLocation(node);
1437-
1438-
// Only allow a symbol to be renamed if it actually has at least one declaration.
1439-
if (symbol) {
1440-
const declarations = symbol.getDeclarations();
1441-
if (declarations && declarations.length > 0) {
1442-
// Disallow rename for elements that are defined in the standard TypeScript library.
1443-
if (forEach(declarations, isDefinedInLibraryFile)) {
1444-
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library));
1445-
}
1446-
1447-
const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node));
1448-
const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node);
1449-
if (kind) {
1450-
return {
1451-
canRename: true,
1452-
kind,
1453-
displayName,
1454-
localizedErrorMessage: undefined,
1455-
fullDisplayName: typeChecker.getFullyQualifiedName(symbol),
1456-
kindModifiers: SymbolDisplay.getSymbolModifiers(symbol),
1457-
triggerSpan: createTriggerSpanForNode(node, sourceFile)
1458-
};
1459-
}
1460-
}
1461-
}
1462-
else if (node.kind === SyntaxKind.StringLiteral) {
1463-
const type = getStringLiteralTypeForNode(<StringLiteral>node, typeChecker);
1464-
if (type) {
1465-
if (isDefinedInLibraryFile(node)) {
1466-
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library));
1467-
}
1468-
else {
1469-
const displayName = stripQuotes(type.text);
1470-
return {
1471-
canRename: true,
1472-
kind: ScriptElementKind.variableElement,
1473-
displayName,
1474-
localizedErrorMessage: undefined,
1475-
fullDisplayName: displayName,
1476-
kindModifiers: ScriptElementKindModifier.none,
1477-
triggerSpan: createTriggerSpanForNode(node, sourceFile)
1478-
};
1479-
}
1480-
}
1481-
}
1482-
}
1483-
}
1484-
1485-
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element));
1486-
1487-
function getRenameInfoError(localizedErrorMessage: string): RenameInfo {
1488-
return {
1489-
canRename: false,
1490-
localizedErrorMessage: localizedErrorMessage,
1491-
displayName: undefined,
1492-
fullDisplayName: undefined,
1493-
kind: undefined,
1494-
kindModifiers: undefined,
1495-
triggerSpan: undefined
1496-
};
1497-
}
1498-
1499-
function isDefinedInLibraryFile(declaration: Node) {
1500-
if (defaultLibFileName) {
1501-
const sourceFile = declaration.getSourceFile();
1502-
const canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName));
1503-
if (canonicalName === canonicalDefaultLibName) {
1504-
return true;
1505-
}
1506-
}
1507-
return false;
1508-
}
1509-
1510-
function createTriggerSpanForNode(node: Node, sourceFile: SourceFile) {
1511-
let start = node.getStart(sourceFile);
1512-
let width = node.getWidth(sourceFile);
1513-
if (node.kind === SyntaxKind.StringLiteral) {
1514-
// Exclude the quotes
1515-
start += 1;
1516-
width -= 2;
1517-
}
1518-
return createTextSpan(start, width);
1519-
}
1424+
return Rename.getRenameInfo(program.getTypeChecker(), defaultLibFileName, getCanonicalFileName, getValidSourceFile(fileName), position);
15201425
}
15211426

15221427
return {

src/services/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"outliningElementsCollector.ts",
5757
"patternMatcher.ts",
5858
"preProcess.ts",
59+
"rename.ts",
5960
"services.ts",
6061
"shims.ts",
6162
"signatureHelp.ts",

src/services/utilities.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,6 @@ namespace ts {
8787
return false;
8888
}
8989

90-
export function isNameOfExternalModuleImportOrDeclaration(node: Node): boolean {
91-
if (node.kind === SyntaxKind.StringLiteral) {
92-
return isNameOfModuleDeclaration(node) || isExpressionOfExternalModuleImportEqualsDeclaration(node);
93-
}
94-
95-
return false;
96-
}
97-
9890
export function isExpressionOfExternalModuleImportEqualsDeclaration(node: Node) {
9991
return isExternalModuleImportEqualsDeclaration(node.parent.parent) &&
10092
getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node;

0 commit comments

Comments
 (0)