Skip to content

Commit e7543d6

Browse files
author
Andy
authored
Simplify getRangeOfEnclosingComment (microsoft#25168)
1 parent c5bd040 commit e7543d6

File tree

5 files changed

+34
-51
lines changed

5 files changed

+34
-51
lines changed

src/services/formatting/formatting.ts

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,50 +1146,38 @@ namespace ts.formatting {
11461146
export function getRangeOfEnclosingComment(
11471147
sourceFile: SourceFile,
11481148
position: number,
1149-
onlyMultiLine: boolean,
11501149
precedingToken?: Node | null, // tslint:disable-line:no-null-keyword
11511150
tokenAtPosition = getTokenAtPosition(sourceFile, position),
1152-
predicate?: (c: CommentRange) => boolean): CommentRange | undefined {
1151+
): CommentRange | undefined {
11531152
const jsdoc = findAncestor(tokenAtPosition, isJSDoc);
11541153
if (jsdoc) tokenAtPosition = jsdoc.parent;
11551154
const tokenStart = tokenAtPosition.getStart(sourceFile);
11561155
if (tokenStart <= position && position < tokenAtPosition.getEnd()) {
11571156
return undefined;
11581157
}
11591158

1160-
if (precedingToken === undefined) {
1161-
precedingToken = findPrecedingToken(position, sourceFile);
1162-
}
1159+
precedingToken = precedingToken === null ? undefined : precedingToken === undefined ? findPrecedingToken(position, sourceFile) : precedingToken;
11631160

11641161
// Between two consecutive tokens, all comments are either trailing on the former
11651162
// or leading on the latter (and none are in both lists).
11661163
const trailingRangesOfPreviousToken = precedingToken && getTrailingCommentRanges(sourceFile.text, precedingToken.end);
11671164
const leadingCommentRangesOfNextToken = getLeadingCommentRangesOfNode(tokenAtPosition, sourceFile);
1168-
const commentRanges = trailingRangesOfPreviousToken && leadingCommentRangesOfNextToken ?
1169-
trailingRangesOfPreviousToken.concat(leadingCommentRangesOfNextToken) :
1170-
trailingRangesOfPreviousToken || leadingCommentRangesOfNextToken;
1171-
if (commentRanges) {
1172-
for (const range of commentRanges) {
1173-
// The end marker of a single-line comment does not include the newline character.
1174-
// With caret at `^`, in the following case, we are inside a comment (^ denotes the cursor position):
1175-
//
1176-
// // asdf ^\n
1177-
//
1178-
// But for closed multi-line comments, we don't want to be inside the comment in the following case:
1179-
//
1180-
// /* asdf */^
1181-
//
1182-
// However, unterminated multi-line comments *do* contain their end.
1183-
//
1184-
// Internally, we represent the end of the comment at the newline and closing '/', respectively.
1185-
//
1186-
if ((range.pos < position && position < range.end ||
1187-
position === range.end && (range.kind === SyntaxKind.SingleLineCommentTrivia || position === sourceFile.getFullWidth()))) {
1188-
return (range.kind === SyntaxKind.MultiLineCommentTrivia || !onlyMultiLine) && (!predicate || predicate(range)) ? range : undefined;
1189-
}
1190-
}
1191-
}
1192-
return undefined;
1165+
const commentRanges = concatenate(trailingRangesOfPreviousToken, leadingCommentRangesOfNextToken);
1166+
return commentRanges && find(commentRanges, range => rangeContainsPositionExclusive(range, position) ||
1167+
// The end marker of a single-line comment does not include the newline character.
1168+
// With caret at `^`, in the following case, we are inside a comment (^ denotes the cursor position):
1169+
//
1170+
// // asdf ^\n
1171+
//
1172+
// But for closed multi-line comments, we don't want to be inside the comment in the following case:
1173+
//
1174+
// /* asdf */^
1175+
//
1176+
// However, unterminated multi-line comments *do* contain their end.
1177+
//
1178+
// Internally, we represent the end of the comment at the newline and closing '/', respectively.
1179+
//
1180+
position === range.end && (range.kind === SyntaxKind.SingleLineCommentTrivia || position === sourceFile.getFullWidth()));
11931181
}
11941182

11951183
function getOpenTokenForList(node: Node, list: ReadonlyArray<Node>) {

src/services/formatting/smartIndenter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ namespace ts.formatting {
3434

3535
const precedingToken = findPrecedingToken(position, sourceFile, /*startNode*/ undefined, /*excludeJsdoc*/ true);
3636

37-
const enclosingCommentRange = getRangeOfEnclosingComment(sourceFile, position, /*onlyMultiLine*/ true, precedingToken || null); // tslint:disable-line:no-null-keyword
38-
if (enclosingCommentRange) {
37+
const enclosingCommentRange = getRangeOfEnclosingComment(sourceFile, position, precedingToken || null); // tslint:disable-line:no-null-keyword
38+
if (enclosingCommentRange && enclosingCommentRange.kind === SyntaxKind.MultiLineCommentTrivia) {
3939
return getCommentIndent(sourceFile, position, options, enclosingCommentRange);
4040
}
4141

src/services/services.ts

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

20502050
function getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan | undefined {
20512051
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
2052-
const range = formatting.getRangeOfEnclosingComment(sourceFile, position, onlyMultiLine);
2053-
return range && createTextSpanFromRange(range);
2052+
const range = formatting.getRangeOfEnclosingComment(sourceFile, position);
2053+
return range && (!onlyMultiLine || range.kind === SyntaxKind.MultiLineCommentTrivia) ? createTextSpanFromRange(range) : undefined;
20542054
}
20552055

20562056
function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] {

src/services/utilities.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,12 +1024,8 @@ namespace ts {
10241024
* @param tokenAtPosition Must equal `getTokenAtPosition(sourceFile, position)
10251025
* @param predicate Additional predicate to test on the comment range.
10261026
*/
1027-
export function isInComment(
1028-
sourceFile: SourceFile,
1029-
position: number,
1030-
tokenAtPosition?: Node,
1031-
predicate?: (c: CommentRange) => boolean): boolean {
1032-
return !!formatting.getRangeOfEnclosingComment(sourceFile, position, /*onlyMultiLine*/ false, /*precedingToken*/ undefined, tokenAtPosition, predicate);
1027+
export function isInComment(sourceFile: SourceFile, position: number, tokenAtPosition?: Node): CommentRange | undefined {
1028+
return formatting.getRangeOfEnclosingComment(sourceFile, position, /*precedingToken*/ undefined, tokenAtPosition);
10331029
}
10341030

10351031
export function hasDocComment(sourceFile: SourceFile, position: number): boolean {
@@ -1140,17 +1136,16 @@ namespace ts {
11401136
}
11411137

11421138
export function isInReferenceComment(sourceFile: SourceFile, position: number): boolean {
1143-
return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, c => {
1144-
const commentText = sourceFile.text.substring(c.pos, c.end);
1145-
return tripleSlashDirectivePrefixRegex.test(commentText);
1146-
});
1139+
return isInReferenceCommentWorker(sourceFile, position, /*shouldBeReference*/ true);
11471140
}
11481141

11491142
export function isInNonReferenceComment(sourceFile: SourceFile, position: number): boolean {
1150-
return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, c => {
1151-
const commentText = sourceFile.text.substring(c.pos, c.end);
1152-
return !tripleSlashDirectivePrefixRegex.test(commentText);
1153-
});
1143+
return isInReferenceCommentWorker(sourceFile, position, /*shouldBeReference*/ false);
1144+
}
1145+
1146+
function isInReferenceCommentWorker(sourceFile: SourceFile, position: number, shouldBeReference: boolean): boolean {
1147+
const range = isInComment(sourceFile, position, /*tokenAtPosition*/ undefined);
1148+
return !!range && shouldBeReference === tripleSlashDirectivePrefixRegex.test(sourceFile.text.substring(range.pos, range.end));
11541149
}
11551150

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

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10787,7 +10787,7 @@ declare namespace ts {
1078710787
* @param tokenAtPosition Must equal `getTokenAtPosition(sourceFile, position)
1078810788
* @param predicate Additional predicate to test on the comment range.
1078910789
*/
10790-
function isInComment(sourceFile: SourceFile, position: number, tokenAtPosition?: Node, predicate?: (c: CommentRange) => boolean): boolean;
10790+
function isInComment(sourceFile: SourceFile, position: number, tokenAtPosition?: Node): CommentRange | undefined;
1079110791
function hasDocComment(sourceFile: SourceFile, position: number): boolean;
1079210792
function getNodeModifiers(node: Node): string;
1079310793
function getTypeArgumentOrTypeParameterList(node: Node): NodeArray<Node> | undefined;
@@ -11407,8 +11407,8 @@ declare namespace ts.formatting {
1140711407
/**
1140811408
* @param precedingToken pass `null` if preceding token was already computed and result was `undefined`.
1140911409
*/
11410-
function getRangeOfEnclosingComment(sourceFile: SourceFile, position: number, onlyMultiLine: boolean, precedingToken?: Node | null, // tslint:disable-line:no-null-keyword
11411-
tokenAtPosition?: Node, predicate?: (c: CommentRange) => boolean): CommentRange | undefined;
11410+
function getRangeOfEnclosingComment(sourceFile: SourceFile, position: number, precedingToken?: Node | null, // tslint:disable-line:no-null-keyword
11411+
tokenAtPosition?: Node): CommentRange | undefined;
1141211412
function getIndentationString(indentation: number, options: EditorSettings): string;
1141311413
}
1141411414
declare namespace ts.formatting {

0 commit comments

Comments
 (0)