Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set startPos at EOF in jsdoc token scanner so node end positions for nodes terminated at EoF are right #24184

Merged
25 changes: 23 additions & 2 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6481,7 +6481,25 @@ namespace ts {
return finishNode(result, end);
}

function isNextNonwhitespaceTokenEndOfFile(): boolean {
// We must use infinite lookahead, as there could be any number of newlines :(
while (true) {
nextJSDocToken();
if (token() === SyntaxKind.EndOfFileToken) {
return true;
}
if (!(token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia)) {
return false;
}
}
}

function skipWhitespace(): void {
if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
}
}
while (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
nextJSDocToken();
}
Expand Down Expand Up @@ -6802,6 +6820,7 @@ namespace ts {
typedefTag.comment = parseTagComments(indent);

typedefTag.typeExpression = typeExpression;
let end: number;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this quirk apply to callback tags too?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From our discussion: yes, and nested @param types too, but the problem isn't bad enough to fix right now. Instead we should fix it by fixing the jsdoc scanner to ignore whitespace (and change the way we generate tag descriptions).

if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) {
let child: JSDocTypeTag | JSDocPropertyTag | false;
let jsdocTypeLiteral: JSDocTypeLiteral;
Expand Down Expand Up @@ -6830,10 +6849,12 @@ namespace ts {
typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ?
childTypeTag.typeExpression :
finishNode(jsdocTypeLiteral);
end = jsdocTypeLiteral.end;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the indent on this statement correct? It looks weird to me.

}
}

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

