From be7edf164677311dea6bd37b459f8fbcd2d98be3 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 21 Nov 2020 21:59:55 +0800 Subject: [PATCH 01/22] Refactor comment attach --- src/language-js/comments.js | 305 +++++++++++++----------------------- src/main/comments-store.js | 57 +++++++ src/main/comments.js | 29 +++- 3 files changed, 189 insertions(+), 202 deletions(-) create mode 100644 src/main/comments-store.js diff --git a/src/language-js/comments.js b/src/language-js/comments.js index 0433fe3c6a1f..1a7c0cff0423 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -6,9 +6,6 @@ const { getNextNonSpaceNonCommentCharacterIndexWithStartIndex, getNextNonSpaceNonCommentCharacter, hasNewlineInRange, - addLeadingComment, - addTrailingComment, - addDanglingComment, getNextNonSpaceNonCommentCharacterIndex, } = require("../common/util"); const { @@ -36,14 +33,16 @@ const { locStart, locEnd } = require("./loc"); * @property {any} options * @property {Node} ast * @property {boolean} isLastComment + * + * @typedef {{node: any; type: string}} CommentHandleResult */ /** * @param {CommentContext} context - * @returns {boolean} + * @returns {CommentHandleResult | void} */ function handleOwnLineComment(context) { - return [ + for (const handler of [ handleIgnoreComments, handleLastFunctionArgComments, handleMemberExpressionComments, @@ -59,15 +58,20 @@ function handleOwnLineComment(context) { handleAssignmentPatternComments, handleMethodNameComments, handleLabeledStatementComments, - ].some((fn) => fn(context)); + ]) { + const result = handler(context); + if (result) { + return result; + } + } } /** * @param {CommentContext} context - * @returns {boolean} + * @returns {CommentHandleResult | void} */ function handleEndOfLineComment(context) { - return [ + for (const handler of [ handleClosureTypeCastComments, handleLastFunctionArgComments, handleConditionalExpressionComments, @@ -82,15 +86,20 @@ function handleEndOfLineComment(context) { handleOnlyComments, handleTypeAliasComments, handleVariableDeclaratorComments, - ].some((fn) => fn(context)); + ]) { + const result = handler(context); + if (result) { + return result; + } + } } /** * @param {CommentContext} context - * @returns {boolean} + * @returns {CommentHandleResult | void} */ function handleRemainingComment(context) { - return [ + for (const handler of [ handleIgnoreComments, handleIfStatementComments, handleWhileComments, @@ -103,43 +112,44 @@ function handleRemainingComment(context) { handleTSMappedTypeComments, handleBreakAndContinueStatementComments, handleTSFunctionTrailingComments, - ].some((fn) => fn(context)); + ]) { + const result = handler(context); + if (result) { + return result; + } + } } /** * @param {Node} node - * @returns {void} + * @returns {CommentHandleResult} */ -function addBlockStatementFirstComment(node, comment) { +function addBlockStatementFirstComment(node) { // @ts-ignore const firstNonEmptyNode = (node.body || node.properties).find( ({ type }) => type !== "EmptyStatement" ); if (firstNonEmptyNode) { - addLeadingComment(firstNonEmptyNode, comment); - } else { - addDanglingComment(node, comment); + return { node: firstNonEmptyNode, type: "leading" }; } + return { node, type: "dangling" }; } /** * @param {Node} node - * @returns {void} + * @returns {CommentHandleResult} */ -function addBlockOrNotComment(node, comment) { +function addBlockOrNotComment(node) { if (node.type === "BlockStatement") { - addBlockStatementFirstComment(node, comment); - } else { - addLeadingComment(node, comment); + return addBlockStatementFirstComment(node); } + return { node, type: "leading" }; } function handleClosureTypeCastComments({ comment, followingNode }) { if (followingNode && isTypeCastComment(comment)) { - addLeadingComment(followingNode, comment); - return true; + return { node: followingNode, type: "leading" }; } - return false; } // There are often comments before the else clause of if statements like @@ -170,7 +180,7 @@ function handleIfStatementComments({ enclosingNode.type !== "IfStatement" || !followingNode ) { - return false; + return; } // We unfortunately have no way using the AST or location of nodes to know @@ -184,8 +194,7 @@ function handleIfStatementComments({ locEnd ); if (nextCharacter === ")") { - addTrailingComment(precedingNode, comment); - return true; + return { node: precedingNode, type: "trailing" }; } // Comments before `else`: @@ -196,21 +205,17 @@ function handleIfStatementComments({ followingNode === enclosingNode.alternate ) { if (precedingNode.type === "BlockStatement") { - addTrailingComment(precedingNode, comment); - } else { - addDanglingComment(enclosingNode, comment); + return { node: precedingNode, type: "trailing" }; } - return true; + return { node: enclosingNode, type: "dangling" }; } if (followingNode.type === "BlockStatement") { - addBlockStatementFirstComment(followingNode, comment); - return true; + return addBlockStatementFirstComment(followingNode); } if (followingNode.type === "IfStatement") { - addBlockOrNotComment(followingNode.consequent, comment); - return true; + return addBlockOrNotComment(followingNode.consequent); } // For comments positioned after the condition parenthesis in an if statement @@ -219,11 +224,8 @@ function handleIfStatementComments({ // we look at the next character to see if the following node // is the consequent for the if statement if (enclosingNode.consequent === followingNode) { - addLeadingComment(followingNode, comment); - return true; + return { node: followingNode, type: "leading" }; } - - return false; } function handleWhileComments({ @@ -238,7 +240,7 @@ function handleWhileComments({ enclosingNode.type !== "WhileStatement" || !followingNode ) { - return false; + return; } // We unfortunately have no way using the AST or location of nodes to know @@ -252,26 +254,20 @@ function handleWhileComments({ locEnd ); if (nextCharacter === ")") { - addTrailingComment(precedingNode, comment); - return true; + return { node: precedingNode, type: "trailing" }; } if (followingNode.type === "BlockStatement") { - addBlockStatementFirstComment(followingNode, comment); - return true; + return addBlockStatementFirstComment(followingNode); } if (enclosingNode.body === followingNode) { - addLeadingComment(followingNode, comment); - return true; + return { node: followingNode, type: "leading" }; } - - return false; } // Same as IfStatement but for TryStatement function handleTryStatementComments({ - comment, precedingNode, enclosingNode, followingNode, @@ -282,37 +278,27 @@ function handleTryStatementComments({ enclosingNode.type !== "CatchClause") || !followingNode ) { - return false; + return; } if (enclosingNode.type === "CatchClause" && precedingNode) { - addTrailingComment(precedingNode, comment); - return true; + return { node: precedingNode, type: "trailing" }; } if (followingNode.type === "BlockStatement") { - addBlockStatementFirstComment(followingNode, comment); - return true; + return addBlockStatementFirstComment(followingNode); } if (followingNode.type === "TryStatement") { - addBlockOrNotComment(followingNode.finalizer, comment); - return true; + return addBlockOrNotComment(followingNode.finalizer); } if (followingNode.type === "CatchClause") { - addBlockOrNotComment(followingNode.body, comment); - return true; + return addBlockOrNotComment(followingNode.body); } - - return false; } -function handleMemberExpressionComments({ - comment, - enclosingNode, - followingNode, -}) { +function handleMemberExpressionComments({ enclosingNode, followingNode }) { if ( enclosingNode && (enclosingNode.type === "MemberExpression" || @@ -320,11 +306,8 @@ function handleMemberExpressionComments({ followingNode && followingNode.type === "Identifier" ) { - addLeadingComment(enclosingNode, comment); - return true; + return { node: enclosingNode, type: "leading" }; } - - return false; } function handleConditionalExpressionComments({ @@ -345,17 +328,11 @@ function handleConditionalExpressionComments({ enclosingNode.type === "TSConditionalType") && followingNode ) { - addLeadingComment(followingNode, comment); - return true; + return { node: followingNode, type: "leading" }; } - return false; } -function handleObjectPropertyAssignment({ - comment, - precedingNode, - enclosingNode, -}) { +function handleObjectPropertyAssignment({ precedingNode, enclosingNode }) { if ( enclosingNode && (enclosingNode.type === "ObjectProperty" || @@ -364,10 +341,8 @@ function handleObjectPropertyAssignment({ enclosingNode.key === precedingNode && enclosingNode.value.type === "AssignmentPattern" ) { - addTrailingComment(enclosingNode.value.left, comment); - return true; + return { node: enclosingNode.value.left, type: "trailing" }; } - return false; } function handleClassComments({ @@ -390,16 +365,14 @@ function handleClassComments({ enclosingNode.decorators.length > 0 && !(followingNode && followingNode.type === "Decorator") ) { - addTrailingComment( - enclosingNode.decorators[enclosingNode.decorators.length - 1], - comment - ); - return true; + return { + node: enclosingNode.decorators[enclosingNode.decorators.length - 1], + type: "trailing", + }; } if (enclosingNode.body && followingNode === enclosingNode.body) { - addBlockStatementFirstComment(enclosingNode.body, comment); - return true; + return addBlockStatementFirstComment(enclosingNode.body); } // Don't add leading comments to `implements`, `extends`, `mixins` to @@ -413,24 +386,16 @@ function handleClassComments({ precedingNode === enclosingNode.typeParameters || precedingNode === enclosingNode.superClass) ) { - addTrailingComment(precedingNode, comment); - } else { - addDanglingComment(enclosingNode, comment, prop); + return { node: precedingNode, type: "trailing" }; } - return true; + return { node: enclosingNode, comment, type: "dangling" }; } } } } - return false; } -function handleMethodNameComments({ - comment, - precedingNode, - enclosingNode, - text, -}) { +function handleMethodNameComments({ precedingNode, enclosingNode, text }) { // This is only needed for estree parsers (flow, typescript) to attach // after a method name: // obj = { fn /*comment*/() {} }; @@ -447,8 +412,7 @@ function handleMethodNameComments({ // comment should be attached to value instead of key getNextNonSpaceNonCommentCharacter(text, precedingNode, locEnd) !== ":" ) { - addTrailingComment(precedingNode, comment); - return true; + return { node: precedingNode, type: "trailing" }; } // Print comments between decorators and class methods as a trailing comment @@ -465,11 +429,8 @@ function handleMethodNameComments({ enclosingNode.type === "TSDeclareMethod" || enclosingNode.type === "MethodDefinition") ) { - addTrailingComment(precedingNode, comment); - return true; + return { node: precedingNode, type: "trailing" }; } - - return false; } function handleFunctionNameComments({ @@ -479,7 +440,7 @@ function handleFunctionNameComments({ text, }) { if (getNextNonSpaceNonCommentCharacter(text, comment, locEnd) !== "(") { - return false; + return; } if ( precedingNode && @@ -490,29 +451,24 @@ function handleFunctionNameComments({ enclosingNode.type === "MethodDefinition" || enclosingNode.type === "ObjectMethod") ) { - addTrailingComment(precedingNode, comment); - return true; + return { node: precedingNode, type: "trailing" }; } - return false; } function handleCommentAfterArrowParams({ comment, enclosingNode, text }) { if (!(enclosingNode && enclosingNode.type === "ArrowFunctionExpression")) { - return false; + return; } const index = getNextNonSpaceNonCommentCharacterIndex(text, comment, locEnd); if (index !== false && text.slice(index, index + 2) === "=>") { - addDanglingComment(enclosingNode, comment); - return true; + return { node: enclosingNode, type: "dangling" }; } - - return false; } function handleCommentInEmptyParens({ comment, enclosingNode, text }) { if (getNextNonSpaceNonCommentCharacter(text, comment, locEnd) !== ")") { - return false; + return; } // Only add dangling comments to fix the case when no params are present, @@ -526,18 +482,15 @@ function handleCommentInEmptyParens({ comment, enclosingNode, text }) { enclosingNode.type === "NewExpression") && enclosingNode.arguments.length === 0)) ) { - addDanglingComment(enclosingNode, comment); - return true; + return { node: enclosingNode, type: "dangling" }; } if ( enclosingNode && enclosingNode.type === "MethodDefinition" && getFunctionParameters(enclosingNode.value).length === 0 ) { - addDanglingComment(enclosingNode.value, comment); - return true; + return { node: enclosingNode.value, type: "dangling" }; } - return false; } function handleLastFunctionArgComments({ @@ -556,8 +509,7 @@ function handleLastFunctionArgComments({ followingNode && followingNode.type !== "FunctionTypeParam" ) { - addTrailingComment(precedingNode, comment); - return true; + return { node: precedingNode, type: "trailing" }; } // Real functions and TypeScript function type definitions @@ -569,8 +521,7 @@ function handleLastFunctionArgComments({ isRealFunctionLikeNode(enclosingNode) && getNextNonSpaceNonCommentCharacter(text, comment, locEnd) === ")" ) { - addTrailingComment(precedingNode, comment); - return true; + return { node: precedingNode, type: "trailing" }; } if ( @@ -600,48 +551,35 @@ function handleLastFunctionArgComments({ ); })(); if (locStart(comment) > functionParamRightParenIndex) { - addBlockStatementFirstComment(followingNode, comment); - return true; + return addBlockStatementFirstComment(followingNode); } } - - return false; } -function handleImportSpecifierComments({ comment, enclosingNode }) { +function handleImportSpecifierComments({ enclosingNode }) { if (enclosingNode && enclosingNode.type === "ImportSpecifier") { - addLeadingComment(enclosingNode, comment); - return true; + return { node: enclosingNode, type: "leading" }; } - return false; } -function handleLabeledStatementComments({ comment, enclosingNode }) { +function handleLabeledStatementComments({ enclosingNode }) { if (enclosingNode && enclosingNode.type === "LabeledStatement") { - addLeadingComment(enclosingNode, comment); - return true; + return { node: enclosingNode, type: "leading" }; } - return false; } -function handleBreakAndContinueStatementComments({ comment, enclosingNode }) { +function handleBreakAndContinueStatementComments({ enclosingNode }) { if ( enclosingNode && (enclosingNode.type === "ContinueStatement" || enclosingNode.type === "BreakStatement") && !enclosingNode.label ) { - addTrailingComment(enclosingNode, comment); - return true; + return { node: enclosingNode, type: "trailing" }; } - return false; } -function handleCallExpressionComments({ - comment, - precedingNode, - enclosingNode, -}) { +function handleCallExpressionComments({ precedingNode, enclosingNode }) { if ( enclosingNode && (enclosingNode.type === "CallExpression" || @@ -650,10 +588,8 @@ function handleCallExpressionComments({ enclosingNode.callee === precedingNode && enclosingNode.arguments.length > 0 ) { - addLeadingComment(enclosingNode.arguments[0], comment); - return true; + return { node: enclosingNode.arguments[0], type: "leading" }; } - return false; } function handleUnionTypeComments({ @@ -672,10 +608,9 @@ function handleUnionTypeComments({ comment.unignore = true; } if (precedingNode) { - addTrailingComment(precedingNode, comment); - return true; + return { node: precedingNode, type: "trailing" }; } - return false; + return; } if ( @@ -686,32 +621,27 @@ function handleUnionTypeComments({ ) { followingNode.types[0].prettierIgnore = true; comment.unignore = true; + return { node: followingNode, type: "ignore" }; } - - return false; } -function handlePropertyComments({ comment, enclosingNode }) { +function handlePropertyComments({ enclosingNode }) { if ( enclosingNode && (enclosingNode.type === "Property" || enclosingNode.type === "ObjectProperty") ) { - addLeadingComment(enclosingNode, comment); - return true; + return { node: enclosingNode, type: "leading" }; } - return false; } -function handleOnlyComments({ comment, enclosingNode, ast, isLastComment }) { +function handleOnlyComments({ enclosingNode, ast, isLastComment }) { // With Flow the enclosingNode is undefined so use the AST instead. if (ast && ast.body && ast.body.length === 0) { if (isLastComment) { - addDanglingComment(ast, comment); - } else { - addLeadingComment(ast, comment); + return { node: ast, type: "dangling" }; } - return true; + return { node: ast, type: "leading" }; } else if ( enclosingNode && enclosingNode.type === "Program" && @@ -720,25 +650,20 @@ function handleOnlyComments({ comment, enclosingNode, ast, isLastComment }) { enclosingNode.directives.length === 0 ) { if (isLastComment) { - addDanglingComment(enclosingNode, comment); - } else { - addLeadingComment(enclosingNode, comment); + return { node: enclosingNode, type: "dangling" }; } - return true; + return { node: enclosingNode, type: "leading" }; } - return false; } -function handleForComments({ comment, enclosingNode }) { +function handleForComments({ enclosingNode }) { if ( enclosingNode && (enclosingNode.type === "ForInStatement" || enclosingNode.type === "ForOfStatement") ) { - addLeadingComment(enclosingNode, comment); - return true; + return { node: enclosingNode, type: "leading" }; } - return false; } function handleImportDeclarationComments({ @@ -754,26 +679,20 @@ function handleImportDeclarationComments({ enclosingNode.type === "ImportDeclaration" && hasNewline(text, locEnd(comment)) ) { - addTrailingComment(precedingNode, comment); - return true; + return { node: precedingNode, type: "trailing" }; } - return false; } -function handleAssignmentPatternComments({ comment, enclosingNode }) { +function handleAssignmentPatternComments({ enclosingNode }) { if (enclosingNode && enclosingNode.type === "AssignmentPattern") { - addLeadingComment(enclosingNode, comment); - return true; + return { node: enclosingNode, type: "leading" }; } - return false; } -function handleTypeAliasComments({ comment, enclosingNode }) { +function handleTypeAliasComments({ enclosingNode }) { if (enclosingNode && enclosingNode.type === "TypeAlias") { - addLeadingComment(enclosingNode, comment); - return true; + return { node: enclosingNode, type: "leading" }; } - return false; } function handleVariableDeclaratorComments({ @@ -792,10 +711,8 @@ function handleVariableDeclaratorComments({ followingNode.type === "TaggedTemplateExpression" || isBlockComment(comment)) ) { - addLeadingComment(followingNode, comment); - return true; + return { node: followingNode, type: "leading" }; } - return false; } function handleTSFunctionTrailingComments({ @@ -812,10 +729,8 @@ function handleTSFunctionTrailingComments({ enclosingNode.type === "TSAbstractMethodDefinition") && getNextNonSpaceNonCommentCharacter(text, comment, locEnd) === ";" ) { - addTrailingComment(enclosingNode, comment); - return true; + return { node: enclosingNode, type: "trailing" }; } - return false; } function handleIgnoreComments({ comment, enclosingNode, followingNode }) { @@ -829,18 +744,17 @@ function handleIgnoreComments({ comment, enclosingNode, followingNode }) { ) { enclosingNode.prettierIgnore = true; comment.unignore = true; - return true; + return { node: enclosingNode, type: "ignore" }; } } function handleTSMappedTypeComments({ - comment, precedingNode, enclosingNode, followingNode, }) { if (!enclosingNode || enclosingNode.type !== "TSMappedType") { - return false; + return; } if ( @@ -848,8 +762,7 @@ function handleTSMappedTypeComments({ followingNode.type === "TSTypeParameter" && followingNode.name ) { - addLeadingComment(followingNode.name, comment); - return true; + return { node: followingNode.name, type: "leading" }; } if ( @@ -857,11 +770,8 @@ function handleTSMappedTypeComments({ precedingNode.type === "TSTypeParameter" && precedingNode.constraint ) { - addTrailingComment(precedingNode.constraint, comment); - return true; + return { node: precedingNode.constraint, type: "trailing" }; } - - return false; } /** @@ -876,7 +786,6 @@ function hasLeadingComment(node, fn = () => true) { if (node.comments) { return node.comments.some((comment) => comment.leading && fn(comment)); } - return false; } /** diff --git a/src/main/comments-store.js b/src/main/comments-store.js new file mode 100644 index 000000000000..155db72a9d45 --- /dev/null +++ b/src/main/comments-store.js @@ -0,0 +1,57 @@ +"use strict"; + +const { + hasNewline, + skipNewline, + skipSpaces, + isPreviousLineEmpty, + addLeadingComment, + addDanglingComment, + addTrailingComment, +} = require("../common/util"); + +class CommentsStore { + constructor() { + this.map = new WeakMap(); + } + addComment(node, comment, type) { + if (!this.map.has(node)) { + this.map.set(node, { + leading: [], + trailing: [], + dangling: [], + ignore: [], + all: [], + }); + } + const comments = this.map.get(node); + comments[type].push(comment); + // TODO: remove this + if (type === "leading") { + addLeadingComment(node, comment); + } else if (type === "trailing") { + addTrailingComment(node, comment); + } else if (type === "dangling") { + addDanglingComment(node, comment); + } + comments.all.push(comment); + } + addLeadingComment(node, comment) { + return this.addComment(node, comment, "leading"); + } + addTrailingComment(node, comment) { + return this.addComment(node, comment, "trailing"); + } + addDanglingComment(node, comment) { + return this.addComment(node, comment, "dangling"); + } + get(node, type = "all") { + if (!this.map.has(node)) { + return []; + } + const comments = this.map.get(node); + return comments[type]; + } +} + +module.exports = CommentsStore; diff --git a/src/main/comments.js b/src/main/comments.js index 6094568e2e03..bf1365436eee 100644 --- a/src/main/comments.js +++ b/src/main/comments.js @@ -25,6 +25,7 @@ const { addDanglingComment, addTrailingComment, } = require("../common/util"); +const CommentsStore = require("./comments-store"); const childNodesCacheKey = Symbol("child-nodes"); @@ -187,6 +188,11 @@ function attach(comments, ast, text, options) { remaining: handleRemainingComment = returnFalse, } = handleComments; + let commentStore; + if (avoidAstMutation) { + commentStore = new CommentsStore(); + } + comments.forEach((comment, i) => { if ( options.parser === "json" || @@ -219,7 +225,7 @@ function attach(comments, ast, text, options) { }; let args; - if (avoidAstMutation) { + if (commentStore) { args = [context]; } else { comment.enclosingNode = enclosingNode; @@ -229,10 +235,15 @@ function attach(comments, ast, text, options) { } if (hasNewline(text, locStart(comment), { backwards: true })) { + const handleResult = handleOwnLineComment(...args); // If a comment exists on its own line, prefer a leading comment. // We also need to check if it's the first line of the file. - if (handleOwnLineComment(...args)) { + if (handleResult) { // We're good + if (commentStore) { + const { node, type } = handleResult; + commentStore.addComment(node, comment, type); + } } else if (followingNode) { // Always a leading comment. addLeadingComment(followingNode, comment); @@ -246,7 +257,12 @@ function attach(comments, ast, text, options) { addDanglingComment(ast, comment); } } else if (hasNewline(text, locEnd(comment))) { - if (handleEndOfLineComment(...args)) { + const handleResult = handleEndOfLineComment(...args); + if (handleResult) { + if (commentStore) { + const { node, type } = handleResult; + commentStore.addComment(node, comment, type); + } // We're good } else if (precedingNode) { // There is content before this comment on the same line, but @@ -262,7 +278,12 @@ function attach(comments, ast, text, options) { addDanglingComment(ast, comment); } } else { - if (handleRemainingComment(...args)) { + const handleResult = handleRemainingComment(...args); + if (handleResult) { + if (commentStore) { + const { node, type } = handleResult; + commentStore.addComment(node, comment, type); + } // We're good } else if (precedingNode && followingNode) { // Otherwise, text exists both before and after the comment on From 091957b98d4fac555ad49b752a7f66dfa6482be2 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 21 Nov 2020 22:13:34 +0800 Subject: [PATCH 02/22] Update attach logic --- src/main/comments.js | 107 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 92 insertions(+), 15 deletions(-) diff --git a/src/main/comments.js b/src/main/comments.js index bf1365436eee..454949add37d 100644 --- a/src/main/comments.js +++ b/src/main/comments.js @@ -214,6 +214,7 @@ function attach(comments, ast, text, options) { const decorated = decorateComment(ast, comment, options); const { precedingNode, enclosingNode, followingNode } = decorated; const context = { + commentStore, comment, precedingNode, enclosingNode, @@ -246,15 +247,31 @@ function attach(comments, ast, text, options) { } } else if (followingNode) { // Always a leading comment. - addLeadingComment(followingNode, comment); + if (commentStore) { + commentStore.addLeadingComment(followingNode, comment); + } else { + addLeadingComment(followingNode, comment); + } } else if (precedingNode) { - addTrailingComment(precedingNode, comment); + if (commentStore) { + commentStore.addTrailingComment(precedingNode, comment); + } else { + addTrailingComment(precedingNode, comment); + } } else if (enclosingNode) { - addDanglingComment(enclosingNode, comment); + if (commentStore) { + commentStore.addDanglingComment(enclosingNode, comment); + } else { + addDanglingComment(enclosingNode, comment); + } } else { // There are no nodes, let's attach it to the root of the ast /* istanbul ignore next */ - addDanglingComment(ast, comment); + if (commentStore) { + commentStore.addDanglingComment(ast, comment); + } else { + addDanglingComment(ast, comment); + } } } else if (hasNewline(text, locEnd(comment))) { const handleResult = handleEndOfLineComment(...args); @@ -267,15 +284,31 @@ function attach(comments, ast, text, options) { } else if (precedingNode) { // There is content before this comment on the same line, but // none after it, so prefer a trailing comment of the previous node. - addTrailingComment(precedingNode, comment); + if (commentStore) { + commentStore.addTrailingComment(precedingNode, comment); + } else { + addTrailingComment(precedingNode, comment); + } } else if (followingNode) { - addLeadingComment(followingNode, comment); + if (commentStore) { + commentStore.addLeadingComment(followingNode, comment); + } else { + addLeadingComment(followingNode, comment); + } } else if (enclosingNode) { - addDanglingComment(enclosingNode, comment); + if (commentStore) { + commentStore.addDanglingComment(enclosingNode, comment); + } else { + addDanglingComment(enclosingNode, comment); + } } else { // There are no nodes, let's attach it to the root of the ast /* istanbul ignore next */ - addDanglingComment(ast, comment); + if (commentStore) { + commentStore.addDanglingComment(ast, comment); + } else { + addDanglingComment(ast, comment); + } } } else { const handleResult = handleRemainingComment(...args); @@ -300,15 +333,31 @@ function attach(comments, ast, text, options) { } tiesToBreak.push(context); } else if (precedingNode) { - addTrailingComment(precedingNode, comment); + if (commentStore) { + commentStore.addTrailingComment(precedingNode, comment); + } else { + addTrailingComment(precedingNode, comment); + } } else if (followingNode) { - addLeadingComment(followingNode, comment); + if (commentStore) { + commentStore.addLeadingComment(followingNode, comment); + } else { + addLeadingComment(followingNode, comment); + } } else if (enclosingNode) { - addDanglingComment(enclosingNode, comment); + if (commentStore) { + commentStore.addDanglingComment(enclosingNode, comment); + } else { + addDanglingComment(enclosingNode, comment); + } } else { // There are no nodes, let's attach it to the root of the ast /* istanbul ignore next */ - addDanglingComment(ast, comment); + if (commentStore) { + commentStore.addDanglingComment(ast, comment); + } else { + addDanglingComment(ast, comment); + } } } }); @@ -332,7 +381,12 @@ function breakTies(tiesToBreak, text, options) { if (tieCount === 0) { return; } - const { precedingNode, followingNode, enclosingNode } = tiesToBreak[0]; + const { + commentStore, + precedingNode, + followingNode, + enclosingNode, + } = tiesToBreak[0]; const gapRegExp = (options.printer.getGapRegex && @@ -373,12 +427,35 @@ function breakTies(tiesToBreak, text, options) { tiesToBreak.forEach(({ comment }, i) => { if (i < indexOfFirstLeadingComment) { - addTrailingComment(precedingNode, comment); + if (commentStore) { + commentStore.addTrailingComment(precedingNode, comment); + } else { + addTrailingComment(precedingNode, comment); + } } else { - addLeadingComment(followingNode, comment); + if (commentStore) { + commentStore.addLeadingComment(followingNode, comment); + } else { + addLeadingComment(followingNode, comment); + } } }); + if (commentStore) { + for (const node of [precedingNode, followingNode]) { + for (const comments of [ + commentStore.get(node, "leading"), + commentStore.get(node, "trailing"), + commentStore.get(node, "dangling"), + commentStore.get(node, "ignore"), + commentStore.get(node, "all"), + ]) { + comments.sort((a, b) => options.locStart(a) - options.locStart(b)); + } + } + } + + // TODO: put this in `if (!commentStore)` for (const node of [precedingNode, followingNode]) { if (node.comments && node.comments.length > 1) { node.comments.sort((a, b) => options.locStart(a) - options.locStart(b)); From 073d11cf2a35262c659a562b2608eb7dd434c1e4 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 21 Nov 2020 22:17:51 +0800 Subject: [PATCH 03/22] Put store into options --- src/main/comments.js | 103 ++++++++++++++++++++++--------------------- src/main/core.js | 6 ++- 2 files changed, 57 insertions(+), 52 deletions(-) diff --git a/src/main/comments.js b/src/main/comments.js index 454949add37d..ad02c2620c46 100644 --- a/src/main/comments.js +++ b/src/main/comments.js @@ -170,11 +170,6 @@ function decorateComment(node, comment, options, enclosingNode) { const returnFalse = () => false; function attach(comments, ast, text, options) { - if (!Array.isArray(comments)) { - return; - } - - const tiesToBreak = []; const { locStart, locEnd, @@ -188,10 +183,14 @@ function attach(comments, ast, text, options) { remaining: handleRemainingComment = returnFalse, } = handleComments; - let commentStore; + let commentsStore; if (avoidAstMutation) { - commentStore = new CommentsStore(); + commentsStore = new CommentsStore(); } + if (!Array.isArray(comments)) { + return commentsStore; + } + const tiesToBreak = []; comments.forEach((comment, i) => { if ( @@ -214,7 +213,7 @@ function attach(comments, ast, text, options) { const decorated = decorateComment(ast, comment, options); const { precedingNode, enclosingNode, followingNode } = decorated; const context = { - commentStore, + commentsStore, comment, precedingNode, enclosingNode, @@ -226,7 +225,7 @@ function attach(comments, ast, text, options) { }; let args; - if (commentStore) { + if (commentsStore) { args = [context]; } else { comment.enclosingNode = enclosingNode; @@ -241,34 +240,34 @@ function attach(comments, ast, text, options) { // We also need to check if it's the first line of the file. if (handleResult) { // We're good - if (commentStore) { + if (commentsStore) { const { node, type } = handleResult; - commentStore.addComment(node, comment, type); + commentsStore.addComment(node, comment, type); } } else if (followingNode) { // Always a leading comment. - if (commentStore) { - commentStore.addLeadingComment(followingNode, comment); + if (commentsStore) { + commentsStore.addLeadingComment(followingNode, comment); } else { addLeadingComment(followingNode, comment); } } else if (precedingNode) { - if (commentStore) { - commentStore.addTrailingComment(precedingNode, comment); + if (commentsStore) { + commentsStore.addTrailingComment(precedingNode, comment); } else { addTrailingComment(precedingNode, comment); } } else if (enclosingNode) { - if (commentStore) { - commentStore.addDanglingComment(enclosingNode, comment); + if (commentsStore) { + commentsStore.addDanglingComment(enclosingNode, comment); } else { addDanglingComment(enclosingNode, comment); } } else { // There are no nodes, let's attach it to the root of the ast /* istanbul ignore next */ - if (commentStore) { - commentStore.addDanglingComment(ast, comment); + if (commentsStore) { + commentsStore.addDanglingComment(ast, comment); } else { addDanglingComment(ast, comment); } @@ -276,36 +275,36 @@ function attach(comments, ast, text, options) { } else if (hasNewline(text, locEnd(comment))) { const handleResult = handleEndOfLineComment(...args); if (handleResult) { - if (commentStore) { + if (commentsStore) { const { node, type } = handleResult; - commentStore.addComment(node, comment, type); + commentsStore.addComment(node, comment, type); } // We're good } else if (precedingNode) { // There is content before this comment on the same line, but // none after it, so prefer a trailing comment of the previous node. - if (commentStore) { - commentStore.addTrailingComment(precedingNode, comment); + if (commentsStore) { + commentsStore.addTrailingComment(precedingNode, comment); } else { addTrailingComment(precedingNode, comment); } } else if (followingNode) { - if (commentStore) { - commentStore.addLeadingComment(followingNode, comment); + if (commentsStore) { + commentsStore.addLeadingComment(followingNode, comment); } else { addLeadingComment(followingNode, comment); } } else if (enclosingNode) { - if (commentStore) { - commentStore.addDanglingComment(enclosingNode, comment); + if (commentsStore) { + commentsStore.addDanglingComment(enclosingNode, comment); } else { addDanglingComment(enclosingNode, comment); } } else { // There are no nodes, let's attach it to the root of the ast /* istanbul ignore next */ - if (commentStore) { - commentStore.addDanglingComment(ast, comment); + if (commentsStore) { + commentsStore.addDanglingComment(ast, comment); } else { addDanglingComment(ast, comment); } @@ -313,9 +312,9 @@ function attach(comments, ast, text, options) { } else { const handleResult = handleRemainingComment(...args); if (handleResult) { - if (commentStore) { + if (commentsStore) { const { node, type } = handleResult; - commentStore.addComment(node, comment, type); + commentsStore.addComment(node, comment, type); } // We're good } else if (precedingNode && followingNode) { @@ -333,28 +332,28 @@ function attach(comments, ast, text, options) { } tiesToBreak.push(context); } else if (precedingNode) { - if (commentStore) { - commentStore.addTrailingComment(precedingNode, comment); + if (commentsStore) { + commentsStore.addTrailingComment(precedingNode, comment); } else { addTrailingComment(precedingNode, comment); } } else if (followingNode) { - if (commentStore) { - commentStore.addLeadingComment(followingNode, comment); + if (commentsStore) { + commentsStore.addLeadingComment(followingNode, comment); } else { addLeadingComment(followingNode, comment); } } else if (enclosingNode) { - if (commentStore) { - commentStore.addDanglingComment(enclosingNode, comment); + if (commentsStore) { + commentsStore.addDanglingComment(enclosingNode, comment); } else { addDanglingComment(enclosingNode, comment); } } else { // There are no nodes, let's attach it to the root of the ast /* istanbul ignore next */ - if (commentStore) { - commentStore.addDanglingComment(ast, comment); + if (commentsStore) { + commentsStore.addDanglingComment(ast, comment); } else { addDanglingComment(ast, comment); } @@ -374,6 +373,8 @@ function attach(comments, ast, text, options) { delete comment.followingNode; }); } + + return commentsStore; } function breakTies(tiesToBreak, text, options) { @@ -382,7 +383,7 @@ function breakTies(tiesToBreak, text, options) { return; } const { - commentStore, + commentsStore, precedingNode, followingNode, enclosingNode, @@ -427,35 +428,35 @@ function breakTies(tiesToBreak, text, options) { tiesToBreak.forEach(({ comment }, i) => { if (i < indexOfFirstLeadingComment) { - if (commentStore) { - commentStore.addTrailingComment(precedingNode, comment); + if (commentsStore) { + commentsStore.addTrailingComment(precedingNode, comment); } else { addTrailingComment(precedingNode, comment); } } else { - if (commentStore) { - commentStore.addLeadingComment(followingNode, comment); + if (commentsStore) { + commentsStore.addLeadingComment(followingNode, comment); } else { addLeadingComment(followingNode, comment); } } }); - if (commentStore) { + if (commentsStore) { for (const node of [precedingNode, followingNode]) { for (const comments of [ - commentStore.get(node, "leading"), - commentStore.get(node, "trailing"), - commentStore.get(node, "dangling"), - commentStore.get(node, "ignore"), - commentStore.get(node, "all"), + commentsStore.get(node, "leading"), + commentsStore.get(node, "trailing"), + commentsStore.get(node, "dangling"), + commentsStore.get(node, "ignore"), + commentsStore.get(node, "all"), ]) { comments.sort((a, b) => options.locStart(a) - options.locStart(b)); } } } - // TODO: put this in `if (!commentStore)` + // TODO: put this in `if (!commentsStore)` for (const node of [precedingNode, followingNode]) { if (node.comments && node.comments.length > 1) { node.comments.sort((a, b) => options.locStart(a) - options.locStart(b)); diff --git a/src/main/core.js b/src/main/core.js index 8ad34c4ec066..8d094777ebf1 100644 --- a/src/main/core.js +++ b/src/main/core.js @@ -26,12 +26,16 @@ const CURSOR = Symbol("cursor"); function attachComments(text, ast, opts) { const astComments = ast.comments; + let commentsStore; if (astComments) { delete ast.comments; - comments.attach(astComments, ast, text, opts); + commentsStore = comments.attach(astComments, ast, text, opts); } opts[Symbol.for("comments")] = astComments || []; opts[Symbol.for("tokens")] = ast.tokens || []; + if (commentsStore) { + opts[Symbol.for("commentsStore")] = commentsStore; + } opts.originalText = text; return astComments; } From 8dc72ff2870862ac502be30ff1cddcea517cbc94 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 21 Nov 2020 22:33:29 +0800 Subject: [PATCH 04/22] Refactor print functions --- src/language-js/print/comment.js | 4 +- src/main/comments.js | 87 +++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 27 deletions(-) diff --git a/src/language-js/print/comment.js b/src/language-js/print/comment.js index b41b1236caf8..4a11013bfeb9 100644 --- a/src/language-js/print/comment.js +++ b/src/language-js/print/comment.js @@ -8,9 +8,7 @@ const { const { isLineComment, isBlockComment } = require("../utils"); const { locStart, locEnd } = require("../loc"); -function printComment(commentPath, options) { - const comment = commentPath.getValue(); - +function printComment(comment, options) { if (isLineComment(comment)) { // Supports `//`, `#!`, `` return options.originalText diff --git a/src/main/comments.js b/src/main/comments.js index ad02c2620c46..b8a7f55a37fe 100644 --- a/src/main/comments.js +++ b/src/main/comments.js @@ -467,7 +467,8 @@ function breakTies(tiesToBreak, text, options) { } function printComment(commentPath, options) { - const comment = commentPath.getValue(); + const commentsStore = getCommentsStore(options); + const comment = commentsStore ? commentPath : commentPath.getValue(); comment.printed = true; return options.printer.printComment(commentPath, options); } @@ -486,9 +487,10 @@ function findExpressionIndexForComment(quasis, comment, options) { /* istanbul ignore next */ return 0; } - +const getCommentsStore = (options) => options[Symbol.for("commentsStore")]; function printLeadingComment(commentPath, options) { - const comment = commentPath.getValue(); + const commentsStore = getCommentsStore(options); + const comment = commentsStore ? commentPath : commentPath.getValue(); const contents = printComment(commentPath, options); /* istanbul ignore next */ if (!contents) { @@ -515,7 +517,8 @@ function printLeadingComment(commentPath, options) { } function printTrailingComment(commentPath, options) { - const comment = commentPath.getValue(); + const commentsStore = getCommentsStore(options); + const comment = commentsStore ? commentPath : commentPath.getValue(); const contents = printComment(commentPath, options); /* istanbul ignore next */ if (!contents) { @@ -559,6 +562,7 @@ function printTrailingComment(commentPath, options) { } function printDanglingComments(path, options, sameIndent, filter) { + const commentsStore = getCommentsStore(options); const parts = []; const node = path.getValue(); @@ -566,17 +570,26 @@ function printDanglingComments(path, options, sameIndent, filter) { return ""; } - path.each((commentPath) => { - const comment = commentPath.getValue(); - if ( - comment && - !comment.leading && - !comment.trailing && - (!filter || filter(comment)) - ) { - parts.push(printComment(commentPath, options)); + if (commentsStore) { + const comments = commentsStore.get(node, "dangling"); + for (const comment of comments) { + if (!filter || filter(comment)) { + parts.push(printComment(comment, options)); + } } - }, "comments"); + } else { + path.each((commentPath) => { + const comment = commentPath.getValue(); + if ( + comment && + !comment.leading && + !comment.trailing && + (!filter || filter(comment)) + ) { + parts.push(printComment(commentPath, options)); + } + }, "comments"); + } if (parts.length === 0) { return ""; @@ -596,9 +609,12 @@ function prependCursorPlaceholder(path, options, printed) { } function printComments(path, print, options, needsSemi) { + const commentsStore = getCommentsStore(options); const value = path.getValue(); const printed = print(path); - const comments = value && value.comments; + const comments = commentsStore + ? commentsStore.get(value) + : value && value.comments; if (!comments || comments.length === 0) { return prependCursorPlaceholder(path, options, printed); @@ -607,12 +623,9 @@ function printComments(path, print, options, needsSemi) { const leadingParts = []; const trailingParts = [needsSemi ? ";" : "", printed]; - path.each((commentPath) => { - const comment = commentPath.getValue(); - const { leading, trailing } = comment; - - if (leading) { - const contents = printLeadingComment(commentPath, options); + if (commentsStore) { + for (const comment of commentsStore.get(value, "leading")) { + const contents = printLeadingComment(comment, options); /* istanbul ignore next */ if (!contents) { return; @@ -627,10 +640,36 @@ function printComments(path, print, options, needsSemi) { if (index !== false && hasNewline(text, index)) { leadingParts.push(hardline); } - } else if (trailing) { - trailingParts.push(printTrailingComment(commentPath, options)); } - }, "comments"); + for (const comment of commentsStore.get(value, "trailing")) { + trailingParts.push(printTrailingComment(comment, options)); + } + } else { + path.each((commentPath) => { + const comment = commentPath.getValue(); + const { leading, trailing } = comment; + + if (leading) { + const contents = printLeadingComment(commentPath, options); + /* istanbul ignore next */ + if (!contents) { + return; + } + leadingParts.push(contents); + + const text = options.originalText; + const index = skipNewline( + text, + skipSpaces(text, options.locEnd(comment)) + ); + if (index !== false && hasNewline(text, index)) { + leadingParts.push(hardline); + } + } else if (trailing) { + trailingParts.push(printTrailingComment(commentPath, options)); + } + }, "comments"); + } return prependCursorPlaceholder( path, From 777d80eea68363ca0049801281a17942d9806f95 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 21 Nov 2020 22:48:28 +0800 Subject: [PATCH 05/22] Fix json --- src/main/comments.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/comments.js b/src/main/comments.js index b8a7f55a37fe..6aebe85e10a7 100644 --- a/src/main/comments.js +++ b/src/main/comments.js @@ -200,11 +200,11 @@ function attach(comments, ast, text, options) { options.parser === "__vue_expression" ) { if (locStart(comment) - locStart(ast) <= 0) { - addLeadingComment(ast, comment); + commentsStore.addLeadingComment(ast, comment); return; } if (locEnd(comment) - locEnd(ast) >= 0) { - addTrailingComment(ast, comment); + commentsStore.addTrailingComment(ast, comment); return; } } @@ -566,10 +566,6 @@ function printDanglingComments(path, options, sameIndent, filter) { const parts = []; const node = path.getValue(); - if (!node || !node.comments) { - return ""; - } - if (commentsStore) { const comments = commentsStore.get(node, "dangling"); for (const comment of comments) { @@ -578,6 +574,10 @@ function printDanglingComments(path, options, sameIndent, filter) { } } } else { + if (!node || !node.comments) { + return ""; + } + path.each((commentPath) => { const comment = commentPath.getValue(); if ( From b9edd77e9e1ba3c526a4cc2e74e55988ccd133e2 Mon Sep 17 00:00:00 2001 From: fisker Date: Wed, 2 Dec 2020 16:52:48 +0800 Subject: [PATCH 06/22] Fix `breakTies` --- src/main/comments.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/comments.js b/src/main/comments.js index 282f0e898f2c..bdc8ab178305 100644 --- a/src/main/comments.js +++ b/src/main/comments.js @@ -195,6 +195,7 @@ function attach(comments, ast, text, options) { options, ast, isLastComment: comments.length - 1 === index, + commentsStore, })); decoratedComments.forEach((context, index) => { @@ -438,10 +439,10 @@ function breakTies(tiesToBreak, text, options) { return; } const { - commentsStore, precedingNode, followingNode, enclosingNode, + commentsStore, } = tiesToBreak[0]; const gapRegExp = @@ -482,6 +483,7 @@ function breakTies(tiesToBreak, text, options) { } tiesToBreak.forEach(({ comment }, i) => { + console.log({ comment, commentsStore }); if (i < indexOfFirstLeadingComment) { if (commentsStore) { commentsStore.addTrailingComment(precedingNode, comment); From 31681fe995df08ae24afd2bb9b765edeea27ba0b Mon Sep 17 00:00:00 2001 From: fisker Date: Wed, 2 Dec 2020 17:01:47 +0800 Subject: [PATCH 07/22] Remove debug info --- src/main/comments-store.js | 4 ---- src/main/comments.js | 1 - 2 files changed, 5 deletions(-) diff --git a/src/main/comments-store.js b/src/main/comments-store.js index 155db72a9d45..ea7ca3a30d91 100644 --- a/src/main/comments-store.js +++ b/src/main/comments-store.js @@ -1,10 +1,6 @@ "use strict"; const { - hasNewline, - skipNewline, - skipSpaces, - isPreviousLineEmpty, addLeadingComment, addDanglingComment, addTrailingComment, diff --git a/src/main/comments.js b/src/main/comments.js index bdc8ab178305..852e98187f28 100644 --- a/src/main/comments.js +++ b/src/main/comments.js @@ -483,7 +483,6 @@ function breakTies(tiesToBreak, text, options) { } tiesToBreak.forEach(({ comment }, i) => { - console.log({ comment, commentsStore }); if (i < indexOfFirstLeadingComment) { if (commentsStore) { commentsStore.addTrailingComment(precedingNode, comment); From 952882e2890a5a09dab7f9a5884181a350600fe7 Mon Sep 17 00:00:00 2001 From: fisker Date: Wed, 2 Dec 2020 17:11:45 +0800 Subject: [PATCH 08/22] don't handle ignore --- src/language-js/comments.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/language-js/comments.js b/src/language-js/comments.js index 1c9860c856af..46aa5bf4339e 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -621,7 +621,6 @@ function handleUnionTypeComments({ ) { followingNode.types[0].prettierIgnore = true; comment.unignore = true; - return { node: followingNode, type: "ignore" }; } } @@ -744,7 +743,6 @@ function handleIgnoreComments({ comment, enclosingNode, followingNode }) { ) { enclosingNode.prettierIgnore = true; comment.unignore = true; - return { node: enclosingNode, type: "ignore" }; } } From 30877c4797abd0e0a61e059bc0ef42daa3474f01 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 3 Dec 2020 16:40:31 +0800 Subject: [PATCH 09/22] Fix multiparser --- src/main/multiparser.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/multiparser.js b/src/main/multiparser.js index 26cc5c3ce8a2..f7941025f882 100644 --- a/src/main/multiparser.js +++ b/src/main/multiparser.js @@ -55,9 +55,12 @@ function textToDoc( const astComments = ast.comments; delete ast.comments; - comments.attach(astComments, ast, text, nextOptions); + const commentsStore = comments.attach(astComments, ast, text, nextOptions); nextOptions[Symbol.for("comments")] = astComments || []; nextOptions[Symbol.for("tokens")] = ast.tokens || []; + if (commentsStore) { + nextOptions[Symbol.for("commentsStore")] = commentsStore; + } const doc = printAstToDoc(ast, nextOptions); comments.ensureAllCommentsPrinted(astComments); From 9ac8c709cb94cc212f0f049fd33318ff2cb29999 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 3 Dec 2020 16:50:18 +0800 Subject: [PATCH 10/22] Fix typing --- src/language-js/comments.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/language-js/comments.js b/src/language-js/comments.js index 46aa5bf4339e..107f513cf65e 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -60,7 +60,7 @@ function handleOwnLineComment(context) { handleLabeledStatementComments, ]) { const result = handler(context); - if (result) { + if (typeof result !== "undefined") { return result; } } @@ -88,7 +88,7 @@ function handleEndOfLineComment(context) { handleVariableDeclaratorComments, ]) { const result = handler(context); - if (result) { + if (typeof result !== "undefined") { return result; } } @@ -114,7 +114,7 @@ function handleRemainingComment(context) { handleTSFunctionTrailingComments, ]) { const result = handler(context); - if (result) { + if (typeof result !== "undefined") { return result; } } From 6c3e6aa0b899e8405538bb408bd6961f87b7afae Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 3 Dec 2020 17:15:29 +0800 Subject: [PATCH 11/22] Fix missing marker --- src/language-js/comments.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/language-js/comments.js b/src/language-js/comments.js index 107f513cf65e..d354abe34013 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -388,6 +388,7 @@ function handleClassComments({ ) { return { node: precedingNode, type: "trailing" }; } + comment.marker = prop; return { node: enclosingNode, comment, type: "dangling" }; } } From 99a91b7261819cde1bb675b549328632577d3b8b Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 3 Dec 2020 18:10:08 +0800 Subject: [PATCH 12/22] Refactor js related functions --- src/language-js/comments.js | 4 +- src/language-js/embed.js | 29 ++++---- src/language-js/embed/css.js | 4 +- src/language-js/embed/graphql.js | 4 +- src/language-js/embed/html.js | 2 +- src/language-js/print/angular.js | 4 +- src/language-js/print/array.js | 2 +- src/language-js/print/assignment.js | 2 +- src/language-js/print/binaryish.js | 5 +- src/language-js/print/block.js | 2 +- src/language-js/print/call-arguments.js | 31 ++++---- src/language-js/print/class.js | 13 ++-- src/language-js/print/function-parameters.js | 11 +-- src/language-js/print/function.js | 16 ++--- src/language-js/print/interface.js | 3 +- src/language-js/print/jsx.js | 34 +++++---- src/language-js/print/member-chain.js | 14 ++-- src/language-js/print/module.js | 6 +- src/language-js/print/object.js | 17 +++-- src/language-js/print/statement.js | 2 +- src/language-js/print/template-literal.js | 12 ++-- src/language-js/print/ternary.js | 6 +- src/language-js/print/type-annotation.js | 4 +- src/language-js/print/type-parameters.js | 4 +- src/language-js/printer-estree.js | 15 ++-- src/language-js/utils.js | 75 +++++++++++--------- src/main/ast-to-doc.js | 2 +- src/main/comments-store.js | 1 - src/main/comments.js | 1 - 29 files changed, 179 insertions(+), 146 deletions(-) diff --git a/src/language-js/comments.js b/src/language-js/comments.js index d354abe34013..e1133e3c2f1e 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -858,7 +858,7 @@ function isTypeCastComment(comment) { * @param {FastPath} path * @returns {boolean} */ -function willPrintOwnComments(path /*, options */) { +function willPrintOwnComments(path , options ) { const node = path.getValue(); const parent = path.getParentNode(); @@ -879,7 +879,7 @@ function willPrintOwnComments(path /*, options */) { ((parent.type === "ClassDeclaration" || parent.type === "ClassExpression") && parent.superClass === node)))) && - (!hasIgnoreComment(path) || + (!hasIgnoreComment(path, options) || parent.type === "UnionTypeAnnotation" || parent.type === "TSUnionType") ); diff --git a/src/language-js/embed.js b/src/language-js/embed.js index 3058e7868dc8..b263f0d6abb0 100644 --- a/src/language-js/embed.js +++ b/src/language-js/embed.js @@ -6,25 +6,25 @@ const formatCss = require("./embed/css"); const formatGraphql = require("./embed/graphql"); const formatHtml = require("./embed/html"); -function getLanguage(path) { +function getLanguage(path, options) { if ( isStyledJsx(path) || - isStyledComponents(path) || + isStyledComponents(path, options) || isCssProp(path) || - isAngularComponentStyles(path) + isAngularComponentStyles(path, options) ) { return "css"; } - if (isGraphQL(path)) { + if (isGraphQL(path, options)) { return "graphql"; } - if (isHtml(path)) { + if (isHtml(path, options)) { return "html"; } - if (isAngularComponentTemplate(path)) { + if (isAngularComponentTemplate(path, options)) { return "angular"; } @@ -45,7 +45,7 @@ function embed(path, print, textToDoc, options) { return; } - const language = getLanguage(path); + const language = getLanguage(path, options); if (!language) { return; } @@ -55,11 +55,11 @@ function embed(path, print, textToDoc, options) { } if (language === "css") { - return formatCss(path, print, textToDoc); + return formatCss(path, print, textToDoc, options); } if (language === "graphql") { - return formatGraphql(path, print, textToDoc); + return formatGraphql(path, print, textToDoc, options); } if (language === "html" || language === "angular") { @@ -241,12 +241,12 @@ function isStyledExtend(node) { * This intentionally excludes Relay Classic tags, as Prettier does not * support Relay Classic formatting. */ -function isGraphQL(path) { +function isGraphQL(path, options) { const node = path.getValue(); const parent = path.getParentNode(); return ( - hasLanguageComment(node, "GraphQL") || + hasLanguageComment(node, "GraphQL", options) || (parent && ((parent.type === "TaggedTemplateExpression" && ((parent.tag.type === "MemberExpression" && @@ -260,13 +260,14 @@ function isGraphQL(path) { ); } -function hasLanguageComment(node, languageName) { +function hasLanguageComment(node, languageName, options) { // This checks for a leading comment that is exactly `/* GraphQL */` // In order to be in line with other implementations of this comment tag // we will not trim the comment value and we will expect exactly one space on // either side of the GraphQL string // Also see ./clean.js return hasComment( + options, node, CommentCheckFlags.Block | CommentCheckFlags.Leading, ({ value }) => value === ` ${languageName} ` @@ -277,9 +278,9 @@ function hasLanguageComment(node, languageName) { * - html`...` * - HTML comment block */ -function isHtml(path) { +function isHtml(path, options) { return ( - hasLanguageComment(path.getValue(), "HTML") || + hasLanguageComment(path.getValue(), "HTML", options) || path.match( (node) => node.type === "TemplateLiteral", (node, name) => diff --git a/src/language-js/embed/css.js b/src/language-js/embed/css.js index 3ee4e1fa344c..94dc51187548 100644 --- a/src/language-js/embed/css.js +++ b/src/language-js/embed/css.js @@ -6,7 +6,7 @@ const { } = require("../../document"); const { printTemplateExpressions } = require("../print/template-literal"); -function format(path, print, textToDoc) { +function format(path, print, textToDoc, options) { const node = path.getValue(); // Get full template literal with expressions replaced by placeholders @@ -22,7 +22,7 @@ function format(path, print, textToDoc) { { parser: "scss" }, { stripTrailingHardline: true } ); - const expressionDocs = printTemplateExpressions(path, print); + const expressionDocs = printTemplateExpressions(path, options, print); return transformCssDoc(doc, node, expressionDocs); } diff --git a/src/language-js/embed/graphql.js b/src/language-js/embed/graphql.js index ba0b4efe1946..0132cbdb76e2 100644 --- a/src/language-js/embed/graphql.js +++ b/src/language-js/embed/graphql.js @@ -8,7 +8,7 @@ const { printTemplateExpressions, } = require("../print/template-literal"); -function format(path, print, textToDoc) { +function format(path, print, textToDoc, options) { const node = path.getValue(); const numQuasis = node.quasis.length; @@ -16,7 +16,7 @@ function format(path, print, textToDoc) { return "``"; } - const expressionDocs = printTemplateExpressions(path, print); + const expressionDocs = printTemplateExpressions(path, options, print); const parts = []; for (let i = 0; i < numQuasis; i++) { diff --git a/src/language-js/embed/html.js b/src/language-js/embed/html.js index f7042de403ee..f931110ba21b 100644 --- a/src/language-js/embed/html.js +++ b/src/language-js/embed/html.js @@ -27,7 +27,7 @@ function format(path, print, textToDoc, options, { parser }) { ) .join(""); - const expressionDocs = printTemplateExpressions(path, print); + const expressionDocs = printTemplateExpressions(path, options, print); if (expressionDocs.length === 0 && text.trim().length === 0) { return "``"; } diff --git a/src/language-js/print/angular.js b/src/language-js/print/angular.js index f025aeeaedf0..f98d0751e912 100644 --- a/src/language-js/print/angular.js +++ b/src/language-js/print/angular.js @@ -15,9 +15,9 @@ function printAngular(path, options, print) { return concat( [].concat( path.call(print, "node"), - !hasComment(n.node) + !hasComment(options, n.node) ? [] - : concat([" //", getComments(n.node)[0].value.trimEnd()]) + : concat([" //", getComments(options, n.node)[0].value.trimEnd()]) ) ); case "NGPipeExpression": diff --git a/src/language-js/print/array.js b/src/language-js/print/array.js index ce7925b6bd1a..d3490ae0d222 100644 --- a/src/language-js/print/array.js +++ b/src/language-js/print/array.js @@ -20,7 +20,7 @@ function printArray(path, options, print) { const openBracket = n.type === "TupleExpression" ? "#[" : "["; const closeBracket = "]"; if (n.elements.length === 0) { - if (!hasComment(n, CommentCheckFlags.Dangling)) { + if (!hasComment(options, n, CommentCheckFlags.Dangling)) { parts.push(openBracket, closeBracket); } else { parts.push( diff --git a/src/language-js/print/assignment.js b/src/language-js/print/assignment.js index 5088c610a3ad..5a23f7f49e45 100644 --- a/src/language-js/print/assignment.js +++ b/src/language-js/print/assignment.js @@ -58,7 +58,7 @@ function printVariableDeclarator(path, options, print) { } function printAssignmentRight(leftNode, rightNode, printedRight, options) { - if (hasLeadingOwnLineComment(options.originalText, rightNode)) { + if (hasLeadingOwnLineComment(options.originalText, rightNode, options)) { return indent(concat([line, printedRight])); } diff --git a/src/language-js/print/binaryish.js b/src/language-js/print/binaryish.js index a1c736d88115..a1a69dcbf9b8 100644 --- a/src/language-js/print/binaryish.js +++ b/src/language-js/print/binaryish.js @@ -217,7 +217,7 @@ function printBinaryishExpressions( (node.operator === "|>" || node.type === "NGPipeExpression" || (node.operator === "|" && options.parser === "__vue_expression")) && - !hasLeadingOwnLineComment(options.originalText, node.right); + !hasLeadingOwnLineComment(options.originalText, node.right, options); const operator = node.type === "NGPipeExpression" ? "|" : node.operator; const rightSuffix = @@ -252,6 +252,7 @@ function printBinaryishExpressions( // in order to avoid having a small right part like -1 be on its own line. const parent = path.getParentNode(); const shouldBreak = hasComment( + options, node.left, CommentCheckFlags.Trailing | CommentCheckFlags.Line ); @@ -270,7 +271,7 @@ function printBinaryishExpressions( // The root comments are already printed, but we need to manually print // the other ones since we don't call the normal print on BinaryExpression, // only for the left and right parts - if (isNested && hasComment(node)) { + if (isNested && hasComment(options, node)) { parts = normalizeParts( printComments(path, () => concat(parts), options).parts ); diff --git a/src/language-js/print/block.js b/src/language-js/print/block.js index aacffab1e35f..f5d0baac3070 100644 --- a/src/language-js/print/block.js +++ b/src/language-js/print/block.js @@ -32,7 +32,7 @@ function printBlock(path, options, print) { if ( !hasContent && !hasDirectives && - !hasComment(n, CommentCheckFlags.Dangling) && + !hasComment(options, n, CommentCheckFlags.Dangling) && (parent.type === "ArrowFunctionExpression" || parent.type === "FunctionExpression" || parent.type === "FunctionDeclaration" || diff --git a/src/language-js/print/call-arguments.js b/src/language-js/print/call-arguments.js index d5c943eb03a1..6f57d857c14f 100644 --- a/src/language-js/print/call-arguments.js +++ b/src/language-js/print/call-arguments.js @@ -55,7 +55,7 @@ function printCallArguments(path, options, print) { getFunctionParameters(args[0]).length === 0 && args[0].body.type === "BlockStatement" && args[1].type === "ArrayExpression" && - !args.some((arg) => hasComment(arg)) + !args.some((arg) => hasComment(options, arg)) ) { return concat([ "(", @@ -149,8 +149,8 @@ function printCallArguments(path, options, print) { return allArgsBrokenOut(); } - const shouldGroupFirst = shouldGroupFirstArg(args); - const shouldGroupLast = shouldGroupLastArg(args); + const shouldGroupFirst = shouldGroupFirstArg(args, options); + const shouldGroupLast = shouldGroupLastArg(args, options); if (shouldGroupFirst || shouldGroupLast) { const shouldBreak = (shouldGroupFirst @@ -232,14 +232,15 @@ function printCallArguments(path, options, print) { }); } -function couldGroupArg(arg) { +function couldGroupArg(arg, options) { return ( (arg.type === "ObjectExpression" && - (arg.properties.length > 0 || hasComment(arg))) || + (arg.properties.length > 0 || hasComment(options, arg))) || (arg.type === "ArrayExpression" && - (arg.elements.length > 0 || hasComment(arg))) || - (arg.type === "TSTypeAssertion" && couldGroupArg(arg.expression)) || - (arg.type === "TSAsExpression" && couldGroupArg(arg.expression)) || + (arg.elements.length > 0 || hasComment(options, arg))) || + (arg.type === "TSTypeAssertion" && + couldGroupArg(arg.expression, options)) || + (arg.type === "TSAsExpression" && couldGroupArg(arg.expression, options)) || arg.type === "FunctionExpression" || (arg.type === "ArrowFunctionExpression" && // we want to avoid breaking inside composite return types but not simple keywords @@ -267,34 +268,34 @@ function couldGroupArg(arg) { ); } -function shouldGroupLastArg(args) { +function shouldGroupLastArg(args, options) { const lastArg = getLast(args); const penultimateArg = getPenultimate(args); return ( - !hasComment(lastArg, CommentCheckFlags.Leading) && - !hasComment(lastArg, CommentCheckFlags.Trailing) && - couldGroupArg(lastArg) && + !hasComment(options, lastArg, CommentCheckFlags.Leading) && + !hasComment(options, lastArg, CommentCheckFlags.Trailing) && + couldGroupArg(lastArg, options) && // If the last two arguments are of the same type, // disable last element expansion. (!penultimateArg || penultimateArg.type !== lastArg.type) ); } -function shouldGroupFirstArg(args) { +function shouldGroupFirstArg(args, options) { if (args.length !== 2) { return false; } const [firstArg, secondArg] = args; return ( - !hasComment(firstArg) && + !hasComment(options, firstArg) && (firstArg.type === "FunctionExpression" || (firstArg.type === "ArrowFunctionExpression" && firstArg.body.type === "BlockStatement")) && secondArg.type !== "FunctionExpression" && secondArg.type !== "ArrowFunctionExpression" && secondArg.type !== "ConditionalExpression" && - !couldGroupArg(secondArg) + !couldGroupArg(secondArg, options) ); } diff --git a/src/language-js/print/class.js b/src/language-js/print/class.js index add6caafa140..51fe06b20296 100644 --- a/src/language-js/print/class.js +++ b/src/language-js/print/class.js @@ -33,8 +33,8 @@ function printClass(path, options, print) { // Keep old behaviour of extends in same line // If there is only on extends and there are not comments const groupMode = - (n.id && hasComment(n.id, CommentCheckFlags.Trailing)) || - (n.superClass && hasComment(n.superClass)) || + (n.id && hasComment(options, n.id, CommentCheckFlags.Trailing)) || + (n.superClass && hasComment(options, n.superClass)) || (n.extends && n.extends.length !== 0) || // DeclareClass (n.mixins && n.mixins.length !== 0) || (n.implements && n.implements.length !== 0); @@ -72,7 +72,7 @@ function printClass(path, options, print) { if (groupMode) { const printedExtends = concat(extendsParts); - if (shouldIndentOnlyHeritageClauses(n)) { + if (shouldIndentOnlyHeritageClauses(n, options)) { parts.push( group( concat( @@ -100,10 +100,11 @@ function hasMultipleHeritage(node) { ); } -function shouldIndentOnlyHeritageClauses(node) { +function shouldIndentOnlyHeritageClauses(node, options) { return ( node.typeParameters && !hasComment( + options, node.typeParameters, CommentCheckFlags.Trailing | CommentCheckFlags.Line ) && @@ -124,7 +125,7 @@ function printList(path, options, print, listName) { ({ marker }) => marker === listName ); return concat([ - shouldIndentOnlyHeritageClauses(n) + shouldIndentOnlyHeritageClauses(n, options) ? ifBreak(" ", line, { groupId: getTypeParametersGroupId(n.typeParameters), }) @@ -178,7 +179,7 @@ function printClassMethod(path, options, print) { function printClassBody(path, options, print) { const n = path.getValue(); - if (!hasComment(n) && n.body.length === 0) { + if (!hasComment(options, n) && n.body.length === 0) { return "{}"; } diff --git a/src/language-js/print/function-parameters.js b/src/language-js/print/function-parameters.js index bcdb6c903ee4..932de7dc7844 100644 --- a/src/language-js/print/function-parameters.js +++ b/src/language-js/print/function-parameters.js @@ -58,9 +58,12 @@ function printFunctionParameters( const parent = path.getParentNode(); const isParametersInTestCall = isTestCall(parent); - const shouldHugParameters = shouldHugFunctionParameters(functionNode); + const shouldHugParameters = shouldHugFunctionParameters( + functionNode, + options + ); const shouldExpandParameters = - expandArg && !parameters.some((node) => hasComment(node)); + expandArg && !parameters.some((node) => hasComment(options, node)); const printed = []; iterateFunctionParametersPath(path, (parameterPath, index) => { const isLastParameter = index === parameters.length - 1; @@ -164,7 +167,7 @@ function printFunctionParameters( ]); } -function shouldHugFunctionParameters(node) { +function shouldHugFunctionParameters(node, options) { if (!node) { return false; } @@ -174,7 +177,7 @@ function shouldHugFunctionParameters(node) { } const [parameter] = parameters; return ( - !hasComment(parameter) && + !hasComment(options, parameter) && (parameter.type === "ObjectPattern" || parameter.type === "ArrayPattern" || (parameter.type === "Identifier" && diff --git a/src/language-js/print/function.js b/src/language-js/print/function.js index df4ee059b5f3..0cdf60fe02e3 100644 --- a/src/language-js/print/function.js +++ b/src/language-js/print/function.js @@ -179,7 +179,7 @@ function printArrowFunctionExpression(path, options, print, args) { // We want to always keep these types of nodes on the same line // as the arrow. if ( - !hasLeadingOwnLineComment(options.originalText, n.body) && + !hasLeadingOwnLineComment(options.originalText, n.body, options) && (n.body.type === "ArrayExpression" || n.body.type === "ObjectExpression" || n.body.type === "BlockStatement" || @@ -209,7 +209,7 @@ function printArrowFunctionExpression(path, options, print, args) { const shouldAddSoftLine = ((args && args.expandLastArg) || path.getParentNode().type === "JSXExpressionContainer") && - !hasComment(n); + !hasComment(options, n); const printTrailingComma = args && args.expandLastArg && shouldPrintComma(options, "all"); @@ -243,15 +243,15 @@ function printArrowFunctionExpression(path, options, print, args) { ); } -function canPrintParamsWithoutParens(node) { +function canPrintParamsWithoutParens(node, options) { const parameters = getFunctionParameters(node); return ( parameters.length === 1 && !node.typeParameters && - !hasComment(node, CommentCheckFlags.Dangling) && + !hasComment(options, node, CommentCheckFlags.Dangling) && parameters[0].type === "Identifier" && !parameters[0].typeAnnotation && - !hasComment(parameters[0]) && + !hasComment(options, parameters[0]) && !parameters[0].optional && !node.predicate && !node.returnType @@ -265,7 +265,7 @@ function shouldPrintParamsWithoutParens(path, options) { if (options.arrowParens === "avoid") { const node = path.getValue(); - return canPrintParamsWithoutParens(node); + return canPrintParamsWithoutParens(node, options); } // Fallback default; should be unreachable @@ -335,7 +335,7 @@ function printReturnAndThrowArgument(path, options, print) { } } - const comments = getComments(node); + const comments = getComments(options, node); const lastComment = comments[comments.length - 1]; const isLastCommentLine = lastComment && isLineComment(lastComment); @@ -343,7 +343,7 @@ function printReturnAndThrowArgument(path, options, print) { parts.push(semi); } - if (hasComment(node, CommentCheckFlags.Dangling)) { + if (hasComment(options, node, CommentCheckFlags.Dangling)) { parts.push( " ", printDanglingComments(path, options, /* sameIndent */ true) diff --git a/src/language-js/print/interface.js b/src/language-js/print/interface.js index 84f42657e750..cfae8a52c715 100644 --- a/src/language-js/print/interface.js +++ b/src/language-js/print/interface.js @@ -37,6 +37,7 @@ function printInterface(path, options, print) { const shouldIndentOnlyHeritageClauses = n.typeParameters && !hasComment( + options, n.typeParameters, CommentCheckFlags.Trailing | CommentCheckFlags.Line ); @@ -56,7 +57,7 @@ function printInterface(path, options, print) { } if ( - (n.id && hasComment(n.id, CommentCheckFlags.Trailing)) || + (n.id && hasComment(options, n.id, CommentCheckFlags.Trailing)) || (n.extends && n.extends.length !== 0) ) { const printedExtends = concat(extendsParts); diff --git a/src/language-js/print/jsx.js b/src/language-js/print/jsx.js index c2a621527ad8..7e48bed7e080 100644 --- a/src/language-js/print/jsx.js +++ b/src/language-js/print/jsx.js @@ -87,7 +87,7 @@ function printJsxElementInternal(path, options, print) { // This makes it easy to turn them into `jsxWhitespace` which // can then print as either a space or `{" "}` when breaking. n.children = n.children.map((child) => { - if (isJSXWhitespaceExpression(child)) { + if (isJSXWhitespaceExpression(child, options)) { return { type: "JSXText", value: " ", @@ -509,7 +509,7 @@ function printJsxExpressionContainer(path, options, print) { const shouldInline = n.expression.type === "JSXEmptyExpression" || - (!hasComment(n.expression) && + (!hasComment(options, n.expression) && (n.expression.type === "ArrayExpression" || n.expression.type === "ObjectExpression" || n.expression.type === "ArrowFunctionExpression" || @@ -544,8 +544,8 @@ function printJsxOpeningElement(path, options, print) { const n = path.getValue(); const nameHasComments = - (n.name && hasComment(n.name)) || - (n.typeParameters && hasComment(n.typeParameters)); + (n.name && hasComment(options, n.name)) || + (n.typeParameters && hasComment(options, n.typeParameters)); // Don't break self-closing elements with no attributes and no comments if (n.selfClosing && !n.attributes.length && !nameHasComments) { @@ -574,7 +574,7 @@ function printJsxOpeningElement(path, options, print) { // // comment // > !nameHasComments && - !hasComment(n.attributes[0]) + !hasComment(options, n.attributes[0]) ) { return group( concat([ @@ -590,7 +590,7 @@ function printJsxOpeningElement(path, options, print) { const lastAttrHasTrailingComments = n.attributes.length && - hasComment(getLast(n.attributes), CommentCheckFlags.Trailing); + hasComment(options, getLast(n.attributes), CommentCheckFlags.Trailing); const bracketSameLine = // Simple tags (no attributes and no comment in tag name) should be @@ -642,10 +642,20 @@ function printJsxClosingElement(path, options, print) { parts.push(" { const printed = concat(["...", print(p)]); const n = p.getValue(); - if (!hasComment(n) || !willPrintOwnComments(p)) { + if (!hasComment(options, n) || !willPrintOwnComments(p, options)) { return printed; } return concat([ diff --git a/src/language-js/print/member-chain.js b/src/language-js/print/member-chain.js index 50859598218e..06eb21cd267e 100644 --- a/src/language-js/print/member-chain.js +++ b/src/language-js/print/member-chain.js @@ -244,7 +244,7 @@ function printMemberChain(path, options, print) { } currentGroup.push(printedNodes[i]); - if (hasComment(printedNodes[i].node, CommentCheckFlags.Trailing)) { + if (hasComment(options,printedNodes[i].node, CommentCheckFlags.Trailing)) { groups.push(currentGroup); currentGroup = []; hasSeenCallExpression = false; @@ -306,7 +306,7 @@ function printMemberChain(path, options, print) { const shouldMerge = groups.length >= 2 && - !hasComment(groups[1][0].node) && + !hasComment(options, groups[1][0].node) && shouldNotWrap(groups); function printGroup(printedGroup) { @@ -341,12 +341,16 @@ function printMemberChain(path, options, print) { const nodeHasComment = flatGroups .slice(1, -1) - .some((node) => hasComment(node.node, CommentCheckFlags.Leading)) || + .some((node) => + hasComment(options, node.node, CommentCheckFlags.Leading) + ) || flatGroups .slice(0, -1) - .some((node) => hasComment(node.node, CommentCheckFlags.Trailing)) || + .some((node) => + hasComment(options, node.node, CommentCheckFlags.Trailing) + ) || (groups[cutoff] && - hasComment(groups[cutoff][0].node, CommentCheckFlags.Leading)); + hasComment(options, groups[cutoff][0].node, CommentCheckFlags.Leading)); // If we only have a single `.`, we shouldn't do anything fancy and just // render everything concatenated together. diff --git a/src/language-js/print/module.js b/src/language-js/print/module.js index af0de27b9ab1..5e727314a769 100644 --- a/src/language-js/print/module.js +++ b/src/language-js/print/module.js @@ -56,13 +56,13 @@ function printExportDeclaration(path, options, print) { parts.push(" default"); } - if (hasComment(node, CommentCheckFlags.Dangling)) { + if (hasComment(options, node, CommentCheckFlags.Dangling)) { parts.push( " ", printDanglingComments(path, options, /* sameIndent */ true) ); - if (needsHardlineAfterDanglingComment(node)) { + if (needsHardlineAfterDanglingComment(options, node)) { parts.push(hardline); } } @@ -204,7 +204,7 @@ function printModuleSpecifiers(path, options, print) { const canBreak = groupedSpecifiers.length > 1 || standaloneSpecifiers.length > 0 || - node.specifiers.some((node) => hasComment(node)); + node.specifiers.some((node) => hasComment(options, node)); if (canBreak) { parts.push( diff --git a/src/language-js/print/object.js b/src/language-js/print/object.js index a5546b1a9e48..1e86b80da9b0 100644 --- a/src/language-js/print/object.js +++ b/src/language-js/print/object.js @@ -116,7 +116,7 @@ function printObject(path, options, print) { (prop.node.type === "TSPropertySignature" || prop.node.type === "TSMethodSignature" || prop.node.type === "TSConstructSignatureDeclaration") && - hasComment(prop.node, CommentCheckFlags.PrettierIgnore) + hasComment(options, prop.node, CommentCheckFlags.PrettierIgnore) ) { separatorParts.shift(); } @@ -129,7 +129,7 @@ function printObject(path, options, print) { if (n.inexact) { let printed; if (hasComment(n, CommentCheckFlags.Dangling)) { - const hasLineComments = hasComment(n, CommentCheckFlags.Line); + const hasLineComments = hasComment(options, n, CommentCheckFlags.Line); const printedDanglingComments = printDanglingComments( path, options, @@ -138,7 +138,10 @@ function printObject(path, options, print) { printed = concat([ printedDanglingComments, hasLineComments || - hasNewline(options.originalText, locEnd(getLast(getComments(n)))) + hasNewline( + options.originalText, + locEnd(getLast(getComments(options, n))) + ) ? hardline : line, "...", @@ -159,12 +162,12 @@ function printObject(path, options, print) { lastElem.type === "TSCallSignatureDeclaration" || lastElem.type === "TSMethodSignature" || lastElem.type === "TSConstructSignatureDeclaration") && - hasComment(lastElem, CommentCheckFlags.PrettierIgnore)) + hasComment(options, lastElem, CommentCheckFlags.PrettierIgnore)) ); let content; if (props.length === 0) { - if (!hasComment(n, CommentCheckFlags.Dangling)) { + if (!hasComment(options, n, CommentCheckFlags.Dangling)) { return concat([ leftBrace, rightBrace, @@ -205,7 +208,7 @@ function printObject(path, options, print) { path.match( (node) => node.type === "ObjectPattern" && !node.decorators, (node, name, number) => - shouldHugFunctionParameters(node) && + shouldHugFunctionParameters(node, options) && (name === "params" || name === "parameters" || name === "this" || @@ -217,7 +220,7 @@ function printObject(path, options, print) { (node, name) => name === "typeAnnotation", (node, name) => name === "typeAnnotation", (node, name, number) => - shouldHugFunctionParameters(node) && + shouldHugFunctionParameters(node, options) && (name === "params" || name === "parameters" || name === "this" || diff --git a/src/language-js/print/statement.js b/src/language-js/print/statement.js index 427a6529593e..faf02b84c42d 100644 --- a/src/language-js/print/statement.js +++ b/src/language-js/print/statement.js @@ -49,7 +49,7 @@ function printStatement({ path, index, bodyNode, isClass }, options, print) { !isTheOnlyJSXElementInMarkdown(options, path) && statementNeedsASIProtection(path, options) ) { - if (hasComment(node, CommentCheckFlags.Leading)) { + if (hasComment(options,node, CommentCheckFlags.Leading)) { parts.push(print(path, { needsSemi: true })); } else { parts.push(";", printed); diff --git a/src/language-js/print/template-literal.js b/src/language-js/print/template-literal.js index 81f68121e4b8..01f6e14e4723 100644 --- a/src/language-js/print/template-literal.js +++ b/src/language-js/print/template-literal.js @@ -43,7 +43,7 @@ function printTemplateLiteral(path, print, options) { const parts = []; let expressions = path.map(print, expressionsKey); - const isSimple = isSimpleTemplateLiteral(node); + const isSimple = isSimpleTemplateLiteral(node, options); if (isSimple) { expressions = expressions.map( @@ -82,7 +82,7 @@ function printTemplateLiteral(path, print, options) { // Breaks at the template element boundaries (${ and }) are preferred to breaking // in the middle of a MemberExpression if ( - hasComment(expression) || + hasComment(options, expression) || expression.type === "MemberExpression" || expression.type === "OptionalMemberExpression" || expression.type === "ConditionalExpression" || @@ -199,18 +199,18 @@ function printJestEachTemplateLiteral(path, options, print) { } } -function printTemplateExpression(path, print) { +function printTemplateExpression(path, options, print) { const node = path.getValue(); let printed = print(path); - if (hasComment(node)) { + if (hasComment(options, node)) { printed = group(concat([indent(concat([softline, printed])), softline])); } return concat(["${", printed, lineSuffixBoundary, "}"]); } -function printTemplateExpressions(path, print) { +function printTemplateExpressions(path, options, print) { return path.map( - (path) => printTemplateExpression(path, print), + (path) => printTemplateExpression(path, options, print), "expressions" ); } diff --git a/src/language-js/print/ternary.js b/src/language-js/print/ternary.js index 43da1f587b8d..bd96d81014d8 100644 --- a/src/language-js/print/ternary.js +++ b/src/language-js/print/ternary.js @@ -278,10 +278,10 @@ function printTernary(path, options, print) { // outer-most ConditionalExpression. const comments = flat([ ...testNodePropertyNames.map((propertyName) => - getComments(node[propertyName]) + getComments(options, node[propertyName]) ), - getComments(consequentNode), - getComments(alternateNode), + getComments(options, consequentNode), + getComments(options, alternateNode), ]); const shouldBreak = comments.some( (comment) => diff --git a/src/language-js/print/type-annotation.js b/src/language-js/print/type-annotation.js index bc1895a41909..5c4cc7d1d4c0 100644 --- a/src/language-js/print/type-annotation.js +++ b/src/language-js/print/type-annotation.js @@ -156,7 +156,7 @@ function printUnionType(path, options, print) { (parent.type === "TypeAlias" || parent.type === "VariableDeclarator" || parent.type === "TSTypeAliasDeclaration") && - hasLeadingOwnLineComment(options.originalText, n) + hasLeadingOwnLineComment(options.originalText, n, options) ); // { @@ -182,7 +182,7 @@ function printUnionType(path, options, print) { } const shouldAddStartLine = - shouldIndent && !hasLeadingOwnLineComment(options.originalText, n); + shouldIndent && !hasLeadingOwnLineComment(options.originalText, n, options); const code = concat([ ifBreak(concat([shouldAddStartLine ? line : "", "| "])), diff --git a/src/language-js/print/type-parameters.js b/src/language-js/print/type-parameters.js index eb1e9fc79364..9d62676c8b33 100644 --- a/src/language-js/print/type-parameters.js +++ b/src/language-js/print/type-parameters.js @@ -82,10 +82,10 @@ function printTypeParameters(path, options, print, paramsKey) { function printDanglingCommentsForInline(path, options) { const n = path.getValue(); - if (!hasComment(n, CommentCheckFlags.Dangling)) { + if (!hasComment(options, n, CommentCheckFlags.Dangling)) { return ""; } - const hasOnlyBlockComments = !hasComment(n, CommentCheckFlags.Line); + const hasOnlyBlockComments = !hasComment(options,n, CommentCheckFlags.Line); const printed = printDanglingComments( path, options, diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index e02dd375eb92..4199cf4c648b 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -261,7 +261,8 @@ function printPathNoParens(path, options, print, args) { case "Program": { const hasContents = - !n.body.every(({ type }) => type === "EmptyStatement") || hasComment(n); + !n.body.every(({ type }) => type === "EmptyStatement") || + hasComment(options, n); // Babel 6 if (n.directives) { @@ -324,7 +325,7 @@ function printPathNoParens(path, options, print, args) { ]); // Babel non-standard node. Used for Closure-style type casts. See postprocess.js. case "ParenthesizedExpression": { - const shouldHug = !hasComment(n.expression); + const shouldHug = !hasComment(options, n.expression); if (shouldHug) { return concat(["(", path.call(print, "expression"), ")"]); } @@ -568,7 +569,7 @@ function printPathNoParens(path, options, print, args) { parts.push(" "); } - if (hasComment(n.argument)) { + if (hasComment(options, n.argument)) { parts.push( group( concat([ @@ -611,7 +612,7 @@ function printPathNoParens(path, options, print, args) { const hasValue = n.declarations.some((decl) => decl.init); let firstVariable; - if (printed.length === 1 && !hasComment(n.declarations[0])) { + if (printed.length === 1 && !hasComment(options, n.declarations[0])) { firstVariable = printed[0]; } else if (printed.length > 0) { // Indent first var to comply with eslint one-var rule @@ -669,14 +670,15 @@ function printPathNoParens(path, options, print, args) { if (n.alternate) { const commentOnOwnLine = hasComment( + options, n.consequent, CommentCheckFlags.Trailing | CommentCheckFlags.Line - ) || needsHardlineAfterDanglingComment(n); + ) || needsHardlineAfterDanglingComment(options, n); const elseOnSameLine = n.consequent.type === "BlockStatement" && !commentOnOwnLine; parts.push(elseOnSameLine ? " " : hardline); - if (hasComment(n, CommentCheckFlags.Dangling)) { + if (hasComment(options, n, CommentCheckFlags.Dangling)) { parts.push( comments.printDanglingComments(path, options, true), commentOnOwnLine ? hardline : " " @@ -849,6 +851,7 @@ function printPathNoParens(path, options, print, args) { case "CatchClause": if (n.param) { const parameterHasComments = hasComment( + options, n.param, (comment) => !isBlockComment(comment) || diff --git a/src/language-js/utils.js b/src/language-js/utils.js index a9302d2cb89c..2aebc22162fa 100644 --- a/src/language-js/utils.js +++ b/src/language-js/utils.js @@ -339,12 +339,12 @@ function isTheOnlyJSXElementInMarkdown(options, path) { } // Detect an expression node representing `{" "}` -function isJSXWhitespaceExpression(node) { +function isJSXWhitespaceExpression(node, options) { return ( node.type === "JSXExpressionContainer" && isLiteral(node.expression) && node.expression.value === " " && - !hasComment(node.expression) + !hasComment(options, node.expression) ); } @@ -579,7 +579,7 @@ function isCallOrOptionalCallExpression(node) { * @param {any} node * @returns {boolean} */ -function isSimpleTemplateLiteral(node) { +function isSimpleTemplateLiteral(node, options) { let expressionsKey = "expressions"; if (node.type === "TSTemplateLiteralType") { expressionsKey = "types"; @@ -592,7 +592,7 @@ function isSimpleTemplateLiteral(node) { return expressions.every((expr) => { // Disallow comments since printDocToString can't print them here - if (hasComment(expr)) { + if (hasComment(options, expr)) { return false; } @@ -620,7 +620,7 @@ function isSimpleTemplateLiteral(node) { return false; } head = head.object; - if (hasComment(head)) { + if (hasComment(options, head)) { return false; } } @@ -756,7 +756,7 @@ function isMeaningfulJSXText(node) { * @param {FastPath} path * @returns {boolean} */ -function hasJsxIgnoreComment(path) { +function hasJsxIgnoreComment(path, options) { const node = path.getValue(); const parent = path.getParentNode(); if (!parent || !node || !isJSXNode(node) || !isJSXNode(parent)) { @@ -779,7 +779,7 @@ function hasJsxIgnoreComment(path) { prevSibling && prevSibling.type === "JSXExpressionContainer" && prevSibling.expression.type === "JSXEmptyExpression" && - hasNodeIgnoreComment(prevSibling.expression) + hasNodeIgnoreComment(prevSibling.expression, options) ); } @@ -805,8 +805,8 @@ function isEmptyJSXElement(node) { * @param {FastPath} path * @returns {boolean} */ -function hasPrettierIgnore(path) { - return hasIgnoreComment(path) || hasJsxIgnoreComment(path); +function hasPrettierIgnore(path, options) { + return hasIgnoreComment(path, options) || hasJsxIgnoreComment(path, options); } /** @@ -845,12 +845,12 @@ function isFlowAnnotationComment(text, typeAnnotation) { * @param {Node} node * @returns {boolean} */ -function hasLeadingOwnLineComment(text, node) { +function hasLeadingOwnLineComment(text, node, options) { if (isJSXNode(node)) { - return hasNodeIgnoreComment(node); + return hasNodeIgnoreComment(node, options); } - return hasComment(node, CommentCheckFlags.Leading, (comment) => + return hasComment(options, node, CommentCheckFlags.Leading, (comment) => hasNewline(text, locEnd(comment)) ); } @@ -859,7 +859,7 @@ function hasLeadingOwnLineComment(text, node) { // (the leftmost leaf node) and, if it (or its parents) has any // leadingComments, returns true (so it can be wrapped in parens). function returnArgumentHasLeadingComment(options, argument) { - if (hasLeadingOwnLineComment(options.originalText, argument)) { + if (hasLeadingOwnLineComment(options.originalText, argument, options)) { return true; } @@ -869,7 +869,7 @@ function returnArgumentHasLeadingComment(options, argument) { while ((newLeftMost = getLeftSide(leftMost))) { leftMost = newLeftMost; - if (hasLeadingOwnLineComment(options.originalText, leftMost)) { + if (hasLeadingOwnLineComment(options.originalText, leftMost, options)) { return true; } } @@ -989,12 +989,12 @@ function isTemplateOnItsOwnLine(n, text) { * @param {Node} node * @returns {boolean} */ -function needsHardlineAfterDanglingComment(node) { - if (!hasComment(node)) { +function needsHardlineAfterDanglingComment(options, node) { + if (!hasComment(options, node)) { return false; } const lastDanglingComment = getLast( - getComments(node, CommentCheckFlags.Dangling) + getComments(options, node, CommentCheckFlags.Dangling) ); return lastDanglingComment && !isBlockComment(lastDanglingComment); } @@ -1410,16 +1410,17 @@ function isPrettierIgnoreComment(comment) { return comment.value.trim() === "prettier-ignore" && !comment.unignore; } -function hasNodeIgnoreComment(node) { +function hasNodeIgnoreComment(node, options) { return ( node && - (node.prettierIgnore || hasComment(node, CommentCheckFlags.PrettierIgnore)) + (node.prettierIgnore || + hasComment(options, node, CommentCheckFlags.PrettierIgnore)) ); } -function hasIgnoreComment(path) { +function hasIgnoreComment(path, options) { const node = path.getValue(); - return hasNodeIgnoreComment(node); + return hasNodeIgnoreComment(node, options); } const CommentCheckFlags = { @@ -1444,7 +1445,7 @@ const CommentCheckFlags = { /** * @returns {function} */ -const getCommentTestFunction = (flags, fn) => { +const getCommentTestFunction = (allComments, flags, fn) => { if (typeof flags === "function") { fn = flags; flags = 0; @@ -1452,10 +1453,12 @@ const getCommentTestFunction = (flags, fn) => { if (flags || fn) { return (comment, index, comments) => !( - (flags & CommentCheckFlags.Leading && !comment.leading) || - (flags & CommentCheckFlags.Trailing && !comment.trailing) || + (flags & CommentCheckFlags.Leading && + !allComments.leading.includes(comment)) || + (flags & CommentCheckFlags.Trailing && + !allComments.trailing.includes(comment)) || (flags & CommentCheckFlags.Dangling && - (comment.leading || comment.trailing)) || + !allComments.dangling.includes(comment)) || (flags & CommentCheckFlags.Block && !isBlockComment(comment)) || (flags & CommentCheckFlags.Line && !isLineComment(comment)) || (flags & CommentCheckFlags.First && index !== 0) || @@ -1472,34 +1475,38 @@ const getCommentTestFunction = (flags, fn) => { * @param {function} [fn] * @returns {boolean} */ -function hasComment(node, flags, fn) { - if (!node || !Array.isArray(node.comments) || node.comments.length === 0) { +function hasComment(options, node, flags, fn) { + const comments = getAllComments(options, node); + if (!comments || comments.all.length === 0) { return false; } - const test = getCommentTestFunction(flags, fn); + const test = getCommentTestFunction(comments, flags, fn); return test - ? node.comments.some((comment, index, comments) => + ? comments.all.some((comment, index, comments) => test(comment, index, comments) ) : true; } +const getAllComments = (options, node) => + node && options[Symbol.for("commentsStore")].map.get(node); /** * @param {Node} node * @param {number | function} [flags] * @param {function} [fn] * @returns {Comment[]} */ -function getComments(node, flags, fn) { - if (!node || !Array.isArray(node.comments)) { +function getComments(options, node, flags, fn) { + const comments = getAllComments(options, node); + if (!comments || !comments.all.length === 0) { return []; } - const test = getCommentTestFunction(flags, fn); + const test = getCommentTestFunction(comments, flags, fn); return test - ? node.comments.filter((comment, index, comments) => + ? comments.all.filter((comment, index, comments) => test(comment, index, comments) ) - : node.comments; + : comments.all; } module.exports = { diff --git a/src/main/ast-to-doc.js b/src/main/ast-to-doc.js index ebf9471d5cd8..a8049f15a9fa 100644 --- a/src/main/ast-to-doc.js +++ b/src/main/ast-to-doc.js @@ -116,7 +116,7 @@ function callPluginPrintFunction(path, options, printPath, args) { const { printer } = options; // Escape hatch - if (printer.hasPrettierIgnore && printer.hasPrettierIgnore(path)) { + if (printer.hasPrettierIgnore && printer.hasPrettierIgnore(path, options)) { return printPrettierIgnoredNode(node, options); } diff --git a/src/main/comments-store.js b/src/main/comments-store.js index ea7ca3a30d91..995b0594e2be 100644 --- a/src/main/comments-store.js +++ b/src/main/comments-store.js @@ -16,7 +16,6 @@ class CommentsStore { leading: [], trailing: [], dangling: [], - ignore: [], all: [], }); } diff --git a/src/main/comments.js b/src/main/comments.js index 852e98187f28..0528b9557ec9 100644 --- a/src/main/comments.js +++ b/src/main/comments.js @@ -504,7 +504,6 @@ function breakTies(tiesToBreak, text, options) { commentsStore.get(node, "leading"), commentsStore.get(node, "trailing"), commentsStore.get(node, "dangling"), - commentsStore.get(node, "ignore"), commentsStore.get(node, "all"), ]) { comments.sort((a, b) => options.locStart(a) - options.locStart(b)); From c31e6ede1159b8fe905293ad01601d6a1a763444 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 3 Dec 2020 18:38:51 +0800 Subject: [PATCH 13/22] Allways call comment.attach to ensure commentsStore exits --- src/main/core.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/core.js b/src/main/core.js index 0daa9be98d23..2e1547355418 100644 --- a/src/main/core.js +++ b/src/main/core.js @@ -26,11 +26,10 @@ const CURSOR = Symbol("cursor"); function attachComments(text, ast, opts) { const astComments = ast.comments; - let commentsStore; if (astComments) { delete ast.comments; - commentsStore = comments.attach(astComments, ast, text, opts); } + const commentsStore = comments.attach(astComments, ast, text, opts); opts[Symbol.for("comments")] = astComments || []; opts[Symbol.for("tokens")] = ast.tokens || []; if (commentsStore) { From 0d34e1537e4273df28239abf16c2ddde78d63361 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 3 Dec 2020 18:41:52 +0800 Subject: [PATCH 14/22] Fix missing `options` --- src/language-js/print/object.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/language-js/print/object.js b/src/language-js/print/object.js index 1e86b80da9b0..4a7bd7b1d1dc 100644 --- a/src/language-js/print/object.js +++ b/src/language-js/print/object.js @@ -128,7 +128,7 @@ function printObject(path, options, print) { if (n.inexact) { let printed; - if (hasComment(n, CommentCheckFlags.Dangling)) { + if (hasComment(options, n, CommentCheckFlags.Dangling)) { const hasLineComments = hasComment(options, n, CommentCheckFlags.Line); const printedDanglingComments = printDanglingComments( path, From 07116d34d97ad1c797fb57ba63221fa84a8d9184 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 3 Dec 2020 19:10:21 +0800 Subject: [PATCH 15/22] Fix angular parsers --- .eslintrc.yml | 3 +-- src/language-js/utils.js | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 4b4ebfc6eae1..d47d16e52aa4 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -116,8 +116,7 @@ overrides: - error - file: "src/language-js/utils.js" functions: - - hasComment - - getComments + - getAllComments - "src/language-js/parse-postprocess.js" - "src/language-js/parser-babel.js" - "src/language-js/parser-meriyah.js" diff --git a/src/language-js/utils.js b/src/language-js/utils.js index 2aebc22162fa..2eaebac464ce 100644 --- a/src/language-js/utils.js +++ b/src/language-js/utils.js @@ -1488,8 +1488,25 @@ function hasComment(options, node, flags, fn) { : true; } -const getAllComments = (options, node) => - node && options[Symbol.for("commentsStore")].map.get(node); +function getAllComments(options, node) { + if (!node) { + return; + } + // `angular` parsers has own `comments` property + if ( + typeof options.parser === "string" && + options.parser.startsWith("__ng_") && + node.comments + ) { + return { + all: node.comments, + leading: [], + trailing: [], + dangling: node.comments, + }; + } + return options[Symbol.for("commentsStore")].map.get(node); +} /** * @param {Node} node * @param {number | function} [flags] From 515a6de772a77b8584e9a051d3f0564faac853e2 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 3 Dec 2020 19:18:04 +0800 Subject: [PATCH 16/22] Make `commentsStore` optional --- src/language-js/utils.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/language-js/utils.js b/src/language-js/utils.js index 2eaebac464ce..821886115bf7 100644 --- a/src/language-js/utils.js +++ b/src/language-js/utils.js @@ -1494,8 +1494,10 @@ function getAllComments(options, node) { } // `angular` parsers has own `comments` property if ( - typeof options.parser === "string" && - options.parser.startsWith("__ng_") && + (options.parser === "__ng_action" || + options.parser === "__ng_binding" || + options.parser === "__ng_interpolation" || + options.parser === "__ng_directive") && node.comments ) { return { @@ -1505,7 +1507,8 @@ function getAllComments(options, node) { dangling: node.comments, }; } - return options[Symbol.for("commentsStore")].map.get(node); + const commentsStore = options[Symbol.for("commentsStore")]; + return commentsStore && commentsStore.map.get(node); } /** * @param {Node} node From a7a5dbc0c032afa977f29c1fbfeef600976f5c28 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 3 Dec 2020 19:33:19 +0800 Subject: [PATCH 17/22] Fix typing --- src/language-js/embed.js | 6 +++--- src/language-js/utils.js | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/language-js/embed.js b/src/language-js/embed.js index b263f0d6abb0..f509f2393321 100644 --- a/src/language-js/embed.js +++ b/src/language-js/embed.js @@ -9,9 +9,9 @@ const formatHtml = require("./embed/html"); function getLanguage(path, options) { if ( isStyledJsx(path) || - isStyledComponents(path, options) || + isStyledComponents(path) || isCssProp(path) || - isAngularComponentStyles(path, options) + isAngularComponentStyles(path) ) { return "css"; } @@ -24,7 +24,7 @@ function getLanguage(path, options) { return "html"; } - if (isAngularComponentTemplate(path, options)) { + if (isAngularComponentTemplate(path)) { return "angular"; } diff --git a/src/language-js/utils.js b/src/language-js/utils.js index 821886115bf7..df2a38f21790 100644 --- a/src/language-js/utils.js +++ b/src/language-js/utils.js @@ -1488,6 +1488,9 @@ function hasComment(options, node, flags, fn) { : true; } +/** + * @returns {{all: Comment[], leading: Comment[], trailing: Comment[], dangling: Comment[]} | undefined} + */ function getAllComments(options, node) { if (!node) { return; @@ -1518,7 +1521,7 @@ function getAllComments(options, node) { */ function getComments(options, node, flags, fn) { const comments = getAllComments(options, node); - if (!comments || !comments.all.length === 0) { + if (!comments || comments.all.length !== 0) { return []; } const test = getCommentTestFunction(comments, flags, fn); From 86061581a1d8d298cc95fe38d90595a38897b306 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 3 Dec 2020 19:34:22 +0800 Subject: [PATCH 18/22] !Stop attaching comments to node! --- src/main/comments-store.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/main/comments-store.js b/src/main/comments-store.js index 995b0594e2be..b282ac5fbf4b 100644 --- a/src/main/comments-store.js +++ b/src/main/comments-store.js @@ -1,11 +1,5 @@ "use strict"; -const { - addLeadingComment, - addDanglingComment, - addTrailingComment, -} = require("../common/util"); - class CommentsStore { constructor() { this.map = new WeakMap(); @@ -21,14 +15,6 @@ class CommentsStore { } const comments = this.map.get(node); comments[type].push(comment); - // TODO: remove this - if (type === "leading") { - addLeadingComment(node, comment); - } else if (type === "trailing") { - addTrailingComment(node, comment); - } else if (type === "dangling") { - addDanglingComment(node, comment); - } comments.all.push(comment); } addLeadingComment(node, comment) { From c1b587c71a592a563d949af0cb0285e69616f54a Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 4 Dec 2020 09:14:45 +0800 Subject: [PATCH 19/22] Fix `getComments` function --- src/language-js/utils.js | 54 +++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/language-js/utils.js b/src/language-js/utils.js index df2a38f21790..b5894cdb652b 100644 --- a/src/language-js/utils.js +++ b/src/language-js/utils.js @@ -1488,31 +1488,6 @@ function hasComment(options, node, flags, fn) { : true; } -/** - * @returns {{all: Comment[], leading: Comment[], trailing: Comment[], dangling: Comment[]} | undefined} - */ -function getAllComments(options, node) { - if (!node) { - return; - } - // `angular` parsers has own `comments` property - if ( - (options.parser === "__ng_action" || - options.parser === "__ng_binding" || - options.parser === "__ng_interpolation" || - options.parser === "__ng_directive") && - node.comments - ) { - return { - all: node.comments, - leading: [], - trailing: [], - dangling: node.comments, - }; - } - const commentsStore = options[Symbol.for("commentsStore")]; - return commentsStore && commentsStore.map.get(node); -} /** * @param {Node} node * @param {number | function} [flags] @@ -1521,7 +1496,7 @@ function getAllComments(options, node) { */ function getComments(options, node, flags, fn) { const comments = getAllComments(options, node); - if (!comments || comments.all.length !== 0) { + if (!comments || comments.all.length === 0) { return []; } const test = getCommentTestFunction(comments, flags, fn); @@ -1532,6 +1507,33 @@ function getComments(options, node, flags, fn) { : comments.all; } +/** + * @returns {{all: Comment[], leading: Comment[], trailing: Comment[], dangling: Comment[]} | undefined} + */ +function getAllComments(options, node) { + if (!node) { + return; + } + // `angular` parsers has own `comments` property + if ( + options.parser === "__ng_action" || + options.parser === "__ng_binding" || + options.parser === "__ng_interpolation" || + options.parser === "__ng_directive" + ) { + return node.comments + ? { + all: node.comments, + leading: [], + trailing: [], + dangling: node.comments, + } + : undefined; + } + const commentsStore = options[Symbol.for("commentsStore")]; + return commentsStore && commentsStore.map.get(node); +} + module.exports = { classChildNeedsASIProtection, classPropMayCauseASIProblems, From 204acc8c552554b3e77000ef4133ca89e34cb18e Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 4 Dec 2020 15:25:28 +0800 Subject: [PATCH 20/22] Fix `CatchClause` comments check --- src/language-js/printer-estree.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 4199cf4c648b..f7b5c3eb3d19 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -850,18 +850,16 @@ function printPathNoParens(path, options, print, args) { ]); case "CatchClause": if (n.param) { - const parameterHasComments = hasComment( - options, - n.param, - (comment) => - !isBlockComment(comment) || - (comment.leading && - hasNewline(options.originalText, locEnd(comment))) || - (comment.trailing && - hasNewline(options.originalText, locStart(comment), { - backwards: true, - })) - ); + const parameterHasComments = + hasComment(options, n.param, CommentCheckFlags.Line) || + hasComment(options, n.param, CommentCheckFlags.Leading, (comment) => + hasNewline(options.originalText, locEnd(comment)) + ) || + hasComment(options, n.param, CommentCheckFlags.Trailing, (comment) => + hasNewline(options.originalText, locStart(comment), { + backwards: true, + }) + ); const param = path.call(print, "param"); return concat([ From a18b6513ac4b55cc1d387859af37174ae0e88b0e Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 4 Dec 2020 15:44:34 +0800 Subject: [PATCH 21/22] Pass `commentType` to `printer.printComment` --- src/language-js/print/comment.js | 4 ++-- src/main/comments.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/language-js/print/comment.js b/src/language-js/print/comment.js index 4a11013bfeb9..675137fcc956 100644 --- a/src/language-js/print/comment.js +++ b/src/language-js/print/comment.js @@ -8,7 +8,7 @@ const { const { isLineComment, isBlockComment } = require("../utils"); const { locStart, locEnd } = require("../loc"); -function printComment(comment, options) { +function printComment(comment, options, type) { if (isLineComment(comment)) { // Supports `//`, `#!`, `` return options.originalText @@ -23,7 +23,7 @@ function printComment(comment, options) { // printed as a `lineSuffix` which causes the comments to be // interleaved. See https://github.com/prettier/prettier/issues/4412 if ( - comment.trailing && + type === "trailing" && !hasNewline(options.originalText, locStart(comment), { backwards: true, }) diff --git a/src/main/comments.js b/src/main/comments.js index 0528b9557ec9..fae327b6e918 100644 --- a/src/main/comments.js +++ b/src/main/comments.js @@ -521,11 +521,11 @@ function breakTies(tiesToBreak, text, options) { tiesToBreak.length = 0; } -function printComment(commentPath, options) { +function printComment(commentPath, options, commentType) { const commentsStore = getCommentsStore(options); const comment = commentsStore ? commentPath : commentPath.getValue(); comment.printed = true; - return options.printer.printComment(commentPath, options); + return options.printer.printComment(commentPath, options, commentType); } function findExpressionIndexForComment(quasis, comment, options) { @@ -574,7 +574,7 @@ function printLeadingComment(commentPath, options) { function printTrailingComment(commentPath, options) { const commentsStore = getCommentsStore(options); const comment = commentsStore ? commentPath : commentPath.getValue(); - const contents = printComment(commentPath, options); + const contents = printComment(commentPath, options, "trailing"); /* istanbul ignore next */ if (!contents) { return ""; From 9d30a0d8ce1ffcd7d81d12fbe83461adcadc96e1 Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 4 Dec 2020 15:51:21 +0800 Subject: [PATCH 22/22] Run `yarn fix` --- src/language-js/comments.js | 2 +- src/language-js/print/member-chain.js | 2 +- src/language-js/print/statement.js | 2 +- src/language-js/print/type-parameters.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/language-js/comments.js b/src/language-js/comments.js index e1133e3c2f1e..0f8a31b2a4e6 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -858,7 +858,7 @@ function isTypeCastComment(comment) { * @param {FastPath} path * @returns {boolean} */ -function willPrintOwnComments(path , options ) { +function willPrintOwnComments(path, options) { const node = path.getValue(); const parent = path.getParentNode(); diff --git a/src/language-js/print/member-chain.js b/src/language-js/print/member-chain.js index 06eb21cd267e..19bfd15a6c28 100644 --- a/src/language-js/print/member-chain.js +++ b/src/language-js/print/member-chain.js @@ -244,7 +244,7 @@ function printMemberChain(path, options, print) { } currentGroup.push(printedNodes[i]); - if (hasComment(options,printedNodes[i].node, CommentCheckFlags.Trailing)) { + if (hasComment(options, printedNodes[i].node, CommentCheckFlags.Trailing)) { groups.push(currentGroup); currentGroup = []; hasSeenCallExpression = false; diff --git a/src/language-js/print/statement.js b/src/language-js/print/statement.js index faf02b84c42d..28902cd19770 100644 --- a/src/language-js/print/statement.js +++ b/src/language-js/print/statement.js @@ -49,7 +49,7 @@ function printStatement({ path, index, bodyNode, isClass }, options, print) { !isTheOnlyJSXElementInMarkdown(options, path) && statementNeedsASIProtection(path, options) ) { - if (hasComment(options,node, CommentCheckFlags.Leading)) { + if (hasComment(options, node, CommentCheckFlags.Leading)) { parts.push(print(path, { needsSemi: true })); } else { parts.push(";", printed); diff --git a/src/language-js/print/type-parameters.js b/src/language-js/print/type-parameters.js index 9d62676c8b33..0e5a610a189d 100644 --- a/src/language-js/print/type-parameters.js +++ b/src/language-js/print/type-parameters.js @@ -85,7 +85,7 @@ function printDanglingCommentsForInline(path, options) { if (!hasComment(options, n, CommentCheckFlags.Dangling)) { return ""; } - const hasOnlyBlockComments = !hasComment(options,n, CommentCheckFlags.Line); + const hasOnlyBlockComments = !hasComment(options, n, CommentCheckFlags.Line); const printed = printDanglingComments( path, options,