Skip to content

Commit abbb79f

Browse files
author
Andy
authored
Combine getTouchingWord and getTouchingPropertyName (microsoft#22127)
1 parent afcced6 commit abbb79f

File tree

6 files changed

+43
-83
lines changed

6 files changed

+43
-83
lines changed

src/services/completions.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ namespace ts.Completions {
844844

845845
// Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS|
846846
// Skip this partial identifier and adjust the contextToken to the token that precedes it.
847-
if (contextToken && position <= contextToken.end && isWord(contextToken.kind)) {
847+
if (contextToken && position <= contextToken.end && (isIdentifier(contextToken) || isKeyword(contextToken.kind))) {
848848
const start = timestamp();
849849
contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined, insideJsDocTagTypeExpression);
850850
log("getCompletionData: Get previous token 2: " + (timestamp() - start));

src/services/documentHighlights.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* @internal */
22
namespace ts.DocumentHighlights {
33
export function getDocumentHighlights(program: Program, cancellationToken: CancellationToken, sourceFile: SourceFile, position: number, sourceFilesToSearch: ReadonlyArray<SourceFile>): DocumentHighlights[] | undefined {
4-
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
4+
const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
55

66
if (node.parent && (isJsxOpeningElement(node.parent) && node.parent.tagName === node || isJsxClosingElement(node.parent))) {
77
// For a JSX element, just highlight the matching tag, not all references.

src/services/findAllReferences.ts

+35-59
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,10 @@ namespace ts.FindAllReferences.Core {
716716
});
717717
}
718718

719+
function getPossibleSymbolReferenceNodes(sourceFile: SourceFile, symbolName: string, container: Node = sourceFile): ReadonlyArray<Node> {
720+
return getPossibleSymbolReferencePositions(sourceFile, symbolName, container).map(pos => getTouchingPropertyName(sourceFile, pos, /*includeJsDocComment*/ true));
721+
}
722+
719723
function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, container: Node = sourceFile): ReadonlyArray<number> {
720724
const positions: number[] = [];
721725

@@ -754,11 +758,9 @@ namespace ts.FindAllReferences.Core {
754758
function getLabelReferencesInNode(container: Node, targetLabel: Identifier): SymbolAndEntries[] {
755759
const sourceFile = container.getSourceFile();
756760
const labelName = targetLabel.text;
757-
const references = mapDefined(getPossibleSymbolReferencePositions(sourceFile, labelName, container), position => {
758-
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
761+
const references = mapDefined(getPossibleSymbolReferenceNodes(sourceFile, labelName, container), node =>
759762
// Only pick labels that are either the target label, or have a target that is the target label
760-
return node && (node === targetLabel || (isJumpStatementTarget(node) && getTargetLabel(node, labelName) === targetLabel)) ? nodeEntry(node) : undefined;
761-
});
763+
node === targetLabel || (isJumpStatementTarget(node) && getTargetLabel(node, labelName) === targetLabel) ? nodeEntry(node) : undefined);
762764
return [{ definition: { type: "label", node: targetLabel }, references }];
763765
}
764766

@@ -788,10 +790,8 @@ namespace ts.FindAllReferences.Core {
788790
function getAllReferencesForKeyword(sourceFiles: ReadonlyArray<SourceFile>, keywordKind: SyntaxKind, cancellationToken: CancellationToken): SymbolAndEntries[] {
789791
const references = flatMap(sourceFiles, sourceFile => {
790792
cancellationToken.throwIfCancellationRequested();
791-
return mapDefined(getPossibleSymbolReferencePositions(sourceFile, tokenToString(keywordKind), sourceFile), position => {
792-
const referenceLocation = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
793-
return referenceLocation.kind === keywordKind ? nodeEntry(referenceLocation) : undefined;
794-
});
793+
return mapDefined(getPossibleSymbolReferenceNodes(sourceFile, tokenToString(keywordKind), sourceFile), referenceLocation =>
794+
referenceLocation.kind === keywordKind ? nodeEntry(referenceLocation) : undefined);
795795
});
796796
return references.length ? [{ definition: { type: "keyword", node: references[0].node }, references }] : undefined;
797797
}
@@ -1255,9 +1255,8 @@ namespace ts.FindAllReferences.Core {
12551255
}
12561256

12571257
const sourceFile = searchSpaceNode.getSourceFile();
1258-
const references = mapDefined(getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode), position => {
1259-
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
1260-
if (!node || node.kind !== SyntaxKind.SuperKeyword) {
1258+
const references = mapDefined(getPossibleSymbolReferenceNodes(sourceFile, "super", searchSpaceNode), node => {
1259+
if (node.kind !== SyntaxKind.SuperKeyword) {
12611260
return;
12621261
}
12631262

@@ -1307,65 +1306,42 @@ namespace ts.FindAllReferences.Core {
13071306
return undefined;
13081307
}
13091308

1310-
const references: Entry[] = [];
1311-
for (const sourceFile of searchSpaceNode.kind === SyntaxKind.SourceFile ? sourceFiles : [searchSpaceNode.getSourceFile()]) {
1309+
const references = flatMap(searchSpaceNode.kind === SyntaxKind.SourceFile ? sourceFiles : [searchSpaceNode.getSourceFile()], sourceFile => {
13121310
cancellationToken.throwIfCancellationRequested();
1313-
const positions = getPossibleSymbolReferencePositions(sourceFile, "this", isSourceFile(searchSpaceNode) ? sourceFile : searchSpaceNode);
1314-
getThisReferencesInFile(sourceFile, searchSpaceNode.kind === SyntaxKind.SourceFile ? sourceFile : searchSpaceNode, positions, staticFlag, references);
1315-
}
1311+
return getPossibleSymbolReferenceNodes(sourceFile, "this", isSourceFile(searchSpaceNode) ? sourceFile : searchSpaceNode).filter(node => {
1312+
if (!isThis(node)) {
1313+
return false;
1314+
}
1315+
const container = getThisContainer(node, /* includeArrowFunctions */ false);
1316+
switch (searchSpaceNode.kind) {
1317+
case SyntaxKind.FunctionExpression:
1318+
case SyntaxKind.FunctionDeclaration:
1319+
return searchSpaceNode.symbol === container.symbol;
1320+
case SyntaxKind.MethodDeclaration:
1321+
case SyntaxKind.MethodSignature:
1322+
return isObjectLiteralMethod(searchSpaceNode) && searchSpaceNode.symbol === container.symbol;
1323+
case SyntaxKind.ClassExpression:
1324+
case SyntaxKind.ClassDeclaration:
1325+
// Make sure the container belongs to the same class
1326+
// and has the appropriate static modifier from the original container.
1327+
return container.parent && searchSpaceNode.symbol === container.parent.symbol && (getModifierFlags(container) & ModifierFlags.Static) === staticFlag;
1328+
case SyntaxKind.SourceFile:
1329+
return container.kind === SyntaxKind.SourceFile && !isExternalModule(<SourceFile>container);
1330+
}
1331+
});
1332+
}).map(n => nodeEntry(n));
13161333

13171334
return [{
13181335
definition: { type: "this", node: thisOrSuperKeyword },
13191336
references
13201337
}];
13211338
}
13221339

1323-
function getThisReferencesInFile(sourceFile: SourceFile, searchSpaceNode: Node, possiblePositions: ReadonlyArray<number>, staticFlag: ModifierFlags, result: Push<Entry>): void {
1324-
forEach(possiblePositions, position => {
1325-
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
1326-
if (!node || !isThis(node)) {
1327-
return;
1328-
}
1329-
1330-
const container = getThisContainer(node, /* includeArrowFunctions */ false);
1331-
1332-
switch (searchSpaceNode.kind) {
1333-
case SyntaxKind.FunctionExpression:
1334-
case SyntaxKind.FunctionDeclaration:
1335-
if (searchSpaceNode.symbol === container.symbol) {
1336-
result.push(nodeEntry(node));
1337-
}
1338-
break;
1339-
case SyntaxKind.MethodDeclaration:
1340-
case SyntaxKind.MethodSignature:
1341-
if (isObjectLiteralMethod(searchSpaceNode) && searchSpaceNode.symbol === container.symbol) {
1342-
result.push(nodeEntry(node));
1343-
}
1344-
break;
1345-
case SyntaxKind.ClassExpression:
1346-
case SyntaxKind.ClassDeclaration:
1347-
// Make sure the container belongs to the same class
1348-
// and has the appropriate static modifier from the original container.
1349-
if (container.parent && searchSpaceNode.symbol === container.parent.symbol && (getModifierFlags(container) & ModifierFlags.Static) === staticFlag) {
1350-
result.push(nodeEntry(node));
1351-
}
1352-
break;
1353-
case SyntaxKind.SourceFile:
1354-
if (container.kind === SyntaxKind.SourceFile && !isExternalModule(<SourceFile>container)) {
1355-
result.push(nodeEntry(node));
1356-
}
1357-
break;
1358-
}
1359-
});
1360-
}
1361-
13621340
function getReferencesForStringLiteral(node: StringLiteral, sourceFiles: ReadonlyArray<SourceFile>, cancellationToken: CancellationToken): SymbolAndEntries[] {
13631341
const references = flatMap(sourceFiles, sourceFile => {
13641342
cancellationToken.throwIfCancellationRequested();
1365-
return mapDefined(getPossibleSymbolReferencePositions(sourceFile, node.text), position => {
1366-
const ref = tryCast(getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false), isStringLiteral);
1367-
return ref && ref.text === node.text ? nodeEntry(ref, /*isInString*/ true) : undefined;
1368-
});
1343+
return mapDefined(getPossibleSymbolReferenceNodes(sourceFile, node.text), ref =>
1344+
isStringLiteral(ref) && ref.text === node.text ? nodeEntry(ref, /*isInString*/ true) : undefined);
13691345
});
13701346

13711347
return [{

src/services/organizeImports.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,7 @@ namespace ts.OrganizeImports {
131131
}
132132

133133
function getExternalModuleName(specifier: Expression) {
134-
return isStringLiteral(specifier) || isNoSubstitutionTemplateLiteral(specifier)
135-
? specifier.text
136-
: undefined;
134+
return isStringLiteralLike(specifier) ? specifier.text : undefined;
137135
}
138136

139137
/* @internal */ // Internal for testing

src/services/rename.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
namespace ts.Rename {
33
export function getRenameInfo(typeChecker: TypeChecker, defaultLibFileName: string, getCanonicalFileName: GetCanonicalFileName, sourceFile: SourceFile, position: number): RenameInfo {
44
const getCanonicalDefaultLibName = memoize(() => getCanonicalFileName(normalizePath(defaultLibFileName)));
5-
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
5+
const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
66
const renameInfo = node && nodeIsEligibleForRename(node)
77
? getRenameInfoForNode(node, typeChecker, sourceFile, isDefinedInLibraryFile)
88
: undefined;

src/services/utilities.ts

+4-18
Original file line numberDiff line numberDiff line change
@@ -627,18 +627,12 @@ namespace ts {
627627
return syntaxList;
628628
}
629629

630-
/* Gets the token whose text has range [start, end) and
631-
* position >= start and (position < end or (position === end && token is keyword or identifier))
632-
*/
633-
export function getTouchingWord(sourceFile: SourceFile, position: number, includeJsDocComment: boolean): Node {
634-
return getTouchingToken(sourceFile, position, includeJsDocComment, n => isWord(n.kind));
635-
}
636-
637-
/* Gets the token whose text has range [start, end) and position >= start
638-
* and (position < end or (position === end && token is keyword or identifier or numeric/string literal))
630+
/**
631+
* Gets the token whose text has range [start, end) and
632+
* position >= start and (position < end or (position === end && token is literal or keyword or identifier))
639633
*/
640634
export function getTouchingPropertyName(sourceFile: SourceFile, position: number, includeJsDocComment: boolean): Node {
641-
return getTouchingToken(sourceFile, position, includeJsDocComment, n => isPropertyName(n.kind));
635+
return getTouchingToken(sourceFile, position, includeJsDocComment, n => isPropertyNameLiteral(n) || isKeyword(n.kind));
642636
}
643637

644638
/**
@@ -1059,14 +1053,6 @@ namespace ts {
10591053
return undefined;
10601054
}
10611055

1062-
export function isWord(kind: SyntaxKind): boolean {
1063-
return kind === SyntaxKind.Identifier || isKeyword(kind);
1064-
}
1065-
1066-
function isPropertyName(kind: SyntaxKind): boolean {
1067-
return kind === SyntaxKind.StringLiteral || kind === SyntaxKind.NumericLiteral || isWord(kind);
1068-
}
1069-
10701056
export function isComment(kind: SyntaxKind): boolean {
10711057
return kind === SyntaxKind.SingleLineCommentTrivia || kind === SyntaxKind.MultiLineCommentTrivia;
10721058
}

0 commit comments

Comments
 (0)