Skip to content

Commit fc4dd2b

Browse files
author
Andy
authored
Merge pull request microsoft#15890 from Microsoft/todoComments
Services utilities: Combine `isInsideComment` with `isInComment`
2 parents ebcbd8f + 0defde7 commit fc4dd2b

3 files changed

Lines changed: 30 additions & 60 deletions

File tree

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
@@ -1854,8 +1854,8 @@ namespace ts {
18541854

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

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;
@@ -816,10 +785,6 @@ namespace ts {
816785
return false;
817786
}
818787

819-
export function isInComment(sourceFile: SourceFile, position: number) {
820-
return isInCommentHelper(sourceFile, position, /*predicate*/ undefined);
821-
}
822-
823788
/**
824789
* returns true if the position is in between the open and close elements of an JSX expression.
825790
*/
@@ -865,15 +830,26 @@ namespace ts {
865830
}
866831

867832
/**
868-
* Returns true if the cursor at position in sourceFile is within a comment that additionally
869-
* satisfies predicate, and false otherwise.
833+
* Returns true if the cursor at position in sourceFile is within a comment.
834+
*
835+
* @param tokenAtPosition Must equal `getTokenAtPosition(sourceFile, position)
836+
* @param predicate Additional predicate to test on the comment range.
870837
*/
871-
export function isInCommentHelper(sourceFile: SourceFile, position: number, predicate?: (c: CommentRange) => boolean): boolean {
872-
const token = getTokenAtPosition(sourceFile, position);
838+
export function isInComment(sourceFile: SourceFile, position: number, tokenAtPosition = getTokenAtPosition(sourceFile, position), predicate?: (c: CommentRange) => boolean): boolean {
839+
return position <= tokenAtPosition.getStart(sourceFile) &&
840+
(isInCommentRange(getLeadingCommentRanges(sourceFile.text, tokenAtPosition.pos)) ||
841+
isInCommentRange(getTrailingCommentRanges(sourceFile.text, tokenAtPosition.pos)));
873842

874-
if (token && position <= token.getStart(sourceFile)) {
875-
const commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos);
843+
function isInCommentRange(commentRanges: CommentRange[]): boolean {
844+
return forEach(commentRanges, c => isPositionInCommentRange(c, position, sourceFile.text) && (!predicate || predicate(c)));
845+
}
846+
}
876847

848+
function isPositionInCommentRange({ pos, end, kind }: ts.CommentRange, position: number, text: string): boolean {
849+
if (pos < position && position < end) {
850+
return true;
851+
}
852+
else if (position === end) {
877853
// The end marker of a single-line comment does not include the newline character.
878854
// In the following case, we are inside a comment (^ denotes the cursor position):
879855
//
@@ -884,15 +860,13 @@ namespace ts {
884860
// /* asdf */^
885861
//
886862
// Internally, we represent the end of the comment at the newline and closing '/', respectively.
887-
return predicate ?
888-
forEach(commentRanges, c => c.pos < position &&
889-
(c.kind === SyntaxKind.SingleLineCommentTrivia ? position <= c.end : position < c.end) &&
890-
predicate(c)) :
891-
forEach(commentRanges, c => c.pos < position &&
892-
(c.kind === SyntaxKind.SingleLineCommentTrivia ? position <= c.end : position < c.end));
863+
return kind === SyntaxKind.SingleLineCommentTrivia ||
864+
// true for unterminated multi-line comment
865+
!(text.charCodeAt(end - 1) === CharacterCodes.slash && text.charCodeAt(end - 2) === CharacterCodes.asterisk);
866+
}
867+
else {
868+
return false;
893869
}
894-
895-
return false;
896870
}
897871

898872
export function hasDocComment(sourceFile: SourceFile, position: number) {
@@ -1075,21 +1049,17 @@ namespace ts {
10751049
}
10761050

10771051
export function isInReferenceComment(sourceFile: SourceFile, position: number): boolean {
1078-
return isInCommentHelper(sourceFile, position, isReferenceComment);
1079-
1080-
function isReferenceComment(c: CommentRange): boolean {
1052+
return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, c => {
10811053
const commentText = sourceFile.text.substring(c.pos, c.end);
10821054
return tripleSlashDirectivePrefixRegex.test(commentText);
1083-
}
1055+
});
10841056
}
10851057

10861058
export function isInNonReferenceComment(sourceFile: SourceFile, position: number): boolean {
1087-
return isInCommentHelper(sourceFile, position, isNonReferenceComment);
1088-
1089-
function isNonReferenceComment(c: CommentRange): boolean {
1059+
return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, c => {
10901060
const commentText = sourceFile.text.substring(c.pos, c.end);
10911061
return !tripleSlashDirectivePrefixRegex.test(commentText);
1092-
}
1062+
});
10931063
}
10941064

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

0 commit comments

Comments
 (0)