Print WithStatement the same as WhileStatement (#18795)

This commit is contained in:
fisker Cheung authored and GitHub committed 2026-01-30 00:11:41 +08:00
1 parent 6966c7e488
commit 46061a160f
13 files changed
+324 -258

No files matched your search

@@ -0,0 +1,60 @@
import {
addLeadingComment,
addTrailingComment,
} from "../../../main/comments/utilities.js";
import getNextNonSpaceNonCommentCharacter from "../../../utilities/get-next-non-space-non-comment-character.js";
import { locEnd } from "../../loc.js";
import { addBlockStatementFirstComment } from "./utilities.js";
/**
@import {CommentContext} from "../handle-comments.js"
*/
/**
@param {CommentContext} param0
*/
function handleWhileLikeComments({
comment,
precedingNode,
enclosingNode,
followingNode,
text,
}) {
if (
!(
(enclosingNode?.type === "WhileStatement" ||
enclosingNode?.type === "WithStatement") &&
followingNode
)
) {
return false;
}
// We unfortunately have no way using the AST or location of nodes to know
// if the comment is positioned before the condition parenthesis:
// while (a /* comment */) {}
// The only workaround I found is to look at the next character to see if
// it is a ).
const nextCharacter = getNextNonSpaceNonCommentCharacter(
text,
locEnd(comment),
);
if (nextCharacter === ")") {
addTrailingComment(precedingNode, comment);
return true;
}
if (followingNode.type === "BlockStatement") {
addBlockStatementFirstComment(followingNode, comment);
return true;
}
if (enclosingNode.body === followingNode) {
addLeadingComment(followingNode, comment);
return true;
}
return false;
}
export { handleWhileLikeComments };
@@ -0,0 +1,38 @@
import {
addDanglingComment,
addLeadingComment,
} from "../../../main/comments/utilities.js";
/**
@import {Node, Comment, NodeMap} from "../../types/estree.js";
*/
/**
* @param {Node} node
* @returns {void}
*/
function addBlockOrNotComment(node, comment) {
if (node.type === "BlockStatement") {
addBlockStatementFirstComment(node, comment);
} else {
addLeadingComment(node, comment);
}
}
/**
* @param {Node} node
* @returns {void}
*/
function addBlockStatementFirstComment(node, comment) {
// @ts-expect-error
const firstNonEmptyNode = (node.body || node.properties).find(
({ type }) => type !== "EmptyStatement",
);
if (firstNonEmptyNode) {
addLeadingComment(firstNonEmptyNode, comment);
} else {
addDanglingComment(node, comment);
}
}
export { addBlockOrNotComment, addBlockStatementFirstComment };
+8 -69
View File
@@ -29,6 +29,11 @@ import {
isUnionType,
} from "../utilities/node-types.js";
import { stripComments } from "../utilities/strip-comments.js";
import { handleWhileLikeComments } from "./attach/handle-while-like-comments.js";
import {
addBlockOrNotComment,
addBlockStatementFirstComment,
} from "./attach/utilities.js";
/**
@import {Node, Comment, NodeMap} from "../types/estree.js";
@@ -69,7 +74,7 @@ function handleOwnLineComment(context) {
handleLastFunctionParameterComments,
handleMemberExpressionComments,
handleIfStatementComments,
handleWhileComments,
handleWhileLikeComments,
handleTryStatementComments,
handleClassComments,
handleForComments,
@@ -99,7 +104,7 @@ function handleEndOfLineComment(context) {
handleConditionalExpressionComments,
handleModuleSpecifiersComments,
handleIfStatementComments,
handleWhileComments,
handleWhileLikeComments,
handleTryStatementComments,
handleClassComments,
handleLabeledStatementComments,
@@ -126,7 +131,7 @@ function handleRemainingComment(context) {
handleCommentInEmptyParens,
handleIgnoreComments,
handleIfStatementComments,
handleWhileComments,
handleWhileLikeComments,
handleMethodNameComments,
handleOnlyComments,
handleTSMappedTypeComments,
@@ -137,34 +142,6 @@ function handleRemainingComment(context) {
].some((fn) => fn(context));
}
/**
* @param {Node} node
* @returns {void}
*/
function addBlockStatementFirstComment(node, comment) {
// @ts-expect-error
const firstNonEmptyNode = (node.body || node.properties).find(
({ type }) => type !== "EmptyStatement",
);
if (firstNonEmptyNode) {
addLeadingComment(firstNonEmptyNode, comment);
} else {
addDanglingComment(node, comment);
}
}
/**
* @param {Node} node
* @returns {void}
*/
function addBlockOrNotComment(node, comment) {
if (node.type === "BlockStatement") {
addBlockStatementFirstComment(node, comment);
} else {
addLeadingComment(node, comment);
}
}
function handleClosureTypeCastComments({ comment, followingNode }) {
if (followingNode && isTypeCastComment(comment)) {
addLeadingComment(followingNode, comment);
@@ -318,44 +295,6 @@ function handleIfStatementComments({
return false;
}
function handleWhileComments({
comment,
precedingNode,
enclosingNode,
followingNode,
text,
}) {
if (enclosingNode?.type !== "WhileStatement" || !followingNode) {
return false;
}
// We unfortunately have no way using the AST or location of nodes to know
// if the comment is positioned before the condition parenthesis:
// while (a /* comment */) {}
// The only workaround I found is to look at the next character to see if
// it is a ).
const nextCharacter = getNextNonSpaceNonCommentCharacter(
text,
locEnd(comment),
);
if (nextCharacter === ")") {
addTrailingComment(precedingNode, comment);
return true;
}
if (followingNode.type === "BlockStatement") {
addBlockStatementFirstComment(followingNode, comment);
return true;
}
if (enclosingNode.body === followingNode) {
addLeadingComment(followingNode, comment);
return true;
}
return false;
}
// Same as IfStatement but for TryStatement
function handleTryStatementComments({
comment,
@@ -0,0 +1,22 @@
import { group, hardline } from "../../document/index.js";
import {
adjustClause,
printDoWhileStatementCondition,
} from "./miscellaneous.js";
function printDoWhileStatement(path, options, print) {
const { body } = path.node;
const clause = adjustClause(body, print("body"));
const doBody = group(["do", clause]);
return [
doBody,
body.type === "BlockStatement" ? " " : hardline,
"while (",
printDoWhileStatementCondition(path, options, print),
")",
options.semi ? ";" : "",
];
}
export { printDoWhileStatement };
+3 -11
View File
@@ -32,6 +32,7 @@ import {
printClassMethod,
printClassProperty,
} from "./class.js";
import { printDoWhileStatement } from "./do-while-statement.js";
import { printExpressionStatement } from "./expression-statement.js";
import { printForStatement } from "./for-statement.js";
import { printFunction, printMethod } from "./function.js";
@@ -66,10 +67,7 @@ import { printTernary } from "./ternary.js";
import { printCatchClause, printTryStatement } from "./try-statement.js";
import { printTypeAnnotationProperty } from "./type-annotation.js";
import { printVariableDeclaration } from "./variable-declaration.js";
import {
printDoWhileStatement,
printWhileStatement,
} from "./while-statement.js";
import { printWhileStatement } from "./while-statement.js";
/**
* @import AstPath from "../../common/ast-path.js"
@@ -253,17 +251,11 @@ function printEstree(path, options, print, args) {
return printTernary(path, options, print, args);
case "VariableDeclaration":
return printVariableDeclaration(path, options, print);
case "WithStatement":
return group([
"with (",
print("object"),
")",
adjustClause(node.body, print("body")),
]);
case "IfStatement":
return printIfStatement(path, options, print);
case "ForStatement":
return printForStatement(path, options, print);
case "WithStatement":
case "WhileStatement":
return printWhileStatement(path, options, print);
case "DoWhileStatement":
+8 -6
View File
@@ -168,10 +168,12 @@ function shouldInlineCondition(node) {
return node.type === "LogicalExpression";
}
function printIfOrWhileCondition(path, options, print) {
const conditionDoc = print("test");
function printIfOrWhileConditionOrWithStatementObject(path, options, print) {
const { node } = path;
const property = node.type === "WithStatement" ? "object" : "test";
const conditionDoc = print(property);
if (shouldInlineCondition(path.node.test)) {
if (shouldInlineCondition(node[property])) {
return conditionDoc;
}
@@ -213,10 +215,10 @@ export {
printDanglingCommentsInList,
printDeclareToken,
printDefiniteToken,
printIfOrWhileCondition as printDoWhileStatementCondition,
printIfOrWhileCondition as printIfStatementCondition,
printIfOrWhileConditionOrWithStatementObject as printDoWhileStatementCondition,
printIfOrWhileConditionOrWithStatementObject as printIfStatementCondition,
printOptionalToken,
printTrailingComma,
printTypeScriptAccessibilityToken,
printIfOrWhileCondition as printWhileStatementCondition,
printIfOrWhileConditionOrWithStatementObject as printWhileStatementCondition,
};
+9 -24
View File
@@ -1,32 +1,17 @@
import { group, hardline } from "../../document/index.js";
import {
adjustClause,
printDoWhileStatementCondition,
printWhileStatementCondition,
} from "./miscellaneous.js";
import { group } from "../../document/index.js";
import { adjustClause, printWhileStatementCondition } from "./miscellaneous.js";
function printWhileStatement(path, options, print) {
const { node } = path;
const keyword = node.type === "WithStatement" ? "with" : "while";
return group([
"while (",
keyword,
" (",
printWhileStatementCondition(path, options, print),
")",
adjustClause(path.node.body, print("body")),
adjustClause(node.body, print("body")),
]);
}
function printDoWhileStatement(path, options, print) {
const { body } = path.node;
const clause = adjustClause(body, print("body"));
const doBody = group(["do", clause]);
return [
doBody,
body.type === "BlockStatement" ? " " : hardline,
"while (",
printDoWhileStatementCondition(path, options, print),
")",
options.semi ? ";" : "",
];
}
export { printDoWhileStatement, printWhileStatement };
export { printWhileStatement };
@@ -7403,128 +7403,3 @@ const foo3 = 123;
================================================================================
`;
exports[`while.js - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
printWidth: 80
semi: false
| printWidth
=====================================input======================================
while(
true
// Comment
) {}
while(true)// Comment
{}
while(true){}// Comment
while(true)/*Comment*/{}
while(
true // Comment
&& true // Comment
){}
while(true) {} // comment
while(true) /* comment */ ++x;
while(1) // Comment
foo();
=====================================output=====================================
while (
true
// Comment
) {}
while (true) {
// Comment
}
while (true) {} // Comment
while (true) {
/*Comment*/
}
while (
true && // Comment
true // Comment
) {}
while (true) {} // comment
while (true) /* comment */ ++x
while (1)
// Comment
foo()
================================================================================
`;
exports[`while.js format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
printWidth: 80
| printWidth
=====================================input======================================
while(
true
// Comment
) {}
while(true)// Comment
{}
while(true){}// Comment
while(true)/*Comment*/{}
while(
true // Comment
&& true // Comment
){}
while(true) {} // comment
while(true) /* comment */ ++x;
while(1) // Comment
foo();
=====================================output=====================================
while (
true
// Comment
) {}
while (true) {
// Comment
}
while (true) {} // Comment
while (true) {
/*Comment*/
}
while (
true && // Comment
true // Comment
) {}
while (true) {} // comment
while (true) /* comment */ ++x;
while (1)
// Comment
foo();
================================================================================
`;
@@ -0,0 +1,129 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`while.js format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
printWidth: 80
| printWidth
=====================================input======================================
while(
true
// 1
) {}
while(true)// 2
{}
while(true){}// 3
while(true)/*4*/{}
while(
true // 5
&& true // 52
){}
while(true) {} // 6
while(true) /* 7 */ ++x;
while(1) // 8
foo();
=====================================output=====================================
while (
true
// 1
) {}
while (true) {
// 2
}
while (true) {} // 3
while (true) {
/*4*/
}
while (
true && // 5
true // 52
) {}
while (true) {} // 6
while (true) /* 7 */ ++x;
while (1)
// 8
foo();
================================================================================
`;
exports[`with.js format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
printWidth: 80
| printWidth
=====================================input======================================
with(
foo
// 1
) {}
with(foo)// 2
{}
with(foo){}// 3
with(foo)/*4*/{}
with(
foo // 5
?? bar // 52
){}
with(foo) {} // 6
with(foo) /* 7 */ ++x;
with(1) // 8
foo();
=====================================output=====================================
with (
foo
// 1
) {
}
with (foo) {
// 2
}
with (foo) {
} // 3
with (foo) {
/*4*/
}
with (
foo ?? // 5
bar // 52
) {
}
with (foo) {
} // 6
with (foo) /* 7 */ ++x;
with (1)
// 8
foo();
================================================================================
`;
@@ -0,0 +1 @@
runFormatTest(import.meta, ["babel", "flow", "typescript"]);
@@ -0,0 +1,23 @@
while(
true
// 1
) {}
while(true)// 2
{}
while(true){}// 3
while(true)/*4*/{}
while(
true // 5
&& true // 52
){}
while(true) {} // 6
while(true) /* 7 */ ++x;
while(1) // 8
foo();
@@ -0,0 +1,23 @@
with(
foo
// 1
) {}
with(foo)// 2
{}
with(foo){}// 3
with(foo)/*4*/{}
with(
foo // 5
?? bar // 52
){}
with(foo) {} // 6
with(foo) /* 7 */ ++x;
with(1) // 8
foo();
-23
View File
@@ -1,23 +0,0 @@
while(
true
// Comment
) {}
while(true)// Comment
{}
while(true){}// Comment
while(true)/*Comment*/{}
while(
true // Comment
&& true // Comment
){}
while(true) {} // comment
while(true) /* comment */ ++x;
while(1) // Comment
foo();