-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
fix(47923): Delete unused JSDoc quick fix changes formatting on rest of JSDoc comment #48482
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8077,7 +8077,9 @@ namespace ts { | |
let comments: string[] = []; | ||
const parts: JSDocComment[] = []; | ||
let linkEnd; | ||
let state = JSDocState.BeginningOfLine; | ||
let sameLineWithTag = true; | ||
let numberOfStatesChanged = 0; | ||
let state = JSDocState.BeginningOfLine as JSDocState; | ||
let previousWhitespace = true; | ||
let margin: number | undefined; | ||
function pushComment(text: string) { | ||
|
@@ -8087,6 +8089,10 @@ namespace ts { | |
comments.push(text); | ||
indent += text.length; | ||
} | ||
function updateState(newState: JSDocState) { | ||
state = newState; | ||
numberOfStatesChanged++; | ||
} | ||
if (initialMargin !== undefined) { | ||
// jump straight to saving comments if there is some initial indentation | ||
if (initialMargin !== "") { | ||
|
@@ -8098,9 +8104,10 @@ namespace ts { | |
loop: while (true) { | ||
switch (tok) { | ||
case SyntaxKind.NewLineTrivia: | ||
state = JSDocState.BeginningOfLine; | ||
updateState(JSDocState.BeginningOfLine); | ||
// don't use pushComment here because we want to keep the margin unchanged | ||
comments.push(scanner.getTokenText()); | ||
sameLineWithTag = false; | ||
indent = 0; | ||
break; | ||
case SyntaxKind.AtToken: | ||
|
@@ -8129,7 +8136,7 @@ namespace ts { | |
} | ||
break; | ||
case SyntaxKind.OpenBraceToken: | ||
state = JSDocState.SavingComments; | ||
updateState(JSDocState.SavingComments); | ||
const commentEnd = scanner.getStartPos(); | ||
const linkStart = scanner.getTextPos() - 1; | ||
const link = parseJSDocLink(linkStart); | ||
|
@@ -8144,26 +8151,42 @@ namespace ts { | |
} | ||
break; | ||
case SyntaxKind.BacktickToken: | ||
if (state === JSDocState.SavingBackticks) { | ||
state = JSDocState.SavingComments; | ||
} | ||
else { | ||
state = JSDocState.SavingBackticks; | ||
} | ||
updateState(state === JSDocState.SavingBackticks ? JSDocState.SavingComments : JSDocState.SavingBackticks); | ||
pushComment(scanner.getTokenText()); | ||
break; | ||
case SyntaxKind.AsteriskToken: | ||
if (state === JSDocState.BeginningOfLine) { | ||
// if there are two ** after a newline, considering it as a pure comment | ||
if (state === JSDocState.BeginningOfLine && lookAhead(() => nextTokenJSDoc() !== SyntaxKind.AsteriskToken)) { | ||
/* | ||
* @param x | ||
* in the first line | ||
*/ | ||
// to check tag starting newline without comments like above | ||
// it needs to actually encounter a newline | ||
if (numberOfStatesChanged === 1 && lookAhead(() => nextTokenJSDoc() !== SyntaxKind.NewLineTrivia)) { | ||
removeTrailingWhitespace(comments); | ||
} | ||
// leading asterisks start recording on the *next* (non-whitespace) token | ||
state = JSDocState.SawAsterisk; | ||
updateState(JSDocState.SawAsterisk); | ||
indent += 1; | ||
break; | ||
} | ||
// record the * as a comment | ||
// falls through | ||
default: | ||
/* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain what the parser changes do and why they're needed? From reading the code, it looks like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. like you mentioned
/*
* @param b // <- there is no type expression, it rollback to this position
*
* something here
*/
/*
* @param x
* in the first line
*/
/*
* @param x
still in the first line
*/ we can not do it at the end like we are currently doing since it is too late because there is a case with I don't really get what you mean by |
||
* @param x | ||
still in the first line | ||
*/ | ||
// by default state starts with BeginningOfLine | ||
// to check tag starting newline without comments like above | ||
// it needs to actually encounter a newline | ||
// we cannot check `comments` since it is reset after {} | ||
if (state === JSDocState.BeginningOfLine && !sameLineWithTag && numberOfStatesChanged === 1) { | ||
removeTrailingWhitespace(comments); | ||
} | ||
if (state !== JSDocState.SavingBackticks) { | ||
state = JSDocState.SavingComments; // leading identifiers start recording as well | ||
updateState(JSDocState.SavingComments); // leading identifiers start recording as well | ||
} | ||
pushComment(scanner.getTokenText()); | ||
break; | ||
|
@@ -8172,8 +8195,8 @@ namespace ts { | |
tok = nextTokenJSDoc(); | ||
} | ||
|
||
removeLeadingNewlines(comments); | ||
removeTrailingWhitespace(comments); | ||
|
||
if (parts.length) { | ||
if (comments.length) { | ||
parts.push(finishNode(factory.createJSDocText(comments.join("")), linkEnd ?? commentsPos)); | ||
|
@@ -8253,8 +8276,15 @@ namespace ts { | |
} | ||
|
||
function tryParseTypeExpression(): JSDocTypeExpression | undefined { | ||
skipWhitespaceOrAsterisk(); | ||
return token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined; | ||
let expression; | ||
tryParse(() => { | ||
skipWhitespaceOrAsterisk(); | ||
if (token() === SyntaxKind.OpenBraceToken) { | ||
expression = parseJSDocTypeExpression(); | ||
return true; | ||
} | ||
}); | ||
return expression; | ||
} | ||
|
||
function parseBracketNameInPropertyAndParamTag(): { name: EntityName, isBracketed: boolean } { | ||
|
@@ -8299,13 +8329,11 @@ namespace ts { | |
skipWhitespaceOrAsterisk(); | ||
|
||
const { name, isBracketed } = parseBracketNameInPropertyAndParamTag(); | ||
const indentText = skipWhitespaceOrAsterisk(); | ||
|
||
if (isNameFirst && !lookAhead(parseJSDocLinkPrefix)) { | ||
typeExpression = tryParseTypeExpression(); | ||
} | ||
|
||
const comment = parseTrailingTagComments(start, getNodePos(), indent, indentText); | ||
const comment = parseTrailingTagComments(start, getNodePos(), indent, ""); | ||
|
||
const nestedTypeLiteral = target !== PropertyLikeParse.CallbackParameter && parseNestedTypeLiteral(typeExpression, name, target, indent); | ||
if (nestedTypeLiteral) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/// <reference path='fourslash.ts' /> | ||
|
||
// @allowJs: true | ||
// @checkJs: true | ||
// @filename: /a.js | ||
/////** | ||
//// * @param c | ||
//// * @param b | ||
//// * | ||
//// * bla bla bla | ||
//// */ | ||
////function add(a, b) { } | ||
|
||
verify.codeFix({ | ||
description: [ts.Diagnostics.Delete_unused_param_tag_0.message, "c"], | ||
index: 0, | ||
newFileContent: | ||
`/** | ||
* @param b | ||
* | ||
* bla bla bla | ||
*/ | ||
function add(a, b) { }` | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,7 +63,7 @@ | |
//// * @random tag This should be third line | ||
//// */ | ||
////function /*h*/h(param1: string) { /*5*/param1 = "hello"; } | ||
/////** | ||
/////** | ||
//// * This is firstLine | ||
//// * This is second Line | ||
//// * @param param1 | ||
|
@@ -101,7 +101,7 @@ | |
//// * | ||
//// * @param param1 | ||
//// * | ||
//// * blank line that shouldnt be shown when starting this | ||
//// * blank line that should be shown when starting this | ||
//// * second time information about the param again | ||
//// */ | ||
////function /*l*/l(param1: string) { /*9*/param1 = "hello"; } | ||
|
@@ -129,22 +129,22 @@ verify.quickInfos({ | |
3: ["(parameter) param1: string", "first line of param\n\nparam information third line"], | ||
|
||
g: ["function g(param1: string): void", "This is firstLine\nThis is second Line"], | ||
4: ["(parameter) param1: string", " param information first line"], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the old output better; This is true of all the changes below. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
4: ["(parameter) param1: string", "\n\nparam information first line"], | ||
|
||
h: ["function h(param1: string): void", "This is firstLine\nThis is second Line"], | ||
5: ["(parameter) param1: string", " param information first line\n\n param information third line"], | ||
5: ["(parameter) param1: string", "\n\nparam information first line\n\nparam information third line"], | ||
|
||
i: ["function i(param1: string): void", "This is firstLine\nThis is second Line"], | ||
6: ["(parameter) param1: string", " param information first line\n\n param information third line"], | ||
6: ["(parameter) param1: string", "\n\nparam information first line\n\nparam information third line"], | ||
|
||
j: ["function j(param1: string): void", "This is firstLine\nThis is second Line"], | ||
7: ["(parameter) param1: string", " param information first line\n\n param information third line"], | ||
7: ["(parameter) param1: string", "\n\nparam information first line\n\nparam information third line"], | ||
|
||
k: ["function k(param1: string): void", "This is firstLine\nThis is second Line"], | ||
8: ["(parameter) param1: string", "hello"], | ||
|
||
l: ["function l(param1: string): void", "This is firstLine\nThis is second Line"], | ||
9: ["(parameter) param1: string", "first Line text\nblank line that shouldnt be shown when starting this \nsecond time information about the param again"], | ||
9: ["(parameter) param1: string", "first Line text\n\n\nblank line that should be shown when starting this \nsecond time information about the param again"], | ||
|
||
m: ["function m(param1: string): void", "This is firstLine\nThis is second Line\n[1]: third * line"], | ||
10: ["(parameter) param1: string", "first Line text\nsecond line text"] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this space make sense when the comment is the only thing in the jsdoc? eg
It looks like it might not emit the
*
as expected for thecommentary 1
line, or else emit an extra space on the line right after the**
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks the same before and after my change

VS Code
VS Code with my changes
