From 02f20818035e3d49a3d4b898403d933d9a8efdb4 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 16 May 2018 16:37:11 -0700 Subject: [PATCH 1/7] Set startPos at EOF in jsdoc token scanner to node end positions for nodes terminated at EoF are right --- src/compiler/parser.ts | 10 +++++++++- src/compiler/scanner.ts | 4 +--- ...ments.parsesCorrectly.Nested @param tags.json | 8 ++++---- ...ts.parsesCorrectly.argSynonymForParamTag.json | 4 ++-- ...rsesCorrectly.argumentSynonymForParamTag.json | 4 ++-- ...ly.less-than and greater-than characters.json | 4 ++-- ...DocComments.parsesCorrectly.noReturnType.json | 4 ++-- .../DocComments.parsesCorrectly.oneParamTag.json | 4 ++-- .../DocComments.parsesCorrectly.paramTag1.json | 4 ++-- ...s.parsesCorrectly.paramTagBracketedName1.json | 4 ++-- ...s.parsesCorrectly.paramTagBracketedName2.json | 4 ++-- ...ts.parsesCorrectly.paramTagNameThenType2.json | 4 ++-- ...omments.parsesCorrectly.paramWithoutType.json | 4 ++-- .../DocComments.parsesCorrectly.templateTag.json | 8 ++++---- ...DocComments.parsesCorrectly.templateTag2.json | 8 ++++---- ...DocComments.parsesCorrectly.templateTag3.json | 8 ++++---- ...DocComments.parsesCorrectly.templateTag4.json | 8 ++++---- ...DocComments.parsesCorrectly.templateTag5.json | 8 ++++---- ...DocComments.parsesCorrectly.twoParamTag2.json | 4 ++-- ...ts.parsesCorrectly.twoParamTagOnSameLine.json | 4 ++-- ...rsesCorrectly.typedefTagWithChildrenTags.json | 8 ++++---- .../incrementalJsDocAdjustsLengthsRight.ts | 16 ++++++++++++++++ 22 files changed, 78 insertions(+), 56 deletions(-) create mode 100644 tests/cases/fourslash/incrementalJsDocAdjustsLengthsRight.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index bbd4edc8507fd..8fb753c144083 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6471,8 +6471,16 @@ namespace ts { return finishNode(result, end); } + function isNextNonwhitespaceTokenEndOfFile() { + nextJSDocToken(); + return token() === SyntaxKind.EndOfFileToken || ((token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) && nextJSDocToken() === SyntaxKind.EndOfFileToken); + } + function skipWhitespace(): void { while (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { + if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) { + return; // Don't skip whitespace prior to EoF (or end of comment) + } nextJSDocToken(); } } @@ -7020,7 +7028,7 @@ namespace ts { const pos = scanner.getTokenPos(); const end = scanner.getTextPos(); const result = createNode(SyntaxKind.Identifier, pos); - result.escapedText = escapeLeadingUnderscores(content.substring(pos, end)); + result.escapedText = escapeLeadingUnderscores(scanner.getTokenText()); finishNode(result, end); nextJSDocToken(); diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index f2a01d22c2480..1f0c097d22aa5 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -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) { diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.Nested @param tags.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.Nested @param tags.json index 03cffdc49ff37..73d3f598059dd 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.Nested @param tags.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.Nested @param tags.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocParameterTag", "pos": 6, - "end": 63, + "end": 64, "atToken": { "kind": "AtToken", "pos": 6, @@ -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", @@ -88,6 +88,6 @@ }, "length": 1, "pos": 6, - "end": 63 + "end": 64 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argSynonymForParamTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argSynonymForParamTag.json index 00d7f0dcc30b6..cde6addda7cc6 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argSynonymForParamTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argSynonymForParamTag.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocParameterTag", "pos": 8, - "end": 40, + "end": 42, "atToken": { "kind": "AtToken", "pos": 8, @@ -40,6 +40,6 @@ }, "length": 1, "pos": 8, - "end": 40 + "end": 42 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argumentSynonymForParamTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argumentSynonymForParamTag.json index 6953601f112ca..f193bc3fe9ef6 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argumentSynonymForParamTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argumentSynonymForParamTag.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocParameterTag", "pos": 8, - "end": 45, + "end": 47, "atToken": { "kind": "AtToken", "pos": 8, @@ -40,6 +40,6 @@ }, "length": 1, "pos": 8, - "end": 45 + "end": 47 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.less-than and greater-than characters.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.less-than and greater-than characters.json index 472fbbeb6bb86..37d4610f9873c 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.less-than and greater-than characters.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.less-than and greater-than characters.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocParameterTag", "pos": 7, - "end": 58, + "end": 59, "atToken": { "kind": "AtToken", "pos": 7, @@ -30,6 +30,6 @@ }, "length": 1, "pos": 7, - "end": 58 + "end": 59 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json index 079d09c6eeb56..204ba39d3dd0b 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocReturnTag", "pos": 8, - "end": 16, + "end": 15, "atToken": { "kind": "AtToken", "pos": 8, @@ -21,6 +21,6 @@ }, "length": 1, "pos": 8, - "end": 16 + "end": 15 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json index 4940bcf325ebc..f5eee243cf57e 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocParameterTag", "pos": 8, - "end": 30, + "end": 32, "atToken": { "kind": "AtToken", "pos": 8, @@ -39,6 +39,6 @@ }, "length": 1, "pos": 8, - "end": 30 + "end": 32 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTag1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTag1.json index b3e58d84923c6..cbbb64b5a73d3 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTag1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTag1.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocParameterTag", "pos": 8, - "end": 55, + "end": 57, "atToken": { "kind": "AtToken", "pos": 8, @@ -40,6 +40,6 @@ }, "length": 1, "pos": 8, - "end": 55 + "end": 57 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName1.json index 6721afb2ea74c..a27e0d158e2b0 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName1.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocParameterTag", "pos": 8, - "end": 57, + "end": 59, "atToken": { "kind": "AtToken", "pos": 8, @@ -40,6 +40,6 @@ }, "length": 1, "pos": 8, - "end": 57 + "end": 59 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName2.json index bf53423ad6a27..d271a3b348373 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName2.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocParameterTag", "pos": 8, - "end": 62, + "end": 64, "atToken": { "kind": "AtToken", "pos": 8, @@ -40,6 +40,6 @@ }, "length": 1, "pos": 8, - "end": 62 + "end": 64 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType2.json index 68edeb9019081..57ab44a68b7db 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType2.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocParameterTag", "pos": 8, - "end": 42, + "end": 44, "atToken": { "kind": "AtToken", "pos": 8, @@ -40,6 +40,6 @@ }, "length": 1, "pos": 8, - "end": 42 + "end": 44 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json index 3d511525c643f..e85d787cd9975 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocParameterTag", "pos": 8, - "end": 19, + "end": 21, "atToken": { "kind": "AtToken", "pos": 8, @@ -29,6 +29,6 @@ }, "length": 1, "pos": 8, - "end": 19 + "end": 21 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json index 8a146e3cfaf2c..4d16157d91d91 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocTemplateTag", "pos": 8, - "end": 20, + "end": 19, "atToken": { "kind": "AtToken", "pos": 8, @@ -22,7 +22,7 @@ "0": { "kind": "TypeParameter", "pos": 18, - "end": 20, + "end": 19, "name": { "kind": "Identifier", "pos": 18, @@ -32,11 +32,11 @@ }, "length": 1, "pos": 18, - "end": 20 + "end": 19 } }, "length": 1, "pos": 8, - "end": 20 + "end": 19 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json index 5bb1df306651c..3f5f2a54ec7c4 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocTemplateTag", "pos": 8, - "end": 22, + "end": 21, "atToken": { "kind": "AtToken", "pos": 8, @@ -33,7 +33,7 @@ "1": { "kind": "TypeParameter", "pos": 20, - "end": 22, + "end": 21, "name": { "kind": "Identifier", "pos": 20, @@ -43,11 +43,11 @@ }, "length": 2, "pos": 18, - "end": 22 + "end": 21 } }, "length": 1, "pos": 8, - "end": 22 + "end": 21 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json index 295b2122daab2..ab1b9db87822e 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocTemplateTag", "pos": 8, - "end": 23, + "end": 22, "atToken": { "kind": "AtToken", "pos": 8, @@ -33,7 +33,7 @@ "1": { "kind": "TypeParameter", "pos": 21, - "end": 23, + "end": 22, "name": { "kind": "Identifier", "pos": 21, @@ -43,11 +43,11 @@ }, "length": 2, "pos": 18, - "end": 23 + "end": 22 } }, "length": 1, "pos": 8, - "end": 23 + "end": 22 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json index 4aa29db309216..193c5c0eb0141 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocTemplateTag", "pos": 8, - "end": 23, + "end": 22, "atToken": { "kind": "AtToken", "pos": 8, @@ -33,7 +33,7 @@ "1": { "kind": "TypeParameter", "pos": 21, - "end": 23, + "end": 22, "name": { "kind": "Identifier", "pos": 21, @@ -43,11 +43,11 @@ }, "length": 2, "pos": 18, - "end": 23 + "end": 22 } }, "length": 1, "pos": 8, - "end": 23 + "end": 22 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json index 5e707f6f03b94..80e127b07592f 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocTemplateTag", "pos": 8, - "end": 24, + "end": 23, "atToken": { "kind": "AtToken", "pos": 8, @@ -33,7 +33,7 @@ "1": { "kind": "TypeParameter", "pos": 22, - "end": 24, + "end": 23, "name": { "kind": "Identifier", "pos": 22, @@ -43,11 +43,11 @@ }, "length": 2, "pos": 18, - "end": 24 + "end": 23 } }, "length": 1, "pos": 8, - "end": 24 + "end": 23 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json index 6f073802fcdc1..3a5e71ef8b1dc 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json @@ -40,7 +40,7 @@ "1": { "kind": "JSDocParameterTag", "pos": 34, - "end": 56, + "end": 58, "atToken": { "kind": "AtToken", "pos": 34, @@ -73,6 +73,6 @@ }, "length": 2, "pos": 8, - "end": 56 + "end": 58 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json index e1ef0adb9263d..51868df260b90 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json @@ -40,7 +40,7 @@ "1": { "kind": "JSDocParameterTag", "pos": 30, - "end": 52, + "end": 54, "atToken": { "kind": "AtToken", "pos": 30, @@ -73,6 +73,6 @@ }, "length": 2, "pos": 8, - "end": 52 + "end": 54 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json index a4a69fc48a6c4..494fd32b57718 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json @@ -6,7 +6,7 @@ "0": { "kind": "JSDocTypedefTag", "pos": 8, - "end": 98, + "end": 100, "atToken": { "kind": "AtToken", "pos": 8, @@ -33,7 +33,7 @@ "typeExpression": { "kind": "JSDocTypeLiteral", "pos": 26, - "end": 98, + "end": 100, "jsDocPropertyTags": [ { "kind": "JSDocPropertyTag", @@ -72,7 +72,7 @@ { "kind": "JSDocPropertyTag", "pos": 74, - "end": 98, + "end": 97, "atToken": { "kind": "AtToken", "pos": 74, @@ -108,6 +108,6 @@ }, "length": 1, "pos": 8, - "end": 98 + "end": 100 } } \ No newline at end of file diff --git a/tests/cases/fourslash/incrementalJsDocAdjustsLengthsRight.ts b/tests/cases/fourslash/incrementalJsDocAdjustsLengthsRight.ts new file mode 100644 index 0000000000000..840ea22163345 --- /dev/null +++ b/tests/cases/fourslash/incrementalJsDocAdjustsLengthsRight.ts @@ -0,0 +1,16 @@ +/// + +// @noLib: true +////function camelcase(flag) { +//// return flag.split('-').reduce(function (str, word) { +//// return str + word[0].toUpperCase() + word.slice(1); +//// }); +////} +//// +/////** +//// * Pad `str` to `width`. +//// * +//// * @param {String} str +//// * @param {Number} wid/*1*/ +goTo.marker('1'); +edit.insert("th\n@"); \ No newline at end of file From 525d091ef86caf7a4fef41739394d9fd110fb97c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 16 May 2018 18:16:20 -0700 Subject: [PATCH 2/7] More complete nonwhitespace token check, fix syntactica jsdoc classifier --- src/compiler/parser.ts | 16 ++++++++++++---- src/services/classifier.ts | 5 +++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 8fb753c144083..6777307b476fd 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6471,16 +6471,24 @@ namespace ts { return finishNode(result, end); } - function isNextNonwhitespaceTokenEndOfFile() { + function isNextNonwhitespaceTokenEndOfFile(): boolean { nextJSDocToken(); - return token() === SyntaxKind.EndOfFileToken || ((token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) && nextJSDocToken() === SyntaxKind.EndOfFileToken); + if (token() === SyntaxKind.EndOfFileToken) { + return true; + } + if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { + return lookAhead(isNextNonwhitespaceTokenEndOfFile); // We must use infinte lookahead, as there could be any number of newlines :( + } + return false; } function skipWhitespace(): void { - while (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { + if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) { - return; // Don't skip whitespace prior to EoF (or end of comment) + 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(); } } diff --git a/src/services/classifier.ts b/src/services/classifier.ts index 89c96a45021b9..9719a1ccdad91 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -706,16 +706,17 @@ namespace ts { break; case SyntaxKind.JSDocTemplateTag: processJSDocTemplateTag(tag); + pos = tag.end; break; case SyntaxKind.JSDocTypeTag: processElement((tag).typeExpression); + pos = tag.end; break; case SyntaxKind.JSDocReturnTag: processElement((tag).typeExpression); + pos = tag.end; break; } - - pos = tag.end; } } From de173eeb96b2ae77e1c4a96efe91b0582a9fc301 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 17 May 2018 11:09:06 -0700 Subject: [PATCH 3/7] Use loop and no nested lookahead --- src/compiler/parser.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 6777307b476fd..523397087054f 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6472,12 +6472,15 @@ namespace ts { } function isNextNonwhitespaceTokenEndOfFile(): boolean { - nextJSDocToken(); - if (token() === SyntaxKind.EndOfFileToken) { - return true; - } - if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { - return lookAhead(isNextNonwhitespaceTokenEndOfFile); // We must use infinte lookahead, as there could be any number of newlines :( + // We must use infinte 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)) { + break; + } } return false; } From 238cb598c814bc8eb60dbd6519e73e673a6b6090 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 17 May 2018 11:20:55 -0700 Subject: [PATCH 4/7] Do thigns unrelated to the bug in the test --- .../incrementalJsDocAdjustsLengthsRight.ts | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/tests/cases/fourslash/incrementalJsDocAdjustsLengthsRight.ts b/tests/cases/fourslash/incrementalJsDocAdjustsLengthsRight.ts index 840ea22163345..626a1e372588a 100644 --- a/tests/cases/fourslash/incrementalJsDocAdjustsLengthsRight.ts +++ b/tests/cases/fourslash/incrementalJsDocAdjustsLengthsRight.ts @@ -1,11 +1,6 @@ /// // @noLib: true -////function camelcase(flag) { -//// return flag.split('-').reduce(function (str, word) { -//// return str + word[0].toUpperCase() + word.slice(1); -//// }); -////} //// /////** //// * Pad `str` to `width`. @@ -13,4 +8,26 @@ //// * @param {String} str //// * @param {Number} wid/*1*/ goTo.marker('1'); -edit.insert("th\n@"); \ No newline at end of file +edit.insert("th\n@"); +const c = classification; +verify.syntacticClassificationsAre( + c.comment("/**\n * Pad `str` to `width`.\n *\n * "), + c.punctuation("@"), + c.docCommentTagName("param"), + c.comment(" "), + c.punctuation("{"), + c.identifier("String"), + c.punctuation("}"), + c.comment(" "), + c.parameterName("str"), + c.comment("\n * "), + c.punctuation("@"), + c.docCommentTagName("param"), + c.comment(" "), + c.punctuation("{"), + c.identifier("Number"), + c.punctuation("}"), + c.comment(" "), + c.parameterName("wid"), + c.comment(""), // syntatic classification verification always just uses input text, so the edits don't appear +); From f3afefec948447b215d8289a1799c2efb6fe9cff Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 17 May 2018 11:26:20 -0700 Subject: [PATCH 5/7] Fix typo move return --- src/compiler/parser.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 523397087054f..2a3010ba0117a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6472,17 +6472,16 @@ namespace ts { } function isNextNonwhitespaceTokenEndOfFile(): boolean { - // We must use infinte lookahead, as there could be any number of newlines :( + // 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)) { - break; + return false; } } - return false; } function skipWhitespace(): void { From 8eabd8980c91e4519e64603aaf677d89730bc0aa Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 17 May 2018 12:56:52 -0700 Subject: [PATCH 6/7] Patch up typedef end pos --- src/compiler/parser.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 8620070e32d7a..1ad6ab7678b78 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6483,7 +6483,7 @@ namespace ts { function isNextNonwhitespaceTokenEndOfFile(): boolean { // We must use infinite lookahead, as there could be any number of newlines :( - while(true) { + while (true) { nextJSDocToken(); if (token() === SyntaxKind.EndOfFileToken) { return true; @@ -6820,6 +6820,7 @@ namespace ts { typedefTag.comment = parseTagComments(indent); typedefTag.typeExpression = typeExpression; + let end: number; if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { let child: JSDocTypeTag | JSDocPropertyTag | false; let jsdocTypeLiteral: JSDocTypeLiteral; @@ -6848,10 +6849,12 @@ namespace ts { typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? childTypeTag.typeExpression : finishNode(jsdocTypeLiteral); + end = jsdocTypeLiteral.end; } } - 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) { From f37086dbfdddc55e8ae17f09eba520547ef30731 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 17 May 2018 14:01:23 -0700 Subject: [PATCH 7/7] Fix indentation, make end pos target more obvious --- src/compiler/parser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1ad6ab7678b78..3a7adbc260915 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6849,7 +6849,7 @@ namespace ts { typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? childTypeTag.typeExpression : finishNode(jsdocTypeLiteral); - end = jsdocTypeLiteral.end; + end = typedefTag.typeExpression.end; } }