Skip to content

Commit d82d35c

Browse files
authored
Set startPos at EOF in jsdoc token scanner so node end positions for nodes terminated at EoF are right (#24184)
* Set startPos at EOF in jsdoc token scanner to node end positions for nodes terminated at EoF are right * More complete nonwhitespace token check, fix syntactica jsdoc classifier * Use loop and no nested lookahead * Do thigns unrelated to the bug in the test * Fix typo move return * Patch up typedef end pos * Fix indentation, make end pos target more obvious
1 parent d579793 commit d82d35c

23 files changed

+112
-59
lines changed

src/compiler/parser.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6481,7 +6481,25 @@ namespace ts {
64816481
return finishNode(result, end);
64826482
}
64836483

6484+
function isNextNonwhitespaceTokenEndOfFile(): boolean {
6485+
// We must use infinite lookahead, as there could be any number of newlines :(
6486+
while (true) {
6487+
nextJSDocToken();
6488+
if (token() === SyntaxKind.EndOfFileToken) {
6489+
return true;
6490+
}
6491+
if (!(token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia)) {
6492+
return false;
6493+
}
6494+
}
6495+
}
6496+
64846497
function skipWhitespace(): void {
6498+
if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
6499+
if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
6500+
return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
6501+
}
6502+
}
64856503
while (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
64866504
nextJSDocToken();
64876505
}
@@ -6802,6 +6820,7 @@ namespace ts {
68026820
typedefTag.comment = parseTagComments(indent);
68036821

68046822
typedefTag.typeExpression = typeExpression;
6823+
let end: number;
68056824
if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) {
68066825
let child: JSDocTypeTag | JSDocPropertyTag | false;
68076826
let jsdocTypeLiteral: JSDocTypeLiteral;
@@ -6830,10 +6849,12 @@ namespace ts {
68306849
typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ?
68316850
childTypeTag.typeExpression :
68326851
finishNode(jsdocTypeLiteral);
6852+
end = typedefTag.typeExpression.end;
68336853
}
68346854
}
68356855

6836-
return finishNode(typedefTag);
6856+
// Only include the characters between the name end and the next token if a comment was actually parsed out - otherwise it's just whitespace
6857+
return finishNode(typedefTag, end || typedefTag.comment !== undefined ? scanner.getStartPos() : (typedefTag.fullName || typedefTag.typeExpression || typedefTag.tagName).end);
68376858
}
68386859

68396860
function parseJSDocTypeNameWithNamespace(nested?: boolean) {
@@ -7075,7 +7096,7 @@ namespace ts {
70757096
const pos = scanner.getTokenPos();
70767097
const end = scanner.getTextPos();
70777098
const result = <Identifier>createNode(SyntaxKind.Identifier, pos);
7078-
result.escapedText = escapeLeadingUnderscores(content.substring(pos, end));
7099+
result.escapedText = escapeLeadingUnderscores(scanner.getTokenText());
70797100
finishNode(result, end);
70807101

70817102
nextJSDocToken();

src/compiler/scanner.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,13 +1928,11 @@ namespace ts {
19281928
}
19291929

19301930
function scanJSDocToken(): JsDocSyntaxKind {
1931+
startPos = tokenPos = pos;
19311932
if (pos >= end) {
19321933
return token = SyntaxKind.EndOfFileToken;
19331934
}
19341935

1935-
startPos = pos;
1936-
tokenPos = pos;
1937-
19381936
const ch = text.charCodeAt(pos);
19391937
pos++;
19401938
switch (ch) {

src/services/classifier.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -706,16 +706,17 @@ namespace ts {
706706
break;
707707
case SyntaxKind.JSDocTemplateTag:
708708
processJSDocTemplateTag(<JSDocTemplateTag>tag);
709+
pos = tag.end;
709710
break;
710711
case SyntaxKind.JSDocTypeTag:
711712
processElement((<JSDocTypeTag>tag).typeExpression);
713+
pos = tag.end;
712714
break;
713715
case SyntaxKind.JSDocReturnTag:
714716
processElement((<JSDocReturnTag>tag).typeExpression);
717+
pos = tag.end;
715718
break;
716719
}
717-
718-
pos = tag.end;
719720
}
720721
}
721722

tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.Nested @param tags.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"0": {
77
"kind": "JSDocParameterTag",
88
"pos": 6,
9-
"end": 63,
9+
"end": 64,
1010
"atToken": {
1111
"kind": "AtToken",
1212
"pos": 6,
@@ -21,11 +21,11 @@
2121
"typeExpression": {
2222
"kind": "JSDocTypeExpression",
2323
"pos": 34,
24-
"end": 63,
24+
"end": 64,
2525
"type": {
2626
"kind": "JSDocTypeLiteral",
2727
"pos": 34,
28-
"end": 63,
28+
"end": 64,
2929
"jsDocPropertyTags": [
3030
{
3131
"kind": "JSDocParameterTag",
@@ -88,6 +88,6 @@
8888
},
8989
"length": 1,
9090
"pos": 6,
91-
"end": 63
91+
"end": 64
9292
}
9393
}

tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argSynonymForParamTag.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"0": {
77
"kind": "JSDocParameterTag",
88
"pos": 8,
9-
"end": 40,
9+
"end": 42,
1010
"atToken": {
1111
"kind": "AtToken",
1212
"pos": 8,
@@ -40,6 +40,6 @@
4040
},
4141
"length": 1,
4242
"pos": 8,
43-
"end": 40
43+
"end": 42
4444
}
4545
}

tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argumentSynonymForParamTag.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"0": {
77
"kind": "JSDocParameterTag",
88
"pos": 8,
9-
"end": 45,
9+
"end": 47,
1010
"atToken": {
1111
"kind": "AtToken",
1212
"pos": 8,
@@ -40,6 +40,6 @@
4040
},
4141
"length": 1,
4242
"pos": 8,
43-
"end": 45
43+
"end": 47
4444
}
4545
}

tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.less-than and greater-than characters.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"0": {
77
"kind": "JSDocParameterTag",
88
"pos": 7,
9-
"end": 58,
9+
"end": 59,
1010
"atToken": {
1111
"kind": "AtToken",
1212
"pos": 7,
@@ -30,6 +30,6 @@
3030
},
3131
"length": 1,
3232
"pos": 7,
33-
"end": 58
33+
"end": 59
3434
}
3535
}

tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"0": {
77
"kind": "JSDocReturnTag",
88
"pos": 8,
9-
"end": 16,
9+
"end": 15,
1010
"atToken": {
1111
"kind": "AtToken",
1212
"pos": 8,
@@ -21,6 +21,6 @@
2121
},
2222
"length": 1,
2323
"pos": 8,
24-
"end": 16
24+
"end": 15
2525
}
2626
}

tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"0": {
77
"kind": "JSDocParameterTag",
88
"pos": 8,
9-
"end": 30,
9+
"end": 32,
1010
"atToken": {
1111
"kind": "AtToken",
1212
"pos": 8,
@@ -39,6 +39,6 @@
3939
},
4040
"length": 1,
4141
"pos": 8,
42-
"end": 30
42+
"end": 32
4343
}
4444
}

tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTag1.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"0": {
77
"kind": "JSDocParameterTag",
88
"pos": 8,
9-
"end": 55,
9+
"end": 57,
1010
"atToken": {
1111
"kind": "AtToken",
1212
"pos": 8,
@@ -40,6 +40,6 @@
4040
},
4141
"length": 1,
4242
"pos": 8,
43-
"end": 55
43+
"end": 57
4444
}
4545
}

tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName1.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"0": {
77
"kind": "JSDocParameterTag",
88
"pos": 8,
9-
"end": 57,
9+
"end": 59,
1010
"atToken": {
1111
"kind": "AtToken",
1212
"pos": 8,
@@ -40,6 +40,6 @@
4040
},
4141
"length": 1,
4242
"pos": 8,
43-
"end": 57
43+
"end": 59
4444
}
4545
}

tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName2.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"0": {
77
"kind": "JSDocParameterTag",
88
"pos": 8,
9-
"end": 62,
9+
"end": 64,
1010
"atToken": {
1111
"kind": "AtToken",
1212
"pos": 8,
@@ -40,6 +40,6 @@
4040
},
4141
"length": 1,
4242
"pos": 8,
43-
"end": 62
43+
"end": 64
4444
}
4545
}

tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType2.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"0": {
77
"kind": "JSDocParameterTag",
88
"pos": 8,
9-
"end": 42,
9+
"end": 44,
1010
"atToken": {
1111
"kind": "AtToken",
1212
"pos": 8,
@@ -40,6 +40,6 @@
4040
},
4141
"length": 1,
4242
"pos": 8,
43-
"end": 42
43+
"end": 44
4444
}
4545
}

tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"0": {
77
"kind": "JSDocParameterTag",
88
"pos": 8,
9-
"end": 19,
9+
"end": 21,
1010
"atToken": {
1111
"kind": "AtToken",
1212
"pos": 8,
@@ -29,6 +29,6 @@
2929
},
3030
"length": 1,
3131
"pos": 8,
32-
"end": 19
32+
"end": 21
3333
}
3434
}

tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"0": {
77
"kind": "JSDocTemplateTag",
88
"pos": 8,
9-
"end": 20,
9+
"end": 19,
1010
"atToken": {
1111
"kind": "AtToken",
1212
"pos": 8,
@@ -22,7 +22,7 @@
2222
"0": {
2323
"kind": "TypeParameter",
2424
"pos": 18,
25-
"end": 20,
25+
"end": 19,
2626
"name": {
2727
"kind": "Identifier",
2828
"pos": 18,
@@ -32,11 +32,11 @@
3232
},
3333
"length": 1,
3434
"pos": 18,
35-
"end": 20
35+
"end": 19
3636
}
3737
},
3838
"length": 1,
3939
"pos": 8,
40-
"end": 20
40+
"end": 19
4141
}
4242
}

tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"0": {
77
"kind": "JSDocTemplateTag",
88
"pos": 8,
9-
"end": 22,
9+
"end": 21,
1010
"atToken": {
1111
"kind": "AtToken",
1212
"pos": 8,
@@ -33,7 +33,7 @@
3333
"1": {
3434
"kind": "TypeParameter",
3535
"pos": 20,
36-
"end": 22,
36+
"end": 21,
3737
"name": {
3838
"kind": "Identifier",
3939
"pos": 20,
@@ -43,11 +43,11 @@
4343
},
4444
"length": 2,
4545
"pos": 18,
46-
"end": 22
46+
"end": 21
4747
}
4848
},
4949
"length": 1,
5050
"pos": 8,
51-
"end": 22
51+
"end": 21
5252
}
5353
}

0 commit comments

Comments
 (0)