function parseJSDocTypeNameWithNamespace(nested?: boolean) {
Expand Down Expand Up @@ -7075,7 +7096,7 @@ namespace ts {
const pos = scanner.getTokenPos();
const end = scanner.getTextPos();
const result = <Identifier>createNode(SyntaxKind.Identifier, pos);
result.escapedText = escapeLeadingUnderscores(content.substring(pos, end));
result.escapedText = escapeLeadingUnderscores(scanner.getTokenText());
finishNode(result, end);

nextJSDocToken();
Expand Down
4 changes: 1 addition & 3 deletions src/compiler/scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1928,13 +1928,11 @@ namespace ts {
}

function scanJSDocToken(): JsDocSyntaxKind {
startPos = tokenPos = pos;
if (pos >= end) {
return token = SyntaxKind.EndOfFileToken;
}

startPos = pos;
tokenPos = pos;

const ch = text.charCodeAt(pos);
pos++;
switch (ch) {
Expand Down
5 changes: 3 additions & 2 deletions src/services/classifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -706,16 +706,17 @@ namespace ts {
break;
case SyntaxKind.JSDocTemplateTag:
processJSDocTemplateTag(<JSDocTemplateTag>tag);
pos = tag.end;
break;
case SyntaxKind.JSDocTypeTag:
processElement((<JSDocTypeTag>tag).typeExpression);
pos = tag.end;
break;
case SyntaxKind.JSDocReturnTag:
processElement((<JSDocReturnTag>tag).typeExpression);
pos = tag.end;
break;
}

pos = tag.end;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what prompts this change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a test expecting a single classification for the trailing whitespace and */ on a comment. With the parse change, the trailing whitespace isn't part of the tag name/type, but is part of the overall tag itself (here, tag) - so using the end from the tag itself was causing us to skip the whitespace in the output. By the way, can I add that whitespace parsing in jsdoc is really inconsistent? Where whitespace is consumed vs isn't is very... Arbitrary? I feel like only newlines should really be significant in jsdoc - do you know why were scanning whitespace into tokens at all?

Copy link
Member

@sandersn sandersn May 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/**
 * @param x Comment starts here
 *            - indented
 *            - indented
 */

Needs to produce a comment text that looks like

Comment starts here
  - indented
  - indented

That is, the second lines need to be indented two spaces, not 0 and not 17 and not 16.

Copy link
Member Author

@weswigham weswigham May 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But... why are we doing that indentation analysis with token scanning and not with string manipulation on the actual comment text? We already manipulate it to strip leading and trailing newlines.

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 6,
"end": 63,
"end": 64,
"atToken": {
"kind": "AtToken",
"pos": 6,
Expand All @@ -21,11 +21,11 @@
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 34,
"end": 63,
"end": 64,
"type": {
"kind": "JSDocTypeLiteral",
"pos": 34,
"end": 63,
"end": 64,
"jsDocPropertyTags": [
{
"kind": "JSDocParameterTag",
Expand Down Expand Up @@ -88,6 +88,6 @@
},
"length": 1,
"pos": 6,
"end": 63
"end": 64
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 40,
"end": 42,
"atToken": {
"kind": "AtToken",
"pos": 8,
Expand Down Expand Up @@ -40,6 +40,6 @@
},
"length": 1,
"pos": 8,
"end": 40
"end": 42
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 45,
"end": 47,
"atToken": {
"kind": "AtToken",
"pos": 8,
Expand Down Expand Up @@ -40,6 +40,6 @@
},
"length": 1,
"pos": 8,
"end": 45
"end": 47
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 7,
"end": 58,
"end": 59,
"atToken": {
"kind": "AtToken",
"pos": 7,
Expand All @@ -30,6 +30,6 @@
},
"length": 1,
"pos": 7,
"end": 58
"end": 59
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"0": {
"kind": "JSDocReturnTag",
"pos": 8,
"end": 16,
"end": 15,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Odd to see all these end position shift sometimes +2, sometime +1, and sometimes -1. I assume you've done a spot check and the new positions are (hopefully more) correct in each case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the end just no longer includes the trailing whitespace at the end of the comment.

"atToken": {
"kind": "AtToken",
"pos": 8,
Expand All @@ -21,6 +21,6 @@
},
"length": 1,
"pos": 8,
"end": 16
"end": 15
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 30,
"end": 32,
"atToken": {
"kind": "AtToken",
"pos": 8,
Expand Down Expand Up @@ -39,6 +39,6 @@
},
"length": 1,
"pos": 8,
"end": 30
"end": 32
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 55,
"end": 57,
"atToken": {
"kind": "AtToken",
"pos": 8,
Expand Down Expand Up @@ -40,6 +40,6 @@
},
"length": 1,
"pos": 8,
"end": 55
"end": 57
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 57,
"end": 59,
"atToken": {
"kind": "AtToken",
"pos": 8,
Expand Down Expand Up @@ -40,6 +40,6 @@
},
"length": 1,
"pos": 8,
"end": 57
"end": 59
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 62,
"end": 64,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per your other comment - why does this one get longer then?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description scanning is including trailing whitespace now that the comment end token's start pos is fixed - nonfinal descriptions already had positions that included trailing whitespace like this, so.... 🤷‍♂️

TBH, I'd prefer if whitespace was nonsignificant in jsdoc parsing and only handled newlines - that's require some changes to how we handle descriptions, though (we'd need to scan them more like jsx text).

"atToken": {
"kind": "AtToken",
"pos": 8,
Expand Down Expand Up @@ -40,6 +40,6 @@
},
"length": 1,
"pos": 8,
"end": 62
"end": 64
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 42,
"end": 44,
"atToken": {
"kind": "AtToken",
"pos": 8,
Expand Down Expand Up @@ -40,6 +40,6 @@
},
"length": 1,
"pos": 8,
"end": 42
"end": 44
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 19,
"end": 21,
"atToken": {
"kind": "AtToken",
"pos": 8,
Expand All @@ -29,6 +29,6 @@
},
"length": 1,
"pos": 8,
"end": 19
"end": 21
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"0": {
"kind": "JSDocTemplateTag",
"pos": 8,
"end": 20,
"end": 19,
"atToken": {
"kind": "AtToken",
"pos": 8,
Expand All @@ -22,7 +22,7 @@
"0": {
"kind": "TypeParameter",
"pos": 18,
"end": 20,
"end": 19,
"name": {
"kind": "Identifier",
"pos": 18,
Expand All @@ -32,11 +32,11 @@
},
"length": 1,
"pos": 18,
"end": 20
"end": 19
}
},
"length": 1,
"pos": 8,
"end": 20
"end": 19
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"0": {
"kind": "JSDocTemplateTag",
"pos": 8,
"end": 22,
"end": 21,
"atToken": {
"kind": "AtToken",
"pos": 8,
Expand All @@ -33,7 +33,7 @@
"1": {
"kind": "TypeParameter",
"pos": 20,
"end": 22,
"end": 21,
"name": {
"kind": "Identifier",
"pos": 20,
Expand All @@ -43,11 +43,11 @@
},
"length": 2,
"pos": 18,
"end": 22
"end": 21
}
},
"length": 1,
"pos": 8,
"end": 22
"end": 21
}
}
Loading