mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-13 02:45:24 -05:00
Fix some bad jsdoc comment indent (#30838)
* First draft Solves the initial problem but breaks commentCommentParsing. I also found a couple more interesting cases. * Add more tests and fix their bugs * Another test case * Some cleanup I may try do a little more; `margin += tag.end - tag.pos` bothers me a bit. * More cleanup
This commit is contained in:
committed by
GitHub
parent
ef4acc8841
commit
ff959096df
@@ -6441,7 +6441,6 @@ namespace ts {
|
||||
// for malformed examples like `/** @param {string} x @returns {number} the length */`
|
||||
state = JSDocState.BeginningOfLine;
|
||||
margin = undefined;
|
||||
indent++;
|
||||
}
|
||||
else {
|
||||
pushComment(scanner.getTokenText());
|
||||
@@ -6536,32 +6535,38 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function skipWhitespaceOrAsterisk(): void {
|
||||
function skipWhitespaceOrAsterisk(): string {
|
||||
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
|
||||
return ""; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
|
||||
}
|
||||
}
|
||||
|
||||
let precedingLineBreak = scanner.hasPrecedingLineBreak();
|
||||
let seenLineBreak = false;
|
||||
let indentText = "";
|
||||
while ((precedingLineBreak && token() === SyntaxKind.AsteriskToken) || token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
|
||||
indentText += scanner.getTokenText();
|
||||
if (token() === SyntaxKind.NewLineTrivia) {
|
||||
precedingLineBreak = true;
|
||||
seenLineBreak = true;
|
||||
indentText = "";
|
||||
}
|
||||
else if (token() === SyntaxKind.AsteriskToken) {
|
||||
precedingLineBreak = false;
|
||||
}
|
||||
nextJSDocToken();
|
||||
}
|
||||
return seenLineBreak ? indentText : "";
|
||||
}
|
||||
|
||||
function parseTag(indent: number) {
|
||||
function parseTag(margin: number) {
|
||||
Debug.assert(token() === SyntaxKind.AtToken);
|
||||
const start = scanner.getTokenPos();
|
||||
nextJSDocToken();
|
||||
|
||||
const tagName = parseJSDocIdentifierName(/*message*/ undefined);
|
||||
skipWhitespaceOrAsterisk();
|
||||
const indentText = skipWhitespaceOrAsterisk();
|
||||
|
||||
let tag: JSDocTag | undefined;
|
||||
switch (tagName.escapedText) {
|
||||
@@ -6582,7 +6587,7 @@ namespace ts {
|
||||
case "arg":
|
||||
case "argument":
|
||||
case "param":
|
||||
return parseParameterOrPropertyTag(start, tagName, PropertyLikeParse.Parameter, indent);
|
||||
return parseParameterOrPropertyTag(start, tagName, PropertyLikeParse.Parameter, margin);
|
||||
case "return":
|
||||
case "returns":
|
||||
tag = parseReturnTag(start, tagName);
|
||||
@@ -6594,10 +6599,10 @@ namespace ts {
|
||||
tag = parseTypeTag(start, tagName);
|
||||
break;
|
||||
case "typedef":
|
||||
tag = parseTypedefTag(start, tagName, indent);
|
||||
tag = parseTypedefTag(start, tagName, margin);
|
||||
break;
|
||||
case "callback":
|
||||
tag = parseCallbackTag(start, tagName, indent);
|
||||
tag = parseCallbackTag(start, tagName, margin);
|
||||
break;
|
||||
default:
|
||||
tag = parseUnknownTag(start, tagName);
|
||||
@@ -6606,12 +6611,15 @@ namespace ts {
|
||||
|
||||
if (!tag.comment) {
|
||||
// some tags, like typedef and callback, have already parsed their comments earlier
|
||||
tag.comment = parseTagComments(indent + tag.end - tag.pos);
|
||||
if (!indentText) {
|
||||
margin += tag.end - tag.pos;
|
||||
}
|
||||
tag.comment = parseTagComments(margin, indentText.slice(margin));
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
function parseTagComments(indent: number): string | undefined {
|
||||
function parseTagComments(indent: number, initialMargin?: string): string | undefined {
|
||||
const comments: string[] = [];
|
||||
let state = JSDocState.BeginningOfLine;
|
||||
let margin: number | undefined;
|
||||
@@ -6622,6 +6630,11 @@ namespace ts {
|
||||
comments.push(text);
|
||||
indent += text.length;
|
||||
}
|
||||
if (initialMargin) {
|
||||
// jump straight to saving comments if there is some initial indentation
|
||||
pushComment(initialMargin);
|
||||
state = JSDocState.SavingComments;
|
||||
}
|
||||
let tok = token() as JsDocSyntaxKind;
|
||||
loop: while (true) {
|
||||
switch (tok) {
|
||||
@@ -6646,7 +6659,7 @@ namespace ts {
|
||||
const whitespace = scanner.getTokenText();
|
||||
// if the whitespace crosses the margin, take only the whitespace that passes the margin
|
||||
if (margin !== undefined && indent + whitespace.length > margin) {
|
||||
comments.push(whitespace.slice(margin - indent - 1));
|
||||
comments.push(whitespace.slice(margin - indent));
|
||||
}
|
||||
indent += whitespace.length;
|
||||
}
|
||||
|
||||
283
tests/baselines/reference/quickInfoForJSDocUnknownTag.baseline
Normal file
283
tests/baselines/reference/quickInfoForJSDocUnknownTag.baseline
Normal file
@@ -0,0 +1,283 @@
|
||||
[
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/quickInfoForJSDocUnknownTag.ts",
|
||||
"position": 64
|
||||
},
|
||||
"quickInfo": {
|
||||
"kind": "function",
|
||||
"kindModifiers": "",
|
||||
"textSpan": {
|
||||
"start": 62,
|
||||
"length": 3
|
||||
},
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "function",
|
||||
"kind": "keyword"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "foo",
|
||||
"kind": "functionName"
|
||||
},
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "string",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"documentation": [],
|
||||
"tags": [
|
||||
{
|
||||
"name": "example",
|
||||
"text": "if (true) {\n foo()\n}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/quickInfoForJSDocUnknownTag.ts",
|
||||
"position": 134
|
||||
},
|
||||
"quickInfo": {
|
||||
"kind": "function",
|
||||
"kindModifiers": "",
|
||||
"textSpan": {
|
||||
"start": 132,
|
||||
"length": 4
|
||||
},
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "function",
|
||||
"kind": "keyword"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "foo2",
|
||||
"kind": "functionName"
|
||||
},
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "string",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"documentation": [],
|
||||
"tags": [
|
||||
{
|
||||
"name": "example",
|
||||
"text": "{\n foo()\n}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/quickInfoForJSDocUnknownTag.ts",
|
||||
"position": 219
|
||||
},
|
||||
"quickInfo": {
|
||||
"kind": "function",
|
||||
"kindModifiers": "",
|
||||
"textSpan": {
|
||||
"start": 218,
|
||||
"length": 3
|
||||
},
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "function",
|
||||
"kind": "keyword"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "moo",
|
||||
"kind": "functionName"
|
||||
},
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "string",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"documentation": [],
|
||||
"tags": [
|
||||
{
|
||||
"name": "example",
|
||||
"text": " x y\n 12345\n b"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/quickInfoForJSDocUnknownTag.ts",
|
||||
"position": 313
|
||||
},
|
||||
"quickInfo": {
|
||||
"kind": "function",
|
||||
"kindModifiers": "",
|
||||
"textSpan": {
|
||||
"start": 312,
|
||||
"length": 3
|
||||
},
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "function",
|
||||
"kind": "keyword"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "boo",
|
||||
"kind": "functionName"
|
||||
},
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "string",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"documentation": [],
|
||||
"tags": [
|
||||
{
|
||||
"name": "func"
|
||||
},
|
||||
{
|
||||
"name": "example",
|
||||
"text": " x y\n 12345\n b"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/quickInfoForJSDocUnknownTag.ts",
|
||||
"position": 426
|
||||
},
|
||||
"quickInfo": {
|
||||
"kind": "function",
|
||||
"kindModifiers": "",
|
||||
"textSpan": {
|
||||
"start": 424,
|
||||
"length": 3
|
||||
},
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "function",
|
||||
"kind": "keyword"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "goo",
|
||||
"kind": "functionName"
|
||||
},
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "string",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"documentation": [],
|
||||
"tags": [
|
||||
{
|
||||
"name": "func"
|
||||
},
|
||||
{
|
||||
"name": "example",
|
||||
"text": "x y\n12345\n b"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
49
tests/cases/fourslash/quickInfoForJSDocUnknownTag.ts
Normal file
49
tests/cases/fourslash/quickInfoForJSDocUnknownTag.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
/////**
|
||||
//// * @example
|
||||
//// * if (true) {
|
||||
//// * foo()
|
||||
//// * }
|
||||
//// */
|
||||
////function fo/*1*/o() {
|
||||
//// return '2';
|
||||
////}
|
||||
/////**
|
||||
//// @example
|
||||
//// {
|
||||
//// foo()
|
||||
//// }
|
||||
//// */
|
||||
////function fo/*2*/o2() {
|
||||
//// return '2';
|
||||
////}
|
||||
/////**
|
||||
//// * @example
|
||||
//// * x y
|
||||
//// * 12345
|
||||
//// * b
|
||||
//// */
|
||||
////function m/*3*/oo() {
|
||||
//// return '2';
|
||||
////}
|
||||
/////**
|
||||
//// * @func
|
||||
//// * @example
|
||||
//// * x y
|
||||
//// * 12345
|
||||
//// * b
|
||||
//// */
|
||||
////function b/*4*/oo() {
|
||||
//// return '2';
|
||||
////}
|
||||
/////**
|
||||
//// * @func
|
||||
//// * @example x y
|
||||
//// * 12345
|
||||
//// * b
|
||||
//// */
|
||||
////function go/*5*/o() {
|
||||
//// return '2';
|
||||
////}
|
||||
verify.baselineQuickInfo();
|
||||
Reference in New Issue
Block a user