Skip to content

Commit 0defde7

Browse files
author
Andy Hanson
committed
Services utilities: Combine isInsideComment with isInComment
1 parent 278fb80 commit 0defde7

File tree

3 files changed

+30
-60
lines changed

3 files changed

+30
-60
lines changed

src/services/completions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ namespace ts.Completions {
359359

360360
start = timestamp();
361361
// Completion not allowed inside comments, bail out if this is the case
362-
const insideComment = isInsideComment(sourceFile, currentToken, position);
362+
const insideComment = isInComment(sourceFile, position, currentToken);
363363
log("getCompletionData: Is inside comment: " + (timestamp() - start));
364364

365365
if (insideComment) {

src/services/services.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,8 +1853,8 @@ namespace ts {
18531853

18541854
// OK, we have found a match in the file. This is only an acceptable match if
18551855
// it is contained within a comment.
1856-
const token = getTokenAtPosition(sourceFile, matchPosition);
1857-
if (!isInsideComment(sourceFile, token, matchPosition)) {
1856+
1857+
if (!isInComment(sourceFile, matchPosition)) {
18581858
continue;
18591859
}
18601860

src/services/utilities.ts

Lines changed: 27 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -256,37 +256,6 @@ namespace ts {
256256
getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node;
257257
}
258258

259-
/** Returns true if the position is within a comment */
260-
export function isInsideComment(sourceFile: SourceFile, token: Node, position: number): boolean {
261-
// The position has to be: 1. in the leading trivia (before token.getStart()), and 2. within a comment
262-
return position <= token.getStart(sourceFile) &&
263-
(isInsideCommentRange(getTrailingCommentRanges(sourceFile.text, token.getFullStart())) ||
264-
isInsideCommentRange(getLeadingCommentRanges(sourceFile.text, token.getFullStart())));
265-
266-
function isInsideCommentRange(comments: CommentRange[]): boolean {
267-
return forEach(comments, comment => {
268-
// either we are 1. completely inside the comment, or 2. at the end of the comment
269-
if (comment.pos < position && position < comment.end) {
270-
return true;
271-
}
272-
else if (position === comment.end) {
273-
const text = sourceFile.text;
274-
const width = comment.end - comment.pos;
275-
// is single line comment or just /*
276-
if (width <= 2 || text.charCodeAt(comment.pos + 1) === CharacterCodes.slash) {
277-
return true;
278-
}
279-
else {
280-
// is unterminated multi-line comment
281-
return !(text.charCodeAt(comment.end - 1) === CharacterCodes.slash &&
282-
text.charCodeAt(comment.end - 2) === CharacterCodes.asterisk);
283-
}
284-
}
285-
return false;
286-
});
287-
}
288-
}
289-
290259
export function getContainerNode(node: Node): Declaration {
291260
while (true) {
292261
node = node.parent;
@@ -834,10 +803,6 @@ namespace ts {
834803
return false;
835804
}
836805

837-
export function isInComment(sourceFile: SourceFile, position: number) {
838-
return isInCommentHelper(sourceFile, position, /*predicate*/ undefined);
839-
}
840-
841806
/**
842807
* returns true if the position is in between the open and close elements of an JSX expression.
843808
*/
@@ -883,15 +848,26 @@ namespace ts {
883848
}
884849

885850
/**
886-
* Returns true if the cursor at position in sourceFile is within a comment that additionally
887-
* satisfies predicate, and false otherwise.
851+
* Returns true if the cursor at position in sourceFile is within a comment.
852+
*
853+
* @param tokenAtPosition Must equal `getTokenAtPosition(sourceFile, position)
854+
* @param predicate Additional predicate to test on the comment range.
888855
*/
889-
export function isInCommentHelper(sourceFile: SourceFile, position: number, predicate?: (c: CommentRange) => boolean): boolean {
890-
const token = getTokenAtPosition(sourceFile, position);
856+
export function isInComment(sourceFile: SourceFile, position: number, tokenAtPosition = getTokenAtPosition(sourceFile, position), predicate?: (c: CommentRange) => boolean): boolean {
857+
return position <= tokenAtPosition.getStart(sourceFile) &&
858+
(isInCommentRange(getLeadingCommentRanges(sourceFile.text, tokenAtPosition.pos)) ||
859+
isInCommentRange(getTrailingCommentRanges(sourceFile.text, tokenAtPosition.pos)));
891860

892-
if (token && position <= token.getStart(sourceFile)) {
893-
const commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos);
861+
function isInCommentRange(commentRanges: CommentRange[]): boolean {
862+
return forEach(commentRanges, c => isPositionInCommentRange(c, position, sourceFile.text) && (!predicate || predicate(c)));
863+
}
864+
}
894865

866+
function isPositionInCommentRange({ pos, end, kind }: ts.CommentRange, position: number, text: string): boolean {
867+
if (pos < position && position < end) {
868+
return true;
869+
}
870+
else if (position === end) {
895871
// The end marker of a single-line comment does not include the newline character.
896872
// In the following case, we are inside a comment (^ denotes the cursor position):
897873
//
@@ -902,15 +878,13 @@ namespace ts {
902878
// /* asdf */^
903879
//
904880
// Internally, we represent the end of the comment at the newline and closing '/', respectively.
905-
return predicate ?
906-
forEach(commentRanges, c => c.pos < position &&
907-
(c.kind === SyntaxKind.SingleLineCommentTrivia ? position <= c.end : position < c.end) &&
908-
predicate(c)) :
909-
forEach(commentRanges, c => c.pos < position &&
910-
(c.kind === SyntaxKind.SingleLineCommentTrivia ? position <= c.end : position < c.end));
881+
return kind === SyntaxKind.SingleLineCommentTrivia ||
882+
// true for unterminated multi-line comment
883+
!(text.charCodeAt(end - 1) === CharacterCodes.slash && text.charCodeAt(end - 2) === CharacterCodes.asterisk);
884+
}
885+
else {
886+
return false;
911887
}
912-
913-
return false;
914888
}
915889

916890
export function hasDocComment(sourceFile: SourceFile, position: number) {
@@ -1093,21 +1067,17 @@ namespace ts {
10931067
}
10941068

10951069
export function isInReferenceComment(sourceFile: SourceFile, position: number): boolean {
1096-
return isInCommentHelper(sourceFile, position, isReferenceComment);
1097-
1098-
function isReferenceComment(c: CommentRange): boolean {
1070+
return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, c => {
10991071
const commentText = sourceFile.text.substring(c.pos, c.end);
11001072
return tripleSlashDirectivePrefixRegex.test(commentText);
1101-
}
1073+
});
11021074
}
11031075

11041076
export function isInNonReferenceComment(sourceFile: SourceFile, position: number): boolean {
1105-
return isInCommentHelper(sourceFile, position, isNonReferenceComment);
1106-
1107-
function isNonReferenceComment(c: CommentRange): boolean {
1077+
return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, c => {
11081078
const commentText = sourceFile.text.substring(c.pos, c.end);
11091079
return !tripleSlashDirectivePrefixRegex.test(commentText);
1110-
}
1080+
});
11111081
}
11121082

11131083
export function createTextSpanFromNode(node: Node, sourceFile?: SourceFile): TextSpan {

0 commit comments

Comments
 (0)