From 3cb0352541c7ce983f89a760628693ee367f0684 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Nov 2020 08:03:44 +0800 Subject: [PATCH 001/299] Build(deps): Bump meriyah from 3.1.2 to 3.1.6 (#9624) * Build(deps): Bump meriyah from 3.1.2 to 3.1.6 Bumps [meriyah](https://github.com/meriyah/meriyah) from 3.1.2 to 3.1.6. - [Release notes](https://github.com/meriyah/meriyah/releases) - [Changelog](https://github.com/meriyah/meriyah/blob/master/CHANGELOG.md) - [Commits](https://github.com/meriyah/meriyah/compare/v3.1.2...v3.1.6) Signed-off-by: dependabot[bot] * Fix typing Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: fisker --- package.json | 2 +- src/language-js/parser-meriyah.js | 2 ++ src/language-js/types/estree.d.ts | 16 ++-------------- yarn.lock | 8 ++++---- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index 384ff6ab3..e1021de13 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "linguist-languages": "7.11.1", "lodash": "4.17.20", "mem": "8.0.0", - "meriyah": "3.1.2", + "meriyah": "3.1.6", "minimatch": "3.0.4", "minimist": "1.2.5", "n-readlines": "1.0.0", diff --git a/src/language-js/parser-meriyah.js b/src/language-js/parser-meriyah.js index 32f10e58c..0d9f9f45a 100644 --- a/src/language-js/parser-meriyah.js +++ b/src/language-js/parser-meriyah.js @@ -45,6 +45,8 @@ function parseWithOptions(text, module) { const { parse } = require("meriyah"); const comments = []; const tokens = []; + + /** @type {any} */ const ast = parse(text, { ...parseOptions, module, diff --git a/src/language-js/types/estree.d.ts b/src/language-js/types/estree.d.ts index 793932d95..9c19b8866 100644 --- a/src/language-js/types/estree.d.ts +++ b/src/language-js/types/estree.d.ts @@ -1,6 +1,7 @@ import * as ESTree from "estree"; import * as Babel from "@babel/types"; import { TSESTree } from "@typescript-eslint/types"; +import { ESTree as Meriyah } from "meriyah"; import * as NGTree from "angular-estree-parser/lib/types"; type AdditionalFields = { @@ -14,24 +15,11 @@ type AdditionalFields = { leadingComments?: ReadonlyArray | Comment[]; }; -type MeriyahComment = { - value: string; - start: number; - end: number; - range: number[]; - type: - | "MultiLine" - | "SingleLine" - | "HashbangComment" - | "HTMLOpen" - | "HTMLClose"; -}; - export type Comment = ( | ESTree.Comment | Babel.Comment | TSESTree.Comment - | MeriyahComment + | Meriyah.Comment ) & { printed?: boolean; trailing?: boolean; diff --git a/yarn.lock b/yarn.lock index c77c7e1fc..76eaa538b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5278,10 +5278,10 @@ merge2@^1.3.0: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -meriyah@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/meriyah/-/meriyah-3.1.2.tgz#42aac8a1e05b186f8e08b74b2ee47ea00306b7b9" - integrity sha512-CXPkXT3xdk7KAVdrOV9SDvKUkE8r24aQe4ee/Uj7UJQcoNAS+Bz2QjOpDyrFiLD81GyJ3e5SrKn/125Ow0Ryqg== +meriyah@3.1.6: + version "3.1.6" + resolved "https://registry.yarnpkg.com/meriyah/-/meriyah-3.1.6.tgz#56c9c0edb63f9640c7609a39a413c60b038e4451" + integrity sha512-JDOSi6DIItDc33U5N52UdV6P8v+gn+fqZKfbAfHzdWApRQyQWdcvxPvAr9t01bI2rBxGvSrKRQSCg3SkZC1qeg== micromatch@^3.1.4: version "3.1.10" From 9311334101c95788e6e5efba59e237d6b90bab27 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Nov 2020 08:04:15 +0800 Subject: [PATCH 002/299] Build(deps): Bump diff from 4.0.2 to 5.0.0 (#9623) Bumps [diff](https://github.com/kpdecker/jsdiff) from 4.0.2 to 5.0.0. - [Release notes](https://github.com/kpdecker/jsdiff/releases) - [Changelog](https://github.com/kpdecker/jsdiff/blob/master/release-notes.md) - [Commits](https://github.com/kpdecker/jsdiff/compare/v4.0.2...v5.0.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e1021de13..d82d06d5b 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "cjk-regex": "2.0.0", "cosmiconfig": "7.0.0", "dashify": "2.0.0", - "diff": "4.0.2", + "diff": "5.0.0", "editorconfig": "0.15.3", "editorconfig-to-prettier": "0.2.0", "escape-string-regexp": "4.0.0", diff --git a/yarn.lock b/yarn.lock index 76eaa538b..6738d0fa7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2891,10 +2891,10 @@ diff-sequences@^26.6.2: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== -diff@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== dir-glob@^3.0.1: version "3.0.1" From 9e9cc85072218048c823c9ab5d93d1eef822dfed Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Tue, 10 Nov 2020 09:06:08 +0800 Subject: [PATCH 003/299] Enable `directly-loc-start-end` for all languages (#9610) --- .eslintrc.yml | 3 +-- src/language-graphql/loc.js | 17 +++++++++++++++++ src/language-graphql/parser-graphql.js | 15 +++------------ src/language-graphql/printer-graphql.js | 11 ++++------- src/language-html/loc.js | 11 +++++++++++ src/language-html/parser-html.js | 9 +-------- src/language-html/printer-html.js | 15 +++++---------- src/language-markdown/loc.js | 11 +++++++++++ src/language-markdown/parser-markdown.js | 5 +++-- src/language-markdown/printer-markdown.js | 10 ++++------ src/language-markdown/utils.js | 7 ++++--- src/language-yaml/loc.js | 11 +++++++++++ src/language-yaml/parser-yaml.js | 10 +++------- src/language-yaml/printer-yaml.js | 8 +++----- 14 files changed, 81 insertions(+), 62 deletions(-) create mode 100644 src/language-graphql/loc.js create mode 100644 src/language-html/loc.js create mode 100644 src/language-markdown/loc.js create mode 100644 src/language-yaml/loc.js diff --git a/.eslintrc.yml b/.eslintrc.yml index ae99a744e..26bc7af25 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -106,7 +106,6 @@ overrides: rules: prettier-internal-rules/prefer-fast-path-each: error - files: - - src/language-js/**/*.js - - src/language-css/**/*.js + - src/language-*/**/*.js rules: prettier-internal-rules/directly-loc-start-end: error diff --git a/src/language-graphql/loc.js b/src/language-graphql/loc.js new file mode 100644 index 000000000..6d5507718 --- /dev/null +++ b/src/language-graphql/loc.js @@ -0,0 +1,17 @@ +"use strict"; + +function locStart(node) { + if (typeof node.start === "number") { + return node.start; + } + return node.loc && node.loc.start; +} + +function locEnd(node) { + if (typeof node.end === "number") { + return node.end; + } + return node.loc && node.loc.end; +} + +module.exports = { locStart, locEnd }; diff --git a/src/language-graphql/parser-graphql.js b/src/language-graphql/parser-graphql.js index 60ec5c9bf..5e732eed7 100644 --- a/src/language-graphql/parser-graphql.js +++ b/src/language-graphql/parser-graphql.js @@ -2,6 +2,7 @@ const createError = require("../common/parser-create-error"); const { hasPragma } = require("./pragma"); +const { locStart, locEnd } = require("./loc"); function parseComments(ast) { const comments = []; @@ -77,18 +78,8 @@ module.exports = { parse, astFormat: "graphql", hasPragma, - locStart(node) { - if (typeof node.start === "number") { - return node.start; - } - return node.loc && node.loc.start; - }, - locEnd(node) { - if (typeof node.end === "number") { - return node.end; - } - return node.loc && node.loc.end; - }, + locStart, + locEnd, }, }, }; diff --git a/src/language-graphql/printer-graphql.js b/src/language-graphql/printer-graphql.js index 2b6b2a048..f787ff050 100644 --- a/src/language-graphql/printer-graphql.js +++ b/src/language-graphql/printer-graphql.js @@ -12,6 +12,7 @@ const { } = require("../document").builders; const { hasIgnoreComment, isNextLineEmpty } = require("../common/util"); const { insertPragma } = require("./pragma"); +const { locStart, locEnd } = require("./loc"); function genericPrint(path, options, print) { const n = path.getValue(); @@ -31,11 +32,7 @@ function genericPrint(path, options, print) { if (index !== n.definitions.length - 1) { parts.push(hardline); if ( - isNextLineEmpty( - options.originalText, - pathChild.getValue(), - options.locEnd - ) + isNextLineEmpty(options.originalText, pathChild.getValue(), locEnd) ) { parts.push(hardline); } @@ -44,7 +41,7 @@ function genericPrint(path, options, print) { return concat([concat(parts), hardline]); } case "OperationDefinition": { - const hasOperation = options.originalText[options.locStart(n)] !== "{"; + const hasOperation = options.originalText[locStart(n)] !== "{"; const hasName = !!n.name; return concat([ hasOperation ? n.operation : "", @@ -627,7 +624,7 @@ function printSequence(sequencePath, options, print) { const printed = print(path); if ( - isNextLineEmpty(options.originalText, path.getValue(), options.locEnd) && + isNextLineEmpty(options.originalText, path.getValue(), locEnd) && i < count - 1 ) { return concat([printed, hardline]); diff --git a/src/language-html/loc.js b/src/language-html/loc.js new file mode 100644 index 000000000..79f8f0c72 --- /dev/null +++ b/src/language-html/loc.js @@ -0,0 +1,11 @@ +"use strict"; + +function locStart(node) { + return node.sourceSpan.start.offset; +} + +function locEnd(node) { + return node.sourceSpan.end.offset; +} + +module.exports = { locStart, locEnd }; diff --git a/src/language-html/parser-html.js b/src/language-html/parser-html.js index 994e0f555..f6424a7a1 100644 --- a/src/language-html/parser-html.js +++ b/src/language-html/parser-html.js @@ -16,6 +16,7 @@ const { const { hasPragma } = require("./pragma"); const { Node } = require("./ast"); const { parseIeConditionalComment } = require("./conditional-comment"); +const { locStart, locEnd } = require("./loc"); function ngHtmlParser( input, @@ -347,14 +348,6 @@ function _parse(text, options, parserOptions, shouldParseFrontMatter = true) { }); } -function locStart(node) { - return node.sourceSpan.start.offset; -} - -function locEnd(node) { - return node.sourceSpan.end.offset; -} - function createParser({ recognizeSelfClosing = false, normalizeTagName = false, diff --git a/src/language-html/printer-html.js b/src/language-html/printer-html.js index 0beeea663..e0649c4bb 100644 --- a/src/language-html/printer-html.js +++ b/src/language-html/printer-html.js @@ -46,6 +46,7 @@ const { } = require("./utils"); const preprocess = require("./preprocess"); const { insertPragma } = require("./pragma"); +const { locStart, locEnd } = require("./loc"); const { printVueFor, printVueSlotScope, @@ -407,10 +408,7 @@ function genericPrint(path, options, print) { printOpeningTagPrefix(node, options), concat( replaceEndOfLineWith( - options.originalText.slice( - options.locStart(node), - options.locEnd(node) - ), + options.originalText.slice(locStart(node), locEnd(node)), literalline ) ), @@ -563,12 +561,12 @@ function printChildren(path, options, print) { printOpeningTagPrefix(child, options), replaceEndOfLineWith( options.originalText.slice( - options.locStart(child) + + locStart(child) + (child.prev && needsToBorrowNextOpeningTagStartMarker(child.prev) ? printOpeningTagStartMarker(child).length : 0), - options.locEnd(child) - + locEnd(child) - (child.next && needsToBorrowPrevClosingTagEndMarker(child.next) ? printClosingTagEndMarker(child, options).length : 0) @@ -698,10 +696,7 @@ function printAttributes(path, options, print) { return hasPrettierIgnoreAttribute(attribute) ? concat( replaceEndOfLineWith( - options.originalText.slice( - options.locStart(attribute), - options.locEnd(attribute) - ), + options.originalText.slice(locStart(attribute), locEnd(attribute)), literalline ) ) diff --git a/src/language-markdown/loc.js b/src/language-markdown/loc.js new file mode 100644 index 000000000..097ca3b54 --- /dev/null +++ b/src/language-markdown/loc.js @@ -0,0 +1,11 @@ +"use strict"; + +function locStart(node) { + return node.position.start.offset; +} + +function locEnd(node) { + return node.position.end.offset; +} + +module.exports = { locStart, locEnd }; diff --git a/src/language-markdown/parser-markdown.js b/src/language-markdown/parser-markdown.js index bb961f103..32499bd34 100644 --- a/src/language-markdown/parser-markdown.js +++ b/src/language-markdown/parser-markdown.js @@ -6,6 +6,7 @@ const remarkMath = require("remark-math"); const footnotes = require("remark-footnotes"); const { parse: parseFrontMatter } = require("../utils/front-matter"); const pragma = require("./pragma"); +const { locStart, locEnd } = require("./loc"); const { mapAst, INLINE_NODE_WRAPPER_TYPES } = require("./utils"); const mdx = require("./mdx"); @@ -158,8 +159,8 @@ function looseItems() { const baseParser = { astFormat: "mdast", hasPragma: pragma.hasPragma, - locStart: (node) => node.position.start.offset, - locEnd: (node) => node.position.end.offset, + locStart, + locEnd, }; const markdownParser = { ...baseParser, parse: createParse({ isMDX: false }) }; diff --git a/src/language-markdown/printer-markdown.js b/src/language-markdown/printer-markdown.js index ca916505a..e95006c58 100644 --- a/src/language-markdown/printer-markdown.js +++ b/src/language-markdown/printer-markdown.js @@ -28,6 +28,7 @@ const { const { replaceEndOfLineWith } = require("../common/util"); const embed = require("./embed"); const { insertPragma } = require("./pragma"); +const { locStart, locEnd } = require("./loc"); const preprocess = require("./preprocess"); const clean = require("./clean"); const { @@ -112,7 +113,7 @@ function genericPrint(path, options, print) { const isFirstSentence = (node, name, index) => node.type === "sentence" && index === 0; const isLastChildAutolink = (node, name, index) => - isAutolink(node.children[index - 1], options); + isAutolink(node.children[index - 1]); if ( escapedValue !== node.value && @@ -147,7 +148,7 @@ function genericPrint(path, options, print) { } case "emphasis": { let style; - if (isAutolink(node.children[0], options)) { + if (isAutolink(node.children[0])) { style = options.originalText[node.position.start.offset]; } else { const parentNode = path.getParentNode(); @@ -463,10 +464,7 @@ function genericPrint(path, options, print) { case "inlineMath": { // remark-math trims content but we don't want to remove whitespaces // since it's very possible that it's recognized as math accidentally - return options.originalText.slice( - options.locStart(node), - options.locEnd(node) - ); + return options.originalText.slice(locStart(node), locEnd(node)); } case "tableRow": // handled in "table" diff --git a/src/language-markdown/utils.js b/src/language-markdown/utils.js index 7782614ae..4396d48f0 100644 --- a/src/language-markdown/utils.js +++ b/src/language-markdown/utils.js @@ -1,6 +1,7 @@ "use strict"; const { getLast } = require("../common/util"); +const { locStart, locEnd } = require("./loc"); const { cjkPattern, kPattern, @@ -221,15 +222,15 @@ function mapAst(ast, handler) { })(ast, null, null); } -function isAutolink(node, options) { +function isAutolink(node) { if (!node || node.type !== "link" || node.children.length !== 1) { return false; } const child = node.children[0]; return ( child && - options.locStart(node) === options.locStart(child) && - options.locEnd(node) === options.locEnd(child) + locStart(node) === locStart(child) && + locEnd(node) === locEnd(child) ); } diff --git a/src/language-yaml/loc.js b/src/language-yaml/loc.js new file mode 100644 index 000000000..097ca3b54 --- /dev/null +++ b/src/language-yaml/loc.js @@ -0,0 +1,11 @@ +"use strict"; + +function locStart(node) { + return node.position.start.offset; +} + +function locEnd(node) { + return node.position.end.offset; +} + +module.exports = { locStart, locEnd }; diff --git a/src/language-yaml/parser-yaml.js b/src/language-yaml/parser-yaml.js index 5b83bd74a..61948c233 100644 --- a/src/language-yaml/parser-yaml.js +++ b/src/language-yaml/parser-yaml.js @@ -2,6 +2,7 @@ const createError = require("../common/parser-create-error"); const { hasPragma } = require("./pragma"); +const { locStart, locEnd } = require("./loc"); function parse(text) { try { @@ -30,13 +31,8 @@ const parser = { astFormat: "yaml", parse, hasPragma, - locStart(node) { - return node.position.start.offset; - }, - /* istanbul ignore next */ - locEnd(node) { - return node.position.end.offset; - }, + locStart, + locEnd, }; module.exports = { diff --git a/src/language-yaml/printer-yaml.js b/src/language-yaml/printer-yaml.js index f13df3580..fa219a50e 100644 --- a/src/language-yaml/printer-yaml.js +++ b/src/language-yaml/printer-yaml.js @@ -20,6 +20,7 @@ const { } = docBuilders; const { replaceEndOfLineWith, isPreviousLineEmpty } = require("../common/util"); const { insertPragma, isPragma } = require("./pragma"); +const { locStart } = require("./loc"); const { getAncestorCount, getBlockValueLineContents, @@ -140,7 +141,7 @@ function genericPrint(path, options, print) { isPreviousLineEmpty( options.originalText, path.getValue(), - options.locStart + locStart ) ? hardline : "", @@ -626,10 +627,7 @@ function shouldPrintDocumentHeadEndMarker( */ (root.children[0] === document && /---(\s|$)/.test( - options.originalText.slice( - options.locStart(document), - options.locStart(document) + 4 - ) + options.originalText.slice(locStart(document), locStart(document) + 4) )) || /** * %DIRECTIVE From 60a5729a192926699055b50ba33924fc8bc1cdf5 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Tue, 10 Nov 2020 09:12:46 +0800 Subject: [PATCH 004/299] Move prettier-ignore related functions into `language-js/` (#9555) --- src/common/util.js | 19 ------------ src/language-css/printer-postcss.js | 2 -- src/language-graphql/printer-graphql.js | 13 ++++++-- src/language-js/comments.js | 11 ++++--- src/language-js/printer-estree.js | 4 +-- src/language-js/utils.js | 30 ++++++++++++++++--- .../__snapshots__/jsfmt.spec.js.snap | 27 +++++++++++++++++ tests/graphql/prettier-ignore/jsfmt.spec.js | 1 + .../prettier-ignore-comment.graphql | 7 +++++ 9 files changed, 81 insertions(+), 33 deletions(-) create mode 100644 tests/graphql/prettier-ignore/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/graphql/prettier-ignore/jsfmt.spec.js create mode 100644 tests/graphql/prettier-ignore/prettier-ignore-comment.graphql diff --git a/src/common/util.js b/src/common/util.js index b362b1649..4b9f3e513 100644 --- a/src/common/util.js +++ b/src/common/util.js @@ -557,23 +557,6 @@ function getStringWidth(text) { return stringWidth(text); } -function hasIgnoreComment(path) { - const node = path.getValue(); - return hasNodeIgnoreComment(node); -} - -function hasNodeIgnoreComment(node) { - return ( - node && - ((node.comments && - node.comments.length > 0 && - node.comments.some( - (comment) => isNodeIgnoreComment(comment) && !comment.unignore - )) || - node.prettierIgnore) - ); -} - function isNodeIgnoreComment(comment) { return comment.value.trim() === "prettier-ignore"; } @@ -683,8 +666,6 @@ module.exports = { getPreferredQuote, printString, printNumber, - hasIgnoreComment, - hasNodeIgnoreComment, isNodeIgnoreComment, makeString, addLeadingComment, diff --git a/src/language-css/printer-postcss.js b/src/language-css/printer-postcss.js index 4818f6241..74b5ec151 100644 --- a/src/language-css/printer-postcss.js +++ b/src/language-css/printer-postcss.js @@ -3,7 +3,6 @@ const { printNumber, printString, - hasIgnoreComment, hasNewline, isFrontMatterNode, isNextLineEmpty, @@ -1062,6 +1061,5 @@ module.exports = { print: genericPrint, embed, insertPragma, - hasPrettierIgnore: hasIgnoreComment, massageAstNode: clean, }; diff --git a/src/language-graphql/printer-graphql.js b/src/language-graphql/printer-graphql.js index f787ff050..0101aef7e 100644 --- a/src/language-graphql/printer-graphql.js +++ b/src/language-graphql/printer-graphql.js @@ -10,7 +10,7 @@ const { indent, ifBreak, } = require("../document").builders; -const { hasIgnoreComment, isNextLineEmpty } = require("../common/util"); +const { isNextLineEmpty } = require("../common/util"); const { insertPragma } = require("./pragma"); const { locStart, locEnd } = require("./loc"); @@ -677,10 +677,19 @@ function printInterfaces(path, options, print) { function clean(/*node, newNode , parent*/) {} clean.ignoredProperties = new Set(["loc", "comments"]); +function hasPrettierIgnore(path) { + const node = path.getValue(); + return ( + node && + Array.isArray(node.comments) && + node.comments.some((comment) => comment.value.trim() === "prettier-ignore") + ); +} + module.exports = { print: genericPrint, massageAstNode: clean, - hasPrettierIgnore: hasIgnoreComment, + hasPrettierIgnore, insertPragma, printComment, canAttachComment, diff --git a/src/language-js/comments.js b/src/language-js/comments.js index c33bff504..53b337ddd 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -6,13 +6,16 @@ const { getNextNonSpaceNonCommentCharacterIndexWithStartIndex, getNextNonSpaceNonCommentCharacter, hasNewlineInRange, - isNodeIgnoreComment, addLeadingComment, addTrailingComment, addDanglingComment, getNextNonSpaceNonCommentCharacterIndex, } = require("../common/util"); -const { isBlockComment, getFunctionParameters } = require("./utils"); +const { + isBlockComment, + getFunctionParameters, + isPrettierIgnoreComment, +} = require("./utils"); const { locStart, locEnd } = require("./loc"); function handleOwnLineComment(comment, text, options, ast, isLastComment) { @@ -697,7 +700,7 @@ function handleUnionTypeComments( (enclosingNode.type === "UnionTypeAnnotation" || enclosingNode.type === "TSUnionType") ) { - if (isNodeIgnoreComment(comment)) { + if (isPrettierIgnoreComment(comment)) { followingNode.prettierIgnore = true; comment.unignore = true; } @@ -712,7 +715,7 @@ function handleUnionTypeComments( followingNode && (followingNode.type === "UnionTypeAnnotation" || followingNode.type === "TSUnionType") && - isNodeIgnoreComment(comment) + isPrettierIgnoreComment(comment) ) { followingNode.types[0].prettierIgnore = true; comment.unignore = true; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 6f3224cc4..add0da277 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -14,8 +14,6 @@ const { getStringWidth, printString, printNumber, - hasIgnoreComment, - hasNodeIgnoreComment, getIndentSize, getPreferredQuote, isNextLineEmpty, @@ -68,6 +66,8 @@ const { hasPrettierIgnore, hasTrailingComment, hasTrailingLineComment, + hasNodeIgnoreComment, + hasIgnoreComment, identity, isBinaryish, isCallOrOptionalCallExpression, diff --git a/src/language-js/utils.js b/src/language-js/utils.js index 6400b5f2e..d5564efba 100644 --- a/src/language-js/utils.js +++ b/src/language-js/utils.js @@ -5,8 +5,6 @@ const { getLast, hasNewline, hasNewlineInRange, - hasIgnoreComment, - hasNodeIgnoreComment, skipWhitespace, } = require("../common/util"); const { locStart, locEnd, hasSameLocStart } = require("./loc"); @@ -843,8 +841,8 @@ function hasJsxIgnoreComment(path) { prevSibling.type === "JSXExpressionContainer" && prevSibling.expression.type === "JSXEmptyExpression" && prevSibling.expression.comments && - prevSibling.expression.comments.some( - (comment) => comment.value.trim() === "prettier-ignore" + prevSibling.expression.comments.some((comment) => + isPrettierIgnoreComment(comment) ) ); } @@ -1448,6 +1446,27 @@ function iterateFunctionParametersPath(path, iteratee) { } } +function isPrettierIgnoreComment(comment) { + return comment.value.trim() === "prettier-ignore"; +} + +function hasNodeIgnoreComment(node) { + return ( + node && + ((node.comments && + node.comments.length > 0 && + node.comments.some( + (comment) => isPrettierIgnoreComment(comment) && !comment.unignore + )) || + node.prettierIgnore) + ); +} + +function hasIgnoreComment(path) { + const node = path.getValue(); + return hasNodeIgnoreComment(node); +} + module.exports = { classChildNeedsASIProtection, classPropMayCauseASIProblems, @@ -1469,10 +1488,13 @@ module.exports = { hasPrettierIgnore, hasTrailingComment, hasTrailingLineComment, + hasIgnoreComment, + hasNodeIgnoreComment, identity, isBinaryish, isBlockComment, isLineComment, + isPrettierIgnoreComment, isCallOrOptionalCallExpression, isEmptyJSXElement, isExportDeclaration, diff --git a/tests/graphql/prettier-ignore/__snapshots__/jsfmt.spec.js.snap b/tests/graphql/prettier-ignore/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..3afabead1 --- /dev/null +++ b/tests/graphql/prettier-ignore/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,27 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`prettier-ignore-comment.graphql format 1`] = ` +====================================options===================================== +parsers: ["graphql"] +printWidth: 80 + | printWidth +=====================================input====================================== +{ + # prettier-ignore + hero { + name + height + } +} + +=====================================output===================================== +{ + # prettier-ignore + hero { + name + height + } +} + +================================================================================ +`; diff --git a/tests/graphql/prettier-ignore/jsfmt.spec.js b/tests/graphql/prettier-ignore/jsfmt.spec.js new file mode 100644 index 000000000..4612e6ac5 --- /dev/null +++ b/tests/graphql/prettier-ignore/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, ["graphql"]); diff --git a/tests/graphql/prettier-ignore/prettier-ignore-comment.graphql b/tests/graphql/prettier-ignore/prettier-ignore-comment.graphql new file mode 100644 index 000000000..14daa32f3 --- /dev/null +++ b/tests/graphql/prettier-ignore/prettier-ignore-comment.graphql @@ -0,0 +1,7 @@ +{ + # prettier-ignore + hero { + name + height + } +} From 58d62e094fec78aa6b47518b8931686a4fab292c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Nov 2020 15:11:46 +0800 Subject: [PATCH 005/299] Build(deps): Bump @glimmer/syntax from 0.62.4 to 0.63.4 (#9635) Bumps [@glimmer/syntax](https://github.com/glimmerjs/glimmer-vm) from 0.62.4 to 0.63.4. - [Release notes](https://github.com/glimmerjs/glimmer-vm/releases) - [Changelog](https://github.com/glimmerjs/glimmer-vm/blob/master/CHANGELOG.md) - [Commits](https://github.com/glimmerjs/glimmer-vm/compare/v0.62.4...v0.63.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 28 ++++++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index d82d06d5b..d41d90c71 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@angular/compiler": "10.2.2", "@babel/code-frame": "7.10.4", "@babel/parser": "7.12.5", - "@glimmer/syntax": "0.62.4", + "@glimmer/syntax": "0.63.4", "@iarna/toml": "2.2.5", "@typescript-eslint/typescript-estree": "3.10.1", "angular-estree-parser": "2.2.1", diff --git a/yarn.lock b/yarn.lock index 6738d0fa7..30bf2d12c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -908,6 +908,13 @@ dependencies: "@simple-dom/interface" "^1.4.0" +"@glimmer/interfaces@0.63.4": + version "0.63.4" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.63.4.tgz#b375b4346b3d67a17a45825a9c90367d2bf167d4" + integrity sha512-XpKKJVqVE9JUcAqEHUu0lwJQZnv3gHPZ93o/xDdyUqnSokipeToHJzehRrhIkknSaiKKyu624fvk0dakQaS5ow== + dependencies: + "@simple-dom/interface" "^1.4.0" + "@glimmer/reference@0.62.4": version "0.62.4" resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.62.4.tgz#50dbd0d202ca94f73bbcdfe19ce450ca5c6babdc" @@ -919,13 +926,13 @@ "@glimmer/util" "0.62.4" "@glimmer/validator" "0.62.4" -"@glimmer/syntax@0.62.4": - version "0.62.4" - resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.62.4.tgz#9d5ec15584fed85d807762992a1879fe7fe15ae8" - integrity sha512-c/c+tqv1Ob+IaiVYe3DfHsLQwk/DZ3RA14gVcrE8Bbqrr7RtmjdKPfgNswiQhx7b+1ygcUhvYUfxfI8nCVswIw== +"@glimmer/syntax@0.63.4": + version "0.63.4" + resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.63.4.tgz#87598c50b097ff6beea4e1611549577050d922c5" + integrity sha512-ndt2ujQHe8bnwv/x8JpAEBqzWvXClqnevNqlAyywTZR4/ur0SYayFRdN9kI3qzRzX6Psc7lxCAqwp8QyKpUbiQ== dependencies: - "@glimmer/interfaces" "0.62.4" - "@glimmer/util" "0.62.4" + "@glimmer/interfaces" "0.63.4" + "@glimmer/util" "0.63.4" "@handlebars/parser" "^1.1.0" simple-html-tokenizer "^0.5.10" @@ -938,6 +945,15 @@ "@glimmer/interfaces" "0.62.4" "@simple-dom/interface" "^1.4.0" +"@glimmer/util@0.63.4": + version "0.63.4" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.63.4.tgz#e051a5b03eb5a04a58a9d393fcd37f25b533c2ab" + integrity sha512-D102O0wRdPn6KOHFZ3+GAKj+Wxaou0KMxePspu5lPD9bQYGd7z+epqpRxpYGb5vbZCg8nTT28+qUU5yMh6NpCA== + dependencies: + "@glimmer/env" "0.1.7" + "@glimmer/interfaces" "0.63.4" + "@simple-dom/interface" "^1.4.0" + "@glimmer/validator@0.62.4": version "0.62.4" resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.62.4.tgz#80570d3fbf9c9a9e6a50e5c022a073da24d14d85" From 23ddeac886e7edb4be51f039ce8d1a5d9b7f0256 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Nov 2020 15:13:19 +0800 Subject: [PATCH 006/299] Build(deps-dev): Bump cspell from 4.1.3 to 4.1.5 (#9633) Bumps [cspell](https://github.com/streetsidesoftware/cspell) from 4.1.3 to 4.1.5. - [Release notes](https://github.com/streetsidesoftware/cspell/releases) - [Commits](https://github.com/streetsidesoftware/cspell/compare/cspell@4.1.3...cspell@4.1.5) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 486 +++++++++++++++++++++++++-------------------------- 2 files changed, 244 insertions(+), 244 deletions(-) diff --git a/package.json b/package.json index d41d90c71..c61a6bd75 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "benchmark": "2.1.4", "builtin-modules": "3.1.0", "cross-env": "7.0.2", - "cspell": "4.1.3", + "cspell": "4.1.5", "eslint": "7.13.0", "eslint-config-prettier": "6.15.0", "eslint-formatter-friendly": "7.0.0", diff --git a/yarn.lock b/yarn.lock index 30bf2d12c..6976a6a46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2444,234 +2444,234 @@ crypto-random-string@^2.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -cspell-dict-aws@^1.0.7: +cspell-dict-aws@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/cspell-dict-aws/-/cspell-dict-aws-1.0.9.tgz#e9600dfc6973aaccb1f54546308be4763f4e0fac" + integrity sha512-DrSXcDEcPK0flggRzP7PgmMcqOKO3TsEv5pClK8MsCHN1GcJB3+FyT683BZu0gcO4RQkj4CjEi2Q5m++fZ30Cg== + dependencies: + configstore "^5.0.1" + +cspell-dict-bash@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/cspell-dict-aws/-/cspell-dict-aws-1.0.7.tgz#c4b9d26de3ff90bd6e16ba7d347ee99d341adbf1" - integrity sha512-/8lvWfwrWuWNe2VPH0v2fLyeKyMBWI/ZkKlB1DwKn/LgzMpjBtdsdZhEAkx0ETBjAXR+bgZnN/QldCWCS1D6wA== + resolved "https://registry.yarnpkg.com/cspell-dict-bash/-/cspell-dict-bash-1.0.7.tgz#ff9154dbeaeb45f2ff37209aad42d7fe6e678e9e" + integrity sha512-u1TFhmCUNZq86lfGFXCpnKHie8Zm3aarGHBu9/cBZC/NVjXp/6S32EUdiNjJm9t+Rlfb244u2ITTKvLPp/IE/A== dependencies: configstore "^5.0.1" -cspell-dict-bash@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/cspell-dict-bash/-/cspell-dict-bash-1.0.5.tgz#3de537b462ec939cfd8f782905a11c042549497a" - integrity sha512-fyF+W6AsSauF3TcUoCqesiMlj4tp9+gf5PWEJKV0dujTjO8p5dy4RwCX0I4Zw2nC92Knt4If3L+J/4TlNzJGtw== - dependencies: - configstore "^5.0.1" - -cspell-dict-companies@^1.0.30: - version "1.0.30" - resolved "https://registry.yarnpkg.com/cspell-dict-companies/-/cspell-dict-companies-1.0.30.tgz#d4046ba6cc98ff310783e7370c0df2d336136c02" - integrity sha512-h+agGF0t+/rNJdpb5sBTZAHGZL7uKCOJfCLVakYi/9E6juocISTq/zDls/Junb1SKiWulbH8y1CeEMgyKAsCaA== - dependencies: - configstore "^5.0.1" - -cspell-dict-cpp@^1.1.29: - version "1.1.29" - resolved "https://registry.yarnpkg.com/cspell-dict-cpp/-/cspell-dict-cpp-1.1.29.tgz#e4de6d2546b5164cd86e94af431ea864c575996b" - integrity sha512-rRSUV53+6oZo5fCiweqq7gwpbV6qXmTfxRo13Dce688w5UaDkSSn9Cz2FEgWqpYZj8l530QtMKeFtmGLgpPBww== - dependencies: - configstore "^5.0.1" - -cspell-dict-cryptocurrencies@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cspell-dict-cryptocurrencies/-/cspell-dict-cryptocurrencies-1.0.4.tgz#8d5f8e0cfbc08bb45aee3ca1bc6748814b97e13a" - integrity sha512-jIiBmxnEyWfQ6AzXoUCvxt8kUMbsCbngNBHZVMcIf75iUzSkJsZVCVRoIS/G9BYaiw6/i5uj0QEdefX+J71N1A== - dependencies: - configstore "^5.0.0" - -cspell-dict-csharp@^1.0.3: - version "1.0.5" - resolved "https://registry.yarnpkg.com/cspell-dict-csharp/-/cspell-dict-csharp-1.0.5.tgz#fc4c187a2412dd5aaecdb24b48ed8cf7c1741ae3" - integrity sha512-BNo5rLAhwCpg5w09+aaInUJozaPv5ND1K/wOwSPrEA9DW8F1EP703ekUxhB0islzYkEcoAuyM7Xu7SKpzh+8PQ== - dependencies: - configstore "^5.0.0" - -cspell-dict-css@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/cspell-dict-css/-/cspell-dict-css-1.0.5.tgz#6d83c3773ae92063e4cdb1c5f46960528f138df1" - integrity sha512-/rs7ctTiP5Yfh50SNLiiT+aPGkOS57KYaF8QFTAjar0O8lKKK9ghAxoMXgjijTEXoqc0yujOK8yQltcJzTdvog== - dependencies: - configstore "^5.0.0" - -cspell-dict-django@^1.0.17: - version "1.0.17" - resolved "https://registry.yarnpkg.com/cspell-dict-django/-/cspell-dict-django-1.0.17.tgz#d18ac063eac966ce0ca136cce582ae6477a45abb" - integrity sha512-6LdpmyqlGpUwgcGZiUXDJKz6rq4gc5Omkv3NZKJ8fwocdRI6ZD0Vlo3/18PSzD8XSYay1c9pCIr6V6N0fexbYw== - dependencies: - configstore "^5.0.1" - -cspell-dict-dotnet@^1.0.16: - version "1.0.16" - resolved "https://registry.yarnpkg.com/cspell-dict-dotnet/-/cspell-dict-dotnet-1.0.16.tgz#1f429dfd758fb7f9c6871cae26671142e409ca19" - integrity sha512-07UbbIuAcj7KDt2cPFwjQRnHplCPyks07/FEpwXc7+WroFdxIbhwqV6d8Ol+DcnIR+1PoK0Ertp8iCBzTHPceA== - dependencies: - configstore "^5.0.1" - -cspell-dict-elixir@^1.0.15: - version "1.0.15" - resolved "https://registry.yarnpkg.com/cspell-dict-elixir/-/cspell-dict-elixir-1.0.15.tgz#dceebd56ce6bfd318bc258a8e1900ddeb252b5b2" - integrity sha512-M6tx+1gI1lrtqaF466hFEihj4VRxLnF+ZxweyJZQJ6elR+VvvwRq2SVD8NAgBE3Dr0oU49uxgzdjuZz3S1kD8w== - dependencies: - configstore "^5.0.1" - -cspell-dict-en-gb@^1.1.20: - version "1.1.20" - resolved "https://registry.yarnpkg.com/cspell-dict-en-gb/-/cspell-dict-en-gb-1.1.20.tgz#6f9c28e2629f1e799506f92a30394230ca519b10" - integrity sha512-cYsJV6UyIqMal8+NMlg6DHn95LwTdM4wcDkjDDatRqQFhVi5m1yUB+l/JfnIbfYxaz51cJfNqpZSOE2LeF38Vw== - dependencies: - configstore "^5.0.1" - -cspell-dict-en_us@^1.2.30: - version "1.2.30" - resolved "https://registry.yarnpkg.com/cspell-dict-en_us/-/cspell-dict-en_us-1.2.30.tgz#4bfcc38dbcf669a490561e6e2b866be865feb727" - integrity sha512-A6tcz4LPBhOQ5uRMx+gjPq4QpgfpMeoMWgd8As41bAoxpun2/ZXe2+A/Gl9GdOF+Zb9o7ccsx10NQDSeodhKgQ== - dependencies: - configstore "^5.0.1" - -cspell-dict-filetypes@^1.0.3: - version "1.1.0" - resolved "https://registry.yarnpkg.com/cspell-dict-filetypes/-/cspell-dict-filetypes-1.1.0.tgz#04dcad32ea000ab145e1f52190da69e9098acca8" - integrity sha512-uzLMSUzR3Z1fcX/6VXY3vrdFIR7BzcDTJHa35Y8mSOIt0sWldBh/1uFB9t+TA1+6Og4Rr7n6rSKhGIppGzU4ZA== - dependencies: - configstore "^5.0.0" - -cspell-dict-fonts@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/cspell-dict-fonts/-/cspell-dict-fonts-1.0.7.tgz#93ec7d9c5b85af0b87750d76b136553548d559c4" - integrity sha512-po4Rb3wEn0PVCLbFBkAWtXd76ljJPzXHDiRCeLjpwr6pjyoBb/S6KvcIBTlgSGWXVQQGdy2XW9ChFtljz1FOOA== - dependencies: - configstore "^5.0.1" - -cspell-dict-fullstack@^1.0.31: +cspell-dict-companies@^1.0.31: version "1.0.31" - resolved "https://registry.yarnpkg.com/cspell-dict-fullstack/-/cspell-dict-fullstack-1.0.31.tgz#3bf06bc0583fd393b74ccc3f5e3c31fbef43479e" - integrity sha512-0xYe5eANBaDPnDsACsf8Vla0qGLspUdk3nPkKU+7LqTUb1LvKAE20As8ihxblD/SxBKsmD5FyLFIhCgYvLb4ng== + resolved "https://registry.yarnpkg.com/cspell-dict-companies/-/cspell-dict-companies-1.0.31.tgz#7f8c3c3fb2c70eeb0c9050fea208b75092243f59" + integrity sha512-DHn7umIg/Zz79f58PHyTmvEO01UFZmG0226Dgi6bA/haGUV/zR0P72cPLMEsoTUUSzsfkmcQ/8k2lHNEwriLaQ== dependencies: configstore "^5.0.1" -cspell-dict-golang@^1.1.16: - version "1.1.16" - resolved "https://registry.yarnpkg.com/cspell-dict-golang/-/cspell-dict-golang-1.1.16.tgz#fa5741542973ac83c3323f9212ed0d8c67e8b455" - integrity sha512-15wd23uwr8jM+3JDsFRsyjmne3psuxDIrrNnM8LWxJuytlm/2d+weXF00XDjMZ/bSDCeyZ8sz08aulr6i9c9cw== +cspell-dict-cpp@^1.1.33: + version "1.1.33" + resolved "https://registry.yarnpkg.com/cspell-dict-cpp/-/cspell-dict-cpp-1.1.33.tgz#f0267f62a08c4a435b75c711379661fb2733d004" + integrity sha512-wCvVCSQl6k3884oEcpGv77l/B1k2dRl2Koo3xrB7tAADg9n4euuk7BBwN681vtHJjJPQXBqW59qeSCwD14y8sw== dependencies: configstore "^5.0.1" -cspell-dict-haskell@^1.0.6: +cspell-dict-cryptocurrencies@^1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/cspell-dict-haskell/-/cspell-dict-haskell-1.0.6.tgz#8945c36631230e85aa3952b774851d7b816b36a6" - integrity sha512-j0hDxShC/9kU6FLw+3wwxdEvZcoHLYSoPdlGhDvhFwMqReogNwdFf/YrzzlVDasxOD5eY25Arqz0t3L3mB3Efg== - dependencies: - configstore "^5.0.1" - -cspell-dict-html-symbol-entities@^1.0.15: - version "1.0.15" - resolved "https://registry.yarnpkg.com/cspell-dict-html-symbol-entities/-/cspell-dict-html-symbol-entities-1.0.15.tgz#50d70ac7632f2ef40a3da7df0c531882403c8ea5" - integrity sha512-F956/ormR3VvLjSNrrRdMQu/5cCVr3kYqsplJGxsTLC/ejrXy+HPJQUMMckXi/zG2SrzmLP7Lg6d5QHf5PcHQQ== - dependencies: - configstore "^5.0.1" - -cspell-dict-html@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/cspell-dict-html/-/cspell-dict-html-1.1.0.tgz#dee8d75e5d70531b9f207c375423ef495e9eb85e" - integrity sha512-KXXqOE6QM/3OdIh0ax0YlfOg/+ogqt7f/WoBTjb+1L2CReYfWsOfYVjuZG+L6j5GW34wnMyq1QYo9APX4NF3nw== + resolved "https://registry.yarnpkg.com/cspell-dict-cryptocurrencies/-/cspell-dict-cryptocurrencies-1.0.6.tgz#4e51b16ac7a5f29f8cddd9f256605e6850a243ae" + integrity sha512-JAjP6CkVsMH8j2K0s6DozAgk7tBfJ2ixLGy5uOhn7/gx+sIf327p9GZOtlRLzAjN3xc2/nzjJ0Li7zGCFlh5cA== dependencies: configstore "^5.0.0" -cspell-dict-java@^1.0.14: - version "1.0.14" - resolved "https://registry.yarnpkg.com/cspell-dict-java/-/cspell-dict-java-1.0.14.tgz#7a5449730b81c69ed29e7142af8a3d3b486dbcbb" - integrity sha512-PemBu/fl4o6PSygaQWYU+ioaLV5qgiBxc0YdqFC2Rxo5g9B6S1yVwf4Vgs+jEJq40gN6I2G/JMw2WlrYj4h4gw== - dependencies: - configstore "^5.0.1" - -cspell-dict-latex@^1.0.15: - version "1.0.15" - resolved "https://registry.yarnpkg.com/cspell-dict-latex/-/cspell-dict-latex-1.0.15.tgz#a74198565dd4eda349382cfbc51f7e30b1a38bed" - integrity sha512-4vHniog3px2qMYIYuCKY55eYoAV9xIUsWsUHrOpT+rqmibZijYH0RnST2ZZ2Q9b0gr9C5TSUHVBBSCeRL3dxbA== - dependencies: - configstore "^5.0.1" - -cspell-dict-lorem-ipsum@^1.0.14: - version "1.0.14" - resolved "https://registry.yarnpkg.com/cspell-dict-lorem-ipsum/-/cspell-dict-lorem-ipsum-1.0.14.tgz#81603b6c074abc0211e789ce9318c42485ad508e" - integrity sha512-4xI3naVG8TnNdF23ElLH91KHO/msdiMS7kUCjguD5NNTOOwUiTxqW8YShMzEXQ7YOsXBCqQi7LstFjgEnV84Ow== - dependencies: - configstore "^5.0.1" - -cspell-dict-lua@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/cspell-dict-lua/-/cspell-dict-lua-1.0.10.tgz#5293172675c5bb92d25396a850ad66f124ac7247" - integrity sha512-+21ca6nsLgLVg/s9GNnsuhEV0JgmkMFXqcV2lvBnTo1NeqPB6CwrcHU2d5OzB6Nnp0M4AbyL727C1EFuX5zLLA== - dependencies: - configstore "^5.0.1" - -cspell-dict-node@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/cspell-dict-node/-/cspell-dict-node-1.0.3.tgz#5d871b811c315b74fc6aa47df5fb55a4708a205c" - integrity sha512-LoSBB63YWIFL6BMpikSHlQ8VILucUpvDAHjFHIKppFpoczK8iubejvBmemDWLMdtEyUKo7sSIrEH4eVojQEHUA== +cspell-dict-csharp@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cspell-dict-csharp/-/cspell-dict-csharp-1.0.6.tgz#6e3dfc77498ab1313469f390000d1bb90c9e396a" + integrity sha512-j/no5CTqhmLh9D23SgtYSS4Nr/k82yOn/+NjIqr6mE2Z57w4vgDxLmfiE7MocDvZGczBkAiHtOgrXLDkOzIkSA== dependencies: configstore "^5.0.0" -cspell-dict-npm@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/cspell-dict-npm/-/cspell-dict-npm-1.0.5.tgz#a4f11b4b1919479607b56251079c9620298a55a1" - integrity sha512-gdEf1obAPnWC9fzU99nCFEV3UGVZ2FSbbsh15hvv9VHe/w5n5RaxQGsd4dDvjdHTYqsRimjX15ppuJb7xjN93Q== +cspell-dict-css@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cspell-dict-css/-/cspell-dict-css-1.0.6.tgz#3a46feedd3bc386f663621d05d1fbb25f01d1eab" + integrity sha512-Io1X4PMdOpY7NVL0fu9uw1NQu9VF4I9ONI1L7t/5Hu19WcljmSTJL7rxKlwqUc4qQ91ICnZwPJ5lztNfcWYe+w== dependencies: configstore "^5.0.0" -cspell-dict-php@^1.0.15: - version "1.0.15" - resolved "https://registry.yarnpkg.com/cspell-dict-php/-/cspell-dict-php-1.0.15.tgz#f8273048958eaa110e4fdfdef0a7f12c654be77d" - integrity sha512-WDUnTV7jje/Ksl3gtaO7ffiB+LW9Ji9bnq0AvD6iOFOeYcrHjZS9t+23b+oP7mRCdXeGv1/AKtchEMY10iyxBA== +cspell-dict-django@^1.0.21: + version "1.0.21" + resolved "https://registry.yarnpkg.com/cspell-dict-django/-/cspell-dict-django-1.0.21.tgz#da3a9539e1af7b962a97a1430b6eb90263879c4f" + integrity sha512-wUlSbFC5CDYw+2+oGkgn/hI356LK2Q/K6h6GOBHTKGCNm0K6Pqrb0/LUKSC2CmZ/FvnAbuz3A6298ZVzQ5INAg== dependencies: configstore "^5.0.1" -cspell-dict-powershell@^1.0.8: +cspell-dict-dotnet@^1.0.20: + version "1.0.20" + resolved "https://registry.yarnpkg.com/cspell-dict-dotnet/-/cspell-dict-dotnet-1.0.20.tgz#f033a535d6663a018b1c65dbf4ca3eb19e17d5fa" + integrity sha512-+h73Kvr6/w+jRp/6yHDqkV0lIr4HaVfDwVGqbVeefO+VkAass94CYAuu78HvmgvwovsyEpym0JJDMnftZA4o5A== + dependencies: + configstore "^5.0.1" + +cspell-dict-elixir@^1.0.19: + version "1.0.19" + resolved "https://registry.yarnpkg.com/cspell-dict-elixir/-/cspell-dict-elixir-1.0.19.tgz#45faa865792f7021071a06c7f3fd50e29af69f65" + integrity sha512-1NtCgvykvAvzXKunQvaZ8UPTkgPFnYyu5thfayWgJXv1PkHtM2TlrwLqypkskj1z8uWDTtQqHH2DES8OOb2Qeg== + dependencies: + configstore "^5.0.1" + +cspell-dict-en-gb@^1.1.24: + version "1.1.24" + resolved "https://registry.yarnpkg.com/cspell-dict-en-gb/-/cspell-dict-en-gb-1.1.24.tgz#b8322f036aa280037e85033eb59639cc50c4e7d0" + integrity sha512-fF+doyWNV039760WY08aYcTFfLyPo6BSwXN8gWsPWAc17f0uKI2EGEhF8IrR/kTIqdwyt9tRiZdYNZM7suTPKg== + dependencies: + configstore "^5.0.1" + +cspell-dict-en_us@^1.2.34: + version "1.2.34" + resolved "https://registry.yarnpkg.com/cspell-dict-en_us/-/cspell-dict-en_us-1.2.34.tgz#27b89a0e120a894ee24f7a7282345bec1765e9be" + integrity sha512-BCiAotkU19/a/FJrhfs3C8c16k6QPGb+KIpQ/sJZQFVTI69nxgGvZ3yidBWS+fo1Q4UDx3atiNEE/cmcY6uZAw== + dependencies: + configstore "^5.0.1" + +cspell-dict-filetypes@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/cspell-dict-filetypes/-/cspell-dict-filetypes-1.1.1.tgz#be05b6a28e1ec90d421e73e26f30a905a491e6c3" + integrity sha512-X313greGPD/2orACD+x86W6rS+C99voSkm4wwbg6ZxmTGPlNV+hTLmY1jgHsjrE3nzL2Uz1//+N+BE6kzQKguQ== + dependencies: + configstore "^5.0.0" + +cspell-dict-fonts@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/cspell-dict-fonts/-/cspell-dict-fonts-1.0.9.tgz#49bf0f796f881f11ffcac07d748b5ba7e8235412" + integrity sha512-tm1VxbWEl08p6TcTZqkB3RbIDJjEHgR4Hs0OmGnX8rASgOw1ogcWWMmTCjE+mxcxmY5zcf0F9Vn8BmEvIwdqog== + dependencies: + configstore "^5.0.1" + +cspell-dict-fullstack@^1.0.32: + version "1.0.32" + resolved "https://registry.yarnpkg.com/cspell-dict-fullstack/-/cspell-dict-fullstack-1.0.32.tgz#8f547d1b78aff0c7ca4c6386db3032bdeb2b94c4" + integrity sha512-rC0ae/iDI7cYsxNbYjSgrP8s4wye5NxLHsJSR4GBFO5tlDejHPCVzQO04bRcrrz+vkYk74rVQ0nJ2s67dgXv1g== + dependencies: + configstore "^5.0.1" + +cspell-dict-golang@^1.1.20: + version "1.1.20" + resolved "https://registry.yarnpkg.com/cspell-dict-golang/-/cspell-dict-golang-1.1.20.tgz#0544c6932094335a4a37288cfeb830dbc0372800" + integrity sha512-9pdJgWTH5TZpZoxcMksJ2dS3EyD0Ur5sHCEMVnDEfA3EU7dZSiNB+uQQET5aGJGupmSJzLrs0Kc9upS1BZzq1w== + dependencies: + configstore "^5.0.1" + +cspell-dict-haskell@^1.0.8: version "1.0.8" - resolved "https://registry.yarnpkg.com/cspell-dict-powershell/-/cspell-dict-powershell-1.0.8.tgz#d3b9afbc3ae449086f8cd453e082a01a1d511f0d" - integrity sha512-Kjcx8XeqBoPaCVg/tbaeIImdLwlScpV9FEakV0ZBDqY2FOh6Wle6wYXVcz77+6EK6ChhS+WTqeoo6ft+oQ3c3A== + resolved "https://registry.yarnpkg.com/cspell-dict-haskell/-/cspell-dict-haskell-1.0.8.tgz#82b1fcc50ce5d35eb7c74c174a3a52f7a8c8a49d" + integrity sha512-JnTbTX4kZGtV7w2wFNWeR+2JlbE/PW7IDeYjJFG+sX9RXcV32MUM4WkV8L4Ucx7GQpSiJOXp1gVyqWrZOvr3Hg== dependencies: configstore "^5.0.1" -cspell-dict-python@^1.0.23: - version "1.0.23" - resolved "https://registry.yarnpkg.com/cspell-dict-python/-/cspell-dict-python-1.0.23.tgz#c8ebbf4fb892bf66483e9b8ff1e1a4a387825a8f" - integrity sha512-nO3boMGkoKbek7LCrz75ZwBJmSOasS9bbhCIYkE9VA8hSr4aempKqCXaI/D4cykIOdBX6H8nvbyXyXxgHBmFLw== +cspell-dict-html-symbol-entities@^1.0.19: + version "1.0.19" + resolved "https://registry.yarnpkg.com/cspell-dict-html-symbol-entities/-/cspell-dict-html-symbol-entities-1.0.19.tgz#dc65ecdfffb847fb0cd6f3c61bd822f117cc7fc7" + integrity sha512-+L2whNDxODc8F3Pjomm6cr+T2rWtC24Aiemkt9ZWe1Jh8BnTQeYMF1oWgMTmiuEPF5rEGlhXADbNfyrSNJI11Q== dependencies: configstore "^5.0.1" -cspell-dict-ruby@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cspell-dict-ruby/-/cspell-dict-ruby-1.0.6.tgz#09bc56863f4430087ad1777dfc62ab2ff8e599ca" - integrity sha512-KJp1aD6hck+e03Kp3cq1mc4crPya0a+9MFgD+KTuca0cQ8S9KbwB1/s9BylGifedsb41q3gVFmxavdDAxrigTg== +cspell-dict-html@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/cspell-dict-html/-/cspell-dict-html-1.1.1.tgz#c83f13ada9c484e33153e985637d10ddad8a2831" + integrity sha512-v2Lu7M3K7QcW/2A6PCI04IOW/w6MeuuoukYuFxaBKtHW/PWjhjO0PJaGf/XAtccGed+U+2ppSGLL57YREwPMnw== dependencies: - configstore "^5.0.1" + configstore "^5.0.0" -cspell-dict-rust@^1.0.14: - version "1.0.14" - resolved "https://registry.yarnpkg.com/cspell-dict-rust/-/cspell-dict-rust-1.0.14.tgz#58bd526599fd5e77d0527ababebba75f45988247" - integrity sha512-dLQwl0JCbXJLGegETNBS1QejW/pNkZf4vCeUwChmLRxciESm61QXYFObks1VE4/h8ayxybdN/mfvLMHOFCmhgA== - dependencies: - configstore "^5.0.1" - -cspell-dict-scala@^1.0.13: - version "1.0.13" - resolved "https://registry.yarnpkg.com/cspell-dict-scala/-/cspell-dict-scala-1.0.13.tgz#ae040b008cc84646799368fa9d4c5a85f04a013f" - integrity sha512-Z4vode68Tl8W1oD8xbkcWa3+Z6UmbLK+CPbYODLpilojtgq6sPdNN6wL9N1bN4NdJ4hUupoU/ZS3xLi+fxL+Eg== - dependencies: - configstore "^5.0.1" - -cspell-dict-software-terms@^1.0.18: +cspell-dict-java@^1.0.18: version "1.0.18" - resolved "https://registry.yarnpkg.com/cspell-dict-software-terms/-/cspell-dict-software-terms-1.0.18.tgz#7a4651d8d758a31da831a477772f5c2d828c6248" - integrity sha512-vi3DPagUre2hyQ6n+pTpOe2HLJlIBWaaazKyHG+/KSWH7pkxQHYvic7bRM6W6enDs5hBQIzBSnxKqaGhbleGDA== + resolved "https://registry.yarnpkg.com/cspell-dict-java/-/cspell-dict-java-1.0.18.tgz#2330499e601f117694f850f7b788691900faf25b" + integrity sha512-wy8BXuV0g4/OHdrOyIpzQL3DfjLRHKwA7S6CCHTAe3EWqLzE3HCOIgfyat/6gxJu8K8GXJ2A3IqFnIXy+wLB1Q== dependencies: configstore "^5.0.1" -cspell-dict-typescript@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/cspell-dict-typescript/-/cspell-dict-typescript-1.0.11.tgz#3c9bf77efb342befe0bfb0f86f30cf0cb0bd0982" - integrity sha512-w6IUN6jVrW8SsPT8I9isFD9Tca3qRGegk63+SJZrtgAe9gM6c/HKz34VmS0cYhoZRtCFOuWuNXVFW96mSrErWw== +cspell-dict-latex@^1.0.19: + version "1.0.19" + resolved "https://registry.yarnpkg.com/cspell-dict-latex/-/cspell-dict-latex-1.0.19.tgz#c7a441b312fc90b82ebb0e0c50eb35a14505de03" + integrity sha512-wjFkbEMCrNANN1XZiBn45yngrqCOkwD7Mha4Un7J1FbYI6fVGX1/+TCcwhMeTvJ+mhOo8VIZUazSm8+pPuOJqQ== + dependencies: + configstore "^5.0.1" + +cspell-dict-lorem-ipsum@^1.0.18: + version "1.0.18" + resolved "https://registry.yarnpkg.com/cspell-dict-lorem-ipsum/-/cspell-dict-lorem-ipsum-1.0.18.tgz#7f16bf50f93b343c12b9ecbeeeaca3b73da8214b" + integrity sha512-fTTEhFktvYG1l6x/pss/i/2DX3XdYk/cLUGUpIjvOe6KpfX7Wk6rnYNyazK3fR2CteRrktsvCPbOqroHYHmfYQ== + dependencies: + configstore "^5.0.1" + +cspell-dict-lua@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/cspell-dict-lua/-/cspell-dict-lua-1.0.12.tgz#6c3f5d6492ebd27debbe00eb5ece9baa10f3b6a0" + integrity sha512-UmXMehOeWXNB7rzZopx0MO1bf8OXsT9ttSfAKklJWZHJrb6/qbGbJ5RDYNuyv7xZvpoMKNZcRJvxup1p3u0aeg== + dependencies: + configstore "^5.0.1" + +cspell-dict-node@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/cspell-dict-node/-/cspell-dict-node-1.0.5.tgz#8922bcb4bec86f67a1d8b84ed16823deba059c3d" + integrity sha512-oNUO0QHm7N/sqWvgh1RIJf/rOlCFfyBGRmK2ecr9lBtt8DhZ+/BU9RM/ZzVuLY69YdZH0Ghjt4+9LGYpd+x3/w== + dependencies: + configstore "^5.0.0" + +cspell-dict-npm@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cspell-dict-npm/-/cspell-dict-npm-1.0.6.tgz#03be3260fd883c7d47bb13404e768f222b01be27" + integrity sha512-nyRUfFQIOgMcmkKZeZuNTVUaJj8mozZXYtd+O3f+SRzEj3zhzSeubenoBfQsEg5naNi3bqEsqKjej83bopRdaQ== + dependencies: + configstore "^5.0.0" + +cspell-dict-php@^1.0.19: + version "1.0.19" + resolved "https://registry.yarnpkg.com/cspell-dict-php/-/cspell-dict-php-1.0.19.tgz#6bfae10f2c413106450a4d12da429cd37a9343eb" + integrity sha512-3LSHgtOFVO0lnUIMnOVWeX/rPoK/trOo6TVEIyottKCdB58SCf1/E/Vw+EhLDolvgvVg5qqjTBf4sx8OXI/hCg== + dependencies: + configstore "^5.0.1" + +cspell-dict-powershell@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/cspell-dict-powershell/-/cspell-dict-powershell-1.0.10.tgz#9d38a519960cb49d14afc0297fa7e6ffa4e5e1cd" + integrity sha512-BwY5UiqwIaHz5WjoXnIp53y6xKCbbihewWTYRZjRsYl0MvfiKnZ1wUQWa8DW/W5gKs+OifYSulgmLWy6N4pYug== + dependencies: + configstore "^5.0.1" + +cspell-dict-python@^1.0.27: + version "1.0.27" + resolved "https://registry.yarnpkg.com/cspell-dict-python/-/cspell-dict-python-1.0.27.tgz#8539f7241ca01cf702d15b273b1811efd4100a06" + integrity sha512-VHGa7O9RhJd3Ke2eDmMbzzoU6mDsoXPN24YrfXzcJ3OVEPC2giR42KQIn3Iq2JzEMRBQuOMloSlf4w+0KtPOOg== + dependencies: + configstore "^5.0.1" + +cspell-dict-ruby@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/cspell-dict-ruby/-/cspell-dict-ruby-1.0.8.tgz#a55676f8cb88c0b6265ee8b17fc9d86474d3e11d" + integrity sha512-Z/OJce6A5XbwOM2LL8HUkJP8wPNCKRNf2SzyfHqPTUYHfPpyE7MWFLTKxiZWZ6h9J/tfUyjFnyoAD3GxpjFQ3Q== + dependencies: + configstore "^5.0.1" + +cspell-dict-rust@^1.0.18: + version "1.0.18" + resolved "https://registry.yarnpkg.com/cspell-dict-rust/-/cspell-dict-rust-1.0.18.tgz#ec79f64ee4beed88f397e4b3c6c81748a449ab04" + integrity sha512-Jolr/EDhRYHWedTJ6lZmAozi2uojzv3dCyBvkOB0j6RftlVH0Y6NlPCy593KRLgDES3kmtQCXIJCNj1orIj0PA== + dependencies: + configstore "^5.0.1" + +cspell-dict-scala@^1.0.17: + version "1.0.17" + resolved "https://registry.yarnpkg.com/cspell-dict-scala/-/cspell-dict-scala-1.0.17.tgz#d35350edd9909f7520c7b2b6f77543246b9a756d" + integrity sha512-ULwdZtIRxxJ8SXxfCbteMstKqs+9HIZC25u2oWwLZmK6fdOGcVE4Z/19tz3vEXeGHOg6rqQVcjAcM5BdaNSHsA== + dependencies: + configstore "^5.0.1" + +cspell-dict-software-terms@^1.0.19: + version "1.0.19" + resolved "https://registry.yarnpkg.com/cspell-dict-software-terms/-/cspell-dict-software-terms-1.0.19.tgz#6d8f4b7b07896432c3952c5ed94c02bfeaa099d7" + integrity sha512-Q1QSDZ63kkStP1rUgGw9fjfXZ6gyinRoJKNX3nu7o7W/D6u2+ZOz7UMo/Vahu7+zqVKZ/7mxtNjJcbVhhPBMgA== + dependencies: + configstore "^5.0.1" + +cspell-dict-typescript@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/cspell-dict-typescript/-/cspell-dict-typescript-1.0.12.tgz#4b102c9c6237217aeddb8099964c6ac12d82a1e0" + integrity sha512-EvqdZEbsmEdCR3svx5/HqGHZdYipg31BZeXKJ63mQ3+/cf3RCOMAbKDuvyGcJFpMS87LUr5vBA5sj0Aiaz3MLQ== dependencies: configstore "^5.0.1" @@ -2682,57 +2682,57 @@ cspell-glob@^0.1.21: dependencies: micromatch "^4.0.2" -cspell-io@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/cspell-io/-/cspell-io-4.1.1.tgz#81b6574564d86c62966ad2a18c273f1454d24b7b" - integrity sha512-KCdjroahNSQRrev06As05tF/tQ93EwVb06ziCKpEYI7kBt+ZpN3+vqYxJh9pj8TQs52TvZFhNVySR9NS9aDb2g== +cspell-io@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/cspell-io/-/cspell-io-4.1.2.tgz#1683cbac336a84187e67bd5f34bd0deb96cfa563" + integrity sha512-FLLojKoCweQPYJBsze9KS9wNI8Cvvp84Zt/pwgNdkiqxPADZEsymIZ8U4xFdL3L+/k+LT2KhJZzxjeTI6/zsNA== dependencies: iconv-lite "^0.6.2" iterable-to-stream "^1.0.1" -cspell-lib@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/cspell-lib/-/cspell-lib-4.3.0.tgz#f2285613909b6eaa976efd190c2f3036cd6b7cf7" - integrity sha512-TkL7nPGOEHeBlPE6t4I2xJYlrPfw5IjpjWzXFkDFV0EWLDjgXZCHReUPjAqsAfkX98U5qXRVx7z7EsGK4fKREA== +cspell-lib@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/cspell-lib/-/cspell-lib-4.3.2.tgz#f1071322b26b4c9ae10c10802b108d01201b4b2a" + integrity sha512-d794ObE18mVblT6DSgvvaFaonkvNv4+HmBnR6IALZxd0AsS8AGxZ33t4o9mgcymiATvAzrZvG0u2zL0/onhNhw== dependencies: comment-json "^4.1.0" configstore "^5.0.1" - cspell-dict-aws "^1.0.7" - cspell-dict-bash "^1.0.5" - cspell-dict-companies "^1.0.30" - cspell-dict-cpp "^1.1.29" - cspell-dict-cryptocurrencies "^1.0.4" - cspell-dict-csharp "^1.0.3" - cspell-dict-css "^1.0.5" - cspell-dict-django "^1.0.17" - cspell-dict-dotnet "^1.0.16" - cspell-dict-elixir "^1.0.15" - cspell-dict-en-gb "^1.1.20" - cspell-dict-en_us "^1.2.30" - cspell-dict-filetypes "^1.0.3" - cspell-dict-fonts "^1.0.7" - cspell-dict-fullstack "^1.0.31" - cspell-dict-golang "^1.1.16" - cspell-dict-haskell "^1.0.6" - cspell-dict-html "^1.1.0" - cspell-dict-html-symbol-entities "^1.0.15" - cspell-dict-java "^1.0.14" - cspell-dict-latex "^1.0.15" - cspell-dict-lorem-ipsum "^1.0.14" - cspell-dict-lua "^1.0.10" - cspell-dict-node "^1.0.3" - cspell-dict-npm "^1.0.5" - cspell-dict-php "^1.0.15" - cspell-dict-powershell "^1.0.8" - cspell-dict-python "^1.0.23" - cspell-dict-ruby "^1.0.6" - cspell-dict-rust "^1.0.14" - cspell-dict-scala "^1.0.13" - cspell-dict-software-terms "^1.0.18" - cspell-dict-typescript "^1.0.11" - cspell-io "^4.1.1" + cspell-dict-aws "^1.0.9" + cspell-dict-bash "^1.0.7" + cspell-dict-companies "^1.0.31" + cspell-dict-cpp "^1.1.33" + cspell-dict-cryptocurrencies "^1.0.6" + cspell-dict-csharp "^1.0.6" + cspell-dict-css "^1.0.6" + cspell-dict-django "^1.0.21" + cspell-dict-dotnet "^1.0.20" + cspell-dict-elixir "^1.0.19" + cspell-dict-en-gb "^1.1.24" + cspell-dict-en_us "^1.2.34" + cspell-dict-filetypes "^1.1.1" + cspell-dict-fonts "^1.0.9" + cspell-dict-fullstack "^1.0.32" + cspell-dict-golang "^1.1.20" + cspell-dict-haskell "^1.0.8" + cspell-dict-html "^1.1.1" + cspell-dict-html-symbol-entities "^1.0.19" + cspell-dict-java "^1.0.18" + cspell-dict-latex "^1.0.19" + cspell-dict-lorem-ipsum "^1.0.18" + cspell-dict-lua "^1.0.12" + cspell-dict-node "^1.0.5" + cspell-dict-npm "^1.0.6" + cspell-dict-php "^1.0.19" + cspell-dict-powershell "^1.0.10" + cspell-dict-python "^1.0.27" + cspell-dict-ruby "^1.0.8" + cspell-dict-rust "^1.0.18" + cspell-dict-scala "^1.0.17" + cspell-dict-software-terms "^1.0.19" + cspell-dict-typescript "^1.0.12" + cspell-io "^4.1.2" cspell-trie-lib "^4.2.2" - cspell-util-bundle "^4.1.2" + cspell-util-bundle "^4.1.4" fs-extra "^9.0.1" gensequence "^3.1.1" minimatch "^3.0.4" @@ -2746,21 +2746,21 @@ cspell-trie-lib@^4.2.2: dependencies: gensequence "^3.1.1" -cspell-util-bundle@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/cspell-util-bundle/-/cspell-util-bundle-4.1.2.tgz#9437df20cca3e72b147098eb33bde85a26d3a394" - integrity sha512-PozIUa5aWGED09nTOTxGdPULtKnYgIDZ6JjflqAaEeeMnIKWD+w0XkIiiMTpqOszZT2CbzyI7VJZGUr8x5sopQ== +cspell-util-bundle@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/cspell-util-bundle/-/cspell-util-bundle-4.1.4.tgz#82f758b39572579b08d97aa1d9eedfd2c56f84d3" + integrity sha512-97TZTl3lqrKYVu63mf9FdekbqH6CYHRka4nUbRN0mm9bOv4L68ZE2k/DwcRuqWz7Rrc190oKOWV7USVZutgAeQ== -cspell@4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/cspell/-/cspell-4.1.3.tgz#ba316864e65fdad5efb0ef64277630d75ef9570e" - integrity sha512-xOoNMswrkubBlGnVs0xcVOjRGLovKYf1y1vtZOUcnGooGTxX7whBkpd02QSTJttDrwPugR/LbuPD7z25gm6fFw== +cspell@4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/cspell/-/cspell-4.1.5.tgz#cec599568898ccc401b3564dcdcacc8e519b9c2a" + integrity sha512-KIVZzQAMtSVsYGeFP5ljXPgbMor1jR49sVkSEHH2MdGFegTyMJZEVkgcwu7pTS0VRI+6O2k06/K3AKOJeK4WSg== dependencies: chalk "^4.1.0" commander "^6.1.0" comment-json "^4.0.6" cspell-glob "^0.1.21" - cspell-lib "^4.3.0" + cspell-lib "^4.3.2" fs-extra "^9.0.1" gensequence "^3.1.1" get-stdin "^8.0.0" From b7dcd9e633ddbf35dd84ecd51ebcf2ecb11ff4db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Nov 2020 15:14:50 +0800 Subject: [PATCH 007/299] Build(deps): Bump @angular/compiler from 10.2.2 to 10.2.3 (#9631) Bumps [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) from 10.2.2 to 10.2.3. - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular/commits/10.2.3/packages/compiler) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index c61a6bd75..42e73e81e 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "bin" ], "dependencies": { - "@angular/compiler": "10.2.2", + "@angular/compiler": "10.2.3", "@babel/code-frame": "7.10.4", "@babel/parser": "7.12.5", "@glimmer/syntax": "0.63.4", diff --git a/yarn.lock b/yarn.lock index 6976a6a46..bc523369e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@angular/compiler@10.2.2": - version "10.2.2" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-10.2.2.tgz#020377613e23c03448483be304018ab3ebf549fb" - integrity sha512-62wb/aj8ORaUyVcI6cxf07gBc3/hb+bVGl9Yni51e8//G2W7gleyQAXtIeZsT9NHi0KX1nKdXvUVwAoq4u7eHw== +"@angular/compiler@10.2.3": + version "10.2.3" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-10.2.3.tgz#4f2a42d1b479d323118fe33e1e62594d029ed5f9" + integrity sha512-Bg+QbyvJVlfGQpJCagEMkkqoRi2LMQc8iuu+cVYVqQOETLO0LxmkPpMQ/7pRLTNWl36PoYEB7IjUkp+qng8xKg== dependencies: tslib "^2.0.0" From dcbad8a83986604857689f1e0b6bdfd7e0cabbd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Nov 2020 08:06:50 +0000 Subject: [PATCH 008/299] Build(deps-dev): Bump @glimmer/reference from 0.62.4 to 0.63.4 (#9634) --- package.json | 2 +- yarn.lock | 50 +++++++++++++++++--------------------------------- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index 42e73e81e..c52695502 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "@babel/core": "7.12.3", "@babel/preset-env": "7.12.1", "@babel/types": "7.12.6", - "@glimmer/reference": "0.62.4", + "@glimmer/reference": "0.63.4", "@rollup/plugin-alias": "3.1.1", "@rollup/plugin-babel": "5.2.1", "@rollup/plugin-commonjs": "16.0.0", diff --git a/yarn.lock b/yarn.lock index bc523369e..7ad29d7d8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -894,20 +894,13 @@ resolved "https://registry.yarnpkg.com/@glimmer/env/-/env-0.1.7.tgz#fd2d2b55a9029c6b37a6c935e8c8871ae70dfa07" integrity sha1-/S0rVakCnGs3psk16MiHGucN+gc= -"@glimmer/global-context@0.62.4": - version "0.62.4" - resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.62.4.tgz#6b942b6ca0d23141a88fe707f7ce6bcac6709336" - integrity sha512-F1vD6+zURXOzFKYUL7Dw+zDasfYKpBWt/7GJ8lUVNJ7XOZQQOOeY8Tr29K4ZUrqu3lByTqyBR46gpE8UdbsJ2w== +"@glimmer/global-context@0.63.4": + version "0.63.4" + resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.63.4.tgz#84bb38d66274438458f222dd19d0c141d74fe036" + integrity sha512-ZffV34JdF7IMB8XNFWWTRug0IO376vrw4cd3xGGyBBPB3tuwM6HtRZ4jVv0IFHJD7zcHqbK8y+eK8BwksEpvzg== dependencies: "@glimmer/env" "^0.1.7" -"@glimmer/interfaces@0.62.4": - version "0.62.4" - resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.62.4.tgz#e9027d637a0ea80522f29a241aa819e686c623ae" - integrity sha512-x3L9YUL17fRgxFrnUvUYTxgnLoh8BipdqkweUEVA5qdIa1dcidUzHUFtWgRiWZ+dKCJBtxh2ubEwjOfgobpMuQ== - dependencies: - "@simple-dom/interface" "^1.4.0" - "@glimmer/interfaces@0.63.4": version "0.63.4" resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.63.4.tgz#b375b4346b3d67a17a45825a9c90367d2bf167d4" @@ -915,16 +908,16 @@ dependencies: "@simple-dom/interface" "^1.4.0" -"@glimmer/reference@0.62.4": - version "0.62.4" - resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.62.4.tgz#50dbd0d202ca94f73bbcdfe19ce450ca5c6babdc" - integrity sha512-oabqcfZrMB8FoVLZqqD4w0cUcWt1/d8uBGtXKGGNLkrV2smPFJO/rcfFpZq8alMgzqII5F9Q57gRL+qh0AD8og== +"@glimmer/reference@0.63.4": + version "0.63.4" + resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.63.4.tgz#3389d74835c10c6df0b7ae223c2f27ac35f44b3f" + integrity sha512-4JAWgPXxlD/DCJ2p99e+OPNwEg/FXquv+gk2LXWXzAPb9u5o0GlNaI3liaaC8EB71Mo/+8/8Dx90MsgSRAjNIg== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.62.4" - "@glimmer/interfaces" "0.62.4" - "@glimmer/util" "0.62.4" - "@glimmer/validator" "0.62.4" + "@glimmer/global-context" "0.63.4" + "@glimmer/interfaces" "0.63.4" + "@glimmer/util" "0.63.4" + "@glimmer/validator" "0.63.4" "@glimmer/syntax@0.63.4": version "0.63.4" @@ -936,15 +929,6 @@ "@handlebars/parser" "^1.1.0" simple-html-tokenizer "^0.5.10" -"@glimmer/util@0.62.4": - version "0.62.4" - resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.62.4.tgz#2e33dd2a8e3e81f5ffc8325fdc9bebb0e274c421" - integrity sha512-7x04I4mQpxveAoEbpFfXFFkYpuJoATHuGdwPjgcQc0nSjAkGDkzIMlRN3stgZAz32eSVj9n7SOXHVtHEhw3cCg== - dependencies: - "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.62.4" - "@simple-dom/interface" "^1.4.0" - "@glimmer/util@0.63.4": version "0.63.4" resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.63.4.tgz#e051a5b03eb5a04a58a9d393fcd37f25b533c2ab" @@ -954,13 +938,13 @@ "@glimmer/interfaces" "0.63.4" "@simple-dom/interface" "^1.4.0" -"@glimmer/validator@0.62.4": - version "0.62.4" - resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.62.4.tgz#80570d3fbf9c9a9e6a50e5c022a073da24d14d85" - integrity sha512-yZ3cfvbW/S3kAu/EDFCxqMrOp4lWiZ5QxKiDej+GVkuz8yirYVBkf1vZnxogmDyCWLZGvmTr/7QimvQZSHQxVw== +"@glimmer/validator@0.63.4": + version "0.63.4" + resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.63.4.tgz#703b4b6011ca41e1b2c7624baf457ad4af7e97d7" + integrity sha512-LCaA/lIPDh0yRN7lrBEmvJAZEq32KdMHdKXO4QPU4pEx05JGNxeIvp/WPjxz6MWTydbuCnupu5dKunAx2Pc4xQ== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.62.4" + "@glimmer/global-context" "0.63.4" "@handlebars/parser@^1.1.0": version "1.1.0" From 13c88511da5cd4cba2df40d66b62ea05c4464314 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Wed, 11 Nov 2020 10:02:47 +0800 Subject: [PATCH 009/299] Refactor: Add `getCallArguments` and `iterateCallArgumentsPath` (#9608) --- src/language-js/print/call-arguments.js | 26 ++++++++-------------- src/language-js/printer-estree.js | 16 +++++++------- src/language-js/utils.js | 29 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/language-js/print/call-arguments.js b/src/language-js/print/call-arguments.js index e36d2d694..0561f1b8b 100644 --- a/src/language-js/print/call-arguments.js +++ b/src/language-js/print/call-arguments.js @@ -15,6 +15,8 @@ const { isJSXNode, isLongCurriedCallExpression, shouldPrintComma, + getCallArguments, + iterateCallArgumentsPath, } = require("../utils"); const { locEnd } = require("../loc"); @@ -36,8 +38,8 @@ const { function printCallArguments(path, options, print) { const node = path.getValue(); const isDynamicImport = node.type === "ImportExpression"; - const args = isDynamicImport ? [node.source] : node.arguments; + const args = getCallArguments(node); if (args.length === 0) { return concat([ "(", @@ -94,7 +96,8 @@ function printCallArguments(path, options, print) { let shouldBreakForArrowFunction = false; let hasEmptyLineFollowingFirstArg = false; const lastArgIndex = args.length - 1; - const printArgument = (argPath, index) => { + const printedArguments = []; + iterateCallArgumentsPath(path, (argPath, index) => { const arg = argPath.getNode(); const parts = [print(argPath)]; @@ -116,11 +119,8 @@ function printCallArguments(path, options, print) { argPath ); - return concat(parts); - }; - const printedArguments = isDynamicImport - ? [path.call((path) => printArgument(path, 0), "source")] - : path.map(printArgument, "arguments"); + printedArguments.push(concat(parts)); + }); const maybeTrailingComma = // Dynamic imports cannot have trailing commas @@ -161,8 +161,7 @@ function printCallArguments(path, options, print) { // We want to print the last argument with a special flag let printedExpanded = []; - let i = 0; - const printArgument = (argPath) => { + iterateCallArgumentsPath(path, (argPath, i) => { if (shouldGroupFirst && i === 0) { printedExpanded = [ concat([ @@ -178,14 +177,7 @@ function printCallArguments(path, options, print) { .slice(0, -1) .concat(argPath.call((p) => print(p, { expandLastArg: true }))); } - i++; - }; - - if (isDynamicImport) { - path.call(printArgument, "source"); - } else { - path.each(printArgument, "arguments"); - } + }); const somePrintedArgumentsWillBreak = printedArguments.some(willBreak); diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index add0da277..b98856f8a 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -53,6 +53,8 @@ const { classChildNeedsASIProtection, classPropMayCauseASIProblems, getFunctionParameters, + getCallArguments, + iterateCallArgumentsPath, getLeftSidePathName, getParentExportDeclaration, getTypeScriptMappedTypeModifier, @@ -966,7 +968,7 @@ function printPathNoParens(path, options, print, args) { const isDynamicImport = n.type === "ImportExpression"; const optional = printOptionalToken(path); - const args = isDynamicImport ? [n.source] : n.arguments; + const args = getCallArguments(n); if ( // We want to keep CommonJS- and AMD-style require calls, and AMD-style // define calls, as a unit. @@ -982,18 +984,16 @@ function printPathNoParens(path, options, print, args) { // e.g. `it('long name', () => {` (!isNew && isTestCall(n, path.getParentNode())) ) { + const printed = []; + iterateCallArgumentsPath(path, (argPath) => { + printed.push(print(argPath)); + }); return concat([ isNew ? "new " : "", path.call(print, "callee"), optional, printFunctionTypeParameters(path, options, print), - concat([ - "(", - isDynamicImport - ? path.call(print, "source") - : join(", ", path.map(print, "arguments")), - ")", - ]), + concat(["(", join(", ", printed), ")"]), ]); } diff --git a/src/language-js/utils.js b/src/language-js/utils.js index d5564efba..412c5d09e 100644 --- a/src/language-js/utils.js +++ b/src/language-js/utils.js @@ -1446,6 +1446,33 @@ function iterateFunctionParametersPath(path, iteratee) { } } +const callArgumentsCache = new WeakMap(); +function getCallArguments(node) { + if (callArgumentsCache.has(node)) { + return callArgumentsCache.get(node); + } + const args = + node.type === "ImportExpression" + ? // No parser except `babel` supports `import("./foo.json", { assert: { type: "json" } })` yet, + // And `babel` parser it as `CallExpression` + // We need add the second argument here + [node.source] + : node.arguments; + + callArgumentsCache.set(node, args); + return args; +} + +function iterateCallArgumentsPath(path, iteratee) { + const node = path.getValue(); + // See comment in `getCallArguments` + if (node.type === "ImportExpression") { + path.call((sourcePath) => iteratee(sourcePath, 0), "source"); + } else { + path.each(iteratee, "arguments"); + } +} + function isPrettierIgnoreComment(comment) { return comment.value.trim() === "prettier-ignore"; } @@ -1472,6 +1499,8 @@ module.exports = { classPropMayCauseASIProblems, getFunctionParameters, iterateFunctionParametersPath, + getCallArguments, + iterateCallArgumentsPath, hasRestParameter, getLeftSidePathName, getParentExportDeclaration, From 6b9c223ced225beae4693b042fe182eb166efe55 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Wed, 11 Nov 2020 13:39:39 +0800 Subject: [PATCH 010/299] DRY `FastPath` (#9617) --- src/common/fast-path.js | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/src/common/fast-path.js b/src/common/fast-path.js index 2b14c7ff2..e2959d3af 100644 --- a/src/common/fast-path.js +++ b/src/common/fast-path.js @@ -77,7 +77,7 @@ class FastPath { } // Similar to FastPath.prototype.call, except that the value obtained by - // accessing this.getValue()[name1][name2]... should be array-like. The + // accessing this.getValue()[name1][name2]... should be array. The // callback will be called with a reference to this path object for each // element of the array. each(callback, ...names) { @@ -91,11 +91,9 @@ class FastPath { } for (let i = 0; i < value.length; ++i) { - if (i in value) { - stack.push(i, value[i]); - callback(this, i); - stack.length -= 2; - } + stack.push(i, value[i]); + callback(this, i); + stack.length -= 2; } stack.length = length; @@ -105,27 +103,10 @@ class FastPath { // callback function invocations are stored in an array and returned at // the end of the iteration. map(callback, ...names) { - const { stack } = this; - const { length } = stack; - let value = getLast(stack); - - for (const name of names) { - value = value[name]; - stack.push(name, value); - } - - const result = new Array(value.length); - - for (let i = 0; i < value.length; ++i) { - if (i in value) { - stack.push(i, value[i]); - result[i] = callback(this, i); - stack.length -= 2; - } - } - - stack.length = length; - + const result = []; + this.each((path, index) => { + result[index] = callback(path, index); + }, ...names); return result; } From 044f0f76dcbc8f81499dfd0238cc7733af82cd91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Nov 2020 05:42:10 +0000 Subject: [PATCH 011/299] Build(deps-dev): Bump babel-loader from 8.1.0 to 8.2.1 in /website (#9637) --- website/package.json | 2 +- website/yarn.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/website/package.json b/website/package.json index 5660dd285..a9c58a5ce 100644 --- a/website/package.json +++ b/website/package.json @@ -18,7 +18,7 @@ "devDependencies": { "@babel/preset-react": "7.12.5", "@sandhose/prettier-animated-logo": "1.0.3", - "babel-loader": "8.1.0", + "babel-loader": "8.2.1", "concurrently": "5.3.0", "docusaurus": "1.14.6", "js-yaml": "3.14.0", diff --git a/website/yarn.lock b/website/yarn.lock index a5cbada72..d8a0305ba 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -1525,14 +1525,14 @@ babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.2" -babel-loader@8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" - integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== +babel-loader@8.2.1: + version "8.2.1" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.1.tgz#e53313254677e86f27536f5071d807e01d24ec00" + integrity sha512-dMF8sb2KQ8kJl21GUjkW1HWmcsL39GOV5vnzjqrCzEPNY0S0UfMLnumidiwIajDSBmKhYf5iRW+HXaM4cvCKBw== dependencies: find-cache-dir "^2.1.0" loader-utils "^1.4.0" - mkdirp "^0.5.3" + make-dir "^2.1.0" pify "^4.0.1" schema-utils "^2.6.5" @@ -4867,7 +4867,7 @@ mixin-deep@^1.1.3, mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.3" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.3.tgz#5a514b7179259287952881e94410ec5465659f8c" integrity sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg== From 6854d67421fb3ee4a5b87b53bdce9679cf11ff34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Nov 2020 06:03:52 +0000 Subject: [PATCH 012/299] Build(deps): Bump @glimmer/syntax from 0.63.4 to 0.63.5 (#9640) --- package.json | 2 +- yarn.lock | 28 ++++++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index c52695502..01c730dd4 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@angular/compiler": "10.2.3", "@babel/code-frame": "7.10.4", "@babel/parser": "7.12.5", - "@glimmer/syntax": "0.63.4", + "@glimmer/syntax": "0.63.5", "@iarna/toml": "2.2.5", "@typescript-eslint/typescript-estree": "3.10.1", "angular-estree-parser": "2.2.1", diff --git a/yarn.lock b/yarn.lock index 7ad29d7d8..fe4863201 100644 --- a/yarn.lock +++ b/yarn.lock @@ -908,6 +908,13 @@ dependencies: "@simple-dom/interface" "^1.4.0" +"@glimmer/interfaces@0.63.5": + version "0.63.5" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.63.5.tgz#ac614608ea618022b61b5d09e66089ceffc26e6e" + integrity sha512-ogozdIFOSxJ2QBU2NE0pk993qbb/zY1wF4BFL1ZN2GrfDDdaYC5vmDSs+RpbbF6JAjrt4kADXlOocs7dBiX4iQ== + dependencies: + "@simple-dom/interface" "^1.4.0" + "@glimmer/reference@0.63.4": version "0.63.4" resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.63.4.tgz#3389d74835c10c6df0b7ae223c2f27ac35f44b3f" @@ -919,13 +926,13 @@ "@glimmer/util" "0.63.4" "@glimmer/validator" "0.63.4" -"@glimmer/syntax@0.63.4": - version "0.63.4" - resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.63.4.tgz#87598c50b097ff6beea4e1611549577050d922c5" - integrity sha512-ndt2ujQHe8bnwv/x8JpAEBqzWvXClqnevNqlAyywTZR4/ur0SYayFRdN9kI3qzRzX6Psc7lxCAqwp8QyKpUbiQ== +"@glimmer/syntax@0.63.5": + version "0.63.5" + resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.63.5.tgz#38ef6e41d9da3474ebc5d704c0e9743367de728e" + integrity sha512-w0/X7jQ5tzO6KevzeP1QBEfS2qjc897JlQa+9eMcFkxRxZCH4IVUjyxeRuu9cY0uV16ByVBTFh9fcGPfgaYULQ== dependencies: - "@glimmer/interfaces" "0.63.4" - "@glimmer/util" "0.63.4" + "@glimmer/interfaces" "0.63.5" + "@glimmer/util" "0.63.5" "@handlebars/parser" "^1.1.0" simple-html-tokenizer "^0.5.10" @@ -938,6 +945,15 @@ "@glimmer/interfaces" "0.63.4" "@simple-dom/interface" "^1.4.0" +"@glimmer/util@0.63.5": + version "0.63.5" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.63.5.tgz#8f2ed10269fcf6ccaf4cc0338915cc618ed845d0" + integrity sha512-9eTXOx3l6N1YySBMe1Vb/F+SGuztgObQCoEVtvxUZ7VB37xTaaUEoZfQVQJyBizFIKIAOvXBhPYCT+cERvN7kw== + dependencies: + "@glimmer/env" "0.1.7" + "@glimmer/interfaces" "0.63.5" + "@simple-dom/interface" "^1.4.0" + "@glimmer/validator@0.63.4": version "0.63.4" resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.63.4.tgz#703b4b6011ca41e1b2c7624baf457ad4af7e97d7" From f86d34ef6c4878ac444d9c8a9a7a7973d340d006 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Nov 2020 07:55:33 +0000 Subject: [PATCH 013/299] Build(deps-dev): Bump @glimmer/reference from 0.63.4 to 0.63.5 (#9639) --- package.json | 2 +- yarn.lock | 50 +++++++++++++++++--------------------------------- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index 01c730dd4..fdf11bf18 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "@babel/core": "7.12.3", "@babel/preset-env": "7.12.1", "@babel/types": "7.12.6", - "@glimmer/reference": "0.63.4", + "@glimmer/reference": "0.63.5", "@rollup/plugin-alias": "3.1.1", "@rollup/plugin-babel": "5.2.1", "@rollup/plugin-commonjs": "16.0.0", diff --git a/yarn.lock b/yarn.lock index fe4863201..b9a2738b0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -894,20 +894,13 @@ resolved "https://registry.yarnpkg.com/@glimmer/env/-/env-0.1.7.tgz#fd2d2b55a9029c6b37a6c935e8c8871ae70dfa07" integrity sha1-/S0rVakCnGs3psk16MiHGucN+gc= -"@glimmer/global-context@0.63.4": - version "0.63.4" - resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.63.4.tgz#84bb38d66274438458f222dd19d0c141d74fe036" - integrity sha512-ZffV34JdF7IMB8XNFWWTRug0IO376vrw4cd3xGGyBBPB3tuwM6HtRZ4jVv0IFHJD7zcHqbK8y+eK8BwksEpvzg== +"@glimmer/global-context@0.63.5": + version "0.63.5" + resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.63.5.tgz#4a8da4fee97d13a376549ceecebd16a5ffc8c4f6" + integrity sha512-xYsptoxo9ROos83oxG8ZT4e8T2QgsH+FdZxsPZNTN4WLumU2LTkxJQaiosW9q294IVY/mIVhZAohJkfNCvSwug== dependencies: "@glimmer/env" "^0.1.7" -"@glimmer/interfaces@0.63.4": - version "0.63.4" - resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.63.4.tgz#b375b4346b3d67a17a45825a9c90367d2bf167d4" - integrity sha512-XpKKJVqVE9JUcAqEHUu0lwJQZnv3gHPZ93o/xDdyUqnSokipeToHJzehRrhIkknSaiKKyu624fvk0dakQaS5ow== - dependencies: - "@simple-dom/interface" "^1.4.0" - "@glimmer/interfaces@0.63.5": version "0.63.5" resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.63.5.tgz#ac614608ea618022b61b5d09e66089ceffc26e6e" @@ -915,16 +908,16 @@ dependencies: "@simple-dom/interface" "^1.4.0" -"@glimmer/reference@0.63.4": - version "0.63.4" - resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.63.4.tgz#3389d74835c10c6df0b7ae223c2f27ac35f44b3f" - integrity sha512-4JAWgPXxlD/DCJ2p99e+OPNwEg/FXquv+gk2LXWXzAPb9u5o0GlNaI3liaaC8EB71Mo/+8/8Dx90MsgSRAjNIg== +"@glimmer/reference@0.63.5": + version "0.63.5" + resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.63.5.tgz#bc99049c9400994641dea054e58bff61e1e31187" + integrity sha512-uE5O5eFcaKedomCDfendXjA7Sh9MYZG5RhadSSA8iD6TUlXxdpIe++tcRzNQOcMwHNbh+Bx7jX50jxtA1ShibQ== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.63.4" - "@glimmer/interfaces" "0.63.4" - "@glimmer/util" "0.63.4" - "@glimmer/validator" "0.63.4" + "@glimmer/global-context" "0.63.5" + "@glimmer/interfaces" "0.63.5" + "@glimmer/util" "0.63.5" + "@glimmer/validator" "0.63.5" "@glimmer/syntax@0.63.5": version "0.63.5" @@ -936,15 +929,6 @@ "@handlebars/parser" "^1.1.0" simple-html-tokenizer "^0.5.10" -"@glimmer/util@0.63.4": - version "0.63.4" - resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.63.4.tgz#e051a5b03eb5a04a58a9d393fcd37f25b533c2ab" - integrity sha512-D102O0wRdPn6KOHFZ3+GAKj+Wxaou0KMxePspu5lPD9bQYGd7z+epqpRxpYGb5vbZCg8nTT28+qUU5yMh6NpCA== - dependencies: - "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.63.4" - "@simple-dom/interface" "^1.4.0" - "@glimmer/util@0.63.5": version "0.63.5" resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.63.5.tgz#8f2ed10269fcf6ccaf4cc0338915cc618ed845d0" @@ -954,13 +938,13 @@ "@glimmer/interfaces" "0.63.5" "@simple-dom/interface" "^1.4.0" -"@glimmer/validator@0.63.4": - version "0.63.4" - resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.63.4.tgz#703b4b6011ca41e1b2c7624baf457ad4af7e97d7" - integrity sha512-LCaA/lIPDh0yRN7lrBEmvJAZEq32KdMHdKXO4QPU4pEx05JGNxeIvp/WPjxz6MWTydbuCnupu5dKunAx2Pc4xQ== +"@glimmer/validator@0.63.5": + version "0.63.5" + resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.63.5.tgz#8d196f1f29191c5ecd60ea5c87d1081f68dff840" + integrity sha512-+/YHIKrspDrqnAz4hE+VgIL2O6tZPxKA9KfI5syDcr+zxQeLjC/7ng6AK2g6+w8nHoS5WOABbA/gpH+wTV6ulQ== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.63.4" + "@glimmer/global-context" "0.63.5" "@handlebars/parser@^1.1.0": version "1.1.0" From b5aab4006d689be1fc1514bd6b056d54524b9e11 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Nov 2020 19:13:14 +0800 Subject: [PATCH 014/299] Build(deps-dev): Bump babel-loader from 8.1.0 to 8.2.1 (#9638) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index fdf11bf18..356959c6a 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "@types/node": "14.14.0", "@typescript-eslint/types": "3.10.1", "babel-jest": "26.6.3", - "babel-loader": "8.1.0", + "babel-loader": "8.2.1", "benchmark": "2.1.4", "builtin-modules": "3.1.0", "cross-env": "7.0.2", diff --git a/yarn.lock b/yarn.lock index b9a2738b0..9ee514fd6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1933,14 +1933,14 @@ babel-jest@26.6.3, babel-jest@^26.6.3: graceful-fs "^4.2.4" slash "^3.0.0" -babel-loader@8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" - integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== +babel-loader@8.2.1: + version "8.2.1" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.1.tgz#e53313254677e86f27536f5071d807e01d24ec00" + integrity sha512-dMF8sb2KQ8kJl21GUjkW1HWmcsL39GOV5vnzjqrCzEPNY0S0UfMLnumidiwIajDSBmKhYf5iRW+HXaM4cvCKBw== dependencies: find-cache-dir "^2.1.0" loader-utils "^1.4.0" - mkdirp "^0.5.3" + make-dir "^2.1.0" pify "^4.0.1" schema-utils "^2.6.5" @@ -5209,7 +5209,7 @@ magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.4" -make-dir@^2.0.0: +make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== @@ -5352,7 +5352,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.1, mkdirp@^0.5.3: +mkdirp@^0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== From 46a3213ec89784a600ef7ddf5004e03f3b7f66b1 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Fri, 13 Nov 2020 00:07:31 +0800 Subject: [PATCH 015/299] Extract `printTemplateLiteral` (#9646) --- src/language-js/print/template-literal.js | 193 ++++++++++++++++++++++ src/language-js/printer-estree.js | 172 +------------------ 2 files changed, 195 insertions(+), 170 deletions(-) create mode 100644 src/language-js/print/template-literal.js diff --git a/src/language-js/print/template-literal.js b/src/language-js/print/template-literal.js new file mode 100644 index 000000000..5be829211 --- /dev/null +++ b/src/language-js/print/template-literal.js @@ -0,0 +1,193 @@ +"use strict"; + +const { getStringWidth, getIndentSize } = require("../../common/util"); +const { + builders: { + concat, + join, + hardline, + softline, + group, + indent, + align, + lineSuffixBoundary, + addAlignmentToDoc, + }, + printer: { printDocToString }, +} = require("../../document"); +const { + isBinaryish, + isJestEachTemplateLiteral, + isSimpleTemplateLiteral, +} = require("../utils"); + +function printTemplateLiteral(path, print, options) { + const node = path.getValue(); + const parentNode = path.getParentNode(); + + if (isJestEachTemplateLiteral(node, parentNode)) { + const printed = printJestEachTemplateLiteral(path, options, print); + if (printed) { + return printed; + } + } + const parts = []; + + let expressions = path.map(print, "expressions"); + const isSimple = isSimpleTemplateLiteral(node); + + if (isSimple) { + expressions = expressions.map( + (doc) => + printDocToString(doc, { ...options, printWidth: Infinity }).formatted + ); + } + + parts.push(lineSuffixBoundary, "`"); + + path.each((childPath) => { + const i = childPath.getName(); + + parts.push(print(childPath)); + + if (i < expressions.length) { + // For a template literal of the following form: + // `someQuery { + // ${call({ + // a, + // b, + // })} + // }` + // the expression is on its own line (there is a \n in the previous + // quasi literal), therefore we want to indent the JavaScript + // expression inside at the beginning of ${ instead of the beginning + // of the `. + const { tabWidth } = options; + const quasi = childPath.getValue(); + const indentSize = getIndentSize(quasi.value.raw, tabWidth); + + let printed = expressions[i]; + + if (!isSimple) { + const expression = node.expressions[i]; + // Breaks at the template element boundaries (${ and }) are preferred to breaking + // in the middle of a MemberExpression + if ( + (expression.comments && expression.comments.length) || + expression.type === "MemberExpression" || + expression.type === "OptionalMemberExpression" || + expression.type === "ConditionalExpression" || + expression.type === "SequenceExpression" || + expression.type === "TSAsExpression" || + isBinaryish(expression) + ) { + printed = concat([indent(concat([softline, printed])), softline]); + } + } + + const aligned = + indentSize === 0 && quasi.value.raw.endsWith("\n") + ? align(-Infinity, printed) + : addAlignmentToDoc(printed, indentSize, tabWidth); + + parts.push(group(concat(["${", aligned, lineSuffixBoundary, "}"]))); + } + }, "quasis"); + + parts.push("`"); + + return concat(parts); +} + +function printJestEachTemplateLiteral(path, options, print) { + /** + * a | b | expected + * ${1} | ${1} | ${2} + * ${1} | ${2} | ${3} + * ${2} | ${1} | ${3} + */ + const node = path.getNode(); + const headerNames = node.quasis[0].value.raw.trim().split(/\s*\|\s*/); + if ( + headerNames.length > 1 || + headerNames.some((headerName) => headerName.length !== 0) + ) { + options.__inJestEach = true; + const expressions = path.map(print, "expressions"); + options.__inJestEach = false; + const parts = []; + const stringifiedExpressions = expressions.map( + (doc) => + "${" + + printDocToString(doc, { + ...options, + printWidth: Infinity, + endOfLine: "lf", + }).formatted + + "}" + ); + + const tableBody = [{ hasLineBreak: false, cells: [] }]; + for (let i = 1; i < node.quasis.length; i++) { + const row = tableBody[tableBody.length - 1]; + const correspondingExpression = stringifiedExpressions[i - 1]; + + row.cells.push(correspondingExpression); + if (correspondingExpression.includes("\n")) { + row.hasLineBreak = true; + } + + if (node.quasis[i].value.raw.includes("\n")) { + tableBody.push({ hasLineBreak: false, cells: [] }); + } + } + + const maxColumnCount = Math.max( + headerNames.length, + ...tableBody.map((row) => row.cells.length) + ); + + const maxColumnWidths = Array.from({ length: maxColumnCount }).fill(0); + const table = [ + { cells: headerNames }, + ...tableBody.filter((row) => row.cells.length !== 0), + ]; + for (const { cells } of table.filter((row) => !row.hasLineBreak)) { + cells.forEach((cell, index) => { + maxColumnWidths[index] = Math.max( + maxColumnWidths[index], + getStringWidth(cell) + ); + }); + } + + parts.push( + lineSuffixBoundary, + "`", + indent( + concat([ + hardline, + join( + hardline, + table.map((row) => + join( + " | ", + row.cells.map((cell, index) => + row.hasLineBreak + ? cell + : cell + + " ".repeat(maxColumnWidths[index] - getStringWidth(cell)) + ) + ) + ) + ), + ]) + ), + hardline, + "`" + ); + return concat(parts); + } +} + +module.exports = printTemplateLiteral; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index b98856f8a..9f6c22578 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -11,10 +11,8 @@ const { hasNewline, hasNewlineInRange, getLast, - getStringWidth, printString, printNumber, - getIndentSize, getPreferredQuote, isNextLineEmpty, getNextNonSpaceNonCommentCharacterIndex, @@ -34,10 +32,8 @@ const { fill, ifBreak, lineSuffixBoundary, - addAlignmentToDoc, }, utils: { willBreak, isLineNext, isEmpty, normalizeParts }, - printer: { printDocToString }, } = require("../document"); const embed = require("./embed"); const clean = require("./clean"); @@ -78,7 +74,6 @@ const { isFlowAnnotationComment, isFunctionNotation, isGetterOrSetter, - isJestEachTemplateLiteral, isJSXNode, isJSXWhitespaceExpression, isLastStatement, @@ -92,7 +87,6 @@ const { isObjectTypePropertyAFunction, isSimpleType, isSimpleNumber, - isSimpleTemplateLiteral, isStringLiteral, isStringPropSafeToUnquote, isTemplateOnItsOwnLine, @@ -129,6 +123,7 @@ const { printFunctionParameters, shouldHugFunctionParameters, } = require("./print/function-parameters"); +const printTemplateLiteral = require("./print/template-literal"); const needsQuoteProps = new WeakMap(); @@ -2233,79 +2228,7 @@ function printPathNoParens(path, options, print, args) { case "TemplateElement": return join(literalline, n.value.raw.split(/\r?\n/g)); case "TemplateLiteral": { - const parentNode = path.getParentNode(); - - if (isJestEachTemplateLiteral(n, parentNode)) { - const printed = printJestEachTemplateLiteral(path, options, print); - if (printed) { - return printed; - } - } - - let expressions = path.map(print, "expressions"); - const isSimple = isSimpleTemplateLiteral(n); - - if (isSimple) { - expressions = expressions.map( - (doc) => - printDocToString(doc, { ...options, printWidth: Infinity }) - .formatted - ); - } - - parts.push(lineSuffixBoundary, "`"); - - path.each((childPath) => { - const i = childPath.getName(); - - parts.push(print(childPath)); - - if (i < expressions.length) { - // For a template literal of the following form: - // `someQuery { - // ${call({ - // a, - // b, - // })} - // }` - // the expression is on its own line (there is a \n in the previous - // quasi literal), therefore we want to indent the JavaScript - // expression inside at the beginning of ${ instead of the beginning - // of the `. - const { tabWidth } = options; - const quasi = childPath.getValue(); - const indentSize = getIndentSize(quasi.value.raw, tabWidth); - - let printed = expressions[i]; - - if (!isSimple) { - // Breaks at the template element boundaries (${ and }) are preferred to breaking - // in the middle of a MemberExpression - if ( - (n.expressions[i].comments && n.expressions[i].comments.length) || - n.expressions[i].type === "MemberExpression" || - n.expressions[i].type === "OptionalMemberExpression" || - n.expressions[i].type === "ConditionalExpression" || - n.expressions[i].type === "SequenceExpression" || - n.expressions[i].type === "TSAsExpression" || - isBinaryish(n.expressions[i]) - ) { - printed = concat([indent(concat([softline, printed])), softline]); - } - } - - const aligned = - indentSize === 0 && quasi.value.raw.endsWith("\n") - ? align(-Infinity, printed) - : addAlignmentToDoc(printed, indentSize, tabWidth); - - parts.push(group(concat(["${", aligned, lineSuffixBoundary, "}"]))); - } - }, "quasis"); - - parts.push("`"); - - return concat(parts); + return printTemplateLiteral(path, print, options); } case "TaggedTemplateExpression": return concat([ @@ -3757,97 +3680,6 @@ function printMethodInternal(path, options, print) { return concat(parts); } -function printJestEachTemplateLiteral(path, options, print) { - /** - * a | b | expected - * ${1} | ${1} | ${2} - * ${1} | ${2} | ${3} - * ${2} | ${1} | ${3} - */ - const node = path.getNode(); - const headerNames = node.quasis[0].value.raw.trim().split(/\s*\|\s*/); - if ( - headerNames.length > 1 || - headerNames.some((headerName) => headerName.length !== 0) - ) { - options.__inJestEach = true; - const expressions = path.map(print, "expressions"); - options.__inJestEach = false; - const parts = []; - const stringifiedExpressions = expressions.map( - (doc) => - "${" + - printDocToString(doc, { - ...options, - printWidth: Infinity, - endOfLine: "lf", - }).formatted + - "}" - ); - - const tableBody = [{ hasLineBreak: false, cells: [] }]; - for (let i = 1; i < node.quasis.length; i++) { - const row = tableBody[tableBody.length - 1]; - const correspondingExpression = stringifiedExpressions[i - 1]; - - row.cells.push(correspondingExpression); - if (correspondingExpression.includes("\n")) { - row.hasLineBreak = true; - } - - if (node.quasis[i].value.raw.includes("\n")) { - tableBody.push({ hasLineBreak: false, cells: [] }); - } - } - - const maxColumnCount = Math.max( - headerNames.length, - ...tableBody.map((row) => row.cells.length) - ); - - const maxColumnWidths = Array.from({ length: maxColumnCount }).fill(0); - const table = [ - { cells: headerNames }, - ...tableBody.filter((row) => row.cells.length !== 0), - ]; - for (const { cells } of table.filter((row) => !row.hasLineBreak)) { - cells.forEach((cell, index) => { - maxColumnWidths[index] = Math.max( - maxColumnWidths[index], - getStringWidth(cell) - ); - }); - } - - parts.push( - lineSuffixBoundary, - "`", - indent( - concat([ - hardline, - join( - hardline, - table.map((row) => - join( - " | ", - row.cells.map((cell, index) => - row.hasLineBreak - ? cell - : cell + - " ".repeat(maxColumnWidths[index] - getStringWidth(cell)) - ) - ) - ) - ), - ]) - ), - hardline, - "`" - ); - return concat(parts); - } -} - function printTypeAnnotation(path, options, print) { const node = path.getValue(); if (!node.typeAnnotation) { From d0f813e5d432c7f3baaabc1b038d3b897567056b Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Thu, 12 Nov 2020 19:49:15 -0500 Subject: [PATCH 016/299] =?UTF-8?q?Revert=20#9011,=20don=E2=80=99t=20add?= =?UTF-8?q?=20parens=20when=20yielding=20simple=20JSX=20expressions=20(#96?= =?UTF-8?q?50)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog_unreleased/javascript/pr-9650.md | 17 +++++++++++++++++ src/language-js/needs-parens.js | 3 ++- tests/js/yield/__snapshots__/jsfmt.spec.js.snap | 4 ++-- 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 changelog_unreleased/javascript/pr-9650.md diff --git a/changelog_unreleased/javascript/pr-9650.md b/changelog_unreleased/javascript/pr-9650.md new file mode 100644 index 000000000..0cb7db6a2 --- /dev/null +++ b/changelog_unreleased/javascript/pr-9650.md @@ -0,0 +1,17 @@ +#### Fix formatting of yielded JSX expressions (#9650 by @brainkim) + + +```jsx +// Input +function* f() { + yield
generator
+} +// Prettier stable +function* f() { + yield (
generator
); +} +// Prettier master +function* f() { + yield
generator
; +} +``` diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index a30c38144..044b010ba 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -725,7 +725,8 @@ function needsParens(path, options) { parent.type !== "ReturnStatement" && parent.type !== "ThrowStatement" && parent.type !== "TypeCastExpression" && - parent.type !== "VariableDeclarator") + parent.type !== "VariableDeclarator" && + parent.type !== "YieldExpression") ); case "TypeAnnotation": return ( diff --git a/tests/js/yield/__snapshots__/jsfmt.spec.js.snap b/tests/js/yield/__snapshots__/jsfmt.spec.js.snap index a2425bb19..67e013e3b 100644 --- a/tests/js/yield/__snapshots__/jsfmt.spec.js.snap +++ b/tests/js/yield/__snapshots__/jsfmt.spec.js.snap @@ -96,7 +96,7 @@ function* f() { =====================================output===================================== function* f() { - yield (
generator
); + yield
generator
; yield (

generator

@@ -120,7 +120,7 @@ function* f() { =====================================output===================================== function* f() { - yield (
generator
); + yield
generator
; yield (

generator

From 28d914b811e085be100c1a6609d1676885d8e05b Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Fri, 13 Nov 2020 09:05:30 +0800 Subject: [PATCH 017/299] Vue: Consistent slot, support Vue3 (#9609) --- changelog_unreleased/vue/pr-9609.md | 73 ++++++++++ src/language-html/printer-html.js | 10 +- src/language-html/syntax-vue.js | 6 +- src/language-html/utils.js | 28 ++++ src/language-js/html-binding.js | 2 +- .../vue-3/__snapshots__/jsfmt.spec.js.snap | 109 +++++++++++++++ tests/vue/vue-3/jsfmt.spec.js | 1 + tests/vue/vue-3/script-setup.vue | 18 +++ tests/vue/vue-3/style-variables.vue | 18 +++ .../vue/vue/__snapshots__/jsfmt.spec.js.snap | 126 ++++++++++++++++-- tests/vue/vue/attributes.vue | 14 +- 11 files changed, 386 insertions(+), 19 deletions(-) create mode 100644 changelog_unreleased/vue/pr-9609.md create mode 100644 tests/vue/vue-3/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/vue/vue-3/jsfmt.spec.js create mode 100644 tests/vue/vue-3/script-setup.vue create mode 100644 tests/vue/vue-3/style-variables.vue diff --git a/changelog_unreleased/vue/pr-9609.md b/changelog_unreleased/vue/pr-9609.md new file mode 100644 index 000000000..b55920e4b --- /dev/null +++ b/changelog_unreleased/vue/pr-9609.md @@ -0,0 +1,73 @@ +#### Fix inconsistent formatting for slots, support Vue 3 `script[setup]` and `style[vars]` (#9609 by @fisker) + +- [SFC Composition API Syntax Sugar (` + + + + + + + + + + + + +``` diff --git a/src/language-html/printer-html.js b/src/language-html/printer-html.js index e0649c4bb..8536f98cf 100644 --- a/src/language-html/printer-html.js +++ b/src/language-html/printer-html.js @@ -36,6 +36,8 @@ const { inferScriptParser, isVueCustomBlock, isVueNonHtmlBlock, + isVueSlotAttribute, + isVueSfcBindingsAttribute, isScriptLikeTag, isTextLikeNode, preferHardlineAsLeadingSpaces, @@ -49,7 +51,7 @@ const { insertPragma } = require("./pragma"); const { locStart, locEnd } = require("./loc"); const { printVueFor, - printVueSlotScope, + printVueBindings, isVueEventBindingExpression, } = require("./syntax-vue"); const { printImgSrcset, printClassNames } = require("./syntax-attribute"); @@ -1078,8 +1080,8 @@ function printEmbeddedAttributeValue(node, originalTextToDoc, options) { return printVueFor(getValue(), textToDoc); } - if (node.fullName === "slot-scope") { - return printVueSlotScope(getValue(), textToDoc); + if (isVueSlotAttribute(node) || isVueSfcBindingsAttribute(node, options)) { + return printVueBindings(getValue(), textToDoc); } /** @@ -1097,7 +1099,7 @@ function printEmbeddedAttributeValue(node, originalTextToDoc, options) { /** * v-if="jsExpression" */ - const jsExpressionBindingPatterns = ["^v-", "^#"]; + const jsExpressionBindingPatterns = ["^v-"]; if (isKeyMatched(vueEventBindingPatterns)) { const value = getValue(); diff --git a/src/language-html/syntax-vue.js b/src/language-html/syntax-vue.js index d5d89789c..1a0ea9b9a 100644 --- a/src/language-html/syntax-vue.js +++ b/src/language-html/syntax-vue.js @@ -63,12 +63,12 @@ function parseVueFor(value) { }; } -function printVueSlotScope(value, textToDoc) { +function printVueBindings(value, textToDoc) { return textToDoc( `function _(${value}) {}`, { parser: "babel", - __isVueSlotScope: true, + __isVueBindings: true, }, { stripTrailingHardline: true } ); @@ -90,5 +90,5 @@ function isVueEventBindingExpression(eventBindingValue) { module.exports = { isVueEventBindingExpression, printVueFor, - printVueSlotScope, + printVueBindings, }; diff --git a/src/language-html/utils.js b/src/language-html/utils.js index 544fe06f6..b5792fcf8 100644 --- a/src/language-html/utils.js +++ b/src/language-html/utils.js @@ -637,6 +637,32 @@ function isVueNonHtmlBlock(node, options) { ); } +function isVueSlotAttribute(attribute) { + const attributeName = attribute.fullName; + return ( + attributeName.charAt(0) === "#" || + attributeName === "slot-scope" || + attributeName === "v-slot" || + attributeName.startsWith("v-slot:") + ); +} + +function isVueSfcBindingsAttribute(attribute, options) { + const element = attribute.parent; + if (!isVueSfcBlock(element, options)) { + return false; + } + const tagName = element.fullName; + const attributeName = attribute.fullName; + + return ( + // https://github.com/vuejs/rfcs/blob/sfc-improvements/active-rfcs/0000-sfc-script-setup.md + (tagName === "script" && attributeName === "setup") || + // https://github.com/vuejs/rfcs/blob/sfc-improvements/active-rfcs/0000-sfc-style-variables.md + (tagName === "style" && attributeName === "vars") + ); +} + module.exports = { HTML_ELEMENT_ATTRIBUTES, HTML_TAGS, @@ -660,6 +686,8 @@ module.exports = { inferScriptParser, isVueCustomBlock, isVueNonHtmlBlock, + isVueSlotAttribute, + isVueSfcBindingsAttribute, isDanglingSpaceSensitiveNode, isIndentationSensitiveNode, isLeadingSpaceSensitiveNode, diff --git a/src/language-js/html-binding.js b/src/language-js/html-binding.js index 33f4843c2..65dba36cd 100644 --- a/src/language-js/html-binding.js +++ b/src/language-js/html-binding.js @@ -41,7 +41,7 @@ function printHtmlBinding(path, options, print) { ); } - if (options.__isVueSlotScope) { + if (options.__isVueBindings) { return path.call( (functionDeclarationPath) => join(concat([",", line]), functionDeclarationPath.map(print, "params")), diff --git a/tests/vue/vue-3/__snapshots__/jsfmt.spec.js.snap b/tests/vue/vue-3/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..6a6a69f9c --- /dev/null +++ b/tests/vue/vue-3/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,109 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`script-setup.vue format 1`] = ` +====================================options===================================== +parsers: ["vue"] +printWidth: 80 + | printWidth +=====================================input====================================== + + + + + + +Not A script + + + + + + + + +=====================================output===================================== + + + + + + +Not A script + + + + + + + + +================================================================================ +`; + +exports[`style-variables.vue format 1`] = ` +====================================options===================================== +parsers: ["vue"] +printWidth: 80 + | printWidth +=====================================input====================================== + + + + + + +Not A style + + + + + + + + +=====================================output===================================== + + + + + + +Not A style + + + + + + + + +================================================================================ +`; diff --git a/tests/vue/vue-3/jsfmt.spec.js b/tests/vue/vue-3/jsfmt.spec.js new file mode 100644 index 000000000..2fd7eede9 --- /dev/null +++ b/tests/vue/vue-3/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, ["vue"]); diff --git a/tests/vue/vue-3/script-setup.vue b/tests/vue/vue-3/script-setup.vue new file mode 100644 index 000000000..c72ac6578 --- /dev/null +++ b/tests/vue/vue-3/script-setup.vue @@ -0,0 +1,18 @@ + + + + + + +Not A script + + + + + + + diff --git a/tests/vue/vue-3/style-variables.vue b/tests/vue/vue-3/style-variables.vue new file mode 100644 index 000000000..a490e8e5a --- /dev/null +++ b/tests/vue/vue-3/style-variables.vue @@ -0,0 +1,18 @@ + + + + + + +Not A style + + + + + + + diff --git a/tests/vue/vue/__snapshots__/jsfmt.spec.js.snap b/tests/vue/vue/__snapshots__/jsfmt.spec.js.snap index 6fb95b8ca..c121080d9 100644 --- a/tests/vue/vue/__snapshots__/jsfmt.spec.js.snap +++ b/tests/vue/vue/__snapshots__/jsfmt.spec.js.snap @@ -44,8 +44,18 @@ semi: false @click=" $emit( 'click' ) " @click=" $emit( 'click' ) ;" @click=" $emit( 'click' ) ;if(something){for(let i=j;i<100;i++){}}else{}" - slot-scope="{row}" - slot-scope="{destructuring:{a:{b}}}" + slot-scope=" foo" + slot-scope=" {row }" + slot-scope="{destructuring:{ a:{b}}}" + #default=" foo" + #default=" {row }" + #default="{destructuring:{ a:{b}}}" + v-slot=" foo" + v-slot=" {row }" + v-slot="{destructuring:{ a:{b}}}" + v-slot:name=" foo" + v-slot:name=" {row }" + v-slot:name="{destructuring:{ a:{b}}}" :class="{ longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: true }" :class="(() => { return 'hello' })()" :key="index /* hello */ " @@ -289,12 +299,34 @@ semi: false } else { } " + slot-scope="foo" slot-scope="{ row }" slot-scope="{ destructuring: { a: { b }, }, }" + #default="foo" + #default="{ row }" + #default="{ + destructuring: { + a: { b }, + }, + }" + v-slot="foo" + v-slot="{ row }" + v-slot="{ + destructuring: { + a: { b }, + }, + }" + v-slot:name="foo" + v-slot:name="{ row }" + v-slot:name="{ + destructuring: { + a: { b }, + }, + }" :class="{ longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: true, }" @@ -323,7 +355,11 @@ semi: false @click="a[1];" @click="a['b'];" @click="a[null]" - #default="{ foo: { bar: { baz } } }" + #default="{ + foo: { + bar: { baz }, + }, + }" >
@@ -374,8 +410,18 @@ trailingComma: "none" @click=" $emit( 'click' ) " @click=" $emit( 'click' ) ;" @click=" $emit( 'click' ) ;if(something){for(let i=j;i<100;i++){}}else{}" - slot-scope="{row}" - slot-scope="{destructuring:{a:{b}}}" + slot-scope=" foo" + slot-scope=" {row }" + slot-scope="{destructuring:{ a:{b}}}" + #default=" foo" + #default=" {row }" + #default="{destructuring:{ a:{b}}}" + v-slot=" foo" + v-slot=" {row }" + v-slot="{destructuring:{ a:{b}}}" + v-slot:name=" foo" + v-slot:name=" {row }" + v-slot:name="{destructuring:{ a:{b}}}" :class="{ longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: true }" :class="(() => { return 'hello' })()" :key="index /* hello */ " @@ -619,12 +665,34 @@ trailingComma: "none" } else { } " + slot-scope="foo" slot-scope="{ row }" slot-scope="{ destructuring: { a: { b } } }" + #default="foo" + #default="{ row }" + #default="{ + destructuring: { + a: { b } + } + }" + v-slot="foo" + v-slot="{ row }" + v-slot="{ + destructuring: { + a: { b } + } + }" + v-slot:name="foo" + v-slot:name="{ row }" + v-slot:name="{ + destructuring: { + a: { b } + } + }" :class="{ longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: true }" @@ -653,7 +721,11 @@ trailingComma: "none" @click="a[1];" @click="a['b'];" @click="a[null]" - #default="{ foo: { bar: { baz } } }" + #default="{ + foo: { + bar: { baz } + } + }" >
@@ -703,8 +775,18 @@ printWidth: 80 @click=" $emit( 'click' ) " @click=" $emit( 'click' ) ;" @click=" $emit( 'click' ) ;if(something){for(let i=j;i<100;i++){}}else{}" - slot-scope="{row}" - slot-scope="{destructuring:{a:{b}}}" + slot-scope=" foo" + slot-scope=" {row }" + slot-scope="{destructuring:{ a:{b}}}" + #default=" foo" + #default=" {row }" + #default="{destructuring:{ a:{b}}}" + v-slot=" foo" + v-slot=" {row }" + v-slot="{destructuring:{ a:{b}}}" + v-slot:name=" foo" + v-slot:name=" {row }" + v-slot:name="{destructuring:{ a:{b}}}" :class="{ longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: true }" :class="(() => { return 'hello' })()" :key="index /* hello */ " @@ -948,12 +1030,34 @@ printWidth: 80 } else { } " + slot-scope="foo" slot-scope="{ row }" slot-scope="{ destructuring: { a: { b }, }, }" + #default="foo" + #default="{ row }" + #default="{ + destructuring: { + a: { b }, + }, + }" + v-slot="foo" + v-slot="{ row }" + v-slot="{ + destructuring: { + a: { b }, + }, + }" + v-slot:name="foo" + v-slot:name="{ row }" + v-slot:name="{ + destructuring: { + a: { b }, + }, + }" :class="{ longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: true, }" @@ -982,7 +1086,11 @@ printWidth: 80 @click="a[1];" @click="a['b'];" @click="a[null]" - #default="{ foo: { bar: { baz } } }" + #default="{ + foo: { + bar: { baz }, + }, + }" > diff --git a/tests/vue/vue/attributes.vue b/tests/vue/vue/attributes.vue index c057c8ef3..571615012 100644 --- a/tests/vue/vue/attributes.vue +++ b/tests/vue/vue/attributes.vue @@ -35,8 +35,18 @@ @click=" $emit( 'click' ) " @click=" $emit( 'click' ) ;" @click=" $emit( 'click' ) ;if(something){for(let i=j;i<100;i++){}}else{}" - slot-scope="{row}" - slot-scope="{destructuring:{a:{b}}}" + slot-scope=" foo" + slot-scope=" {row }" + slot-scope="{destructuring:{ a:{b}}}" + #default=" foo" + #default=" {row }" + #default="{destructuring:{ a:{b}}}" + v-slot=" foo" + v-slot=" {row }" + v-slot="{destructuring:{ a:{b}}}" + v-slot:name=" foo" + v-slot:name=" {row }" + v-slot:name="{destructuring:{ a:{b}}}" :class="{ longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: true }" :class="(() => { return 'hello' })()" :key="index /* hello */ " From 2a9d0f66d584b7ef1eea24d5bb20922974495d4a Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Fri, 13 Nov 2020 09:06:02 +0800 Subject: [PATCH 018/299] Typescript: Fix `prettier-ignore`d mapped types (#9551) Co-authored-by: Georgii Dolzhykov --- changelog_unreleased/typescript/pr-9551.md | 22 +++ src/language-js/comments.js | 35 +++++ .../__snapshots__/jsfmt.spec.js.snap | 140 ++++++++++++++++++ .../typescript/prettier-ignore/jsfmt.spec.js | 1 + .../prettier-ignore/mapped-types.ts | 68 +++++++++ tests_config/run_spec.js | 1 + 6 files changed, 267 insertions(+) create mode 100644 changelog_unreleased/typescript/pr-9551.md create mode 100644 tests/typescript/prettier-ignore/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/typescript/prettier-ignore/jsfmt.spec.js create mode 100644 tests/typescript/prettier-ignore/mapped-types.ts diff --git a/changelog_unreleased/typescript/pr-9551.md b/changelog_unreleased/typescript/pr-9551.md new file mode 100644 index 000000000..77ffc2676 --- /dev/null +++ b/changelog_unreleased/typescript/pr-9551.md @@ -0,0 +1,22 @@ +#### Fix `prettier-ignore`d mapped types (#9551 by @fisker) + + +```ts +// Input +type a= { + // prettier-ignore + [A in B]: C | D + } + +// Prettier master +type a = { + // prettier-ignore + A in B: C | D; +}; + +// Prettier stable +type a = { + // prettier-ignore + [A in B]: C | D + }; +``` diff --git a/src/language-js/comments.js b/src/language-js/comments.js index 53b337ddd..f9088cc4d 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -21,6 +21,13 @@ const { locStart, locEnd } = require("./loc"); function handleOwnLineComment(comment, text, options, ast, isLastComment) { const { precedingNode, enclosingNode, followingNode } = comment; return ( + handleIgnoreComments( + text, + enclosingNode, + precedingNode, + followingNode, + comment + ) || handleLastFunctionArgComments( text, precedingNode, @@ -124,6 +131,13 @@ function handleRemainingComment(comment, text, options, ast, isLastComment) { const { precedingNode, enclosingNode, followingNode } = comment; if ( + handleIgnoreComments( + text, + enclosingNode, + precedingNode, + followingNode, + comment + ) || handleIfStatementComments( text, precedingNode, @@ -851,6 +865,27 @@ function handleTSFunctionTrailingComments( return false; } +function handleIgnoreComments( + text, + enclosingNode, + precedingNode, + followingNode, + comment +) { + if ( + isNodeIgnoreComment(comment) && + enclosingNode && + enclosingNode.type === "TSMappedType" && + followingNode && + followingNode.type === "TSTypeParameter" && + followingNode.constraint + ) { + enclosingNode.prettierIgnore = true; + comment.unignore = true; + return true; + } +} + function handleTSMappedTypeComments( text, enclosingNode, diff --git a/tests/typescript/prettier-ignore/__snapshots__/jsfmt.spec.js.snap b/tests/typescript/prettier-ignore/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..60bdf3b3f --- /dev/null +++ b/tests/typescript/prettier-ignore/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,140 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`mapped-types.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +type a= { + // prettier-ignore + [A in B]: C | D + } + +type a= { + [ + // prettier-ignore + A in B + ]: C | D + } + +type a= { + [ + A in + // prettier-ignore + B + ]: C | D + } + +type a= { + [A in B]: + // prettier-ignore + C | D + } + +type a= { + [ + /* prettier-ignore */ + A in B + ]: C | D + } + +type a= { + [ + A in + /* prettier-ignore */ + B + ]: C | D + } + +type a= { + [A in B]: + /* prettier-ignore */ + C | D + } + + +type a= { + /* prettier-ignore */ [A in B]: C | D + } + +type a= { + [/* prettier-ignore */ A in B ]: C | D + } + +type a= { + [A in /* prettier-ignore */ B]: C | D + } + +type a= { + [A in B]: /* prettier-ignore */ C | D + } + +type a= { + /* prettier-ignore */ + [A in B]: C | D + } + +=====================================output===================================== +type a = { + // prettier-ignore + [A in B]: C | D + }; + +type a = { + [ + // prettier-ignore + A in B + ]: C | D + }; + +type a = { + [A in // prettier-ignore + B]: C | D; +}; + +type a = { + [A in B]: // prettier-ignore + C | D; +}; + +type a = { + [ + /* prettier-ignore */ + A in B + ]: C | D + }; + +type a = { + [A in /* prettier-ignore */ + B]: C | D; +}; + +type a = { + [A in B]: /* prettier-ignore */ + C | D; +}; + +type a = { + /* prettier-ignore */ [A in B]: C | D + }; + +type a = { + [/* prettier-ignore */ A in B ]: C | D + }; + +type a = { + [A in /* prettier-ignore */ B]: C | D; +}; + +type a = { + [A in B /* prettier-ignore */]: C | D; +}; + +type a = { + /* prettier-ignore */ + [A in B]: C | D + }; + +================================================================================ +`; diff --git a/tests/typescript/prettier-ignore/jsfmt.spec.js b/tests/typescript/prettier-ignore/jsfmt.spec.js new file mode 100644 index 000000000..2ea3bb6eb --- /dev/null +++ b/tests/typescript/prettier-ignore/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, ["typescript"]); diff --git a/tests/typescript/prettier-ignore/mapped-types.ts b/tests/typescript/prettier-ignore/mapped-types.ts new file mode 100644 index 000000000..5a37a573b --- /dev/null +++ b/tests/typescript/prettier-ignore/mapped-types.ts @@ -0,0 +1,68 @@ +type a= { + // prettier-ignore + [A in B]: C | D + } + +type a= { + [ + // prettier-ignore + A in B + ]: C | D + } + +type a= { + [ + A in + // prettier-ignore + B + ]: C | D + } + +type a= { + [A in B]: + // prettier-ignore + C | D + } + +type a= { + [ + /* prettier-ignore */ + A in B + ]: C | D + } + +type a= { + [ + A in + /* prettier-ignore */ + B + ]: C | D + } + +type a= { + [A in B]: + /* prettier-ignore */ + C | D + } + + +type a= { + /* prettier-ignore */ [A in B]: C | D + } + +type a= { + [/* prettier-ignore */ A in B ]: C | D + } + +type a= { + [A in /* prettier-ignore */ B]: C | D + } + +type a= { + [A in B]: /* prettier-ignore */ C | D + } + +type a= { + /* prettier-ignore */ + [A in B]: C | D + } diff --git a/tests_config/run_spec.js b/tests_config/run_spec.js index 862ad62a9..27e25c9fc 100644 --- a/tests_config/run_spec.js +++ b/tests_config/run_spec.js @@ -40,6 +40,7 @@ const unstableTests = new Map( ], ["js/no-semi/comments.js", (options) => options.semi === false], ["flow/no-semi/comments.js", (options) => options.semi === false], + "typescript/prettier-ignore/mapped-types.ts", "js/comments/html-like/comment.js", ].map((fixture) => { const [file, isUnstable = () => true] = Array.isArray(fixture) From 47fbf284df3b6bf0f31f5c9fce534dc7df010402 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Fri, 13 Nov 2020 09:06:16 +0800 Subject: [PATCH 019/299] Fix glimmer `locStart` and `locEnd` (#9626) --- src/language-handlebars/loc.js | 11 +++++++ src/language-handlebars/parser-glimmer.js | 38 ++++++++++++++-------- src/language-handlebars/printer-glimmer.js | 15 +++------ 3 files changed, 40 insertions(+), 24 deletions(-) create mode 100644 src/language-handlebars/loc.js diff --git a/src/language-handlebars/loc.js b/src/language-handlebars/loc.js new file mode 100644 index 000000000..a1bd54d9d --- /dev/null +++ b/src/language-handlebars/loc.js @@ -0,0 +1,11 @@ +"use strict"; + +function locStart(node) { + return node.loc.start.offset; +} + +function locEnd(node) { + return node.loc.end.offset; +} + +module.exports = { locStart, locEnd }; diff --git a/src/language-handlebars/parser-glimmer.js b/src/language-handlebars/parser-glimmer.js index 3750847f7..3df6859c3 100644 --- a/src/language-handlebars/parser-glimmer.js +++ b/src/language-handlebars/parser-glimmer.js @@ -1,6 +1,8 @@ "use strict"; +const LinesAndColumns = require("lines-and-columns").default; const createError = require("../common/parser-create-error"); +const { locStart, locEnd } = require("./loc"); /* from the following template: `non-escaped mustache \\{{helper}}` * glimmer parser will produce an AST missing a backslash @@ -17,11 +19,31 @@ function addBackslash(/* options*/) { }; } +// Add `loc.{start,end}.offset` +function addOffset(text) { + const lines = new LinesAndColumns(text); + const calculateOffset = ({ line, column }) => + lines.indexForLocation({ line: line - 1, column }); + return (/* options*/) => ({ + name: "addOffset", + visitor: { + All(node) { + const { start, end } = node.loc; + start.offset = calculateOffset(start); + end.offset = calculateOffset(end); + }, + }, + }); +} + function parse(text) { const { preprocess: glimmer } = require("@glimmer/syntax"); let ast; try { - ast = glimmer(text, { mode: "codemod", plugins: { ast: [addBackslash] } }); + ast = glimmer(text, { + mode: "codemod", + plugins: { ast: [addBackslash, addOffset(text)] }, + }); } catch (error) { const location = getErrorLocation(error); @@ -59,18 +81,8 @@ module.exports = { glimmer: { parse, astFormat: "glimmer", - // TODO: `locStart` and `locEnd` should return a number offset - // https://prettier.io/docs/en/plugins.html#parsers - // but we need access to the original text to use - // `loc.start` and `loc.end` objects to calculate the offset - /* istanbul ignore next */ - locStart(node) { - return node.loc && node.loc.start; - }, - /* istanbul ignore next */ - locEnd(node) { - return node.loc && node.loc.end; - }, + locStart, + locEnd, }, }, }; diff --git a/src/language-handlebars/printer-glimmer.js b/src/language-handlebars/printer-glimmer.js index 21e46762f..2876a2ac7 100644 --- a/src/language-handlebars/printer-glimmer.js +++ b/src/language-handlebars/printer-glimmer.js @@ -10,8 +10,7 @@ const { line, softline, } = require("../document").builders; -const locationToOffset = require("../utils/line-column-to-index"); - +const { locStart, locEnd } = require("./loc"); const clean = require("./clean"); const { getNextNode, @@ -37,11 +36,7 @@ function print(path, options, print) { } if (hasPrettierIgnore(path)) { - const startOffset = locationToOffset(n.loc.start, options.originalText); - const endOffset = locationToOffset(n.loc.end, options.originalText); - - const ignoredText = options.originalText.slice(startOffset, endOffset); - return ignoredText; + return options.originalText.slice(locStart(n), locEnd(n)); } switch (n.type) { @@ -145,12 +140,10 @@ function print(path, options, print) { const isText = n.value.type === "TextNode"; const isEmptyText = isText && n.value.chars === ""; - // If the text is empty and the value's loc start and end columns are the + // If the text is empty and the value's loc start and end offsets are the // same, there is no value for this AttrNode and it should be printed // without the `=""`. Example: `` -> `` - const isEmptyValue = - isEmptyText && n.value.loc.start.column === n.value.loc.end.column; - if (isEmptyValue) { + if (isEmptyText && locStart(n.value) === locEnd(n.value)) { return concat([n.name]); } const value = path.call(print, "value"); From 9b206b56056406f7d7281826c7ac67ac18e763f3 Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 13 Nov 2020 09:14:07 +0800 Subject: [PATCH 020/299] Fix renamed function `isNodeIgnoreComment` -> `isPrettierIgnoreComment` --- src/language-js/comments.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/language-js/comments.js b/src/language-js/comments.js index f9088cc4d..925cf0a7d 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -873,7 +873,7 @@ function handleIgnoreComments( comment ) { if ( - isNodeIgnoreComment(comment) && + isPrettierIgnoreComment(comment) && enclosingNode && enclosingNode.type === "TSMappedType" && followingNode && From 4bcf8a3a366a5c7c6297b2e00aed1446ce6e4859 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Fri, 13 Nov 2020 19:13:03 +0800 Subject: [PATCH 021/299] Markdown: Fix extra empty line added after empty table (#9654) --- changelog_unreleased/markdown/pr-9654.md | 29 ++++ src/language-markdown/printer-markdown.js | 35 +++-- .../__snapshots__/jsfmt.spec.js.snap | 140 ++++++++++++++++++ .../markdown/table/empty-table/empty-table.md | 11 ++ .../markdown/table/empty-table/jsfmt.spec.js | 4 + 5 files changed, 201 insertions(+), 18 deletions(-) create mode 100644 changelog_unreleased/markdown/pr-9654.md create mode 100644 tests/markdown/table/empty-table/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/markdown/table/empty-table/empty-table.md create mode 100644 tests/markdown/table/empty-table/jsfmt.spec.js diff --git a/changelog_unreleased/markdown/pr-9654.md b/changelog_unreleased/markdown/pr-9654.md new file mode 100644 index 000000000..5028ba8b9 --- /dev/null +++ b/changelog_unreleased/markdown/pr-9654.md @@ -0,0 +1,29 @@ +#### Fix extra empty line added after empty table (#9654 by @fisker) + + +```markdown + +Test line 1 + +| Specify the selected option : | Option 1 | +| ----------------------------- | -------- | + +Test line 6 + + +Test line 1 + +| Specify the selected option : | Option 1 | +| ----------------------------- | -------- | + + +Test line 6 + + +Test line 1 + +| Specify the selected option : | Option 1 | +| ----------------------------- | -------- | + +Test line 6 +``` diff --git a/src/language-markdown/printer-markdown.js b/src/language-markdown/printer-markdown.js index e95006c58..dad7bbec8 100644 --- a/src/language-markdown/printer-markdown.js +++ b/src/language-markdown/printer-markdown.js @@ -595,33 +595,32 @@ function printTable(path, options, print) { ), contents[0].map(() => 3) // minimum width = 3 (---, :--, :-:, --:) ); - const alignedTable = join(hardlineWithoutBreakParent, [ - printRow(contents[0]), - printSeparator(), - join( - hardlineWithoutBreakParent, - contents.slice(1).map((rowContents) => printRow(rowContents)) - ), - ]); + const alignedTable = printTableContents(/* isCompact */ false); if (options.proseWrap !== "never") { return concat([breakParent, alignedTable]); } // Only if the --prose-wrap never is set and it exceeds the print width. - const compactTable = join(hardlineWithoutBreakParent, [ - printRow(contents[0], /* isCompact */ true), - printSeparator(/* isCompact */ true), - join( - hardlineWithoutBreakParent, - contents - .slice(1) - .map((rowContents) => printRow(rowContents, /* isCompact */ true)) - ), - ]); + const compactTable = printTableContents(/* isCompact */ true); return concat([breakParent, group(ifBreak(compactTable, alignedTable))]); + function printTableContents(isCompact) { + const parts = [printRow(contents[0], isCompact), printSeparator(isCompact)]; + if (contents.length > 1) { + parts.push( + join( + hardlineWithoutBreakParent, + contents + .slice(1) + .map((rowContents) => printRow(rowContents, isCompact)) + ) + ); + } + return join(hardlineWithoutBreakParent, parts); + } + function printSeparator(isCompact) { return concat([ "| ", diff --git a/tests/markdown/table/empty-table/__snapshots__/jsfmt.spec.js.snap b/tests/markdown/table/empty-table/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..747deca3f --- /dev/null +++ b/tests/markdown/table/empty-table/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,140 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`empty-table.md - {"proseWrap":"always"} format 1`] = ` +====================================options===================================== +parsers: ["markdown"] +printWidth: 80 +proseWrap: "always" + | printWidth +=====================================input====================================== +Text + +| Specify the selected option : | Option 1 | +|:--| --- | + +Text + +| Should print as compact table when --proseWrap=never|a long long long long long long long long long long long long long head| +|---|--:| + +Text + +=====================================output===================================== +Text + +| Specify the selected option : | Option 1 | +| :---------------------------- | -------- | + +Text + +| Should print as compact table when --proseWrap=never | a long long long long long long long long long long long long long head | +| ---------------------------------------------------- | ----------------------------------------------------------------------: | + +Text + +================================================================================ +`; + +exports[`empty-table.md - {"proseWrap":"never"} format 1`] = ` +====================================options===================================== +parsers: ["markdown"] +printWidth: 80 +proseWrap: "never" + | printWidth +=====================================input====================================== +Text + +| Specify the selected option : | Option 1 | +|:--| --- | + +Text + +| Should print as compact table when --proseWrap=never|a long long long long long long long long long long long long long head| +|---|--:| + +Text + +=====================================output===================================== +Text + +| Specify the selected option : | Option 1 | +| :---------------------------- | -------- | + +Text + +| Should print as compact table when --proseWrap=never | a long long long long long long long long long long long long long head | +| --- | --: | + +Text + +================================================================================ +`; + +exports[`empty-table.md - {"proseWrap":"preserve"} format 1`] = ` +====================================options===================================== +parsers: ["markdown"] +printWidth: 80 +proseWrap: "preserve" + | printWidth +=====================================input====================================== +Text + +| Specify the selected option : | Option 1 | +|:--| --- | + +Text + +| Should print as compact table when --proseWrap=never|a long long long long long long long long long long long long long head| +|---|--:| + +Text + +=====================================output===================================== +Text + +| Specify the selected option : | Option 1 | +| :---------------------------- | -------- | + +Text + +| Should print as compact table when --proseWrap=never | a long long long long long long long long long long long long long head | +| ---------------------------------------------------- | ----------------------------------------------------------------------: | + +Text + +================================================================================ +`; + +exports[`empty-table.md format 1`] = ` +====================================options===================================== +parsers: ["markdown"] +printWidth: 80 + | printWidth +=====================================input====================================== +Text + +| Specify the selected option : | Option 1 | +|:--| --- | + +Text + +| Should print as compact table when --proseWrap=never|a long long long long long long long long long long long long long head| +|---|--:| + +Text + +=====================================output===================================== +Text + +| Specify the selected option : | Option 1 | +| :---------------------------- | -------- | + +Text + +| Should print as compact table when --proseWrap=never | a long long long long long long long long long long long long long head | +| ---------------------------------------------------- | ----------------------------------------------------------------------: | + +Text + +================================================================================ +`; diff --git a/tests/markdown/table/empty-table/empty-table.md b/tests/markdown/table/empty-table/empty-table.md new file mode 100644 index 000000000..3765cc404 --- /dev/null +++ b/tests/markdown/table/empty-table/empty-table.md @@ -0,0 +1,11 @@ +Text + +| Specify the selected option : | Option 1 | +|:--| --- | + +Text + +| Should print as compact table when --proseWrap=never|a long long long long long long long long long long long long long head| +|---|--:| + +Text diff --git a/tests/markdown/table/empty-table/jsfmt.spec.js b/tests/markdown/table/empty-table/jsfmt.spec.js new file mode 100644 index 000000000..54dea461f --- /dev/null +++ b/tests/markdown/table/empty-table/jsfmt.spec.js @@ -0,0 +1,4 @@ +run_spec(__dirname, ["markdown"]); +run_spec(__dirname, ["markdown"], { proseWrap: "never" }); +run_spec(__dirname, ["markdown"], { proseWrap: "always" }); +run_spec(__dirname, ["markdown"], { proseWrap: "preserve" }); From 3e20fc244c6b54b445d8a0a99c515953af9e69a2 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Sat, 14 Nov 2020 12:45:30 +0800 Subject: [PATCH 022/299] Lint: Report duplicated changelog (#9666) --- scripts/lint-changelog.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/scripts/lint-changelog.js b/scripts/lint-changelog.js index 66348a2f0..fbb1a78e5 100644 --- a/scripts/lint-changelog.js +++ b/scripts/lint-changelog.js @@ -2,6 +2,7 @@ "use strict"; const fs = require("fs"); const path = require("path"); +const { outdent } = require("outdent"); const CHANGELOG_DIR = "changelog_unreleased"; const TEMPLATE_FILE = "TEMPLATE.md"; @@ -61,6 +62,7 @@ const template = fs.readFileSync( ); const [templateComment] = template.match(//); const [templateAuthorLink] = template.match(authorRegex); +const checkedFiles = new Map(); for (const category of CHANGELOG_CATEGORIES) { const files = fs.readdirSync(path.join(CHANGELOG_ROOT, category)); @@ -85,11 +87,21 @@ for (const category of CHANGELOG_CATEGORIES) { continue; } const [, prNumber] = match; + const prLink = `#${prNumber}`; + if (checkedFiles.has(prNumber)) { + showErrorMessage( + outdent` + Duplicate files for ${prLink} found. + - ${checkedFiles.get(prNumber)} + - ${displayPath} + ` + ); + } + checkedFiles.set(prNumber, displayPath); const content = fs.readFileSync( path.join(CHANGELOG_DIR, category, prFile), "utf8" ); - const prLink = `#${prNumber}`; if (!content.includes(prLink)) { showErrorMessage(`[${displayPath}]: PR link "${prLink}" is missing.`); From 7d608bafc7f3a1fd45745c3d58307b58636aa079 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Sat, 14 Nov 2020 14:55:07 +0800 Subject: [PATCH 023/299] Rename `preprocess` and `postprocess` file (#9651) --- src/language-html/{preprocess.js => print-preprocess.js} | 0 src/language-html/printer-html.js | 2 +- src/language-js/{postprocess.js => parse-postprocess.js} | 0 src/language-js/parser-babel.js | 2 +- src/language-js/parser-espree.js | 2 +- src/language-js/parser-flow.js | 2 +- src/language-js/parser-meriyah.js | 2 +- src/language-js/parser-typescript.js | 2 +- src/language-js/{preprocess.js => print-preprocess.js} | 0 src/language-js/printer-estree-json.js | 2 +- src/language-js/printer-estree.js | 2 +- src/language-markdown/{preprocess.js => print-preprocess.js} | 0 src/language-markdown/printer-markdown.js | 2 +- 13 files changed, 9 insertions(+), 9 deletions(-) rename src/language-html/{preprocess.js => print-preprocess.js} (100%) rename src/language-js/{postprocess.js => parse-postprocess.js} (100%) rename src/language-js/{preprocess.js => print-preprocess.js} (100%) rename src/language-markdown/{preprocess.js => print-preprocess.js} (100%) diff --git a/src/language-html/preprocess.js b/src/language-html/print-preprocess.js similarity index 100% rename from src/language-html/preprocess.js rename to src/language-html/print-preprocess.js diff --git a/src/language-html/printer-html.js b/src/language-html/printer-html.js index 8536f98cf..4ae1b9dcf 100644 --- a/src/language-html/printer-html.js +++ b/src/language-html/printer-html.js @@ -46,7 +46,7 @@ const { unescapeQuoteEntities, isPreLikeNode, } = require("./utils"); -const preprocess = require("./preprocess"); +const preprocess = require("./print-preprocess"); const { insertPragma } = require("./pragma"); const { locStart, locEnd } = require("./loc"); const { diff --git a/src/language-js/postprocess.js b/src/language-js/parse-postprocess.js similarity index 100% rename from src/language-js/postprocess.js rename to src/language-js/parse-postprocess.js diff --git a/src/language-js/parser-babel.js b/src/language-js/parser-babel.js index 539571361..b26aa83b8 100644 --- a/src/language-js/parser-babel.js +++ b/src/language-js/parser-babel.js @@ -7,7 +7,7 @@ const { } = require("../common/util"); const { hasPragma } = require("./pragma"); const { locStart, locEnd } = require("./loc"); -const postprocess = require("./postprocess"); +const postprocess = require("./parse-postprocess"); function babelOptions({ sourceType, extraPlugins = [] }) { return { diff --git a/src/language-js/parser-espree.js b/src/language-js/parser-espree.js index 0f637f1d3..ede9745cf 100644 --- a/src/language-js/parser-espree.js +++ b/src/language-js/parser-espree.js @@ -3,7 +3,7 @@ const { getShebang } = require("../common/util"); const createError = require("../common/parser-create-error"); const { hasPragma } = require("./pragma"); const { locStart, locEnd } = require("./loc"); -const postprocess = require("./postprocess"); +const postprocess = require("./parse-postprocess"); const espreeOptions = { range: true, diff --git a/src/language-js/parser-flow.js b/src/language-js/parser-flow.js index 201e438a2..f38494d72 100644 --- a/src/language-js/parser-flow.js +++ b/src/language-js/parser-flow.js @@ -3,7 +3,7 @@ const createError = require("../common/parser-create-error"); const { hasPragma } = require("./pragma"); const { locStart, locEnd } = require("./loc"); -const postprocess = require("./postprocess"); +const postprocess = require("./parse-postprocess"); function parse(text, parsers, opts) { // Inline the require to avoid loading all the JS if we don't use it diff --git a/src/language-js/parser-meriyah.js b/src/language-js/parser-meriyah.js index 0d9f9f45a..4086ca389 100644 --- a/src/language-js/parser-meriyah.js +++ b/src/language-js/parser-meriyah.js @@ -3,7 +3,7 @@ const createError = require("../common/parser-create-error"); const { hasPragma } = require("./pragma"); const { locStart, locEnd } = require("./loc"); -const postprocess = require("./postprocess"); +const postprocess = require("./parse-postprocess"); // https://github.com/meriyah/meriyah/blob/4676f60b6c149d7082bde2c9147f9ae2359c8075/src/parser.ts#L185 const parseOptions = { diff --git a/src/language-js/parser-typescript.js b/src/language-js/parser-typescript.js index c7dfb2cbc..1c3221f69 100644 --- a/src/language-js/parser-typescript.js +++ b/src/language-js/parser-typescript.js @@ -3,7 +3,7 @@ const createError = require("../common/parser-create-error"); const { hasPragma } = require("./pragma"); const { locStart, locEnd } = require("./loc"); -const postprocess = require("./postprocess"); +const postprocess = require("./parse-postprocess"); function parse(text, parsers, opts) { const jsx = isProbablyJsx(text); diff --git a/src/language-js/preprocess.js b/src/language-js/print-preprocess.js similarity index 100% rename from src/language-js/preprocess.js rename to src/language-js/print-preprocess.js diff --git a/src/language-js/printer-estree-json.js b/src/language-js/printer-estree-json.js index 63af2bd25..61d90c199 100644 --- a/src/language-js/printer-estree-json.js +++ b/src/language-js/printer-estree-json.js @@ -1,7 +1,7 @@ "use strict"; const { concat, hardline, indent, join } = require("../document").builders; -const preprocess = require("./preprocess"); +const preprocess = require("./print-preprocess"); function genericPrint(path, options, print) { const node = path.getValue(); diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 9f6c22578..b6be2237f 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -44,7 +44,7 @@ const { printHtmlBinding, isVueEventBindingExpression, } = require("./html-binding"); -const preprocess = require("./preprocess"); +const preprocess = require("./print-preprocess"); const { classChildNeedsASIProtection, classPropMayCauseASIProblems, diff --git a/src/language-markdown/preprocess.js b/src/language-markdown/print-preprocess.js similarity index 100% rename from src/language-markdown/preprocess.js rename to src/language-markdown/print-preprocess.js diff --git a/src/language-markdown/printer-markdown.js b/src/language-markdown/printer-markdown.js index dad7bbec8..17a6373a0 100644 --- a/src/language-markdown/printer-markdown.js +++ b/src/language-markdown/printer-markdown.js @@ -29,7 +29,7 @@ const { replaceEndOfLineWith } = require("../common/util"); const embed = require("./embed"); const { insertPragma } = require("./pragma"); const { locStart, locEnd } = require("./loc"); -const preprocess = require("./preprocess"); +const preprocess = require("./print-preprocess"); const clean = require("./clean"); const { getFencedCodeBlockValue, From 6745a2797571e9c86e6f665d12cda168e921b406 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Sat, 14 Nov 2020 15:43:11 +0800 Subject: [PATCH 024/299] Refactor: Reduce comment related functions parameters (#9621) --- src/language-js/comments.js | 349 +++++++++++------------------------- 1 file changed, 104 insertions(+), 245 deletions(-) diff --git a/src/language-js/comments.js b/src/language-js/comments.js index 925cf0a7d..6dd6b85a6 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -19,159 +19,58 @@ const { const { locStart, locEnd } = require("./loc"); function handleOwnLineComment(comment, text, options, ast, isLastComment) { - const { precedingNode, enclosingNode, followingNode } = comment; return ( - handleIgnoreComments( - text, - enclosingNode, - precedingNode, - followingNode, - comment - ) || - handleLastFunctionArgComments( - text, - precedingNode, - enclosingNode, - followingNode, - comment - ) || - handleMemberExpressionComments(enclosingNode, followingNode, comment) || - handleIfStatementComments( - text, - precedingNode, - enclosingNode, - followingNode, - comment - ) || - handleWhileComments( - text, - precedingNode, - enclosingNode, - followingNode, - comment - ) || - handleTryStatementComments( - enclosingNode, - precedingNode, - followingNode, - comment - ) || - handleClassComments(enclosingNode, precedingNode, followingNode, comment) || - handleImportSpecifierComments(enclosingNode, comment) || - handleForComments(enclosingNode, precedingNode, comment) || - handleUnionTypeComments( - precedingNode, - enclosingNode, - followingNode, - comment - ) || - handleOnlyComments(enclosingNode, ast, comment, isLastComment) || - handleImportDeclarationComments( - text, - enclosingNode, - precedingNode, - comment - ) || - handleAssignmentPatternComments(enclosingNode, comment) || - handleMethodNameComments(text, enclosingNode, precedingNode, comment) || - handleLabeledStatementComments(enclosingNode, comment) + handleIgnoreComments(comment) || + handleLastFunctionArgComments(comment, text) || + handleMemberExpressionComments(comment) || + handleIfStatementComments(comment, text) || + handleWhileComments(comment, text) || + handleTryStatementComments(comment) || + handleClassComments(comment) || + handleImportSpecifierComments(comment) || + handleForComments(comment) || + handleUnionTypeComments(comment) || + handleOnlyComments(comment, ast, isLastComment) || + handleImportDeclarationComments(comment, text) || + handleAssignmentPatternComments(comment) || + handleMethodNameComments(comment, text) || + handleLabeledStatementComments(comment) ); } function handleEndOfLineComment(comment, text, options, ast, isLastComment) { - const { precedingNode, enclosingNode, followingNode } = comment; return ( - handleClosureTypeCastComments(followingNode, comment) || - handleLastFunctionArgComments( - text, - precedingNode, - enclosingNode, - followingNode, - comment - ) || - handleConditionalExpressionComments( - enclosingNode, - precedingNode, - followingNode, - comment, - text - ) || - handleImportSpecifierComments(enclosingNode, comment) || - handleIfStatementComments( - text, - precedingNode, - enclosingNode, - followingNode, - comment - ) || - handleWhileComments( - text, - precedingNode, - enclosingNode, - followingNode, - comment - ) || - handleTryStatementComments( - enclosingNode, - precedingNode, - followingNode, - comment - ) || - handleClassComments(enclosingNode, precedingNode, followingNode, comment) || - handleLabeledStatementComments(enclosingNode, comment) || - handleCallExpressionComments(precedingNode, enclosingNode, comment) || - handlePropertyComments(enclosingNode, comment) || - handleOnlyComments(enclosingNode, ast, comment, isLastComment) || - handleTypeAliasComments(enclosingNode, followingNode, comment) || - handleVariableDeclaratorComments(enclosingNode, followingNode, comment) + handleClosureTypeCastComments(comment) || + handleLastFunctionArgComments(comment, text) || + handleConditionalExpressionComments(comment, text) || + handleImportSpecifierComments(comment) || + handleIfStatementComments(comment, text) || + handleWhileComments(comment, text) || + handleTryStatementComments(comment) || + handleClassComments(comment) || + handleLabeledStatementComments(comment) || + handleCallExpressionComments(comment) || + handlePropertyComments(comment) || + handleOnlyComments(comment, ast, isLastComment) || + handleTypeAliasComments(comment) || + handleVariableDeclaratorComments(comment) ); } function handleRemainingComment(comment, text, options, ast, isLastComment) { - const { precedingNode, enclosingNode, followingNode } = comment; - if ( - handleIgnoreComments( - text, - enclosingNode, - precedingNode, - followingNode, - comment - ) || - handleIfStatementComments( - text, - precedingNode, - enclosingNode, - followingNode, - comment - ) || - handleWhileComments( - text, - precedingNode, - enclosingNode, - followingNode, - comment - ) || - handleObjectPropertyAssignment(enclosingNode, precedingNode, comment) || - handleCommentInEmptyParens(text, enclosingNode, comment) || - handleMethodNameComments(text, enclosingNode, precedingNode, comment) || - handleOnlyComments(enclosingNode, ast, comment, isLastComment) || - handleCommentAfterArrowParams(text, enclosingNode, comment) || - handleFunctionNameComments(text, enclosingNode, precedingNode, comment) || - handleTSMappedTypeComments( - text, - enclosingNode, - precedingNode, - followingNode, - comment - ) || - handleBreakAndContinueStatementComments(enclosingNode, comment) || - handleTSFunctionTrailingComments( - text, - enclosingNode, - followingNode, - comment - ) + handleIgnoreComments(comment) || + handleIfStatementComments(comment, text) || + handleWhileComments(comment, text) || + handleObjectPropertyAssignment(comment) || + handleCommentInEmptyParens(comment, text) || + handleMethodNameComments(comment, text) || + handleOnlyComments(comment, ast, isLastComment) || + handleCommentAfterArrowParams(comment, text) || + handleFunctionNameComments(comment, text) || + handleTSMappedTypeComments(comment) || + handleBreakAndContinueStatementComments(comment) || + handleTSFunctionTrailingComments(comment, text) ) { return true; } @@ -179,13 +78,13 @@ function handleRemainingComment(comment, text, options, ast, isLastComment) { } function addBlockStatementFirstComment(node, comment) { - const body = (node.body || node.properties).filter( - (n) => n.type !== "EmptyStatement" + const firstNonEmptyNode = (node.body || node.properties).find( + ({ type }) => type !== "EmptyStatement" ); - if (body.length === 0) { - addDanglingComment(node, comment); + if (firstNonEmptyNode) { + addLeadingComment(firstNonEmptyNode, comment); } else { - addLeadingComment(body[0], comment); + addDanglingComment(node, comment); } } @@ -197,7 +96,8 @@ function addBlockOrNotComment(node, comment) { } } -function handleClosureTypeCastComments(followingNode, comment) { +function handleClosureTypeCastComments(comment) { + const { followingNode } = comment; if (followingNode && isTypeCastComment(comment)) { addLeadingComment(followingNode, comment); return true; @@ -221,13 +121,8 @@ function handleClosureTypeCastComments(followingNode, comment) { // // comment // ... // } -function handleIfStatementComments( - text, - precedingNode, - enclosingNode, - followingNode, - comment -) { +function handleIfStatementComments(comment, text) { + const { precedingNode, enclosingNode, followingNode } = comment; if ( !enclosingNode || enclosingNode.type !== "IfStatement" || @@ -289,13 +184,8 @@ function handleIfStatementComments( return false; } -function handleWhileComments( - text, - precedingNode, - enclosingNode, - followingNode, - comment -) { +function handleWhileComments(comment, text) { + const { precedingNode, enclosingNode, followingNode } = comment; if ( !enclosingNode || enclosingNode.type !== "WhileStatement" || @@ -333,12 +223,8 @@ function handleWhileComments( } // Same as IfStatement but for TryStatement -function handleTryStatementComments( - enclosingNode, - precedingNode, - followingNode, - comment -) { +function handleTryStatementComments(comment) { + const { precedingNode, enclosingNode, followingNode } = comment; if ( !enclosingNode || (enclosingNode.type !== "TryStatement" && @@ -371,7 +257,9 @@ function handleTryStatementComments( return false; } -function handleMemberExpressionComments(enclosingNode, followingNode, comment) { +function handleMemberExpressionComments(comment) { + const { enclosingNode, followingNode } = comment; + if ( enclosingNode && (enclosingNode.type === "MemberExpression" || @@ -386,13 +274,8 @@ function handleMemberExpressionComments(enclosingNode, followingNode, comment) { return false; } -function handleConditionalExpressionComments( - enclosingNode, - precedingNode, - followingNode, - comment, - text -) { +function handleConditionalExpressionComments(comment, text) { + const { precedingNode, enclosingNode, followingNode } = comment; const isSameLineAsPrecedingNode = precedingNode && !hasNewlineInRange(text, locEnd(precedingNode), locStart(comment)); @@ -410,7 +293,8 @@ function handleConditionalExpressionComments( return false; } -function handleObjectPropertyAssignment(enclosingNode, precedingNode, comment) { +function handleObjectPropertyAssignment(comment) { + const { precedingNode, enclosingNode } = comment; if ( enclosingNode && (enclosingNode.type === "ObjectProperty" || @@ -425,12 +309,8 @@ function handleObjectPropertyAssignment(enclosingNode, precedingNode, comment) { return false; } -function handleClassComments( - enclosingNode, - precedingNode, - followingNode, - comment -) { +function handleClassComments(comment) { + const { precedingNode, enclosingNode, followingNode } = comment; if ( enclosingNode && (enclosingNode.type === "ClassDeclaration" || @@ -480,7 +360,8 @@ function handleClassComments( return false; } -function handleMethodNameComments(text, enclosingNode, precedingNode, comment) { +function handleMethodNameComments(comment, text) { + const { precedingNode, enclosingNode } = comment; // This is only needed for estree parsers (flow, typescript) to attach // after a method name: // obj = { fn /*comment*/() {} }; @@ -522,16 +403,12 @@ function handleMethodNameComments(text, enclosingNode, precedingNode, comment) { return false; } -function handleFunctionNameComments( - text, - enclosingNode, - precedingNode, - comment -) { +function handleFunctionNameComments(comment, text) { if (getNextNonSpaceNonCommentCharacter(text, comment, locEnd) !== "(") { return false; } + const { precedingNode, enclosingNode } = comment; if ( precedingNode && enclosingNode && @@ -547,7 +424,8 @@ function handleFunctionNameComments( return false; } -function handleCommentAfterArrowParams(text, enclosingNode, comment) { +function handleCommentAfterArrowParams(comment, text) { + const { enclosingNode } = comment; if (!(enclosingNode && enclosingNode.type === "ArrowFunctionExpression")) { return false; } @@ -561,11 +439,12 @@ function handleCommentAfterArrowParams(text, enclosingNode, comment) { return false; } -function handleCommentInEmptyParens(text, enclosingNode, comment) { +function handleCommentInEmptyParens(comment, text) { if (getNextNonSpaceNonCommentCharacter(text, comment, locEnd) !== ")") { return false; } + const { enclosingNode } = comment; // Only add dangling comments to fix the case when no params are present, // i.e. a function without any argument. if ( @@ -591,13 +470,9 @@ function handleCommentInEmptyParens(text, enclosingNode, comment) { return false; } -function handleLastFunctionArgComments( - text, - precedingNode, - enclosingNode, - followingNode, - comment -) { +function handleLastFunctionArgComments(comment, text) { + const { precedingNode, enclosingNode, followingNode } = comment; + // Flow function type definitions if ( precedingNode && @@ -659,7 +534,8 @@ function handleLastFunctionArgComments( return false; } -function handleImportSpecifierComments(enclosingNode, comment) { +function handleImportSpecifierComments(comment) { + const { enclosingNode } = comment; if (enclosingNode && enclosingNode.type === "ImportSpecifier") { addLeadingComment(enclosingNode, comment); return true; @@ -667,7 +543,8 @@ function handleImportSpecifierComments(enclosingNode, comment) { return false; } -function handleLabeledStatementComments(enclosingNode, comment) { +function handleLabeledStatementComments(comment) { + const { enclosingNode } = comment; if (enclosingNode && enclosingNode.type === "LabeledStatement") { addLeadingComment(enclosingNode, comment); return true; @@ -675,7 +552,8 @@ function handleLabeledStatementComments(enclosingNode, comment) { return false; } -function handleBreakAndContinueStatementComments(enclosingNode, comment) { +function handleBreakAndContinueStatementComments(comment) { + const { enclosingNode } = comment; if ( enclosingNode && (enclosingNode.type === "ContinueStatement" || @@ -688,7 +566,8 @@ function handleBreakAndContinueStatementComments(enclosingNode, comment) { return false; } -function handleCallExpressionComments(precedingNode, enclosingNode, comment) { +function handleCallExpressionComments(comment) { + const { precedingNode, enclosingNode } = comment; if ( enclosingNode && (enclosingNode.type === "CallExpression" || @@ -703,12 +582,8 @@ function handleCallExpressionComments(precedingNode, enclosingNode, comment) { return false; } -function handleUnionTypeComments( - precedingNode, - enclosingNode, - followingNode, - comment -) { +function handleUnionTypeComments(comment) { + const { precedingNode, enclosingNode, followingNode } = comment; if ( enclosingNode && (enclosingNode.type === "UnionTypeAnnotation" || @@ -738,7 +613,8 @@ function handleUnionTypeComments( return false; } -function handlePropertyComments(enclosingNode, comment) { +function handlePropertyComments(comment) { + const { enclosingNode } = comment; if ( enclosingNode && (enclosingNode.type === "Property" || @@ -750,7 +626,8 @@ function handlePropertyComments(enclosingNode, comment) { return false; } -function handleOnlyComments(enclosingNode, ast, comment, isLastComment) { +function handleOnlyComments(comment, ast, isLastComment) { + const { enclosingNode } = comment; // With Flow the enclosingNode is undefined so use the AST instead. if (ast && ast.body && ast.body.length === 0) { if (isLastComment) { @@ -776,7 +653,8 @@ function handleOnlyComments(enclosingNode, ast, comment, isLastComment) { return false; } -function handleForComments(enclosingNode, precedingNode, comment) { +function handleForComments(comment) { + const { enclosingNode } = comment; if ( enclosingNode && (enclosingNode.type === "ForInStatement" || @@ -788,12 +666,8 @@ function handleForComments(enclosingNode, precedingNode, comment) { return false; } -function handleImportDeclarationComments( - text, - enclosingNode, - precedingNode, - comment -) { +function handleImportDeclarationComments(comment, text) { + const { precedingNode, enclosingNode } = comment; if ( precedingNode && precedingNode.type === "ImportSpecifier" && @@ -807,7 +681,8 @@ function handleImportDeclarationComments( return false; } -function handleAssignmentPatternComments(enclosingNode, comment) { +function handleAssignmentPatternComments(comment) { + const { enclosingNode } = comment; if (enclosingNode && enclosingNode.type === "AssignmentPattern") { addLeadingComment(enclosingNode, comment); return true; @@ -815,7 +690,8 @@ function handleAssignmentPatternComments(enclosingNode, comment) { return false; } -function handleTypeAliasComments(enclosingNode, followingNode, comment) { +function handleTypeAliasComments(comment) { + const { enclosingNode } = comment; if (enclosingNode && enclosingNode.type === "TypeAlias") { addLeadingComment(enclosingNode, comment); return true; @@ -823,11 +699,8 @@ function handleTypeAliasComments(enclosingNode, followingNode, comment) { return false; } -function handleVariableDeclaratorComments( - enclosingNode, - followingNode, - comment -) { +function handleVariableDeclaratorComments(comment) { + const { enclosingNode, followingNode } = comment; if ( enclosingNode && (enclosingNode.type === "VariableDeclarator" || @@ -845,12 +718,8 @@ function handleVariableDeclaratorComments( return false; } -function handleTSFunctionTrailingComments( - text, - enclosingNode, - followingNode, - comment -) { +function handleTSFunctionTrailingComments(comment, text) { + const { enclosingNode, followingNode } = comment; if ( !followingNode && enclosingNode && @@ -865,13 +734,8 @@ function handleTSFunctionTrailingComments( return false; } -function handleIgnoreComments( - text, - enclosingNode, - precedingNode, - followingNode, - comment -) { +function handleIgnoreComments(comment) { + const { enclosingNode, followingNode } = comment; if ( isPrettierIgnoreComment(comment) && enclosingNode && @@ -886,13 +750,8 @@ function handleIgnoreComments( } } -function handleTSMappedTypeComments( - text, - enclosingNode, - precedingNode, - followingNode, - comment -) { +function handleTSMappedTypeComments(comment) { + const { precedingNode, enclosingNode, followingNode } = comment; if (!enclosingNode || enclosingNode.type !== "TSMappedType") { return false; } From 0e4ac80f32f2cf8e64aa60ac24cc05a201c6c0ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Nov 2020 10:51:17 +0000 Subject: [PATCH 025/299] Build(deps-dev): Bump eslint-plugin-jest from 24.1.0 to 24.1.3 (#9657) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 356959c6a..a0cfe5589 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "eslint-config-prettier": "6.15.0", "eslint-formatter-friendly": "7.0.0", "eslint-plugin-import": "2.22.1", - "eslint-plugin-jest": "24.1.0", + "eslint-plugin-jest": "24.1.3", "eslint-plugin-prettier-internal-rules": "file:scripts/tools/eslint-plugin-prettier-internal-rules", "eslint-plugin-react": "7.21.5", "eslint-plugin-unicorn": "23.0.0", diff --git a/yarn.lock b/yarn.lock index 9ee514fd6..df1c7b26c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3153,10 +3153,10 @@ eslint-plugin-import@2.22.1: resolve "^1.17.0" tsconfig-paths "^3.9.0" -eslint-plugin-jest@24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.1.0.tgz#6708037d7602e5288ce877fd0103f329dc978361" - integrity sha512-827YJ+E8B9PvXu/0eiVSNFfxxndbKv+qE/3GSMhdorCaeaOehtqHGX2YDW9B85TEOre9n/zscledkFW/KbnyGg== +eslint-plugin-jest@24.1.3: + version "24.1.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.1.3.tgz#fa3db864f06c5623ff43485ca6c0e8fc5fe8ba0c" + integrity sha512-dNGGjzuEzCE3d5EPZQ/QGtmlMotqnYWD/QpCZ1UuZlrMAdhG5rldh0N0haCvhGnUkSeuORS5VNROwF9Hrgn3Lg== dependencies: "@typescript-eslint/experimental-utils" "^4.0.1" From fb6b92e7c452a9f555cbefeba6e2a7e83d75f936 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Nov 2020 10:51:29 +0000 Subject: [PATCH 026/299] Build(deps): Bump @glimmer/syntax from 0.63.5 to 0.64.0 (#9656) --- package.json | 2 +- yarn.lock | 28 ++++++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index a0cfe5589..c6e1e2e82 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@angular/compiler": "10.2.3", "@babel/code-frame": "7.10.4", "@babel/parser": "7.12.5", - "@glimmer/syntax": "0.63.5", + "@glimmer/syntax": "0.64.0", "@iarna/toml": "2.2.5", "@typescript-eslint/typescript-estree": "3.10.1", "angular-estree-parser": "2.2.1", diff --git a/yarn.lock b/yarn.lock index df1c7b26c..8df84b7a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -908,6 +908,13 @@ dependencies: "@simple-dom/interface" "^1.4.0" +"@glimmer/interfaces@0.64.0": + version "0.64.0" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.64.0.tgz#8d6330ece98e20c97608ec6429fc9732824452bc" + integrity sha512-Y7HmwqtBNOzu9RL8N4WGQGGNCIO8REMORewMbnrZtLuFWcdDPCGVlNkxC77GStkHD+V54oEoW9Y+84MLFxkicg== + dependencies: + "@simple-dom/interface" "^1.4.0" + "@glimmer/reference@0.63.5": version "0.63.5" resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.63.5.tgz#bc99049c9400994641dea054e58bff61e1e31187" @@ -919,13 +926,13 @@ "@glimmer/util" "0.63.5" "@glimmer/validator" "0.63.5" -"@glimmer/syntax@0.63.5": - version "0.63.5" - resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.63.5.tgz#38ef6e41d9da3474ebc5d704c0e9743367de728e" - integrity sha512-w0/X7jQ5tzO6KevzeP1QBEfS2qjc897JlQa+9eMcFkxRxZCH4IVUjyxeRuu9cY0uV16ByVBTFh9fcGPfgaYULQ== +"@glimmer/syntax@0.64.0": + version "0.64.0" + resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.64.0.tgz#4e665c8936dfb93c17bb53a2f355342fa29662b5" + integrity sha512-BVziEjDC7EKvPv4O3B9hfkevihiqZkBlWBkZbTJe45wImfl+6A4KvwP/s8r5u/yAhYnsA3LO77IuoYYr/I08Tg== dependencies: - "@glimmer/interfaces" "0.63.5" - "@glimmer/util" "0.63.5" + "@glimmer/interfaces" "0.64.0" + "@glimmer/util" "0.64.0" "@handlebars/parser" "^1.1.0" simple-html-tokenizer "^0.5.10" @@ -938,6 +945,15 @@ "@glimmer/interfaces" "0.63.5" "@simple-dom/interface" "^1.4.0" +"@glimmer/util@0.64.0": + version "0.64.0" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.64.0.tgz#872103ebb2313a693161ec69e5b70252b56a6cd5" + integrity sha512-evcvCmQ2VUgWQF3ecDwtkwW+D+FL2f4Z0X8XDUgHQTGbA9PkqQRwyyD0WdURVPYpt3YkbR1VLapADll9fjpevg== + dependencies: + "@glimmer/env" "0.1.7" + "@glimmer/interfaces" "0.64.0" + "@simple-dom/interface" "^1.4.0" + "@glimmer/validator@0.63.5": version "0.63.5" resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.63.5.tgz#8d196f1f29191c5ecd60ea5c87d1081f68dff840" From 804684197821fdc40fb7ea160adf00fb03c02062 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Nov 2020 10:51:46 +0000 Subject: [PATCH 027/299] Build(deps): Bump n-readlines from 1.0.0 to 1.0.1 (#9647) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index c6e1e2e82..b9ec9f5a2 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "meriyah": "3.1.6", "minimatch": "3.0.4", "minimist": "1.2.5", - "n-readlines": "1.0.0", + "n-readlines": "1.0.1", "outdent": "0.7.1", "parse-srcset": "ikatyang/parse-srcset#54eb9c1cb21db5c62b4d0e275d7249516df6f0ee", "please-upgrade-node": "3.2.0", diff --git a/yarn.lock b/yarn.lock index 8df84b7a5..ff31b9ec6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5390,10 +5390,10 @@ multimap@^1.1.0: resolved "https://registry.yarnpkg.com/multimap/-/multimap-1.1.0.tgz#5263febc085a1791c33b59bb3afc6a76a2a10ca8" integrity sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw== -n-readlines@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/n-readlines/-/n-readlines-1.0.0.tgz#c353797f216c253fdfef7e91da4e8b17c29a91a6" - integrity sha512-ISDqGcspVu6U3VKqtJZG1uR55SmNNF9uK0EMq1IvNVVZOui6MW6VR0+pIZhqz85ORAGp+4zW+5fJ/SE7bwEibA== +n-readlines@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/n-readlines/-/n-readlines-1.0.1.tgz#bbb7364d38bc31a170a199f986fcacfa76b95f6e" + integrity sha512-z4SyAIVgMy7CkgsoNw7YVz40v0g4+WWvvqy8+ZdHrCtgevcEO758WQyrYcw3XPxcLxF+//RszTz/rO48nzD0wQ== nanomatch@^1.2.9: version "1.2.13" From e721ef30ea0ae287936b42e29e4d436ddcc5c06a Mon Sep 17 00:00:00 2001 From: Georgii Dolzhykov Date: Sat, 14 Nov 2020 13:17:01 +0200 Subject: [PATCH 028/299] Flatten function expression parameters in hugged last argument (#9662) Fixes #3376 This was done for arrow functions in #1305 ("Avoid breaking arguments for last arg expansion"). This PR enables the same for function expressions unless the function expression is the only argument. --- changelog_unreleased/javascript/pr-9662.md | 29 ++++ src/language-js/printer-estree.js | 15 +- .../__snapshots__/jsfmt.spec.js.snap | 142 ++++++++++++------ .../function-expression.js | 20 +++ 4 files changed, 158 insertions(+), 48 deletions(-) create mode 100644 changelog_unreleased/javascript/pr-9662.md create mode 100644 tests/js/last-argument-expansion/function-expression.js diff --git a/changelog_unreleased/javascript/pr-9662.md b/changelog_unreleased/javascript/pr-9662.md new file mode 100644 index 000000000..ec48a9bb3 --- /dev/null +++ b/changelog_unreleased/javascript/pr-9662.md @@ -0,0 +1,29 @@ +#### Flatten function expression parameters in hugged last argument (#9662 by @thorn0) + + +```jsx +// Prettier stable +function* mySagas() { + yield effects.takeEvery(rexpress.actionTypes.REQUEST_START, function* ({ + id + }) { + console.log(id); + yield rexpress.actions(store).writeHead(id, 400); + yield rexpress.actions(store).end(id, "pong"); + console.log("pong"); + }); +} + +// Prettier master +function* mySagas() { + yield effects.takeEvery( + rexpress.actionTypes.REQUEST_START, + function* ({ id }) { + console.log(id); + yield rexpress.actions(store).writeHead(id, 400); + yield rexpress.actions(store).end(id, "pong"); + console.log("pong"); + } + ); +} +``` diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index b6be2237f..d9473ed70 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -644,7 +644,16 @@ function printPathNoParens(path, options, print, args) { ]); case "FunctionDeclaration": case "FunctionExpression": - parts.push(printFunctionDeclaration(path, print, options)); + parts.push( + printFunctionDeclaration( + path, + print, + options, + args && + args.expandLastArg && + getCallArguments(path.getParentNode()).length > 1 + ) + ); if (!n.body) { parts.push(semi); } @@ -3736,7 +3745,7 @@ function canPrintParamsWithoutParens(node) { ); } -function printFunctionDeclaration(path, print, options) { +function printFunctionDeclaration(path, print, options, expandArg) { const n = path.getValue(); const parts = []; @@ -3758,7 +3767,7 @@ function printFunctionDeclaration(path, print, options) { printFunctionTypeParameters(path, options, print), group( concat([ - printFunctionParameters(path, print, options), + printFunctionParameters(path, print, options, expandArg), printReturnType(path, print, options), ]) ), diff --git a/tests/js/last-argument-expansion/__snapshots__/jsfmt.spec.js.snap b/tests/js/last-argument-expansion/__snapshots__/jsfmt.spec.js.snap index c52a30092..54cf63cff 100644 --- a/tests/js/last-argument-expansion/__snapshots__/jsfmt.spec.js.snap +++ b/tests/js/last-argument-expansion/__snapshots__/jsfmt.spec.js.snap @@ -186,26 +186,26 @@ a( exports.examples = [ { - render: withGraphQLQuery("node(1234567890){image{uri}}", function ( - container, - data - ) { - return ( -
- - - -
- ); - }), + render: withGraphQLQuery( + "node(1234567890){image{uri}}", + function (container, data) { + return ( +
+ + + +
+ ); + } + ), }, ]; @@ -217,32 +217,32 @@ someReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyReal ] ); -(function webpackUniversalModuleDefinition() {})(this, function ( - __WEBPACK_EXTERNAL_MODULE_85__, - __WEBPACK_EXTERNAL_MODULE_115__ -) { - return /******/ (function (modules) { - // webpackBootstrap - /******/ - })( - /************************************************************************/ - /******/ [ - /* 0 */ - /***/ function (module, exports, __webpack_require__) { - /***/ - }, - /* 1 */ - /***/ function (module, exports, __webpack_require__) { - /***/ - }, - /* 2 */ - /***/ function (module, exports, __webpack_require__) { - /***/ - }, +(function webpackUniversalModuleDefinition() {})( + this, + function (__WEBPACK_EXTERNAL_MODULE_85__, __WEBPACK_EXTERNAL_MODULE_115__) { + return /******/ (function (modules) { + // webpackBootstrap /******/ - ] - ); -}); + })( + /************************************************************************/ + /******/ [ + /* 0 */ + /***/ function (module, exports, __webpack_require__) { + /***/ + }, + /* 1 */ + /***/ function (module, exports, __webpack_require__) { + /***/ + }, + /* 2 */ + /***/ function (module, exports, __webpack_require__) { + /***/ + }, + /******/ + ] + ); + } +); ================================================================================ `; @@ -309,6 +309,58 @@ func( ================================================================================ `; +exports[`function-expression.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow"] +printWidth: 80 + | printWidth +=====================================input====================================== +function* mySagas() { + yield effects.takeEvery( + rexpress.actionTypes.REQUEST_START, + function*({ id }) { + console.log(id); + yield rexpress.actions(store).writeHead(id, 400); + yield rexpress.actions(store).end(id, 'pong'); + console.log('pong'); + } + ); +} + +function mySagas2() { + return effects.takeEvery( + rexpress.actionTypes.REQUEST_START, + function({ id }) { + console.log(id); + } + ); +} + +=====================================output===================================== +function* mySagas() { + yield effects.takeEvery( + rexpress.actionTypes.REQUEST_START, + function* ({ id }) { + console.log(id); + yield rexpress.actions(store).writeHead(id, 400); + yield rexpress.actions(store).end(id, "pong"); + console.log("pong"); + } + ); +} + +function mySagas2() { + return effects.takeEvery( + rexpress.actionTypes.REQUEST_START, + function ({ id }) { + console.log(id); + } + ); +} + +================================================================================ +`; + exports[`jsx.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow"] diff --git a/tests/js/last-argument-expansion/function-expression.js b/tests/js/last-argument-expansion/function-expression.js new file mode 100644 index 000000000..dc369091b --- /dev/null +++ b/tests/js/last-argument-expansion/function-expression.js @@ -0,0 +1,20 @@ +function* mySagas() { + yield effects.takeEvery( + rexpress.actionTypes.REQUEST_START, + function*({ id }) { + console.log(id); + yield rexpress.actions(store).writeHead(id, 400); + yield rexpress.actions(store).end(id, 'pong'); + console.log('pong'); + } + ); +} + +function mySagas2() { + return effects.takeEvery( + rexpress.actionTypes.REQUEST_START, + function({ id }) { + console.log(id); + } + ); +} From ae22b4716ffb2bde0c7ffd0546a3ac93281a960b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Nov 2020 11:51:20 +0000 Subject: [PATCH 029/299] Build(deps): Bump resolve from 1.18.1 to 1.19.0 (#9641) --- package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index b9ec9f5a2..f97576800 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "remark-footnotes": "2.0.0", "remark-math": "1.0.6", "remark-parse": "8.0.3", - "resolve": "1.18.1", + "resolve": "1.19.0", "semver": "7.3.2", "string-width": "4.2.0", "typescript": "4.0.5", diff --git a/yarn.lock b/yarn.lock index ff31b9ec6..ca5ddd2b7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4065,10 +4065,10 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.0.0.tgz#58531b70aed1db7c0e8d4eb1a0a2d1ddd64bd12d" - integrity sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw== +is-core-module@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.1.0.tgz#a4cc031d9b1aca63eecbd18a650e13cb4eeab946" + integrity sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA== dependencies: has "^1.0.3" @@ -6330,12 +6330,12 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@1.18.1, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.3.2: - version "1.18.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130" - integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== +resolve@1.19.0, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.3.2: + version "1.19.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" + integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== dependencies: - is-core-module "^2.0.0" + is-core-module "^2.1.0" path-parse "^1.0.6" ret@~0.1.10: From e56dbba6c71c941219f04fe199e52615acad2c48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Nov 2020 06:11:16 -0800 Subject: [PATCH 030/299] Build(deps-dev): Bump @glimmer/reference from 0.63.5 to 0.65.0 (#9675) --- package.json | 2 +- yarn.lock | 66 ++++++++++++++++++++++++++-------------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index f97576800..00580a2af 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "@babel/core": "7.12.3", "@babel/preset-env": "7.12.1", "@babel/types": "7.12.6", - "@glimmer/reference": "0.63.5", + "@glimmer/reference": "0.65.0", "@rollup/plugin-alias": "3.1.1", "@rollup/plugin-babel": "5.2.1", "@rollup/plugin-commonjs": "16.0.0", diff --git a/yarn.lock b/yarn.lock index ca5ddd2b7..3d6ad5d4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -894,20 +894,13 @@ resolved "https://registry.yarnpkg.com/@glimmer/env/-/env-0.1.7.tgz#fd2d2b55a9029c6b37a6c935e8c8871ae70dfa07" integrity sha1-/S0rVakCnGs3psk16MiHGucN+gc= -"@glimmer/global-context@0.63.5": - version "0.63.5" - resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.63.5.tgz#4a8da4fee97d13a376549ceecebd16a5ffc8c4f6" - integrity sha512-xYsptoxo9ROos83oxG8ZT4e8T2QgsH+FdZxsPZNTN4WLumU2LTkxJQaiosW9q294IVY/mIVhZAohJkfNCvSwug== +"@glimmer/global-context@0.65.0": + version "0.65.0" + resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.65.0.tgz#96d8b99d1a805be72d4dcf5d2eb90cd2ecfff550" + integrity sha512-czdgBmQRHFdrpKicZ1qJ0cd2yzNf/T4OV9VT+7dR356At3C7OWU0GJiIfA1IcW7nqS7x27rC8GDsUZm0ntEFRQ== dependencies: "@glimmer/env" "^0.1.7" -"@glimmer/interfaces@0.63.5": - version "0.63.5" - resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.63.5.tgz#ac614608ea618022b61b5d09e66089ceffc26e6e" - integrity sha512-ogozdIFOSxJ2QBU2NE0pk993qbb/zY1wF4BFL1ZN2GrfDDdaYC5vmDSs+RpbbF6JAjrt4kADXlOocs7dBiX4iQ== - dependencies: - "@simple-dom/interface" "^1.4.0" - "@glimmer/interfaces@0.64.0": version "0.64.0" resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.64.0.tgz#8d6330ece98e20c97608ec6429fc9732824452bc" @@ -915,16 +908,23 @@ dependencies: "@simple-dom/interface" "^1.4.0" -"@glimmer/reference@0.63.5": - version "0.63.5" - resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.63.5.tgz#bc99049c9400994641dea054e58bff61e1e31187" - integrity sha512-uE5O5eFcaKedomCDfendXjA7Sh9MYZG5RhadSSA8iD6TUlXxdpIe++tcRzNQOcMwHNbh+Bx7jX50jxtA1ShibQ== +"@glimmer/interfaces@0.65.0": + version "0.65.0" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.65.0.tgz#e3852efb63fc9f18268991caea4ab362b75ae231" + integrity sha512-Ka9/w1u7SjWt8ZKa3Gs9IbFtLLDlaCdCTO7B+/Lat0bxGIctyEAyjxUdVqUwXWO4pMfkEFWKBP3L/t9CRT8sVQ== + dependencies: + "@simple-dom/interface" "^1.4.0" + +"@glimmer/reference@0.65.0": + version "0.65.0" + resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.65.0.tgz#8863308d0865d45ae1fc5d07d5ccef9da4dff2d7" + integrity sha512-Cxb5Q91x+oV494dMtjx/fo5QudFCI1yJ4gg2Uj9hWWp2r8EqRmW2rlboLdnkjBDuY5MMuqwY9I8mc+SSAqQ46w== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.63.5" - "@glimmer/interfaces" "0.63.5" - "@glimmer/util" "0.63.5" - "@glimmer/validator" "0.63.5" + "@glimmer/global-context" "0.65.0" + "@glimmer/interfaces" "0.65.0" + "@glimmer/util" "0.65.0" + "@glimmer/validator" "0.65.0" "@glimmer/syntax@0.64.0": version "0.64.0" @@ -936,15 +936,6 @@ "@handlebars/parser" "^1.1.0" simple-html-tokenizer "^0.5.10" -"@glimmer/util@0.63.5": - version "0.63.5" - resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.63.5.tgz#8f2ed10269fcf6ccaf4cc0338915cc618ed845d0" - integrity sha512-9eTXOx3l6N1YySBMe1Vb/F+SGuztgObQCoEVtvxUZ7VB37xTaaUEoZfQVQJyBizFIKIAOvXBhPYCT+cERvN7kw== - dependencies: - "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.63.5" - "@simple-dom/interface" "^1.4.0" - "@glimmer/util@0.64.0": version "0.64.0" resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.64.0.tgz#872103ebb2313a693161ec69e5b70252b56a6cd5" @@ -954,13 +945,22 @@ "@glimmer/interfaces" "0.64.0" "@simple-dom/interface" "^1.4.0" -"@glimmer/validator@0.63.5": - version "0.63.5" - resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.63.5.tgz#8d196f1f29191c5ecd60ea5c87d1081f68dff840" - integrity sha512-+/YHIKrspDrqnAz4hE+VgIL2O6tZPxKA9KfI5syDcr+zxQeLjC/7ng6AK2g6+w8nHoS5WOABbA/gpH+wTV6ulQ== +"@glimmer/util@0.65.0": + version "0.65.0" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.65.0.tgz#8a90382500334e415415bf51b269bc7484b17543" + integrity sha512-tfsKVJpCJ5ADWXgpouiitIKlNacWQseYAlppgn8Y6LnzxcywgnumwFObkfzYlFE6Nd1IiymNxgEeSNJKylWl1A== + dependencies: + "@glimmer/env" "0.1.7" + "@glimmer/interfaces" "0.65.0" + "@simple-dom/interface" "^1.4.0" + +"@glimmer/validator@0.65.0": + version "0.65.0" + resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.65.0.tgz#e4411e0a979f002efe236e3bcc91de5f5aaeaed2" + integrity sha512-nwFReFT9zOOV+9iSqhNookTfHbOsqqPvtsALXl5Rn4QmtAHFLdehiWyN6ddb/sJwllWq+fNW8DxQdiY1xRwn9A== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.63.5" + "@glimmer/global-context" "0.65.0" "@handlebars/parser@^1.1.0": version "1.1.0" From 35a149702472dbb524e13af22beb074e816ec8d7 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 16 Nov 2020 01:03:35 +0800 Subject: [PATCH 031/299] Update `remark-math` to v3 (#7938) * bump remark-math to 3.0.1 * escape $ only it was escaped in the input * remove unsupported syntax from tests remark-math@3 doesn't support text after the closing fence ($$). Such $$ aren't parsed as a closing fence anymore. * refactor * add a test Co-authored-by: Georgii Dolzhykov --- changelog_unreleased/markdown/pr-7938.md | 19 +++++++++++++ package.json | 2 +- src/language-markdown/print-preprocess.js | 28 ++++++++----------- src/language-markdown/printer-markdown.js | 2 +- .../math/__snapshots__/jsfmt.spec.js.snap | 17 +++++++---- tests/markdown/math/math-like.md | 2 ++ tests/markdown/math/remark-math.md | 2 +- .../spec/__snapshots__/jsfmt.spec.js.snap | 2 +- yarn.lock | 12 ++++---- 9 files changed, 53 insertions(+), 33 deletions(-) create mode 100644 changelog_unreleased/markdown/pr-7938.md diff --git a/changelog_unreleased/markdown/pr-7938.md b/changelog_unreleased/markdown/pr-7938.md new file mode 100644 index 000000000..97e0b9d17 --- /dev/null +++ b/changelog_unreleased/markdown/pr-7938.md @@ -0,0 +1,19 @@ +#### Update remark-math to 3.0.1; escape dollar signs only if originally escaped (#7938 by @fisker and @thorn0) + + +```markdown + +Paragraph with $14 million. + +Paragraph with $14 million. But if more $dollars on the same line... + + +Paragraph with \$14 million. + +Paragraph with $14 million. But if more $dollars on the same line... + + +Paragraph with $14 million. + +Paragraph with $14 million. But if more $dollars on the same line... +``` diff --git a/package.json b/package.json index 00580a2af..e76adcff4 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "postcss-values-parser": "2.0.1", "regexp-util": "1.2.2", "remark-footnotes": "2.0.0", - "remark-math": "1.0.6", + "remark-math": "3.0.1", "remark-parse": "8.0.3", "resolve": "1.19.0", "semver": "7.3.2", diff --git a/src/language-markdown/print-preprocess.js b/src/language-markdown/print-preprocess.js index 5b97c7e42..afde0c065 100644 --- a/src/language-markdown/print-preprocess.js +++ b/src/language-markdown/print-preprocess.js @@ -39,25 +39,21 @@ function transformInlineCode(ast) { } function restoreUnescapedCharacter(ast, options) { - return mapAst(ast, (node) => { - return node.type !== "text" + return mapAst(ast, (node) => + node.type !== "text" || + node.value === "*" || + node.value === "_" || // handle these cases in printer + !isSingleCharRegex.test(node.value) || + node.position.end.offset - node.position.start.offset === node.value.length ? node : { ...node, - value: - node.value !== "*" && - node.value !== "_" && - node.value !== "$" && // handle these cases in printer - isSingleCharRegex.test(node.value) && - node.position.end.offset - node.position.start.offset !== - node.value.length - ? options.originalText.slice( - node.position.start.offset, - node.position.end.offset - ) - : node.value, - }; - }); + value: options.originalText.slice( + node.position.start.offset, + node.position.end.offset + ), + } + ); } function mergeContinuousImportExport(ast) { diff --git a/src/language-markdown/printer-markdown.js b/src/language-markdown/printer-markdown.js index 17a6373a0..5ea2257b8 100644 --- a/src/language-markdown/printer-markdown.js +++ b/src/language-markdown/printer-markdown.js @@ -94,7 +94,7 @@ function genericPrint(path, options, print) { return printChildren(path, options, print); case "word": { let escapedValue = node.value - .replace(/[$*]/g, "\\$&") // escape all `*` and `$` (math) + .replace(/\*/g, "\\$&") // escape all `*` .replace( new RegExp( [ diff --git a/tests/markdown/math/__snapshots__/jsfmt.spec.js.snap b/tests/markdown/math/__snapshots__/jsfmt.spec.js.snap index 04f8107b4..a7f91efd7 100644 --- a/tests/markdown/math/__snapshots__/jsfmt.spec.js.snap +++ b/tests/markdown/math/__snapshots__/jsfmt.spec.js.snap @@ -15,11 +15,11 @@ $ \\\\\\$ =====================================output===================================== -\\$ +$ \\$ -\\\\\\$ +\\\\$ \\\\\\$ @@ -50,9 +50,13 @@ printWidth: 80 =====================================input====================================== $10 - $20 +Paragraph with $14 million. But if more $dollars on the same line... + =====================================output===================================== $10 - $20 +Paragraph with $14 million. But if more $dollars on the same line... + ================================================================================ `; @@ -136,7 +140,7 @@ $$ $$ must \\alpha -$$ be ignored +$$ --- @@ -156,7 +160,7 @@ $$ --- -\\$\\alpha\\$ +$\\alpha\\$ --- @@ -168,11 +172,11 @@ $$ --- -\`$\`\\alpha\\$ +\`$\`\\alpha$ --- -\\$\\alpha\`$\` foo +$\\alpha\`$\` foo --- @@ -223,6 +227,7 @@ $$ --- $$ +must \\alpha $$ diff --git a/tests/markdown/math/math-like.md b/tests/markdown/math/math-like.md index 832901386..95e606e37 100644 --- a/tests/markdown/math/math-like.md +++ b/tests/markdown/math/math-like.md @@ -1 +1,3 @@ $10 - $20 + +Paragraph with $14 million. But if more $dollars on the same line... diff --git a/tests/markdown/math/remark-math.md b/tests/markdown/math/remark-math.md index 1c1a6ca92..dbf1828d8 100644 --- a/tests/markdown/math/remark-math.md +++ b/tests/markdown/math/remark-math.md @@ -72,7 +72,7 @@ $$ $$ must \alpha -$$ be ignored +$$ --- diff --git a/tests/markdown/spec/__snapshots__/jsfmt.spec.js.snap b/tests/markdown/spec/__snapshots__/jsfmt.spec.js.snap index 5af5a7b02..4be0bcab9 100644 --- a/tests/markdown/spec/__snapshots__/jsfmt.spec.js.snap +++ b/tests/markdown/spec/__snapshots__/jsfmt.spec.js.snap @@ -10750,7 +10750,7 @@ proseWrap: "always" hello $.;'there =====================================output===================================== -hello \\$.;'there +hello $.;'there ================================================================================ `; diff --git a/yarn.lock b/yarn.lock index 3d6ad5d4a..a9259cae6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6202,12 +6202,10 @@ remark-footnotes@2.0.0: resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-2.0.0.tgz#9001c4c2ffebba55695d2dd80ffb8b82f7e6303f" integrity sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ== -remark-math@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/remark-math/-/remark-math-1.0.6.tgz#49eb3dd15d298734c9ae21673115389793af4d1b" - integrity sha512-I43wU/QOQpXvVFXKjA4FHp5xptK65+5F6yolm8+69/JV0EqSOB64wURUZ3JK50JtnTL8FvwLiH2PZ+fvsBxviA== - dependencies: - trim-trailing-lines "^1.1.0" +remark-math@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/remark-math/-/remark-math-3.0.1.tgz#85a02a15b15cad34b89a27244d4887b3a95185bb" + integrity sha512-epT77R/HK0x7NqrWHdSV75uNLwn8g9qTyMqCRCDujL0vj/6T6+yhdrR7mjELWtkse+Fw02kijAaBuVcHBor1+Q== remark-parse@8.0.3: version "8.0.3" @@ -7083,7 +7081,7 @@ tr46@^2.0.2: dependencies: punycode "^2.1.1" -trim-trailing-lines@^1.0.0, trim-trailing-lines@^1.1.0: +trim-trailing-lines@^1.0.0: version "1.1.3" resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz#7f0739881ff76657b7776e10874128004b625a94" integrity sha512-4ku0mmjXifQcTVfYDfR5lpgV7zVqPg6zV9rdZmwOPqq0+Zq19xDqEgagqVbc4pOOShbncuAOIs59R3+3gcF3ZA== From f9f66711b9ecee811a9f3a6855cb646cf39fea2a Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 16 Nov 2020 01:11:53 +0800 Subject: [PATCH 032/299] Fix comments in `require()` with no argument (#9670) --- changelog_unreleased/javascript/pr-9670.md | 13 ++++ src/language-js/printer-estree.js | 16 ++-- .../__snapshots__/jsfmt.spec.js.snap | 73 +++++++++++++++++++ tests/js/call/no-argument/import.js | 2 + tests/js/call/no-argument/jsfmt.spec.js | 8 ++ tests/js/call/no-argument/special-cases.js | 6 ++ 6 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 changelog_unreleased/javascript/pr-9670.md create mode 100644 tests/js/call/no-argument/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/js/call/no-argument/import.js create mode 100644 tests/js/call/no-argument/jsfmt.spec.js create mode 100644 tests/js/call/no-argument/special-cases.js diff --git a/changelog_unreleased/javascript/pr-9670.md b/changelog_unreleased/javascript/pr-9670.md new file mode 100644 index 000000000..5c79184ec --- /dev/null +++ b/changelog_unreleased/javascript/pr-9670.md @@ -0,0 +1,13 @@ +#### Fix crash on `require(/* comment */)` (#9670 by @fisker) + + +```jsx +// Input +require(/* comment */) + +// Prettier stable +Error: Comment "comment" was not printed. Please report this error! + +// Prettier master +require(/* comment */); +``` diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index d9473ed70..a4f179e3b 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -974,19 +974,21 @@ function printPathNoParens(path, options, print, args) { const optional = printOptionalToken(path); const args = getCallArguments(n); if ( + // Dangling comments not handled, all these special cases should has argument #9668 + args.length > 0 && // We want to keep CommonJS- and AMD-style require calls, and AMD-style // define calls, as a unit. // e.g. `define(["some/lib", (lib) => {` - (!isDynamicImport && + ((!isDynamicImport && !isNew && n.callee.type === "Identifier" && (n.callee.name === "require" || n.callee.name === "define")) || - // Template literals as single arguments - (args.length === 1 && - isTemplateOnItsOwnLine(args[0], options.originalText)) || - // Keep test declarations on a single line - // e.g. `it('long name', () => {` - (!isNew && isTestCall(n, path.getParentNode())) + // Template literals as single arguments + (args.length === 1 && + isTemplateOnItsOwnLine(args[0], options.originalText)) || + // Keep test declarations on a single line + // e.g. `it('long name', () => {` + (!isNew && isTestCall(n, path.getParentNode()))) ) { const printed = []; iterateCallArgumentsPath(path, (argPath) => { diff --git a/tests/js/call/no-argument/__snapshots__/jsfmt.spec.js.snap b/tests/js/call/no-argument/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..d211bc9a1 --- /dev/null +++ b/tests/js/call/no-argument/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,73 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`import.js [espree] format 1`] = ` +"Unexpected token ) (1:21) +> 1 | import(/* comment */) + | ^ + 2 | new import(/* comment */) + 3 | " +`; + +exports[`import.js [flow] format 1`] = ` +"Unexpected token \`)\` (1:21) +> 1 | import(/* comment */) + | ^ + 2 | new import(/* comment */) + 3 | " +`; + +exports[`import.js [meriyah] format 1`] = ` +"[1:21]: Unexpected token: ')' (1:21) +> 1 | import(/* comment */) + | ^ + 2 | new import(/* comment */) + 3 | " +`; + +exports[`import.js [typescript] format 1`] = ` +"Expression expected. (2:5) + 1 | import(/* comment */) +> 2 | new import(/* comment */) + | ^ + 3 | " +`; + +exports[`import.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +import(/* comment */) +new import(/* comment */) + +=====================================output===================================== +import(/* comment */); +new import(/* comment */); + +================================================================================ +`; + +exports[`special-cases.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +require(/* comment */) +new require(/* comment */) +define(/* comment */) +new define(/* comment */) +it(/* comment */) +new it(/* comment */) + +=====================================output===================================== +require(/* comment */); +new require(/* comment */); +define(/* comment */); +new define(/* comment */); +it(/* comment */); +new it(/* comment */); + +================================================================================ +`; diff --git a/tests/js/call/no-argument/import.js b/tests/js/call/no-argument/import.js new file mode 100644 index 000000000..05c1f508b --- /dev/null +++ b/tests/js/call/no-argument/import.js @@ -0,0 +1,2 @@ +import(/* comment */) +new import(/* comment */) diff --git a/tests/js/call/no-argument/jsfmt.spec.js b/tests/js/call/no-argument/jsfmt.spec.js new file mode 100644 index 000000000..7fa97b7ad --- /dev/null +++ b/tests/js/call/no-argument/jsfmt.spec.js @@ -0,0 +1,8 @@ +run_spec(__dirname, ["babel", "flow", "typescript"], { + errors: { + espree: ["import.js"], + meriyah: ["import.js"], + flow: ["import.js"], + typescript: ["import.js"], + }, +}); diff --git a/tests/js/call/no-argument/special-cases.js b/tests/js/call/no-argument/special-cases.js new file mode 100644 index 000000000..23d50de2a --- /dev/null +++ b/tests/js/call/no-argument/special-cases.js @@ -0,0 +1,6 @@ +require(/* comment */) +new require(/* comment */) +define(/* comment */) +new define(/* comment */) +it(/* comment */) +new it(/* comment */) From dc541cc9b97540ad31d62c686d79610dce4c1a7d Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 16 Nov 2020 01:15:01 +0800 Subject: [PATCH 033/299] JS: Refactor embed (#9653) --- src/language-js/embed.js | 399 +--------------------- src/language-js/embed/css.js | 103 ++++++ src/language-js/embed/graphql.js | 114 +++++++ src/language-js/embed/html.js | 109 ++++++ src/language-js/embed/markdown.js | 42 +++ src/language-js/print/template-literal.js | 48 ++- src/language-js/printer-estree.js | 2 +- 7 files changed, 432 insertions(+), 385 deletions(-) create mode 100644 src/language-js/embed/css.js create mode 100644 src/language-js/embed/graphql.js create mode 100644 src/language-js/embed/html.js create mode 100644 src/language-js/embed/markdown.js diff --git a/src/language-js/embed.js b/src/language-js/embed.js index 9daf9b028..7c7ee3eb9 100644 --- a/src/language-js/embed.js +++ b/src/language-js/embed.js @@ -1,31 +1,20 @@ "use strict"; -const { - builders: { - indent, - join, - line, - hardline, - softline, - literalline, - concat, - group, - dedentToRoot, - lineSuffixBoundary, - }, - utils: { mapDoc, replaceNewlinesWithLiterallines }, -} = require("../document"); const { isBlockComment } = require("./utils"); const { hasLeadingComment } = require("./comments"); +const formatMarkdown = require("./embed/markdown"); +const formatCss = require("./embed/css"); +const formatGraphql = require("./embed/graphql"); +const formatHtml = require("./embed/html"); -function getParser(path) { +function getLanguage(path) { if ( isStyledJsx(path) || isStyledComponents(path) || isCssProp(path) || isAngularComponentStyles(path) ) { - return "scss"; + return "css"; } if (isGraphQL(path)) { @@ -57,130 +46,25 @@ function embed(path, print, textToDoc, options) { return; } - const parser = getParser(path); - if (!parser) { + const language = getLanguage(path); + if (!language) { return; } - if (parser === "markdown") { - let text = node.quasis[0].value.raw.replace( - /((?:\\\\)*)\\`/g, - (_, backslashes) => "\\".repeat(backslashes.length / 2) + "`" - ); - const indentation = getIndentation(text); - const hasIndent = indentation !== ""; - if (hasIndent) { - text = text.replace(new RegExp(`^${indentation}`, "gm"), ""); - } - const doc = printMarkdown(text, textToDoc); - return concat([ - "`", - hasIndent - ? indent(concat([softline, doc])) - : concat([literalline, dedentToRoot(doc)]), - softline, - "`", - ]); + if (language === "markdown") { + return formatMarkdown(path, print, textToDoc); } - const expressionDocs = path.map( - (path) => printTemplateExpression(path, print), - "expressions" - ); - - if (parser === "scss") { - // Get full template literal with expressions replaced by placeholders - const rawQuasis = node.quasis.map((q) => q.value.raw); - let placeholderID = 0; - const text = rawQuasis.reduce((prevVal, currVal, idx) => { - return idx === 0 - ? currVal - : prevVal + - "@prettier-placeholder-" + - placeholderID++ + - "-id" + - currVal; - }, ""); - const doc = textToDoc(text, { parser }, { stripTrailingHardline: true }); - return transformCssDoc(doc, node, expressionDocs); + if (language === "css") { + return formatCss(path, print, textToDoc); } - if (parser === "graphql") { - const numQuasis = node.quasis.length; - if (numQuasis === 1 && node.quasis[0].value.raw.trim() === "") { - return "``"; - } - - const parts = []; - - for (let i = 0; i < numQuasis; i++) { - const templateElement = node.quasis[i]; - const isFirst = i === 0; - const isLast = i === numQuasis - 1; - const text = templateElement.value.cooked; - - const lines = text.split("\n"); - const numLines = lines.length; - const expressionDoc = expressionDocs[i]; - - const startsWithBlankLine = - numLines > 2 && lines[0].trim() === "" && lines[1].trim() === ""; - const endsWithBlankLine = - numLines > 2 && - lines[numLines - 1].trim() === "" && - lines[numLines - 2].trim() === ""; - - const commentsAndWhitespaceOnly = lines.every((line) => - /^\s*(?:#[^\n\r]*)?$/.test(line) - ); - - // Bail out if an interpolation occurs within a comment. - if (!isLast && /#[^\n\r]*$/.test(lines[numLines - 1])) { - return null; - } - - let doc = null; - - if (commentsAndWhitespaceOnly) { - doc = printGraphqlComments(lines); - } else { - doc = textToDoc(text, { parser }, { stripTrailingHardline: true }); - } - - if (doc) { - doc = escapeTemplateCharacters(doc, false); - if (!isFirst && startsWithBlankLine) { - parts.push(""); - } - parts.push(doc); - if (!isLast && endsWithBlankLine) { - parts.push(""); - } - } else if (!isFirst && !isLast && startsWithBlankLine) { - parts.push(""); - } - - if (expressionDoc) { - parts.push(expressionDoc); - } - } - - return concat([ - "`", - indent(concat([hardline, join(hardline, parts)])), - hardline, - "`", - ]); + if (language === "graphql") { + return formatGraphql(path, print, textToDoc); } - if (parser === "html" || parser === "angular") { - return printHtmlTemplateLiteral( - node, - expressionDocs, - textToDoc, - parser, - options - ); + if (language === "html" || language === "angular") { + return formatHtml(path, print, textToDoc, options, { parser: language }); } } @@ -200,153 +84,6 @@ function isMarkdown(path) { ); } -function printTemplateExpression(path, print) { - const node = path.getValue(); - let printed = print(path); - if (node.comments && node.comments.length) { - printed = group(concat([indent(concat([softline, printed])), softline])); - } - return concat(["${", printed, lineSuffixBoundary, "}"]); -} - -function printMarkdown(text, textToDoc) { - const doc = textToDoc( - text, - { parser: "markdown", __inJsTemplate: true }, - { stripTrailingHardline: true } - ); - return escapeTemplateCharacters(doc, true); -} - -function getIndentation(str) { - const firstMatchedIndent = str.match(/^([^\S\n]*)\S/m); - return firstMatchedIndent === null ? "" : firstMatchedIndent[1]; -} - -function uncook(cookedValue) { - return cookedValue.replace(/([\\`]|\${)/g, "\\$1"); -} - -function escapeTemplateCharacters(doc, raw) { - return mapDoc(doc, (currentDoc) => { - if (!currentDoc.parts) { - return currentDoc; - } - - const parts = currentDoc.parts.map((part) => { - if (typeof part === "string") { - return raw ? part.replace(/(\\*)`/g, "$1$1\\`") : uncook(part); - } - - return part; - }); - - return { ...currentDoc, parts }; - }); -} - -function transformCssDoc(quasisDoc, parentNode, expressionDocs) { - const isEmpty = - parentNode.quasis.length === 1 && !parentNode.quasis[0].value.raw.trim(); - if (isEmpty) { - return "``"; - } - - const newDoc = replacePlaceholders(quasisDoc, expressionDocs); - /* istanbul ignore if */ - if (!newDoc) { - throw new Error("Couldn't insert all the expressions"); - } - return concat(["`", indent(concat([hardline, newDoc])), softline, "`"]); -} - -// Search all the placeholders in the quasisDoc tree -// and replace them with the expression docs one by one -// returns a new doc with all the placeholders replaced, -// or null if it couldn't replace any expression -function replacePlaceholders(quasisDoc, expressionDocs) { - if (!expressionDocs || !expressionDocs.length) { - return quasisDoc; - } - - let replaceCounter = 0; - const newDoc = mapDoc(quasisDoc, (doc) => { - if (!doc || !doc.parts || !doc.parts.length) { - return doc; - } - - let { parts } = doc; - const atIndex = parts.indexOf("@"); - const placeholderIndex = atIndex + 1; - if ( - atIndex > -1 && - typeof parts[placeholderIndex] === "string" && - parts[placeholderIndex].startsWith("prettier-placeholder") - ) { - // If placeholder is split, join it - const at = parts[atIndex]; - const placeholder = parts[placeholderIndex]; - const rest = parts.slice(placeholderIndex + 1); - parts = parts - .slice(0, atIndex) - .concat([at + placeholder]) - .concat(rest); - } - - const replacedParts = []; - parts.forEach((part) => { - if (typeof part !== "string" || !part.includes("@prettier-placeholder")) { - replacedParts.push(part); - return; - } - - // When we have multiple placeholders in one line, like: - // ${Child}${Child2}:not(:first-child) - part.split(/@prettier-placeholder-(\d+)-id/).forEach((component, idx) => { - // The placeholder is always at odd indices - if (idx % 2 === 0) { - replacedParts.push(replaceNewlinesWithLiterallines(component)); - return; - } - - // The component will always be a number at odd index - replacedParts.push(expressionDocs[component]); - replaceCounter++; - }); - }); - return { ...doc, parts: replacedParts }; - }); - return expressionDocs.length === replaceCounter ? newDoc : null; -} - -function printGraphqlComments(lines) { - const parts = []; - let seenComment = false; - - lines - .map((textLine) => textLine.trim()) - .forEach((textLine, i, array) => { - // Lines are either whitespace only, or a comment (with potential whitespace - // around it). Drop whitespace-only lines. - if (textLine === "") { - return; - } - - if (array[i - 1] === "" && seenComment) { - // If a non-first comment is preceded by a blank (whitespace only) line, - // add in a blank line. - parts.push(concat([hardline, textLine])); - } else { - parts.push(textLine); - } - - seenComment = true; - }); - - // If `lines` was whitespace only, return `null`. - return parts.length === 0 ? null : join(hardline, parts); -} - /** * Template literal in these contexts: * @@ -555,110 +292,6 @@ function isHtml(path) { ); } -// The counter is needed to distinguish nested embeds. -let htmlTemplateLiteralCounter = 0; - -function printHtmlTemplateLiteral( - node, - expressionDocs, - textToDoc, - parser, - options -) { - const counter = htmlTemplateLiteralCounter; - htmlTemplateLiteralCounter = (htmlTemplateLiteralCounter + 1) >>> 0; - - const composePlaceholder = (index) => - `PRETTIER_HTML_PLACEHOLDER_${index}_${counter}_IN_JS`; - - const text = node.quasis - .map((quasi, index, quasis) => - index === quasis.length - 1 - ? quasi.value.cooked - : quasi.value.cooked + composePlaceholder(index) - ) - .join(""); - - if (expressionDocs.length === 0 && text.trim().length === 0) { - return "``"; - } - - const placeholderRegex = new RegExp(composePlaceholder("(\\d+)"), "g"); - let topLevelCount = 0; - - const contentDoc = mapDoc( - textToDoc( - text, - { - parser, - __onHtmlRoot(root) { - topLevelCount = root.children.length; - }, - }, - { stripTrailingHardline: true } - ), - (doc) => { - if (typeof doc !== "string") { - return doc; - } - - const parts = []; - - const components = doc.split(placeholderRegex); - for (let i = 0; i < components.length; i++) { - let component = components[i]; - - if (i % 2 === 0) { - if (component) { - component = uncook(component); - if (options.embeddedInHtml) { - component = component.replace(/<\/(script)\b/gi, "<\\/$1"); - } - parts.push(component); - } - continue; - } - - const placeholderIndex = +component; - parts.push(expressionDocs[placeholderIndex]); - } - - return concat(parts); - } - ); - - const leadingWhitespace = /^\s/.test(text) ? " " : ""; - const trailingWhitespace = /\s$/.test(text) ? " " : ""; - - const linebreak = - options.htmlWhitespaceSensitivity === "ignore" - ? hardline - : leadingWhitespace && trailingWhitespace - ? line - : null; - - if (linebreak) { - return group( - concat([ - "`", - indent(concat([linebreak, group(contentDoc)])), - linebreak, - "`", - ]) - ); - } - - return group( - concat([ - "`", - leadingWhitespace, - topLevelCount > 1 ? indent(group(contentDoc)) : group(contentDoc), - trailingWhitespace, - "`", - ]) - ); -} - function hasInvalidCookedValue({ quasis }) { return quasis.some(({ value: { cooked } }) => cooked === null); } diff --git a/src/language-js/embed/css.js b/src/language-js/embed/css.js new file mode 100644 index 000000000..3ee4e1fa3 --- /dev/null +++ b/src/language-js/embed/css.js @@ -0,0 +1,103 @@ +"use strict"; + +const { + builders: { indent, hardline, softline, concat }, + utils: { mapDoc, replaceNewlinesWithLiterallines }, +} = require("../../document"); +const { printTemplateExpressions } = require("../print/template-literal"); + +function format(path, print, textToDoc) { + const node = path.getValue(); + + // Get full template literal with expressions replaced by placeholders + const rawQuasis = node.quasis.map((q) => q.value.raw); + let placeholderID = 0; + const text = rawQuasis.reduce((prevVal, currVal, idx) => { + return idx === 0 + ? currVal + : prevVal + "@prettier-placeholder-" + placeholderID++ + "-id" + currVal; + }, ""); + const doc = textToDoc( + text, + { parser: "scss" }, + { stripTrailingHardline: true } + ); + const expressionDocs = printTemplateExpressions(path, print); + return transformCssDoc(doc, node, expressionDocs); +} + +function transformCssDoc(quasisDoc, parentNode, expressionDocs) { + const isEmpty = + parentNode.quasis.length === 1 && !parentNode.quasis[0].value.raw.trim(); + if (isEmpty) { + return "``"; + } + + const newDoc = replacePlaceholders(quasisDoc, expressionDocs); + /* istanbul ignore if */ + if (!newDoc) { + throw new Error("Couldn't insert all the expressions"); + } + return concat(["`", indent(concat([hardline, newDoc])), softline, "`"]); +} + +// Search all the placeholders in the quasisDoc tree +// and replace them with the expression docs one by one +// returns a new doc with all the placeholders replaced, +// or null if it couldn't replace any expression +function replacePlaceholders(quasisDoc, expressionDocs) { + if (!expressionDocs || !expressionDocs.length) { + return quasisDoc; + } + + let replaceCounter = 0; + const newDoc = mapDoc(quasisDoc, (doc) => { + if (!doc || !doc.parts || !doc.parts.length) { + return doc; + } + + let { parts } = doc; + const atIndex = parts.indexOf("@"); + const placeholderIndex = atIndex + 1; + if ( + atIndex > -1 && + typeof parts[placeholderIndex] === "string" && + parts[placeholderIndex].startsWith("prettier-placeholder") + ) { + // If placeholder is split, join it + const at = parts[atIndex]; + const placeholder = parts[placeholderIndex]; + const rest = parts.slice(placeholderIndex + 1); + parts = parts + .slice(0, atIndex) + .concat([at + placeholder]) + .concat(rest); + } + + const replacedParts = []; + parts.forEach((part) => { + if (typeof part !== "string" || !part.includes("@prettier-placeholder")) { + replacedParts.push(part); + return; + } + + // When we have multiple placeholders in one line, like: + // ${Child}${Child2}:not(:first-child) + part.split(/@prettier-placeholder-(\d+)-id/).forEach((component, idx) => { + // The placeholder is always at odd indices + if (idx % 2 === 0) { + replacedParts.push(replaceNewlinesWithLiterallines(component)); + return; + } + + // The component will always be a number at odd index + replacedParts.push(expressionDocs[component]); + replaceCounter++; + }); + }); + return { ...doc, parts: replacedParts }; + }); + return expressionDocs.length === replaceCounter ? newDoc : null; +} + +module.exports = format; diff --git a/src/language-js/embed/graphql.js b/src/language-js/embed/graphql.js new file mode 100644 index 000000000..ba0b4efe1 --- /dev/null +++ b/src/language-js/embed/graphql.js @@ -0,0 +1,114 @@ +"use strict"; + +const { + builders: { indent, join, hardline, concat }, +} = require("../../document"); +const { + escapeTemplateCharacters, + printTemplateExpressions, +} = require("../print/template-literal"); + +function format(path, print, textToDoc) { + const node = path.getValue(); + + const numQuasis = node.quasis.length; + if (numQuasis === 1 && node.quasis[0].value.raw.trim() === "") { + return "``"; + } + + const expressionDocs = printTemplateExpressions(path, print); + const parts = []; + + for (let i = 0; i < numQuasis; i++) { + const templateElement = node.quasis[i]; + const isFirst = i === 0; + const isLast = i === numQuasis - 1; + const text = templateElement.value.cooked; + + const lines = text.split("\n"); + const numLines = lines.length; + const expressionDoc = expressionDocs[i]; + + const startsWithBlankLine = + numLines > 2 && lines[0].trim() === "" && lines[1].trim() === ""; + const endsWithBlankLine = + numLines > 2 && + lines[numLines - 1].trim() === "" && + lines[numLines - 2].trim() === ""; + + const commentsAndWhitespaceOnly = lines.every((line) => + /^\s*(?:#[^\n\r]*)?$/.test(line) + ); + + // Bail out if an interpolation occurs within a comment. + if (!isLast && /#[^\n\r]*$/.test(lines[numLines - 1])) { + return null; + } + + let doc = null; + + if (commentsAndWhitespaceOnly) { + doc = printGraphqlComments(lines); + } else { + doc = textToDoc( + text, + { parser: "graphql" }, + { stripTrailingHardline: true } + ); + } + + if (doc) { + doc = escapeTemplateCharacters(doc, false); + if (!isFirst && startsWithBlankLine) { + parts.push(""); + } + parts.push(doc); + if (!isLast && endsWithBlankLine) { + parts.push(""); + } + } else if (!isFirst && !isLast && startsWithBlankLine) { + parts.push(""); + } + + if (expressionDoc) { + parts.push(expressionDoc); + } + } + + return concat([ + "`", + indent(concat([hardline, join(hardline, parts)])), + hardline, + "`", + ]); +} + +function printGraphqlComments(lines) { + const parts = []; + let seenComment = false; + + lines + .map((textLine) => textLine.trim()) + .forEach((textLine, i, array) => { + // Lines are either whitespace only, or a comment (with potential whitespace + // around it). Drop whitespace-only lines. + if (textLine === "") { + return; + } + + if (array[i - 1] === "" && seenComment) { + // If a non-first comment is preceded by a blank (whitespace only) line, + // add in a blank line. + parts.push(concat([hardline, textLine])); + } else { + parts.push(textLine); + } + + seenComment = true; + }); + + // If `lines` was whitespace only, return `null`. + return parts.length === 0 ? null : join(hardline, parts); +} + +module.exports = format; diff --git a/src/language-js/embed/html.js b/src/language-js/embed/html.js new file mode 100644 index 000000000..f7042de40 --- /dev/null +++ b/src/language-js/embed/html.js @@ -0,0 +1,109 @@ +"use strict"; + +const { + builders: { indent, line, hardline, concat, group }, + utils: { mapDoc }, +} = require("../../document"); +const { + printTemplateExpressions, + uncookTemplateElementValue, +} = require("../print/template-literal"); + +// The counter is needed to distinguish nested embeds. +let htmlTemplateLiteralCounter = 0; +function format(path, print, textToDoc, options, { parser }) { + const node = path.getValue(); + const counter = htmlTemplateLiteralCounter; + htmlTemplateLiteralCounter = (htmlTemplateLiteralCounter + 1) >>> 0; + + const composePlaceholder = (index) => + `PRETTIER_HTML_PLACEHOLDER_${index}_${counter}_IN_JS`; + + const text = node.quasis + .map((quasi, index, quasis) => + index === quasis.length - 1 + ? quasi.value.cooked + : quasi.value.cooked + composePlaceholder(index) + ) + .join(""); + + const expressionDocs = printTemplateExpressions(path, print); + if (expressionDocs.length === 0 && text.trim().length === 0) { + return "``"; + } + + const placeholderRegex = new RegExp(composePlaceholder("(\\d+)"), "g"); + let topLevelCount = 0; + const doc = textToDoc( + text, + { + parser, + __onHtmlRoot(root) { + topLevelCount = root.children.length; + }, + }, + { stripTrailingHardline: true } + ); + + const contentDoc = mapDoc(doc, (doc) => { + if (typeof doc !== "string") { + return doc; + } + + const parts = []; + + const components = doc.split(placeholderRegex); + for (let i = 0; i < components.length; i++) { + let component = components[i]; + + if (i % 2 === 0) { + if (component) { + component = uncookTemplateElementValue(component); + if (options.embeddedInHtml) { + component = component.replace(/<\/(script)\b/gi, "<\\/$1"); + } + parts.push(component); + } + continue; + } + + const placeholderIndex = +component; + parts.push(expressionDocs[placeholderIndex]); + } + + return concat(parts); + }); + + const leadingWhitespace = /^\s/.test(text) ? " " : ""; + const trailingWhitespace = /\s$/.test(text) ? " " : ""; + + const linebreak = + options.htmlWhitespaceSensitivity === "ignore" + ? hardline + : leadingWhitespace && trailingWhitespace + ? line + : null; + + if (linebreak) { + return group( + concat([ + "`", + indent(concat([linebreak, group(contentDoc)])), + linebreak, + "`", + ]) + ); + } + + return group( + concat([ + "`", + leadingWhitespace, + topLevelCount > 1 ? indent(group(contentDoc)) : group(contentDoc), + trailingWhitespace, + "`", + ]) + ); +} + +module.exports = format; diff --git a/src/language-js/embed/markdown.js b/src/language-js/embed/markdown.js new file mode 100644 index 000000000..2cef8f5d9 --- /dev/null +++ b/src/language-js/embed/markdown.js @@ -0,0 +1,42 @@ +"use strict"; + +const { + builders: { indent, softline, literalline, concat, dedentToRoot }, +} = require("../../document"); +const { escapeTemplateCharacters } = require("../print/template-literal"); + +function format(path, print, textToDoc) { + const node = path.getValue(); + let text = node.quasis[0].value.raw.replace( + /((?:\\\\)*)\\`/g, + (_, backslashes) => "\\".repeat(backslashes.length / 2) + "`" + ); + const indentation = getIndentation(text); + const hasIndent = indentation !== ""; + if (hasIndent) { + text = text.replace(new RegExp(`^${indentation}`, "gm"), ""); + } + const doc = escapeTemplateCharacters( + textToDoc( + text, + { parser: "markdown", __inJsTemplate: true }, + { stripTrailingHardline: true } + ), + true + ); + return concat([ + "`", + hasIndent + ? indent(concat([softline, doc])) + : concat([literalline, dedentToRoot(doc)]), + softline, + "`", + ]); +} + +function getIndentation(str) { + const firstMatchedIndent = str.match(/^([^\S\n]*)\S/m); + return firstMatchedIndent === null ? "" : firstMatchedIndent[1]; +} + +module.exports = format; diff --git a/src/language-js/print/template-literal.js b/src/language-js/print/template-literal.js index 5be829211..2ef4d77f9 100644 --- a/src/language-js/print/template-literal.js +++ b/src/language-js/print/template-literal.js @@ -14,6 +14,7 @@ const { addAlignmentToDoc, }, printer: { printDocToString }, + utils: { mapDoc }, } = require("../../document"); const { isBinaryish, @@ -190,4 +191,49 @@ function printJestEachTemplateLiteral(path, options, print) { } } -module.exports = printTemplateLiteral; +function printTemplateExpression(path, print) { + const node = path.getValue(); + let printed = print(path); + if (node.comments && node.comments.length) { + printed = group(concat([indent(concat([softline, printed])), softline])); + } + return concat(["${", printed, lineSuffixBoundary, "}"]); +} + +function printTemplateExpressions(path, print) { + return path.map( + (path) => printTemplateExpression(path, print), + "expressions" + ); +} + +function escapeTemplateCharacters(doc, raw) { + return mapDoc(doc, (currentDoc) => { + if (!currentDoc.parts) { + return currentDoc; + } + + const parts = currentDoc.parts.map((part) => { + if (typeof part === "string") { + return raw + ? part.replace(/(\\*)`/g, "$1$1\\`") + : uncookTemplateElementValue(part); + } + + return part; + }); + + return { ...currentDoc, parts }; + }); +} + +function uncookTemplateElementValue(cookedValue) { + return cookedValue.replace(/([\\`]|\${)/g, "\\$1"); +} + +module.exports = { + printTemplateLiteral, + printTemplateExpressions, + escapeTemplateCharacters, + uncookTemplateElementValue, +}; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index a4f179e3b..a6b8c0bc3 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -123,7 +123,7 @@ const { printFunctionParameters, shouldHugFunctionParameters, } = require("./print/function-parameters"); -const printTemplateLiteral = require("./print/template-literal"); +const { printTemplateLiteral } = require("./print/template-literal"); const needsQuoteProps = new WeakMap(); From ef6a2c5f8a448bb16bcbaeab06f29e2be98a958d Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 16 Nov 2020 08:56:45 +0800 Subject: [PATCH 034/299] Refactor: Simplify markdown table print (#9660) --- src/language-markdown/printer-markdown.js | 115 ++++++++-------------- 1 file changed, 43 insertions(+), 72 deletions(-) diff --git a/src/language-markdown/printer-markdown.js b/src/language-markdown/printer-markdown.js index 5ea2257b8..ec0644bc1 100644 --- a/src/language-markdown/printer-markdown.js +++ b/src/language-markdown/printer-markdown.js @@ -41,6 +41,10 @@ const { isAutolink, } = require("./utils"); +/** + * @typedef {import("../document").Doc} Doc + */ + const TRAILING_HARDLINE_NODES = new Set(["importExport"]); const SINGLE_LINE_NODE_TYPES = ["heading", "tableCell", "link", "wikiLink"]; const SIBLING_NODE_TYPES = new Set([ @@ -577,37 +581,34 @@ function printTable(path, options, print) { const hardlineWithoutBreakParent = hardline.parts[0]; const node = path.getValue(); - // { [rowIndex: number]: { [columnIndex: number]: string } } + const columnMaxWidths = []; + // { [rowIndex: number]: { [columnIndex: number]: {text: string, width: number} } } const contents = path.map( (rowPath) => - rowPath.map( - (cellPath) => printDocToString(cellPath.call(print), options).formatted, - "children" - ), + rowPath.map((cellPath, columnIndex) => { + const text = printDocToString(cellPath.call(print), options).formatted; + const width = getStringWidth(text); + columnMaxWidths[columnIndex] = Math.max( + columnMaxWidths[columnIndex] || 3, // minimum width = 3 (---, :--, :-:, --:) + width + ); + return { text, width }; + }, "children"), "children" ); - // Get the width of each column - const columnMaxWidths = contents.reduce( - (currentWidths, rowContents) => - currentWidths.map((width, columnIndex) => - Math.max(width, getStringWidth(rowContents[columnIndex])) - ), - contents[0].map(() => 3) // minimum width = 3 (---, :--, :-:, --:) - ); const alignedTable = printTableContents(/* isCompact */ false); - if (options.proseWrap !== "never") { return concat([breakParent, alignedTable]); } // Only if the --prose-wrap never is set and it exceeds the print width. const compactTable = printTableContents(/* isCompact */ true); - return concat([breakParent, group(ifBreak(compactTable, alignedTable))]); function printTableContents(isCompact) { - const parts = [printRow(contents[0], isCompact), printSeparator(isCompact)]; + /** @type{Doc[]} */ + const parts = [printRow(contents[0], isCompact), printAlign(isCompact)]; if (contents.length > 1) { parts.push( join( @@ -621,66 +622,36 @@ function printTable(path, options, print) { return join(hardlineWithoutBreakParent, parts); } - function printSeparator(isCompact) { - return concat([ - "| ", - join( - " | ", - columnMaxWidths.map((width, index) => { - const spaces = isCompact ? 3 : width; - switch (node.align[index]) { - case "left": - return ":" + "-".repeat(spaces - 1); - case "right": - return "-".repeat(spaces - 1) + ":"; - case "center": - return ":" + "-".repeat(spaces - 2) + ":"; - default: - return "-".repeat(spaces); - } - }) - ), - " |", - ]); + function printAlign(isCompact) { + const align = columnMaxWidths.map((width, index) => { + const align = node.align[index]; + const first = align === "center" || align === "left" ? ":" : "-"; + const last = align === "center" || align === "right" ? ":" : "-"; + const middle = isCompact ? "-" : "-".repeat(width - 2); + return `${first}${middle}${last}`; + }); + + return `| ${align.join(" | ")} |`; } function printRow(rowContents, isCompact) { - return concat([ - "| ", - join( - " | ", - isCompact - ? rowContents - : rowContents.map((rowContent, columnIndex) => { - switch (node.align[columnIndex]) { - case "right": - return alignRight(rowContent, columnMaxWidths[columnIndex]); - case "center": - return alignCenter(rowContent, columnMaxWidths[columnIndex]); - default: - return alignLeft(rowContent, columnMaxWidths[columnIndex]); - } - }) - ), - " |", - ]); - } + const columns = rowContents.map(({ text, width }, columnIndex) => { + if (isCompact) { + return text; + } + const spaces = columnMaxWidths[columnIndex] - width; + const align = node.align[columnIndex]; + let before = 0; + if (align === "right") { + before = spaces; + } else if (align === "center") { + before = Math.floor(spaces / 2); + } + const after = spaces - before; + return `${" ".repeat(before)}${text}${" ".repeat(after)}`; + }); - function alignLeft(text, width) { - const spaces = width - getStringWidth(text); - return concat([text, " ".repeat(spaces)]); - } - - function alignRight(text, width) { - const spaces = width - getStringWidth(text); - return concat([" ".repeat(spaces), text]); - } - - function alignCenter(text, width) { - const spaces = width - getStringWidth(text); - const left = Math.floor(spaces / 2); - const right = spaces - left; - return concat([" ".repeat(left), text, " ".repeat(right)]); + return `| ${columns.join(" | ")} |`; } } From fe789dc1d1014a9612949289310f42f36189845b Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Mon, 16 Nov 2020 14:17:36 +0900 Subject: [PATCH 035/299] Reuse dirPath variable (#9683) --- scripts/draft-blog-post.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/draft-blog-post.js b/scripts/draft-blog-post.js index 39f48c59a..2477a35d1 100644 --- a/scripts/draft-blog-post.js +++ b/scripts/draft-blog-post.js @@ -57,7 +57,7 @@ for (const dir of dirs) { } category.entries = fs - .readdirSync(path.join(changelogUnreleasedDir, dir.name)) + .readdirSync(dirPath) .filter((fileName) => /^pr-\d+\.md$/.test(fileName)) .map((fileName) => { const [title, ...rest] = fs From 8c85a1a35bdc0ede7ea22b13fedc9076ccd195e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Nov 2020 14:44:19 +0800 Subject: [PATCH 036/299] Build(deps): Bump flow-parser from 0.137.0 to 0.138.0 (#9688) Bumps [flow-parser](https://github.com/facebook/flow) from 0.137.0 to 0.138.0. - [Release notes](https://github.com/facebook/flow/releases) - [Changelog](https://github.com/facebook/flow/blob/master/Changelog.md) - [Commits](https://github.com/facebook/flow/compare/v0.137.0...v0.138.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e76adcff4..c49a83944 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "fast-glob": "3.2.4", "fast-json-stable-stringify": "2.1.0", "find-parent-dir": "0.3.0", - "flow-parser": "0.137.0", + "flow-parser": "0.138.0", "get-stdin": "8.0.0", "globby": "11.0.1", "graphql": "15.4.0", diff --git a/yarn.lock b/yarn.lock index a9259cae6..0f96e8f78 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3605,10 +3605,10 @@ flatten@^1.0.2: resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== -flow-parser@0.137.0: - version "0.137.0" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.137.0.tgz#8c05612ff9344648d8bcdeaa4c58d131e875d842" - integrity sha512-i3KXJZ8lhlQI0n+BoZzIeH/rv+fNvAiu1i9/s64MklBV+HuhFbycUML7367J2eng0gapLnwvYPFNaPZys8POsA== +flow-parser@0.138.0: + version "0.138.0" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.138.0.tgz#2d9818f6b804d66f90949dfa8b4892f3a0af546d" + integrity sha512-LFnTyjrv39UvCWl8NOcpByr/amj8a5k5z7isO2wv4T43nNrUnHQwX3rarTz9zcpHXkDAQv6X4MfQ4ZzJUptpbw== for-in@^1.0.2: version "1.0.2" From 8f5464d07b87f9e21a4a2947eb81fec86fdd1f15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Nov 2020 14:44:47 +0800 Subject: [PATCH 037/299] Build(deps-dev): Bump cspell from 4.1.5 to 4.2.0 (#9684) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 58 ++++++++++++++++++++++++++-------------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index c49a83944..592b8c40b 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "benchmark": "2.1.4", "builtin-modules": "3.1.0", "cross-env": "7.0.2", - "cspell": "4.1.5", + "cspell": "4.2.0", "eslint": "7.13.0", "eslint-config-prettier": "6.15.0", "eslint-formatter-friendly": "7.0.0", diff --git a/yarn.lock b/yarn.lock index 0f96e8f78..d1f92f697 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2675,25 +2675,25 @@ cspell-dict-typescript@^1.0.12: dependencies: configstore "^5.0.1" -cspell-glob@^0.1.21: - version "0.1.21" - resolved "https://registry.yarnpkg.com/cspell-glob/-/cspell-glob-0.1.21.tgz#a2993fa485fdc4ec3df128d11592cdcc10ac0e93" - integrity sha512-+xwxxB0QZRKKgehZP0Jp48mBKiYa3RkGb0XgxcBrEZr9u0GBLOYUDi6iDox9VR+/rihvUvQKt8tTRGsMyNKe0A== +cspell-glob@^0.1.23: + version "0.1.23" + resolved "https://registry.yarnpkg.com/cspell-glob/-/cspell-glob-0.1.23.tgz#63256b384ca2f010f02a8039a8e5f4b8c2e38156" + integrity sha512-Q6iBxMvxXtPB358jvw3sMSC9AcNecZcQ2aD3oYhmgXYJRxX3TDij/3iXMrDkTAKcZx8V2BBZQJo/aJxkYnP0/A== dependencies: micromatch "^4.0.2" -cspell-io@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/cspell-io/-/cspell-io-4.1.2.tgz#1683cbac336a84187e67bd5f34bd0deb96cfa563" - integrity sha512-FLLojKoCweQPYJBsze9KS9wNI8Cvvp84Zt/pwgNdkiqxPADZEsymIZ8U4xFdL3L+/k+LT2KhJZzxjeTI6/zsNA== +cspell-io@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/cspell-io/-/cspell-io-4.1.4.tgz#945b527c7e8f06c3c0329991bdcf63b6d04400b2" + integrity sha512-qWVBUpu/+HzWwyjBiAxYGgv/w5w5290kYBtT5D42qQ9x/GxTjrq3AILCeWOOh/JtU4XmpiI2QUuyWEsxLSldZw== dependencies: iconv-lite "^0.6.2" iterable-to-stream "^1.0.1" -cspell-lib@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/cspell-lib/-/cspell-lib-4.3.2.tgz#f1071322b26b4c9ae10c10802b108d01201b4b2a" - integrity sha512-d794ObE18mVblT6DSgvvaFaonkvNv4+HmBnR6IALZxd0AsS8AGxZ33t4o9mgcymiATvAzrZvG0u2zL0/onhNhw== +cspell-lib@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/cspell-lib/-/cspell-lib-4.3.4.tgz#471048dac762eb712c5390073ec7f61bf74690c0" + integrity sha512-ykbrrAiOwh8Q0X4H5tFuTvtKg+L2nthPgN/5eiw7y1SM8DU8/LVGavDI47qcJ4HJSwuSwZ4RH60Ol1Q5zwqh/Q== dependencies: comment-json "^4.1.0" configstore "^5.0.1" @@ -2730,37 +2730,37 @@ cspell-lib@^4.3.2: cspell-dict-scala "^1.0.17" cspell-dict-software-terms "^1.0.19" cspell-dict-typescript "^1.0.12" - cspell-io "^4.1.2" - cspell-trie-lib "^4.2.2" - cspell-util-bundle "^4.1.4" + cspell-io "^4.1.4" + cspell-trie-lib "^4.2.4" + cspell-util-bundle "^4.1.6" fs-extra "^9.0.1" gensequence "^3.1.1" minimatch "^3.0.4" resolve-from "^5.0.0" vscode-uri "^2.1.2" -cspell-trie-lib@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/cspell-trie-lib/-/cspell-trie-lib-4.2.2.tgz#0d3a2d6c8343a7f08fb78111f2a48ca2db8d5f6b" - integrity sha512-FKwubuKs7XhFIAZN8Twh4RUSKc1h2X+EHsaSu8Y4E9QIcz5vBKooejCC3HTCgTzARXbX4pw0HazehSDqjraE+g== +cspell-trie-lib@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/cspell-trie-lib/-/cspell-trie-lib-4.2.4.tgz#4a2f6368b63317ece6ad5cec33fc4fe404c44dfd" + integrity sha512-a+jknY90yav3yGndN9PDQLUeo9nFiGZ2a8j9NSiMkieRnFCHmH7iHOwwoXxiMJ6x4+0zeyhSYF1pXuNA7eE2pw== dependencies: gensequence "^3.1.1" -cspell-util-bundle@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/cspell-util-bundle/-/cspell-util-bundle-4.1.4.tgz#82f758b39572579b08d97aa1d9eedfd2c56f84d3" - integrity sha512-97TZTl3lqrKYVu63mf9FdekbqH6CYHRka4nUbRN0mm9bOv4L68ZE2k/DwcRuqWz7Rrc190oKOWV7USVZutgAeQ== +cspell-util-bundle@^4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/cspell-util-bundle/-/cspell-util-bundle-4.1.6.tgz#6bc54fe8e73e282f4dbe2e7683cc43e339cf9029" + integrity sha512-wpCmiZRNRZ1fEXuColE2qeX15qicfhgwibSt5zNm77PZYhgkSLam52nIgGlnzSQCCFtOp8iaUeUQy40lJ0V+3Q== -cspell@4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/cspell/-/cspell-4.1.5.tgz#cec599568898ccc401b3564dcdcacc8e519b9c2a" - integrity sha512-KIVZzQAMtSVsYGeFP5ljXPgbMor1jR49sVkSEHH2MdGFegTyMJZEVkgcwu7pTS0VRI+6O2k06/K3AKOJeK4WSg== +cspell@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/cspell/-/cspell-4.2.0.tgz#01fffa15dc7d102315edc67fa0b385decd4ee2d1" + integrity sha512-5hKiPYapirbSoCuPpTXnDLA47c4vMV3U+ScFP56YF4lhQiz7yAJnNrgK31RiMHkv/pIUIlnuaKZYDD/7fgEgxg== dependencies: chalk "^4.1.0" commander "^6.1.0" comment-json "^4.0.6" - cspell-glob "^0.1.21" - cspell-lib "^4.3.2" + cspell-glob "^0.1.23" + cspell-lib "^4.3.4" fs-extra "^9.0.1" gensequence "^3.1.1" get-stdin "^8.0.0" From c454d7783582ff51174d63dd0833601c71a3237a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Nov 2020 14:50:54 +0800 Subject: [PATCH 038/299] Build(deps-dev): Bump rollup from 2.33.1 to 2.33.2 (#9686) Bumps [rollup](https://github.com/rollup/rollup) from 2.33.1 to 2.33.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v2.33.1...v2.33.2) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 592b8c40b..440880dab 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "path-browserify": "1.0.1", "prettier": "2.1.2", "rimraf": "3.0.2", - "rollup": "2.33.1", + "rollup": "2.33.2", "rollup-plugin-node-globals": "1.4.0", "rollup-plugin-terser": "7.0.2", "shelljs": "0.8.4", diff --git a/yarn.lock b/yarn.lock index d1f92f697..23f0a2e35 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6389,10 +6389,10 @@ rollup-pluginutils@^2.3.1: dependencies: estree-walker "^0.6.1" -rollup@2.33.1: - version "2.33.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.33.1.tgz#802795164164ee63cd47769d8879c33ec8ae0c40" - integrity sha512-uY4O/IoL9oNW8MMcbA5hcOaz6tZTMIh7qJHx/tzIJm+n1wLoY38BLn6fuy7DhR57oNFLMbDQtDeJoFURt5933w== +rollup@2.33.2: + version "2.33.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.33.2.tgz#c4c76cd405a7605e6ebe90976398c46d4c2ea166" + integrity sha512-QPQ6/fWCrzHtSXkI269rhKaC7qXGghYBwXU04b1JsDZ6ibZa3DJ9D1SFAYRMgx1inDg0DaTbb3N4Z1NK/r3fhw== optionalDependencies: fsevents "~2.1.2" From 73613720164b5928648de26c7e5aa605d11b12cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Nov 2020 14:51:14 +0800 Subject: [PATCH 039/299] Build(deps): Bump @glimmer/syntax from 0.64.0 to 0.65.0 (#9685) Bumps [@glimmer/syntax](https://github.com/glimmerjs/glimmer-vm) from 0.64.0 to 0.65.0. - [Release notes](https://github.com/glimmerjs/glimmer-vm/releases) - [Changelog](https://github.com/glimmerjs/glimmer-vm/blob/master/CHANGELOG.md) - [Commits](https://github.com/glimmerjs/glimmer-vm/compare/v0.64.0...v0.65.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 28 ++++++---------------------- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 440880dab..17c7ccbf2 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@angular/compiler": "10.2.3", "@babel/code-frame": "7.10.4", "@babel/parser": "7.12.5", - "@glimmer/syntax": "0.64.0", + "@glimmer/syntax": "0.65.0", "@iarna/toml": "2.2.5", "@typescript-eslint/typescript-estree": "3.10.1", "angular-estree-parser": "2.2.1", diff --git a/yarn.lock b/yarn.lock index 23f0a2e35..84968eee6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -901,13 +901,6 @@ dependencies: "@glimmer/env" "^0.1.7" -"@glimmer/interfaces@0.64.0": - version "0.64.0" - resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.64.0.tgz#8d6330ece98e20c97608ec6429fc9732824452bc" - integrity sha512-Y7HmwqtBNOzu9RL8N4WGQGGNCIO8REMORewMbnrZtLuFWcdDPCGVlNkxC77GStkHD+V54oEoW9Y+84MLFxkicg== - dependencies: - "@simple-dom/interface" "^1.4.0" - "@glimmer/interfaces@0.65.0": version "0.65.0" resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.65.0.tgz#e3852efb63fc9f18268991caea4ab362b75ae231" @@ -926,25 +919,16 @@ "@glimmer/util" "0.65.0" "@glimmer/validator" "0.65.0" -"@glimmer/syntax@0.64.0": - version "0.64.0" - resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.64.0.tgz#4e665c8936dfb93c17bb53a2f355342fa29662b5" - integrity sha512-BVziEjDC7EKvPv4O3B9hfkevihiqZkBlWBkZbTJe45wImfl+6A4KvwP/s8r5u/yAhYnsA3LO77IuoYYr/I08Tg== +"@glimmer/syntax@0.65.0": + version "0.65.0" + resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.65.0.tgz#a4fd943ca558e15c77619d49a4d4500dd252868c" + integrity sha512-juVFrA62oFdr2FSxLMb7c3j7KU/onQlC7c4E9rnkivXqE7EmNGI7/+I48L/DsMmDOZDOf4bIhjeCWbXNB4dS9g== dependencies: - "@glimmer/interfaces" "0.64.0" - "@glimmer/util" "0.64.0" + "@glimmer/interfaces" "0.65.0" + "@glimmer/util" "0.65.0" "@handlebars/parser" "^1.1.0" simple-html-tokenizer "^0.5.10" -"@glimmer/util@0.64.0": - version "0.64.0" - resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.64.0.tgz#872103ebb2313a693161ec69e5b70252b56a6cd5" - integrity sha512-evcvCmQ2VUgWQF3ecDwtkwW+D+FL2f4Z0X8XDUgHQTGbA9PkqQRwyyD0WdURVPYpt3YkbR1VLapADll9fjpevg== - dependencies: - "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.64.0" - "@simple-dom/interface" "^1.4.0" - "@glimmer/util@0.65.0": version "0.65.0" resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.65.0.tgz#8a90382500334e415415bf51b269bc7484b17543" From 76c6d977fb19923832f59c5b5c47c6125df14d62 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Nov 2020 15:19:35 +0800 Subject: [PATCH 040/299] Build(deps): Bump linguist-languages from 7.11.1 to 7.12.1 (#9687) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: fisker --- package.json | 2 +- .../__tests__/__snapshots__/support-info.js.snap | 1 + yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 17c7ccbf2..49c1b927f 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "json5": "2.1.3", "leven": "3.1.0", "lines-and-columns": "1.1.6", - "linguist-languages": "7.11.1", + "linguist-languages": "7.12.1", "lodash": "4.17.20", "mem": "8.0.0", "meriyah": "3.1.6", diff --git a/tests_integration/__tests__/__snapshots__/support-info.js.snap b/tests_integration/__tests__/__snapshots__/support-info.js.snap index 5d9431681..b368e7d1e 100644 --- a/tests_integration/__tests__/__snapshots__/support-info.js.snap +++ b/tests_integration/__tests__/__snapshots__/support-info.js.snap @@ -495,6 +495,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\".jscsrc\\", \\".jshintrc\\", \\".jslintrc\\", + \\"devcontainer.json\\", \\"jsconfig.json\\", \\"language-configuration.json\\", \\"tsconfig.json\\", diff --git a/yarn.lock b/yarn.lock index 84968eee6..26d604b14 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5098,10 +5098,10 @@ lines-and-columns@1.1.6, lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -linguist-languages@7.11.1: - version "7.11.1" - resolved "https://registry.yarnpkg.com/linguist-languages/-/linguist-languages-7.11.1.tgz#69938a526bb6090c2fc173d0e440693bb0667818" - integrity sha512-+cRUk+1WTbydcdzipXQER2iilX+wMrb1LPkbkGuDP/IcGPJRDmOZH6Olf1iH6sHlHwPnJYiNJH39YsFCVZxvUQ== +linguist-languages@7.12.1: + version "7.12.1" + resolved "https://registry.yarnpkg.com/linguist-languages/-/linguist-languages-7.12.1.tgz#bf4928f25953ce3e00369cf956ac4d016923d55f" + integrity sha512-+2CmUIeNOvJ7MWn6MY5h7mpDcw62MjKjXKC1wH0zLYnDQnn/0/+j3LcWO0v4+M9Vh/yqbt0codmlA7Z82bDnLA== load-json-file@^2.0.0: version "2.0.0" From 386759c6f7d51ba1a608e6487ad2839407f27265 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 16 Nov 2020 15:19:50 +0800 Subject: [PATCH 041/299] Test: Allow multiple parsers in error test (#9648) --- .../__snapshots__/jsfmt.spec.js.snap | 4 +- tests/misc/errors/babel-flow/jsfmt.spec.js | 3 +- .../babel-ts/__snapshots__/jsfmt.spec.js.snap | 6 +-- .../__snapshots__/jsfmt.spec.js.snap | 2 +- .../flow/__snapshots__/jsfmt.spec.js.snap | 16 +++---- .../graphql/__snapshots__/jsfmt.spec.js.snap | 2 +- .../__snapshots__/jsfmt.spec.js.snap | 6 +-- .../invalid/__snapshots__/jsfmt.spec.js.snap | 42 ++++++++--------- tests/misc/errors/invalid/jsfmt.spec.js | 23 +++------ .../js/__snapshots__/jsfmt.spec.js.snap | 40 ++++++++-------- .../json/__snapshots__/jsfmt.spec.js.snap | 12 ++--- .../less/__snapshots__/jsfmt.spec.js.snap | 6 +-- .../__snapshots__/jsfmt.spec.js.snap | 26 +++++----- .../vue/__snapshots__/jsfmt.spec.js.snap | 6 +-- .../yaml/__snapshots__/jsfmt.spec.js.snap | 2 +- tests_config/run_spec.js | 47 ++++++++++--------- 16 files changed, 119 insertions(+), 124 deletions(-) diff --git a/tests/misc/errors/babel-flow/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/babel-flow/__snapshots__/jsfmt.spec.js.snap index d3842ea9e..dbf1f0a6c 100644 --- a/tests/misc/errors/babel-flow/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/babel-flow/__snapshots__/jsfmt.spec.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`async-arrow-invalid.js error test 1`] = ` +exports[`async-arrow-invalid.js [babel] format 1`] = ` "Type parameters must come after the async keyword, e.g. instead of \` async (3:1) 1 | // https://github.com/babel/babel/pull/11979 2 | @@ -9,7 +9,7 @@ exports[`async-arrow-invalid.js error test 1`] = ` 4 | " `; -exports[`async-arrow-invalid.js error test 2`] = ` +exports[`async-arrow-invalid.js [babel-flow] format 1`] = ` "Type parameters must come after the async keyword, e.g. instead of \` async (3:1) 1 | // https://github.com/babel/babel/pull/11979 2 | diff --git a/tests/misc/errors/babel-flow/jsfmt.spec.js b/tests/misc/errors/babel-flow/jsfmt.spec.js index 2ecb070a2..30c9667cc 100644 --- a/tests/misc/errors/babel-flow/jsfmt.spec.js +++ b/tests/misc/errors/babel-flow/jsfmt.spec.js @@ -1,2 +1 @@ -run_spec(__dirname, ["babel-flow"]); -run_spec(__dirname, ["babel"]); +run_spec(__dirname, ["babel-flow", "babel"]); diff --git a/tests/misc/errors/babel-ts/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/babel-ts/__snapshots__/jsfmt.spec.js.snap index e5c310454..f700fa83d 100644 --- a/tests/misc/errors/babel-ts/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/babel-ts/__snapshots__/jsfmt.spec.js.snap @@ -1,20 +1,20 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`type-annotation-expr-statement.ts error test 1`] = ` +exports[`type-annotation-expr-statement.ts [babel-ts] format 1`] = ` "Did not expect a type annotation here. (1:3) > 1 | (a: T); | ^ 2 | " `; -exports[`type-annotation-func.ts error test 1`] = ` +exports[`type-annotation-func.ts [babel-ts] format 1`] = ` "Did not expect a type annotation here. (1:10) > 1 | func(a: T); | ^ 2 | " `; -exports[`type-annotation-in-jsx.tsx error test 1`] = ` +exports[`type-annotation-in-jsx.tsx [babel-ts] format 1`] = ` "Did not expect a type annotation here. (3:22) 1 | function Foo() { 2 | return ( diff --git a/tests/misc/errors/broken-plugin/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/broken-plugin/__snapshots__/jsfmt.spec.js.snap index f96ac1f0f..d305d8102 100644 --- a/tests/misc/errors/broken-plugin/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/broken-plugin/__snapshots__/jsfmt.spec.js.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`snippet: #0 error test 1`] = `"Comment \\"comment\\" was not printed. Please report this error!"`; +exports[`snippet: #0 [missing-comments] format 1`] = `"Comment \\"comment\\" was not printed. Please report this error!"`; diff --git a/tests/misc/errors/flow/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/flow/__snapshots__/jsfmt.spec.js.snap index 1055035e4..dc8b03d92 100644 --- a/tests/misc/errors/flow/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/flow/__snapshots__/jsfmt.spec.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`async-arrow-invalid.js error test 1`] = ` +exports[`async-arrow-invalid.js [flow] format 1`] = ` "Unexpected token ILLEGAL (4:1) 2 | 3 | async () => {} @@ -8,42 +8,42 @@ exports[`async-arrow-invalid.js error test 1`] = ` | ^" `; -exports[`default-escaped.js error test 1`] = ` +exports[`default-escaped.js [flow] format 1`] = ` "Unexpected identifier, expected the token \`{\` (1:8) > 1 | export asyn\\\\u{63} from \\"async\\"; | ^^^^^^^^^^ 2 | " `; -exports[`dynamic-import.js error test 1`] = ` +exports[`dynamic-import.js [flow] format 1`] = ` "Unexpected token \`,\`, expected the token \`)\` (1:24) > 1 | import('./prettier.mjs', {}) | ^ 2 | " `; -exports[`function-async.js error test 1`] = ` +exports[`function-async.js [flow] format 1`] = ` "Unexpected token \`;\`, expected the token \`=>\` (2:11) 1 | // Flow can't parse this since \`v0.128.0\`, #8661 > 2 | async(); | ^" `; -exports[`module-attributes-dynamic.js error test 1`] = ` +exports[`module-attributes-dynamic.js [flow] format 1`] = ` "Unexpected token \`,\`, expected the token \`)\` (1:18) > 1 | import(\\"foo.json\\", { with: { type: \\"json\\" } }) | ^ 2 | " `; -exports[`module-attributes-static.js error test 1`] = ` +exports[`module-attributes-static.js [flow] format 1`] = ` "Unexpected token \`with\`, expected the token \`;\` (1:28) > 1 | import foo from \\"foo.json\\" with type: \\"json\\"; | ^^^^ 2 | " `; -exports[`newline-before-arrow.js error test 1`] = ` +exports[`newline-before-arrow.js [flow] format 1`] = ` "Illegal newline before arrow (2:1) 1 | async x > 2 | => x @@ -51,7 +51,7 @@ exports[`newline-before-arrow.js error test 1`] = ` 3 | " `; -exports[`number.js error test 1`] = ` +exports[`number.js [flow] format 1`] = ` "Unexpected token ILLEGAL (3:5) 1 | // https://github.com/babel/babel/pull/11854 2 | diff --git a/tests/misc/errors/graphql/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/graphql/__snapshots__/jsfmt.spec.js.snap index b76ad98e9..0db971b0a 100644 --- a/tests/misc/errors/graphql/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/graphql/__snapshots__/jsfmt.spec.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`type-interfaces.graphql error test 1`] = ` +exports[`type-interfaces.graphql [graphql] format 1`] = ` "Syntax Error: Unexpected \\"|\\". (5:21) 3 | # which will break seperator detection added in #7305 4 | diff --git a/tests/misc/errors/handlebars/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/handlebars/__snapshots__/jsfmt.spec.js.snap index cc16a9652..bc710fce6 100644 --- a/tests/misc/errors/handlebars/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/handlebars/__snapshots__/jsfmt.spec.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`invalid.hbs error test 1`] = ` +exports[`invalid.hbs [glimmer] format 1`] = ` "Parse error on line 2: x, {{@name} --------------^ @@ -11,7 +11,7 @@ Expecting 'CLOSE_RAW_BLOCK', 'CLOSE', 'CLOSE_UNESCAPED', 'OPEN_SEXPR', 'CLOSE_SE 3 | " `; -exports[`invalid-2.hbs error test 1`] = ` +exports[`invalid-2.hbs [glimmer] format 1`] = ` "Unclosed element \`@name\` (on line 3). (3:0) 1 | 2 | @@ -19,7 +19,7 @@ exports[`invalid-2.hbs error test 1`] = ` 4 | " `; -exports[`invalid-3.hbs error test 1`] = ` +exports[`invalid-3.hbs [glimmer] format 1`] = ` "Parse error on line 3: {{}} -----^ diff --git a/tests/misc/errors/invalid/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/invalid/__snapshots__/jsfmt.spec.js.snap index 0c8fd5a18..80ad23314 100644 --- a/tests/misc/errors/invalid/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/invalid/__snapshots__/jsfmt.spec.js.snap @@ -1,37 +1,37 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`snippet: #0 error test 1`] = ` +exports[`snippet: #0 [babel] format 1`] = ` "Unexpected token, expected \\"(\\" (1:5) > 1 | for each (a in b) {} | ^" `; -exports[`snippet: #0 error test 2`] = ` +exports[`snippet: #0 [babel-flow] format 1`] = ` +"Unexpected token, expected \\"(\\" (1:5) +> 1 | for each (a in b) {} + | ^" +`; + +exports[`snippet: #0 [babel-ts] format 1`] = ` +"Unexpected token, expected \\"(\\" (1:5) +> 1 | for each (a in b) {} + | ^" +`; + +exports[`snippet: #0 [espree] format 1`] = ` +"Unexpected token each (1:5) +> 1 | for each (a in b) {} + | ^" +`; + +exports[`snippet: #0 [flow] format 1`] = ` "Unexpected identifier, expected the token \`(\` (1:5) > 1 | for each (a in b) {} | ^^^^" `; -exports[`snippet: #0 error test 3`] = ` +exports[`snippet: #0 [typescript] format 1`] = ` "'(' expected. (1:5) > 1 | for each (a in b) {} | ^" `; - -exports[`snippet: #0 error test 4`] = ` -"Unexpected token, expected \\"(\\" (1:5) -> 1 | for each (a in b) {} - | ^" -`; - -exports[`snippet: #0 error test 5`] = ` -"Unexpected token, expected \\"(\\" (1:5) -> 1 | for each (a in b) {} - | ^" -`; - -exports[`snippet: #0 error test 6`] = ` -"Unexpected token each (1:5) -> 1 | for each (a in b) {} - | ^" -`; diff --git a/tests/misc/errors/invalid/jsfmt.spec.js b/tests/misc/errors/invalid/jsfmt.spec.js index a8e44852b..7912c9794 100644 --- a/tests/misc/errors/invalid/jsfmt.spec.js +++ b/tests/misc/errors/invalid/jsfmt.spec.js @@ -1,16 +1,7 @@ -for (const parser of [ - "babel", - "flow", - "typescript", - "babel-flow", - "babel-ts", - "espree", -]) { - run_spec( - { - dirname: __dirname, - snippets: ["for each (a in b) {}"], - }, - [parser] - ); -} +run_spec( + { + dirname: __dirname, + snippets: ["for each (a in b) {}"], + }, + ["babel", "flow", "typescript", "babel-flow", "babel-ts", "espree"] +); diff --git a/tests/misc/errors/js/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/js/__snapshots__/jsfmt.spec.js.snap index 8c01590d2..783e27cbf 100644 --- a/tests/misc/errors/js/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/js/__snapshots__/jsfmt.spec.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`html-like-comments.js error test 1`] = ` +exports[`html-like-comments.js [babel] format 1`] = ` "Unexpected token (3:1) 1 | // Only support HTML-like comment in HTML 2 | alert( @@ -11,28 +11,28 @@ exports[`html-like-comments.js error test 1`] = ` 6 | " `; -exports[`import-assertions-for-export-without-from.js error test 1`] = ` +exports[`import-assertions-for-export-without-from.js [babel] format 1`] = ` "Unexpected token, expected \\";\\" (1:16) > 1 | export { foo } assert { type: \\"json\\" }; | ^ 2 | " `; -exports[`import-assertions-with-parens.js error test 1`] = ` +exports[`import-assertions-with-parens.js [babel] format 1`] = ` "Unexpected token (1:19) > 1 | import \\"x\\" assert ({type: 'json'}); | ^ 2 | " `; -exports[`module-attributes.js error test 1`] = ` +exports[`module-attributes.js [babel] format 1`] = ` "Unexpected token, expected \\";\\" (1:28) > 1 | import foo from \\"foo.json\\" with type: \\"json\\"; | ^ 2 | " `; -exports[`no-for-in-init-concise-binary-in.js error test 1`] = ` +exports[`no-for-in-init-concise-binary-in.js [babel] format 1`] = ` "Unexpected token, expected \\")\\" (3:18) 1 | // https://github.com/babel/babel/pull/11931 2 | @@ -41,7 +41,7 @@ exports[`no-for-in-init-concise-binary-in.js error test 1`] = ` 4 | " `; -exports[`partial-template-strings.js error test 1`] = ` +exports[`partial-template-strings.js [babel] format 1`] = ` "Unexpected token (6:42) 4 | 5 | const Diagnostics = { @@ -52,43 +52,43 @@ exports[`partial-template-strings.js error test 1`] = ` 9 | Diagnostics.name_not_found(\\"foo\\"); // \\"'foo' not found.\\"" `; -exports[`snippet: #0 error test 1`] = ` +exports[`snippet: #0 [babel] format 1`] = ` "Binding should be performed on object property. (1:3) > 1 | ::%DebugPrint(null) | ^" `; -exports[`snippet: #1 error test 1`] = ` +exports[`snippet: #1 [babel] format 1`] = ` "Unexpected token (1:3) > 1 | a.%DebugPrint(); | ^" `; -exports[`snippet: #2 error test 1`] = ` +exports[`snippet: #2 [babel] format 1`] = ` "Unexpected token (1:11) > 1 | const i = %DebugPrint; | ^" `; -exports[`snippet: #3 error test 1`] = ` +exports[`snippet: #3 [babel] format 1`] = ` "Unexpected token (1:7) > 1 | f(x + ?) | ^" `; -exports[`snippet: #4 error test 1`] = ` +exports[`snippet: #4 [babel] format 1`] = ` "Unexpected token (1:5) > 1 | x + ? | ^" `; -exports[`snippet: #5 error test 1`] = ` +exports[`snippet: #5 [babel] format 1`] = ` "Unexpected token (1:1) > 1 | ?.f() | ^" `; -exports[`snippet: #6 error test 1`] = ` +exports[`snippet: #6 [babel] format 1`] = ` "Unexpected token (5:12) 3 | 4 | static isC(obj) { @@ -98,43 +98,43 @@ exports[`snippet: #6 error test 1`] = ` 7 | }" `; -exports[`snippet: #7 error test 1`] = ` +exports[`snippet: #7 [babel] format 1`] = ` "Unexpected token (1:7) > 1 | const #{ a, b } = #{ a: 1, b: 2 }; | ^" `; -exports[`snippet: #8 error test 1`] = ` +exports[`snippet: #8 [babel] format 1`] = ` "Unexpected token (1:7) > 1 | const #[a, b] = #[1, 2]; | ^" `; -exports[`snippet: #9 error test 1`] = ` +exports[`snippet: #9 [babel] format 1`] = ` "Tuple expressions starting with '[|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar' (1:1) > 1 | [| 1 |] | ^" `; -exports[`snippet: #10 error test 1`] = ` +exports[`snippet: #10 [babel] format 1`] = ` "Invalid decimal (1:1) > 1 | 0b101011101m; | ^" `; -exports[`snippet: #11 error test 1`] = ` +exports[`snippet: #11 [babel] format 1`] = ` "Invalid decimal (1:1) > 1 | 0x16432m; | ^" `; -exports[`snippet: #12 error test 1`] = ` +exports[`snippet: #12 [babel] format 1`] = ` "Invalid decimal (1:1) > 1 | 0o16432m; | ^" `; -exports[`static-import-source-should-not-has-extra-token.js error test 1`] = ` +exports[`static-import-source-should-not-has-extra-token.js [babel] format 1`] = ` "Unexpected token (4:16) 2 | // be parenthesized, that accidentally break #8016 3 | diff --git a/tests/misc/errors/json/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/json/__snapshots__/jsfmt.spec.js.snap index 3c7fb6bc4..c39a1a644 100644 --- a/tests/misc/errors/json/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/json/__snapshots__/jsfmt.spec.js.snap @@ -1,36 +1,36 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`snippet: #0 error test 1`] = ` +exports[`snippet: #0 [json-stringify] format 1`] = ` "ObjectProperty with shorthand=true is not allowed in JSON. (1:2) > 1 | {foo} | ^" `; -exports[`snippet: #1 error test 1`] = ` +exports[`snippet: #1 [json-stringify] format 1`] = ` "ObjectProperty with computed=true is not allowed in JSON. (1:2) > 1 | {[\\"foo\\"]:\\"bar\\"} | ^" `; -exports[`snippet: #2 error test 1`] = ` +exports[`snippet: #2 [json-stringify] format 1`] = ` "UnaryExpression with operator=\\"~\\" is not allowed in JSON. (1:9) > 1 | {\\"foo\\": ~1} | ^" `; -exports[`snippet: #3 error test 1`] = ` +exports[`snippet: #3 [json-stringify] format 1`] = ` "LogicalExpression is not allowed in JSON. (1:9) > 1 | {\\"foo\\": false || \\"bar\\"} | ^" `; -exports[`snippet: #4 error test 1`] = ` +exports[`snippet: #4 [json-stringify] format 1`] = ` "Identifier is not allowed in JSON. (1:9) > 1 | {\\"foo\\": undefined} | ^" `; -exports[`snippet: #5 error test 1`] = ` +exports[`snippet: #5 [json-stringify] format 1`] = ` "ArrowFunctionExpression is not allowed in JSON. (1:9) > 1 | {\\"foo\\": () => {}} | ^" diff --git a/tests/misc/errors/less/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/less/__snapshots__/jsfmt.spec.js.snap index ae6a1f615..1d010b2d6 100644 --- a/tests/misc/errors/less/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/less/__snapshots__/jsfmt.spec.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`inline-comment.less error test 1`] = ` +exports[`inline-comment.less [less] format 1`] = ` "CssSyntaxError: Unknown word (5:4) 3 | a{ 4 | prop @@ -11,7 +11,7 @@ exports[`inline-comment.less error test 1`] = ` 8 | }" `; -exports[`open-double-quote.less error test 1`] = ` +exports[`open-double-quote.less [less] format 1`] = ` "CssSyntaxError: Unclosed string (2:17) 1 | a { > 2 | background: url(\\" @@ -20,7 +20,7 @@ exports[`open-double-quote.less error test 1`] = ` 4 | " `; -exports[`open-sigle-quote.less error test 1`] = ` +exports[`open-sigle-quote.less [less] format 1`] = ` "CssSyntaxError: Unclosed string (2:17) 1 | a { > 2 | background: url(' diff --git a/tests/misc/errors/typescript/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/typescript/__snapshots__/jsfmt.spec.js.snap index 6b75a8729..a5ea5bf94 100644 --- a/tests/misc/errors/typescript/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/typescript/__snapshots__/jsfmt.spec.js.snap @@ -1,20 +1,20 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`default-escaped.ts error test 1`] = ` +exports[`default-escaped.ts [typescript] format 1`] = ` "Declaration or statement expected. (1:1) > 1 | export asyn\\\\u{63} from \\"async\\"; | ^ 2 | " `; -exports[`dynamic-import.ts error test 1`] = ` +exports[`dynamic-import.ts [typescript] format 1`] = ` "Dynamic import must have one specifier as an argument. (1:8) > 1 | import('./prettier.mjs', {}) | ^ 2 | " `; -exports[`invalid-jsx-1.ts error test 1`] = ` +exports[`invalid-jsx-1.ts [typescript] format 1`] = ` "Unexpected token. Did you mean \`{'>'}\` or \`>\`? (3:45) 1 | // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-9.html#-and--are-now-invalid-jsx-text-characters 2 | @@ -23,23 +23,23 @@ exports[`invalid-jsx-1.ts error test 1`] = ` 4 | " `; -exports[`issue-8773.ts error test 1`] = `"Comment \\"comment\\" was not printed. Please report this error!"`; +exports[`issue-8773.ts [typescript] format 1`] = `"Comment \\"comment\\" was not printed. Please report this error!"`; -exports[`module-attributes-dynamic.ts error test 1`] = ` +exports[`module-attributes-dynamic.ts [typescript] format 1`] = ` "Dynamic import must have one specifier as an argument. (1:8) > 1 | import(\\"foo.json\\", { with: { type: \\"json\\" } }) | ^ 2 | " `; -exports[`module-attributes-static.ts error test 1`] = ` +exports[`module-attributes-static.ts [typescript] format 1`] = ` "';' expected. (1:28) > 1 | import foo from \\"foo.json\\" with type: \\"json\\"; | ^ 2 | " `; -exports[`newline-before-arrow.ts error test 1`] = ` +exports[`newline-before-arrow.ts [typescript] format 1`] = ` "';' expected. (1:7) > 1 | async x | ^ @@ -47,37 +47,37 @@ exports[`newline-before-arrow.ts error test 1`] = ` 3 | " `; -exports[`snippet: #0 error test 1`] = ` +exports[`snippet: #0 [typescript] format 1`] = ` "Unexpected token. Did you mean \`{'}'}\` or \`}\`? (1:15) > 1 | let x1 =
}
; | ^" `; -exports[`snippet: #1 error test 1`] = ` +exports[`snippet: #1 [typescript] format 1`] = ` "Unexpected token. Did you mean \`{'>'}\` or \`>\`? (1:15) > 1 | let x2 =
>
; | ^" `; -exports[`snippet: #2 error test 1`] = ` +exports[`snippet: #2 [typescript] format 1`] = ` "':' expected. (1:21) > 1 | let x3 =
{\\"foo\\"}}
; | ^" `; -exports[`snippet: #3 error test 1`] = ` +exports[`snippet: #3 [typescript] format 1`] = ` "':' expected. (1:21) > 1 | let x4 =
{\\"foo\\"}>
; | ^" `; -exports[`snippet: #4 error test 1`] = ` +exports[`snippet: #4 [typescript] format 1`] = ` "Expression expected. (1:15) > 1 | let x5 =
}{\\"foo\\"}
; | ^" `; -exports[`snippet: #5 error test 1`] = ` +exports[`snippet: #5 [typescript] format 1`] = ` "Expression expected. (1:15) > 1 | let x6 =
>{\\"foo\\"}
; | ^" diff --git a/tests/misc/errors/vue/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/vue/__snapshots__/jsfmt.spec.js.snap index 1ec225d39..b78064eac 100644 --- a/tests/misc/errors/vue/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/vue/__snapshots__/jsfmt.spec.js.snap @@ -1,13 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`unclosed_tag.vue error test 1`] = ` +exports[`unclosed_tag.vue [vue] format 1`] = ` "Unexpected character \\"EOF\\" (2:1) 1 |
2 | | ^" `; -exports[`unclosed_tag_in_template.vue error test 1`] = ` +exports[`unclosed_tag_in_template.vue [vue] format 1`] = ` "Unexpected character \\"/\\" (4:2) 2 |

Templates are formatted as well... 3 | 7 | diff --git a/tests/misc/errors/yaml/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/yaml/__snapshots__/jsfmt.spec.js.snap index 0fdb2e7c2..f33b25c05 100644 --- a/tests/misc/errors/yaml/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/yaml/__snapshots__/jsfmt.spec.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`block-scalar-with-spaces-only.yml error test 1`] = ` +exports[`block-scalar-with-spaces-only.yml [yaml] format 1`] = ` "Block scalars with more-indented leading empty lines must use an explicit indentation indicator (1:21) > 1 | empty block scalar: > | ^ diff --git a/tests_config/run_spec.js b/tests_config/run_spec.js index 27e25c9fc..d2e2a1f04 100644 --- a/tests_config/run_spec.js +++ b/tests_config/run_spec.js @@ -70,6 +70,10 @@ const isUnstable = (filename, options) => { const shouldThrowOnFormat = (filename, options) => { const { errors = {} } = options; + if (errors === true) { + return true; + } + const files = errors[options.parser]; if (files === true || (Array.isArray(files) && files.includes(filename))) { @@ -98,6 +102,9 @@ function runSpec(fixtures, parsers, options) { // - syntax parser hasn't supported yet // - syntax errors that should throws const IS_ERROR_TESTS = isTestDirectory(dirname, "misc/errors"); + if (IS_ERROR_TESTS) { + options = { errors: true, ...options }; + } if (IS_PARSER_INFERENCE_TESTS) { parsers = [undefined]; @@ -146,16 +153,18 @@ function runSpec(fixtures, parsers, options) { const [parser] = parsers; const allParsers = [...parsers]; - if (parsers.includes("typescript") && !parsers.includes("babel-ts")) { - allParsers.push("babel-ts"); - } - - if (parsers.includes("babel") && isTestDirectory(dirname, "js")) { - if (!parsers.includes("espree") && !espreeDisabledTests.has(dirname)) { - allParsers.push("espree"); + if (!IS_ERROR_TESTS) { + if (parsers.includes("typescript") && !parsers.includes("babel-ts")) { + allParsers.push("babel-ts"); } - if (!parsers.includes("meriyah") && !meriyahDisabledTests.has(dirname)) { - allParsers.push("meriyah"); + + if (parsers.includes("babel") && isTestDirectory(dirname, "js")) { + if (!parsers.includes("espree") && !espreeDisabledTests.has(dirname)) { + allParsers.push("espree"); + } + if (!parsers.includes("meriyah") && !meriyahDisabledTests.has(dirname)) { + allParsers.push("meriyah"); + } } } @@ -173,16 +182,9 @@ function runSpec(fixtures, parsers, options) { filepath: filename, parser, }; - const formatWithMainParser = () => format(code, formatOptions); - - if (IS_ERROR_TESTS) { - test("error test", () => { - expect(formatWithMainParser).toThrowErrorMatchingSnapshot(); - }); - return; - } - - const mainParserFormatResult = formatWithMainParser(); + const mainParserFormatResult = shouldThrowOnFormat(name, formatOptions) + ? { options: formatOptions, error: true } + : format(code, formatOptions); for (const currentParser of allParsers) { runTest({ @@ -214,8 +216,11 @@ function runTest({ let formatResult = mainParserFormatResult; let formatTestTitle = "format"; - // Verify parsers - if (parser !== parsers[0]) { + // Verify parsers or error tests + if ( + mainParserFormatResult.error || + mainParserFormatOptions.parser !== parser + ) { formatTestTitle = `[${parser}] format`; formatOptions = { ...mainParserFormatResult.options, parser }; const runFormat = () => format(code, formatOptions); From ed49bf10a00dde513679576e2a4abe04fb2eac73 Mon Sep 17 00:00:00 2001 From: Florent Chehab Date: Mon, 16 Nov 2020 11:27:34 +0100 Subject: [PATCH 042/299] Moved pre-commit support to github.com/pre-commit/mirrors-prettier (#8937) Co-authored-by: fisker Cheung Co-authored-by: sosukesuzuki --- .pre-commit-hooks.yaml | 7 +++++-- docs/precommit.md | 4 ++-- website/versioned_docs/version-stable/precommit.md | 4 +++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index ac74494a2..510d631cb 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,4 +1,7 @@ +# Remove this file after year 2020 + - id: prettier name: prettier - entry: prettier --write --list-different --ignore-unknown - language: node + entry: Prettier support for pre-commit has been moved to https://github.com/pre-commit/mirrors-prettier, please use the new repository. + language: fail + pass_filenames: false diff --git a/docs/precommit.md b/docs/precommit.md index 24627270f..66f32326a 100644 --- a/docs/precommit.md +++ b/docs/precommit.md @@ -61,13 +61,13 @@ Read more at the [pretty-quick](https://github.com/azz/pretty-quick) repo. Copy the following config into your `.pre-commit-config.yaml` file: ```yaml -- repo: https://github.com/prettier/prettier +- repo: https://github.com/pre-commit/mirrors-prettier rev: "" # Use the sha or tag you want to point at hooks: - id: prettier ``` -Read more at the [pre-commit](https://pre-commit.com) website. +Read more at [mirror of prettier package for pre-commit](https://github.com/pre-commit/mirrors-prettier) and the [pre-commit](https://pre-commit.com) website. ## Option 4. [git-format-staged](https://github.com/hallettj/git-format-staged) diff --git a/website/versioned_docs/version-stable/precommit.md b/website/versioned_docs/version-stable/precommit.md index 9ea0cf8fe..4a0d7a6a7 100644 --- a/website/versioned_docs/version-stable/precommit.md +++ b/website/versioned_docs/version-stable/precommit.md @@ -62,12 +62,14 @@ Read more at the [pretty-quick](https://github.com/azz/pretty-quick) repo. Copy the following config into your `.pre-commit-config.yaml` file: ```yaml -- repo: https://github.com/prettier/prettier +- repo: https://github.com/pre-commit/mirrors-prettier rev: "" # Use the sha or tag you want to point at hooks: - id: prettier ``` +Read more at [mirror of prettier package for pre-commit](https://github.com/pre-commit/mirrors-prettier) and the [pre-commit](https://pre-commit.com) website. + Read more at the [pre-commit](https://pre-commit.com) website. ## Option 4. [git-format-staged](https://github.com/hallettj/git-format-staged) From e73576a64b2ce0f71873216be1cda46ec78aef4b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Nov 2020 07:59:26 +0000 Subject: [PATCH 043/299] Build(deps): Bump @glimmer/syntax from 0.65.0 to 0.66.0 (#9693) --- package.json | 2 +- .../__snapshots__/jsfmt.spec.js.snap | 9 +++++- yarn.lock | 28 +++++++++++++++---- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 49c1b927f..48d2655ca 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@angular/compiler": "10.2.3", "@babel/code-frame": "7.10.4", "@babel/parser": "7.12.5", - "@glimmer/syntax": "0.65.0", + "@glimmer/syntax": "0.66.0", "@iarna/toml": "2.2.5", "@typescript-eslint/typescript-estree": "3.10.1", "angular-estree-parser": "2.2.1", diff --git a/tests/misc/errors/handlebars/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/handlebars/__snapshots__/jsfmt.spec.js.snap index bc710fce6..ab5091dd0 100644 --- a/tests/misc/errors/handlebars/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/handlebars/__snapshots__/jsfmt.spec.js.snap @@ -12,10 +12,17 @@ Expecting 'CLOSE_RAW_BLOCK', 'CLOSE', 'CLOSE_UNESCAPED', 'OPEN_SEXPR', 'CLOSE_SE `; exports[`invalid-2.hbs [glimmer] format 1`] = ` -"Unclosed element \`@name\` (on line 3). (3:0) +"Syntax Error: Unclosed element \`@name\`: + +| +| <{@name> +| + +(error occurred in 'an unknown module' @ line 3 : column 0) (3:0) 1 | 2 | > 3 | <{@name> + | ^^^^^^^^ 4 | " `; diff --git a/yarn.lock b/yarn.lock index 26d604b14..22b186279 100644 --- a/yarn.lock +++ b/yarn.lock @@ -908,6 +908,13 @@ dependencies: "@simple-dom/interface" "^1.4.0" +"@glimmer/interfaces@0.66.0": + version "0.66.0" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.66.0.tgz#f281e1985d6b7f63648d960cc2745c68562fdb92" + integrity sha512-fw1pO6oyczSKeTPR6anrSI4OarLlaAR0SSDAhsYrINXfW7Xd/U/es7i6VE1JjLSZqfnsAxjNOFDe0lA5lmV/dw== + dependencies: + "@simple-dom/interface" "^1.4.0" + "@glimmer/reference@0.65.0": version "0.65.0" resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.65.0.tgz#8863308d0865d45ae1fc5d07d5ccef9da4dff2d7" @@ -919,13 +926,13 @@ "@glimmer/util" "0.65.0" "@glimmer/validator" "0.65.0" -"@glimmer/syntax@0.65.0": - version "0.65.0" - resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.65.0.tgz#a4fd943ca558e15c77619d49a4d4500dd252868c" - integrity sha512-juVFrA62oFdr2FSxLMb7c3j7KU/onQlC7c4E9rnkivXqE7EmNGI7/+I48L/DsMmDOZDOf4bIhjeCWbXNB4dS9g== +"@glimmer/syntax@0.66.0": + version "0.66.0" + resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.66.0.tgz#d38561be48f6c4deeb94c24a1344a3426bb7e925" + integrity sha512-sgGQvoLprHjGV/TW2WY5wTmJaUjkHHgXhRJp+nLL5+JVC1zoR/mbGJk2Wfbj/R5D3pKzPln08HsSdXKj9Dl36g== dependencies: - "@glimmer/interfaces" "0.65.0" - "@glimmer/util" "0.65.0" + "@glimmer/interfaces" "0.66.0" + "@glimmer/util" "0.66.0" "@handlebars/parser" "^1.1.0" simple-html-tokenizer "^0.5.10" @@ -938,6 +945,15 @@ "@glimmer/interfaces" "0.65.0" "@simple-dom/interface" "^1.4.0" +"@glimmer/util@0.66.0": + version "0.66.0" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.66.0.tgz#c457951951f4ea1d5a1d63fa11c9ffeae8efa4f6" + integrity sha512-4J3sihRKZ7N4igk2BZGryC/E6qIy+20d3Dl9+jYhsM8SdviPm+PtFy7tdJsb3E+u/yITqHnvzt7+Cr+VtlT7KA== + dependencies: + "@glimmer/env" "0.1.7" + "@glimmer/interfaces" "0.66.0" + "@simple-dom/interface" "^1.4.0" + "@glimmer/validator@0.65.0": version "0.65.0" resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.65.0.tgz#e4411e0a979f002efe236e3bcc91de5f5aaeaed2" From 688a06d35a51245986b661d8153b76b99b11c231 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Nov 2020 18:55:04 +0800 Subject: [PATCH 044/299] Build(deps-dev): Bump @glimmer/reference from 0.65.0 to 0.66.0 (#9695) Bumps @glimmer/reference from 0.65.0 to 0.66.0. Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 50 +++++++++++++++++--------------------------------- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index 48d2655ca..e02482f24 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "@babel/core": "7.12.3", "@babel/preset-env": "7.12.1", "@babel/types": "7.12.6", - "@glimmer/reference": "0.65.0", + "@glimmer/reference": "0.66.0", "@rollup/plugin-alias": "3.1.1", "@rollup/plugin-babel": "5.2.1", "@rollup/plugin-commonjs": "16.0.0", diff --git a/yarn.lock b/yarn.lock index 22b186279..192bbf370 100644 --- a/yarn.lock +++ b/yarn.lock @@ -894,20 +894,13 @@ resolved "https://registry.yarnpkg.com/@glimmer/env/-/env-0.1.7.tgz#fd2d2b55a9029c6b37a6c935e8c8871ae70dfa07" integrity sha1-/S0rVakCnGs3psk16MiHGucN+gc= -"@glimmer/global-context@0.65.0": - version "0.65.0" - resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.65.0.tgz#96d8b99d1a805be72d4dcf5d2eb90cd2ecfff550" - integrity sha512-czdgBmQRHFdrpKicZ1qJ0cd2yzNf/T4OV9VT+7dR356At3C7OWU0GJiIfA1IcW7nqS7x27rC8GDsUZm0ntEFRQ== +"@glimmer/global-context@0.66.0": + version "0.66.0" + resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.66.0.tgz#4efc0d90ffc33a07e2f86b1462e71541f4e36cdd" + integrity sha512-3kaSDZptEF3dmCO/rcQptJ0qZQub8ax1C19+IkuBnTbeYOEgdW61rPFdApqAzY/EydMjBmxZRLhS/IMRx4wJcQ== dependencies: "@glimmer/env" "^0.1.7" -"@glimmer/interfaces@0.65.0": - version "0.65.0" - resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.65.0.tgz#e3852efb63fc9f18268991caea4ab362b75ae231" - integrity sha512-Ka9/w1u7SjWt8ZKa3Gs9IbFtLLDlaCdCTO7B+/Lat0bxGIctyEAyjxUdVqUwXWO4pMfkEFWKBP3L/t9CRT8sVQ== - dependencies: - "@simple-dom/interface" "^1.4.0" - "@glimmer/interfaces@0.66.0": version "0.66.0" resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.66.0.tgz#f281e1985d6b7f63648d960cc2745c68562fdb92" @@ -915,16 +908,16 @@ dependencies: "@simple-dom/interface" "^1.4.0" -"@glimmer/reference@0.65.0": - version "0.65.0" - resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.65.0.tgz#8863308d0865d45ae1fc5d07d5ccef9da4dff2d7" - integrity sha512-Cxb5Q91x+oV494dMtjx/fo5QudFCI1yJ4gg2Uj9hWWp2r8EqRmW2rlboLdnkjBDuY5MMuqwY9I8mc+SSAqQ46w== +"@glimmer/reference@0.66.0": + version "0.66.0" + resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.66.0.tgz#3d1acb1755fe6c1660275aec7482cbc9935a656c" + integrity sha512-HNY2bxx+2/i5jEDQO5tVX3TZGVzCfpvVE5whkNxS+vDTV+E3KACWvxNz4e3cKbA98tYoZJjGw/jWOhgak3Bbvg== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.65.0" - "@glimmer/interfaces" "0.65.0" - "@glimmer/util" "0.65.0" - "@glimmer/validator" "0.65.0" + "@glimmer/global-context" "0.66.0" + "@glimmer/interfaces" "0.66.0" + "@glimmer/util" "0.66.0" + "@glimmer/validator" "0.66.0" "@glimmer/syntax@0.66.0": version "0.66.0" @@ -936,15 +929,6 @@ "@handlebars/parser" "^1.1.0" simple-html-tokenizer "^0.5.10" -"@glimmer/util@0.65.0": - version "0.65.0" - resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.65.0.tgz#8a90382500334e415415bf51b269bc7484b17543" - integrity sha512-tfsKVJpCJ5ADWXgpouiitIKlNacWQseYAlppgn8Y6LnzxcywgnumwFObkfzYlFE6Nd1IiymNxgEeSNJKylWl1A== - dependencies: - "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.65.0" - "@simple-dom/interface" "^1.4.0" - "@glimmer/util@0.66.0": version "0.66.0" resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.66.0.tgz#c457951951f4ea1d5a1d63fa11c9ffeae8efa4f6" @@ -954,13 +938,13 @@ "@glimmer/interfaces" "0.66.0" "@simple-dom/interface" "^1.4.0" -"@glimmer/validator@0.65.0": - version "0.65.0" - resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.65.0.tgz#e4411e0a979f002efe236e3bcc91de5f5aaeaed2" - integrity sha512-nwFReFT9zOOV+9iSqhNookTfHbOsqqPvtsALXl5Rn4QmtAHFLdehiWyN6ddb/sJwllWq+fNW8DxQdiY1xRwn9A== +"@glimmer/validator@0.66.0": + version "0.66.0" + resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.66.0.tgz#a127e6f9e36a41665f6bbb8d6635412db8160824" + integrity sha512-9xZK3Z8kIbTa3UoDU3lxel5AeQvr9bI6hQSbx21E2sO7R7dnozWM0GQjvnjCeyU5JLGJH/YKpeItZFhHhbDvtQ== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.65.0" + "@glimmer/global-context" "0.66.0" "@handlebars/parser@^1.1.0": version "1.1.0" From 1fb2188eb228846e3450747ab9b5fc81a24b0e17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Nov 2020 18:57:06 +0800 Subject: [PATCH 045/299] Build(deps): Bump codecov/codecov-action from v1.0.14 to v1.0.15 (#9692) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dev-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dev-test.yml b/.github/workflows/dev-test.yml index f8a2a2d5c..343651405 100644 --- a/.github/workflows/dev-test.yml +++ b/.github/workflows/dev-test.yml @@ -62,7 +62,7 @@ jobs: run: yarn test --maxWorkers=2 - name: Upload Coverage - uses: codecov/codecov-action@v1.0.14 + uses: codecov/codecov-action@v1.0.15 if: matrix.ENABLE_CODE_COVERAGE with: token: ${{ secrets.CODECOV_TOKEN }} @@ -76,7 +76,7 @@ jobs: PRETTIER_FALLBACK_RESOLVE: true - name: Upload Coverage (PRETTIER_FALLBACK_RESOLVE) - uses: codecov/codecov-action@v1.0.14 + uses: codecov/codecov-action@v1.0.15 if: matrix.ENABLE_CODE_COVERAGE with: token: ${{ secrets.CODECOV_TOKEN }} From 85e5cfaf2fcd6477fcee77e5290d3f8fb2f91ac0 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Tue, 17 Nov 2020 21:38:50 +0800 Subject: [PATCH 046/299] YAML: Fix comments in `flowMapping` and `flowSequence` (#9669) --- changelog_unreleased/yaml/pr-9669.md | 60 ++++++++++++++ src/language-yaml/printer-yaml.js | 14 +++- .../comment/__snapshots__/jsfmt.spec.js.snap | 78 +++++++++++++++++++ tests/yaml/comment/flow-sequence-mapping.yml | 33 ++++++++ 4 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 changelog_unreleased/yaml/pr-9669.md create mode 100644 tests/yaml/comment/flow-sequence-mapping.yml diff --git a/changelog_unreleased/yaml/pr-9669.md b/changelog_unreleased/yaml/pr-9669.md new file mode 100644 index 000000000..70aa1fba0 --- /dev/null +++ b/changelog_unreleased/yaml/pr-9669.md @@ -0,0 +1,60 @@ +#### Fix comments inside `flowMapping` and `flowSequence` (#9669 by @fisker) + + +```yaml +# Input +a: + [ + a, b, + # comment + ] + +b: + # prettier-ignore + { + a: 1, b: 2, + # comment + } + +# Prettier stable +a: [a, b] + # comment + +b: + # prettier-ignore + { + a: 1, b: 2, + # comment + } + # comment + + +# Prettier stable (second format) +a: + [a, b] + # comment + +b: + # prettier-ignore + { + a: 1, b: 2, + # comment + } + # comment + # comment + + +# Prettier master +a: [ + a, + b, + # comment + ] + +b: + # prettier-ignore + { + a: 1, b: 2, + # comment + } +``` diff --git a/src/language-yaml/printer-yaml.js b/src/language-yaml/printer-yaml.js index fa219a50e..fa13a5081 100644 --- a/src/language-yaml/printer-yaml.js +++ b/src/language-yaml/printer-yaml.js @@ -527,6 +527,12 @@ function _print(node, parentNode, path, options, print) { ) ), ifBreak(",", ""), + hasEndComments(node) + ? concat([ + hardline, + join(hardline, path.map(print, "endComments")), + ]) + : "", ]) ), isLastItemEmptyMappingItem ? "" : bracketSpacing, @@ -703,7 +709,13 @@ function needsSpaceInFrontOfMappingValue(node) { function shouldPrintEndComments(node) { return ( - hasEndComments(node) && !isNode(node, ["documentHead", "documentBody"]) + hasEndComments(node) && + !isNode(node, [ + "documentHead", + "documentBody", + "flowMapping", + "flowSequence", + ]) ); } diff --git a/tests/yaml/comment/__snapshots__/jsfmt.spec.js.snap b/tests/yaml/comment/__snapshots__/jsfmt.spec.js.snap index 9e899d762..40c5720ed 100644 --- a/tests/yaml/comment/__snapshots__/jsfmt.spec.js.snap +++ b/tests/yaml/comment/__snapshots__/jsfmt.spec.js.snap @@ -108,6 +108,84 @@ A: ================================================================================ `; +exports[`flow-sequence-mapping.yml format 1`] = ` +====================================options===================================== +parsers: ["yaml"] +printWidth: 80 + | printWidth +=====================================input====================================== + a: + [ + check-format, check-lint, + check-spelling, + # coverage, + # install-and-run-from-git, + ] + + b: + { + a: check-format, b: check-lint, + c: check-spelling, + # d: coverage, + # e: install-and-run-from-git, + } + + d: + # prettier-ignore + [ + check-format, check-lint, + check-spelling, + # coverage, + # install-and-run-from-git, + ] + + e: + # prettier-ignore + { + a: check-format, b: check-lint, + c: check-spelling, + # d: coverage, + # e: install-and-run-from-git, + } + +=====================================output===================================== +a: [ + check-format, + check-lint, + check-spelling, + # coverage, + # install-and-run-from-git, + ] + +b: { + a: check-format, + b: check-lint, + c: check-spelling, + # d: coverage, + # e: install-and-run-from-git, + } + +d: + # prettier-ignore + [ + check-format, check-lint, + check-spelling, + # coverage, + # install-and-run-from-git, + ] + +e: + # prettier-ignore + { + a: check-format, b: check-lint, + c: check-spelling, + # d: coverage, + # e: install-and-run-from-git, + } + +================================================================================ +`; + exports[`in-empty-item-without-newlline.yml format 1`] = ` ====================================options===================================== parsers: ["yaml"] diff --git a/tests/yaml/comment/flow-sequence-mapping.yml b/tests/yaml/comment/flow-sequence-mapping.yml new file mode 100644 index 000000000..6a2e1d952 --- /dev/null +++ b/tests/yaml/comment/flow-sequence-mapping.yml @@ -0,0 +1,33 @@ + a: + [ + check-format, check-lint, + check-spelling, + # coverage, + # install-and-run-from-git, + ] + + b: + { + a: check-format, b: check-lint, + c: check-spelling, + # d: coverage, + # e: install-and-run-from-git, + } + + d: + # prettier-ignore + [ + check-format, check-lint, + check-spelling, + # coverage, + # install-and-run-from-git, + ] + + e: + # prettier-ignore + { + a: check-format, b: check-lint, + c: check-spelling, + # d: coverage, + # e: install-and-run-from-git, + } From 702f543635d26ae9547e967c2ed43e998e5ff1eb Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Wed, 18 Nov 2020 09:05:56 +0800 Subject: [PATCH 047/299] YAML: Apply `trailingComma` option (#9665) --- changelog_unreleased/yaml/pr-9665.md | 46 ++++ src/language-yaml/printer-yaml.js | 4 +- .../__snapshots__/jsfmt.spec.js.snap | 184 +++++++++++++ .../trailing-comma/flow-mapping.yml | 19 ++ .../flow-mapping/trailing-comma/jsfmt.spec.js | 4 + .../__snapshots__/jsfmt.spec.js.snap | 192 +++++++++++++ .../trailing-comma/flow-sequence.yml | 19 ++ .../trailing-comma/jsfmt.spec.js | 4 + .../__snapshots__/jsfmt.spec.js.snap | 252 ++++++++++++++++++ tests/yaml/json/trailing-comma/jsfmt.spec.js | 4 + tests/yaml/json/trailing-comma/json.yml | 26 ++ 11 files changed, 753 insertions(+), 1 deletion(-) create mode 100644 changelog_unreleased/yaml/pr-9665.md create mode 100644 tests/yaml/flow-mapping/trailing-comma/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/yaml/flow-mapping/trailing-comma/flow-mapping.yml create mode 100644 tests/yaml/flow-mapping/trailing-comma/jsfmt.spec.js create mode 100644 tests/yaml/flow-sequence/trailing-comma/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/yaml/flow-sequence/trailing-comma/flow-sequence.yml create mode 100644 tests/yaml/flow-sequence/trailing-comma/jsfmt.spec.js create mode 100644 tests/yaml/json/trailing-comma/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/yaml/json/trailing-comma/jsfmt.spec.js create mode 100644 tests/yaml/json/trailing-comma/json.yml diff --git a/changelog_unreleased/yaml/pr-9665.md b/changelog_unreleased/yaml/pr-9665.md new file mode 100644 index 000000000..5e9990203 --- /dev/null +++ b/changelog_unreleased/yaml/pr-9665.md @@ -0,0 +1,46 @@ +#### Apply `trailingComma` option (#9665 by @fisker) + +When `--trailing-comma=none`, should not add trailing comma to flowMapping and flowSequence. + + +```yaml +# Input +flow-mapping: + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + } +flow-sequence: + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma IS added here" + ] + +# Prettier stable +mapping: + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here", + } +flow-sequence: + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma IS added here", + ] + +# Prettier master +flow-mapping: + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + } +flow-sequence: + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma IS added here" + ] +``` diff --git a/src/language-yaml/printer-yaml.js b/src/language-yaml/printer-yaml.js index fa13a5081..4177c3b3e 100644 --- a/src/language-yaml/printer-yaml.js +++ b/src/language-yaml/printer-yaml.js @@ -499,6 +499,8 @@ function _print(node, parentNode, path, options, print) { lastItem.type === "flowMappingItem" && isEmptyNode(lastItem.key) && isEmptyNode(lastItem.value))(getLast(node.children)); + const trailingComma = + options.trailingComma === "none" ? "" : ifBreak(",", ""); return concat([ openMarker, indent( @@ -526,7 +528,7 @@ function _print(node, parentNode, path, options, print) { "children" ) ), - ifBreak(",", ""), + trailingComma, hasEndComments(node) ? concat([ hardline, diff --git a/tests/yaml/flow-mapping/trailing-comma/__snapshots__/jsfmt.spec.js.snap b/tests/yaml/flow-mapping/trailing-comma/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..2a5515d04 --- /dev/null +++ b/tests/yaml/flow-mapping/trailing-comma/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,184 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`flow-mapping.yml - {"trailingComma":"all"} format 1`] = ` +====================================options===================================== +parsers: ["yaml"] +printWidth: 80 +trailingComma: "all" + | printWidth +=====================================input====================================== +failing: + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + } + +expected: + { + "object-fits-within-print-width": "", + "TEST": "comma NOT here" + } + +--- + +does not suffice: > + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + } + +=====================================output===================================== +failing: + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here", + } + +expected: { "object-fits-within-print-width": "", "TEST": "comma NOT here" } + +--- +does not suffice: > + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + } + +================================================================================ +`; + +exports[`flow-mapping.yml - {"trailingComma":"es5"} format 1`] = ` +====================================options===================================== +parsers: ["yaml"] +printWidth: 80 +trailingComma: "es5" + | printWidth +=====================================input====================================== +failing: + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + } + +expected: + { + "object-fits-within-print-width": "", + "TEST": "comma NOT here" + } + +--- + +does not suffice: > + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + } + +=====================================output===================================== +failing: + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here", + } + +expected: { "object-fits-within-print-width": "", "TEST": "comma NOT here" } + +--- +does not suffice: > + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + } + +================================================================================ +`; + +exports[`flow-mapping.yml - {"trailingComma":"none"} format 1`] = ` +====================================options===================================== +parsers: ["yaml"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +failing: + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + } + +expected: + { + "object-fits-within-print-width": "", + "TEST": "comma NOT here" + } + +--- + +does not suffice: > + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + } + +=====================================output===================================== +failing: + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + } + +expected: { "object-fits-within-print-width": "", "TEST": "comma NOT here" } + +--- +does not suffice: > + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + } + +================================================================================ +`; + +exports[`flow-mapping.yml format 1`] = ` +====================================options===================================== +parsers: ["yaml"] +printWidth: 80 + | printWidth +=====================================input====================================== +failing: + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + } + +expected: + { + "object-fits-within-print-width": "", + "TEST": "comma NOT here" + } + +--- + +does not suffice: > + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + } + +=====================================output===================================== +failing: + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here", + } + +expected: { "object-fits-within-print-width": "", "TEST": "comma NOT here" } + +--- +does not suffice: > + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + } + +================================================================================ +`; diff --git a/tests/yaml/flow-mapping/trailing-comma/flow-mapping.yml b/tests/yaml/flow-mapping/trailing-comma/flow-mapping.yml new file mode 100644 index 000000000..103e9c803 --- /dev/null +++ b/tests/yaml/flow-mapping/trailing-comma/flow-mapping.yml @@ -0,0 +1,19 @@ +failing: + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + } + +expected: + { + "object-fits-within-print-width": "", + "TEST": "comma NOT here" + } + +--- + +does not suffice: > + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + } diff --git a/tests/yaml/flow-mapping/trailing-comma/jsfmt.spec.js b/tests/yaml/flow-mapping/trailing-comma/jsfmt.spec.js new file mode 100644 index 000000000..6bdc1ebe6 --- /dev/null +++ b/tests/yaml/flow-mapping/trailing-comma/jsfmt.spec.js @@ -0,0 +1,4 @@ +run_spec(__dirname, ["yaml"]); +run_spec(__dirname, ["yaml"], { trailingComma: "none" }); +run_spec(__dirname, ["yaml"], { trailingComma: "es5" }); +run_spec(__dirname, ["yaml"], { trailingComma: "all" }); diff --git a/tests/yaml/flow-sequence/trailing-comma/__snapshots__/jsfmt.spec.js.snap b/tests/yaml/flow-sequence/trailing-comma/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..a21a27c5b --- /dev/null +++ b/tests/yaml/flow-sequence/trailing-comma/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,192 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`flow-sequence.yml - {"trailingComma":"all"} format 1`] = ` +====================================options===================================== +parsers: ["yaml"] +printWidth: 80 +trailingComma: "all" + | printWidth +=====================================input====================================== +failing: + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma IS added here" + ] + +expected: + [ + "object-fits-within-print-width", "", + "TEST", "comma NOT here" + ] + +--- + +does not suffice: > + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] + +=====================================output===================================== +failing: + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma IS added here", + ] + +expected: ["object-fits-within-print-width", "", "TEST", "comma NOT here"] + +--- +does not suffice: > + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] + +================================================================================ +`; + +exports[`flow-sequence.yml - {"trailingComma":"es5"} format 1`] = ` +====================================options===================================== +parsers: ["yaml"] +printWidth: 80 +trailingComma: "es5" + | printWidth +=====================================input====================================== +failing: + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma IS added here" + ] + +expected: + [ + "object-fits-within-print-width", "", + "TEST", "comma NOT here" + ] + +--- + +does not suffice: > + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] + +=====================================output===================================== +failing: + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma IS added here", + ] + +expected: ["object-fits-within-print-width", "", "TEST", "comma NOT here"] + +--- +does not suffice: > + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] + +================================================================================ +`; + +exports[`flow-sequence.yml - {"trailingComma":"none"} format 1`] = ` +====================================options===================================== +parsers: ["yaml"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +failing: + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma IS added here" + ] + +expected: + [ + "object-fits-within-print-width", "", + "TEST", "comma NOT here" + ] + +--- + +does not suffice: > + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] + +=====================================output===================================== +failing: + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma IS added here" + ] + +expected: ["object-fits-within-print-width", "", "TEST", "comma NOT here"] + +--- +does not suffice: > + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] + +================================================================================ +`; + +exports[`flow-sequence.yml format 1`] = ` +====================================options===================================== +parsers: ["yaml"] +printWidth: 80 + | printWidth +=====================================input====================================== +failing: + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma IS added here" + ] + +expected: + [ + "object-fits-within-print-width", "", + "TEST", "comma NOT here" + ] + +--- + +does not suffice: > + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] + +=====================================output===================================== +failing: + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma IS added here", + ] + +expected: ["object-fits-within-print-width", "", "TEST", "comma NOT here"] + +--- +does not suffice: > + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] + +================================================================================ +`; diff --git a/tests/yaml/flow-sequence/trailing-comma/flow-sequence.yml b/tests/yaml/flow-sequence/trailing-comma/flow-sequence.yml new file mode 100644 index 000000000..769ff94ba --- /dev/null +++ b/tests/yaml/flow-sequence/trailing-comma/flow-sequence.yml @@ -0,0 +1,19 @@ +failing: + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma IS added here" + ] + +expected: + [ + "object-fits-within-print-width", "", + "TEST", "comma NOT here" + ] + +--- + +does not suffice: > + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] diff --git a/tests/yaml/flow-sequence/trailing-comma/jsfmt.spec.js b/tests/yaml/flow-sequence/trailing-comma/jsfmt.spec.js new file mode 100644 index 000000000..6bdc1ebe6 --- /dev/null +++ b/tests/yaml/flow-sequence/trailing-comma/jsfmt.spec.js @@ -0,0 +1,4 @@ +run_spec(__dirname, ["yaml"]); +run_spec(__dirname, ["yaml"], { trailingComma: "none" }); +run_spec(__dirname, ["yaml"], { trailingComma: "es5" }); +run_spec(__dirname, ["yaml"], { trailingComma: "all" }); diff --git a/tests/yaml/json/trailing-comma/__snapshots__/jsfmt.spec.js.snap b/tests/yaml/json/trailing-comma/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..9580a7a6b --- /dev/null +++ b/tests/yaml/json/trailing-comma/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,252 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`json.yml - {"trailingComma":"all"} format 1`] = ` +====================================options===================================== +parsers: ["yaml"] +printWidth: 80 +trailingComma: "all" + | printWidth +=====================================input====================================== +[ + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + }, + { + "object-fits-within-print-width": "", + "TEST": "comma NOT here" + }, + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + }, + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma IS added here" + ], + [ + "object-fits-within-print-width", "", + "TEST", "comma NOT here" + ], + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] +] + +=====================================output===================================== +[ + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here", + }, + { "object-fits-within-print-width": "", "TEST": "comma NOT here" }, + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'", + }, + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma IS added here", + ], + ["object-fits-within-print-width", "", "TEST", "comma NOT here"], + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma NOT here — but object's now a string due to '>'", + ], +] + +================================================================================ +`; + +exports[`json.yml - {"trailingComma":"es5"} format 1`] = ` +====================================options===================================== +parsers: ["yaml"] +printWidth: 80 +trailingComma: "es5" + | printWidth +=====================================input====================================== +[ + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + }, + { + "object-fits-within-print-width": "", + "TEST": "comma NOT here" + }, + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + }, + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma IS added here" + ], + [ + "object-fits-within-print-width", "", + "TEST", "comma NOT here" + ], + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] +] + +=====================================output===================================== +[ + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here", + }, + { "object-fits-within-print-width": "", "TEST": "comma NOT here" }, + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'", + }, + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma IS added here", + ], + ["object-fits-within-print-width", "", "TEST", "comma NOT here"], + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma NOT here — but object's now a string due to '>'", + ], +] + +================================================================================ +`; + +exports[`json.yml - {"trailingComma":"none"} format 1`] = ` +====================================options===================================== +parsers: ["yaml"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +[ + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + }, + { + "object-fits-within-print-width": "", + "TEST": "comma NOT here" + }, + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + }, + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma IS added here" + ], + [ + "object-fits-within-print-width", "", + "TEST", "comma NOT here" + ], + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] +] + +=====================================output===================================== +[ + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + }, + { "object-fits-within-print-width": "", "TEST": "comma NOT here" }, + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + }, + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma IS added here" + ], + ["object-fits-within-print-width", "", "TEST", "comma NOT here"], + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma NOT here — but object's now a string due to '>'" + ] +] + +================================================================================ +`; + +exports[`json.yml format 1`] = ` +====================================options===================================== +parsers: ["yaml"] +printWidth: 80 + | printWidth +=====================================input====================================== +[ + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + }, + { + "object-fits-within-print-width": "", + "TEST": "comma NOT here" + }, + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + }, + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma IS added here" + ], + [ + "object-fits-within-print-width", "", + "TEST", "comma NOT here" + ], + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] +] + +=====================================output===================================== +[ + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here", + }, + { "object-fits-within-print-width": "", "TEST": "comma NOT here" }, + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'", + }, + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma IS added here", + ], + ["object-fits-within-print-width", "", "TEST", "comma NOT here"], + [ + "object-does-not-fit-within-print-width", + "------", + "TEST", + "comma NOT here — but object's now a string due to '>'", + ], +] + +================================================================================ +`; diff --git a/tests/yaml/json/trailing-comma/jsfmt.spec.js b/tests/yaml/json/trailing-comma/jsfmt.spec.js new file mode 100644 index 000000000..6bdc1ebe6 --- /dev/null +++ b/tests/yaml/json/trailing-comma/jsfmt.spec.js @@ -0,0 +1,4 @@ +run_spec(__dirname, ["yaml"]); +run_spec(__dirname, ["yaml"], { trailingComma: "none" }); +run_spec(__dirname, ["yaml"], { trailingComma: "es5" }); +run_spec(__dirname, ["yaml"], { trailingComma: "all" }); diff --git a/tests/yaml/json/trailing-comma/json.yml b/tests/yaml/json/trailing-comma/json.yml new file mode 100644 index 000000000..c317d3820 --- /dev/null +++ b/tests/yaml/json/trailing-comma/json.yml @@ -0,0 +1,26 @@ +[ + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma IS added here" + }, + { + "object-fits-within-print-width": "", + "TEST": "comma NOT here" + }, + { + "object-does-not-fit-within-print-width": "------", + "TEST": "comma NOT here — but object's now a string due to '>'" + }, + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma IS added here" + ], + [ + "object-fits-within-print-width", "", + "TEST", "comma NOT here" + ], + [ + "object-does-not-fit-within-print-width", "------", + "TEST", "comma NOT here — but object's now a string due to '>'" + ] +] From 4cc149248a78491eecacccce7e04b82e751afb64 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Wed, 18 Nov 2020 10:59:58 +0900 Subject: [PATCH 048/299] Support TypeScript 4.1 via typescript-estree (#9636) * Update typescript and typescript-estree * Add AST transformation for TSTemplateLiteralType * Update tests for template-literal-types * Fix transformChainExpression * Update tests for key-remapping-in-mapped-types * Implement recoverInvalidDecorators * Update changelog * Avoid typecheck error * Add os.platform() shim * Update config.js * Update config.js * Shim os.cpus * Update `process.versions.node` * Attempt to fix build * Update ts parserOptions * Fix code style * Remove `errorOnUnknownASTType`, fix code style * Use `[] ||` instead of `[] //` * Fix hack * Add invalid tests * checkMissingDecorators * Update tests * Fix tests * Add comment * Revert "Implement recoverInvalidDecorators" This reverts commit 27e7b46ed41df36fb585791117c85e1b2dab932c. * Add ref pr link * Simplify logic * Don't transform `TSTemplateLiteralType` * Add `TSTemplateLiteralType` as simple type * Fix tests * Update comments * Add comment * Fix logic * Minor tweak * use multiple parsers * Update @typescript-eslint/typescript-estree to v4.8.0 * Switch to `parseWithNodeMaps` * Rename `esNode` -> `esTreeNode` * Update @typescript-eslint/typescript-estree to 4.8.1-alpha.1 * Use @typescript-eslint/typescript-estree 4.8.1 Co-authored-by: fisker Cheung --- changelog_unreleased/typescript/pr-9473.md | 4 +- package.json | 4 +- scripts/build/config.js | 5 + scripts/build/shims/os.mjs | 2 + src/language-graphql/printer-graphql.js | 11 +-- src/language-handlebars/printer-glimmer.js | 11 +-- src/language-js/parse-postprocess.js | 59 +++++++++++- src/language-js/parser-typescript.js | 17 ++-- src/language-js/print/template-literal.js | 15 ++- src/language-js/printer-estree-json.js | 4 +- src/language-js/printer-estree.js | 1 + src/language-js/utils.js | 11 ++- src/main/comments.js | 20 ++-- .../__snapshots__/jsfmt.spec.js.snap | 96 +++++++++++++++++++ .../decorator.ts | 0 .../invalid-typescript-decorators/enums.ts | 9 ++ .../invalid-typescript-decorators/function.ts | 4 + .../interface.ts | 4 +- .../jsfmt.spec.js | 1 + .../__snapshots__/jsfmt.spec.js.snap | 30 ------ .../conformance/types/decorator/jsfmt.spec.js | 1 - .../__snapshots__/jsfmt.spec.js.snap | 35 ------- tests/typescript/decorators/jsfmt.spec.js | 4 +- .../__snapshots__/jsfmt.spec.js.snap | 10 -- .../jsfmt.spec.js | 4 +- .../__snapshots__/jsfmt.spec.js.snap | 9 -- .../template-literal-types/jsfmt.spec.js | 4 +- .../__snapshots__/jsfmt.spec.js.snap | 36 +++++++ .../typeparams/consistent/jsfmt.spec.js | 8 +- .../consistent/template-literal-types.ts | 1 + .../typeparams/consistent/typescript-only.ts | 2 +- yarn.lock | 50 +++++----- 32 files changed, 304 insertions(+), 168 deletions(-) create mode 100644 tests/misc/errors/invalid-typescript-decorators/__snapshots__/jsfmt.spec.js.snap rename tests/{typescript/conformance/types/decorator => misc/errors/invalid-typescript-decorators}/decorator.ts (100%) create mode 100644 tests/misc/errors/invalid-typescript-decorators/enums.ts create mode 100644 tests/misc/errors/invalid-typescript-decorators/function.ts rename tests/{typescript/decorators => misc/errors/invalid-typescript-decorators}/interface.ts (55%) create mode 100644 tests/misc/errors/invalid-typescript-decorators/jsfmt.spec.js delete mode 100644 tests/typescript/conformance/types/decorator/__snapshots__/jsfmt.spec.js.snap delete mode 100644 tests/typescript/conformance/types/decorator/jsfmt.spec.js create mode 100644 tests/typescript/typeparams/consistent/template-literal-types.ts diff --git a/changelog_unreleased/typescript/pr-9473.md b/changelog_unreleased/typescript/pr-9473.md index ed18101ee..1c0f69efd 100644 --- a/changelog_unreleased/typescript/pr-9473.md +++ b/changelog_unreleased/typescript/pr-9473.md @@ -1,6 +1,4 @@ -#### [HIGHLIGHT]Support TypeScript 4.1 via Babel (#9473 by @sosukesuzuki) - -`--parser=babel-ts` is required. +#### [HIGHLIGHT]Support TypeScript 4.1 (#9473, #9636 by @sosukesuzuki) ##### Key Remapping In Mapped Types diff --git a/package.json b/package.json index e02482f24..fd5977015 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@babel/parser": "7.12.5", "@glimmer/syntax": "0.66.0", "@iarna/toml": "2.2.5", - "@typescript-eslint/typescript-estree": "3.10.1", + "@typescript-eslint/typescript-estree": "4.8.1", "angular-estree-parser": "2.2.1", "angular-html-parser": "1.7.1", "camelcase": "6.2.0", @@ -78,7 +78,7 @@ "resolve": "1.19.0", "semver": "7.3.2", "string-width": "4.2.0", - "typescript": "4.0.5", + "typescript": "4.1.1-rc", "unicode-regex": "3.0.0", "unified": "9.2.0", "vnopts": "1.0.2", diff --git a/scripts/build/config.js b/scripts/build/config.js index 5e527e6a4..c154f53d5 100644 --- a/scripts/build/config.js +++ b/scripts/build/config.js @@ -40,6 +40,11 @@ const parsers = [ // `TypeScript`, `toolsVersion`, `globalThis` 'typeof process === "undefined" || process.browser': "false", 'typeof globalThis === "object"': "true", + // `@typescript-eslint/typescript-estree` v4 + 'require("globby")': "{}", + "extra.projects = prepareAndTransformProjects(": + "extra.projects = [] || prepareAndTransformProjects(", + "process.versions.node": "'999.999.999'", }, }, { diff --git a/scripts/build/shims/os.mjs b/scripts/build/shims/os.mjs index 17621df9f..27e543d96 100644 --- a/scripts/build/shims/os.mjs +++ b/scripts/build/shims/os.mjs @@ -1,3 +1,5 @@ export default { EOL: "\n", + platform: () => "browser", + cpus: () => [{ model: "Prettier" }], }; diff --git a/src/language-graphql/printer-graphql.js b/src/language-graphql/printer-graphql.js index 0101aef7e..28cc63a8f 100644 --- a/src/language-graphql/printer-graphql.js +++ b/src/language-graphql/printer-graphql.js @@ -1,15 +1,8 @@ "use strict"; const { - concat, - join, - hardline, - line, - softline, - group, - indent, - ifBreak, -} = require("../document").builders; + builders: { concat, join, hardline, line, softline, group, indent, ifBreak }, +} = require("../document"); const { isNextLineEmpty } = require("../common/util"); const { insertPragma } = require("./pragma"); const { locStart, locEnd } = require("./loc"); diff --git a/src/language-handlebars/printer-glimmer.js b/src/language-handlebars/printer-glimmer.js index 2876a2ac7..ff63ca325 100644 --- a/src/language-handlebars/printer-glimmer.js +++ b/src/language-handlebars/printer-glimmer.js @@ -1,15 +1,8 @@ "use strict"; const { - concat, - group, - hardline, - ifBreak, - indent, - join, - line, - softline, -} = require("../document").builders; + builders: { concat, group, hardline, ifBreak, indent, join, line, softline }, +} = require("../document"); const { locStart, locEnd } = require("./loc"); const clean = require("./clean"); const { diff --git a/src/language-js/parse-postprocess.js b/src/language-js/parse-postprocess.js index 3efece636..9aa82f603 100644 --- a/src/language-js/parse-postprocess.js +++ b/src/language-js/parse-postprocess.js @@ -5,6 +5,7 @@ const { getNextNonSpaceNonCommentCharacter, getShebang, } = require("../common/util"); +const createError = require("../common/parser-create-error"); const { composeLoc, locStart, locEnd } = require("./loc"); const { isTypeCastComment } = require("./comments"); @@ -17,6 +18,50 @@ function postprocess(ast, options) { includeShebang(ast, options); } + // Invalid decorators are removed since `@typescript-eslint/typescript-estree` v4 + // https://github.com/typescript-eslint/typescript-eslint/pull/2375 + if (options.parser === "typescript" && options.originalText.includes("@")) { + const { + esTreeNodeToTSNodeMap, + tsNodeToESTreeNodeMap, + } = options.tsParseResult; + ast = visitNode(ast, (node) => { + const tsNode = esTreeNodeToTSNodeMap.get(node); + if (!tsNode) { + return; + } + const tsDecorators = tsNode.decorators; + if (!Array.isArray(tsDecorators)) { + return; + } + // `esTreeNodeToTSNodeMap.get(ClassBody)` and `esTreeNodeToTSNodeMap.get(ClassDeclaration)` has the same tsNode + const esTreeNode = tsNodeToESTreeNodeMap.get(tsNode); + if (esTreeNode !== node) { + return; + } + const esTreeDecorators = esTreeNode.decorators; + if ( + !Array.isArray(esTreeDecorators) || + esTreeDecorators.length !== tsDecorators.length || + tsDecorators.some((tsDecorator) => { + const esTreeDecorator = tsNodeToESTreeNodeMap.get(tsDecorator); + return ( + !esTreeDecorator || !esTreeDecorators.includes(esTreeDecorator) + ); + }) + ) { + const { start, end } = esTreeNode.loc; + throw createError( + "Leading decorators must be attached to a class declaration", + { + start: { line: start.line, column: start.column + 1 }, + end: { line: end.line, column: end.column + 1 }, + } + ); + } + }); + } + // Keep Babel's non-standard ParenthesizedExpression nodes only if they have Closure-style type cast comments. if ( options.parser !== "typescript" && @@ -146,9 +191,9 @@ function postprocess(ast, options) { } } -// This is a workaround to transform `ChainExpression` from `espree` into -// `babel` shape AST, we should do the opposite, since `ChainExpression` is the -// standard `estree` AST for `optional chaining` +// This is a workaround to transform `ChainExpression` from `espree`, `meriyah`, +// and `typescript` into `babel` shape AST, we should do the opposite, +// since `ChainExpression` is the standard `estree` AST for `optional chaining` // https://github.com/estree/estree/blob/master/es2020.md function transformChainExpression(node) { if (node.type === "CallExpression") { @@ -158,6 +203,10 @@ function transformChainExpression(node) { node.type = "OptionalMemberExpression"; node.object = transformChainExpression(node.object); } + // typescript + else if (node.type === "TSNonNullExpression") { + node.expression = transformChainExpression(node.expression); + } return node; } @@ -180,6 +229,10 @@ function visitNode(node, fn) { node[key] = visitNode(child, fn); } + if (Array.isArray(node)) { + return node; + } + return fn(node) || node; } diff --git a/src/language-js/parser-typescript.js b/src/language-js/parser-typescript.js index 1c3221f69..bf60d724a 100644 --- a/src/language-js/parser-typescript.js +++ b/src/language-js/parser-typescript.js @@ -7,14 +7,14 @@ const postprocess = require("./parse-postprocess"); function parse(text, parsers, opts) { const jsx = isProbablyJsx(text); - let ast; + let result; try { // Try passing with our best guess first. - ast = tryParseTypeScript(text, jsx); + result = tryParseTypeScript(text, jsx); } catch (firstError) { try { // But if we get it wrong, try the opposite. - ast = tryParseTypeScript(text, !jsx); + result = tryParseTypeScript(text, !jsx); } catch (secondError) { // Suppose our guess is correct, throw the first error const { message, lineNumber, column } = firstError; @@ -30,12 +30,16 @@ function parse(text, parsers, opts) { } } - return postprocess(ast, { ...opts, originalText: text }); + return postprocess(result.ast, { + ...opts, + originalText: text, + tsParseResult: result, + }); } function tryParseTypeScript(text, jsx) { - const parser = require("@typescript-eslint/typescript-estree"); - return parser.parse(text, { + const { parseWithNodeMaps } = require("@typescript-eslint/typescript-estree"); + return parseWithNodeMaps(text, { // `jest@<=26.4.2` rely on `loc` // https://github.com/facebook/jest/issues/10444 loc: true, @@ -45,6 +49,7 @@ function tryParseTypeScript(text, jsx) { jsx, tokens: true, loggerFn: false, + project: [], }); } diff --git a/src/language-js/print/template-literal.js b/src/language-js/print/template-literal.js index 2ef4d77f9..157ddc018 100644 --- a/src/language-js/print/template-literal.js +++ b/src/language-js/print/template-literal.js @@ -24,17 +24,24 @@ const { function printTemplateLiteral(path, print, options) { const node = path.getValue(); - const parentNode = path.getParentNode(); + const isTemplateLiteral = node.type === "TemplateLiteral"; - if (isJestEachTemplateLiteral(node, parentNode)) { + if ( + isTemplateLiteral && + isJestEachTemplateLiteral(node, path.getParentNode()) + ) { const printed = printJestEachTemplateLiteral(path, options, print); if (printed) { return printed; } } + let expressionsKey = "expressions"; + if (node.type === "TSTemplateLiteralType") { + expressionsKey = "types"; + } const parts = []; - let expressions = path.map(print, "expressions"); + let expressions = path.map(print, expressionsKey); const isSimple = isSimpleTemplateLiteral(node); if (isSimple) { @@ -70,7 +77,7 @@ function printTemplateLiteral(path, print, options) { let printed = expressions[i]; if (!isSimple) { - const expression = node.expressions[i]; + const expression = node[expressionsKey][i]; // Breaks at the template element boundaries (${ and }) are preferred to breaking // in the middle of a MemberExpression if ( diff --git a/src/language-js/printer-estree-json.js b/src/language-js/printer-estree-json.js index 61d90c199..4ba8849ba 100644 --- a/src/language-js/printer-estree-json.js +++ b/src/language-js/printer-estree-json.js @@ -1,6 +1,8 @@ "use strict"; -const { concat, hardline, indent, join } = require("../document").builders; +const { + builders: { concat, hardline, indent, join }, +} = require("../document"); const preprocess = require("./print-preprocess"); function genericPrint(path, options, print) { diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index a6b8c0bc3..4657fa348 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -2238,6 +2238,7 @@ function printPathNoParens(path, options, print, args) { return concat(parts); case "TemplateElement": return join(literalline, n.value.raw.split(/\r?\n/g)); + case "TSTemplateLiteralType": case "TemplateLiteral": { return printTemplateLiteral(path, print, options); } diff --git a/src/language-js/utils.js b/src/language-js/utils.js index 412c5d09e..a98e8c8b6 100644 --- a/src/language-js/utils.js +++ b/src/language-js/utils.js @@ -464,6 +464,7 @@ const simpleTypeAnnotations = new Set([ "BigIntLiteralTypeAnnotation", "NumberLiteralTypeAnnotation", "TSLiteralType", + "TSTemplateLiteralType", // flow only, `empty`, `mixed` "EmptyTypeAnnotation", "MixedTypeAnnotation", @@ -647,11 +648,17 @@ function isNgForOf(node, index, parentNode) { * @returns {boolean} */ function isSimpleTemplateLiteral(node) { - if (node.expressions.length === 0) { + let expressionsKey = "expressions"; + if (node.type === "TSTemplateLiteralType") { + expressionsKey = "types"; + } + const expressions = node[expressionsKey]; + + if (expressions.length === 0) { return false; } - return node.expressions.every((expr) => { + return expressions.every((expr) => { // Disallow comments since printDocToString can't print them here if (expr.comments) { return false; diff --git a/src/main/comments.js b/src/main/comments.js index acb834360..98209cc3b 100644 --- a/src/main/comments.js +++ b/src/main/comments.js @@ -4,15 +4,17 @@ const assert = require("assert"); const { - concat, - line, - hardline, - breakParent, - indent, - lineSuffix, - join, - cursor, -} = require("../document").builders; + builders: { + concat, + line, + hardline, + breakParent, + indent, + lineSuffix, + join, + cursor, + }, +} = require("../document"); const { hasNewline, diff --git a/tests/misc/errors/invalid-typescript-decorators/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/invalid-typescript-decorators/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..3d93c7204 --- /dev/null +++ b/tests/misc/errors/invalid-typescript-decorators/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,96 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`decorator.ts [babel-ts] format 1`] = ` +"Leading decorators must be attached to a class declaration (4:1) + 2 | + 3 | @dec +> 4 | enum E {} + | ^ + 5 | " +`; + +exports[`decorator.ts [typescript] format 1`] = ` +"Leading decorators must be attached to a class declaration (3:1) + 1 | declare function dec(target: T): T; + 2 | +> 3 | @dec + | ^^^^ +> 4 | enum E {} + | ^^^^^^^^^^ + 5 | " +`; + +exports[`enums.ts [babel-ts] format 1`] = ` +"Leading decorators must be attached to a class declaration (4:1) + 2 | + 3 | @decorator() +> 4 | enum Direction { + | ^ + 5 | Up = 1, + 6 | Down, + 7 | Left," +`; + +exports[`enums.ts [typescript] format 1`] = ` +"Leading decorators must be attached to a class declaration (3:1) + 1 | // https://github.com/typescript-eslint/typescript-eslint/pull/2375 + 2 | +> 3 | @decorator() + | ^^^^^^^^^^^^ +> 4 | enum Direction { + | ^^^^^^^^^^^^^^^^ +> 5 | Up = 1, + | ^^^^^^^^^^^^^^^^ +> 6 | Down, + | ^^^^^^^^^^^^^^^^ +> 7 | Left, + | ^^^^^^^^^^^^^^^^ +> 8 | Right + | ^^^^^^^^^^^^^^^^ +> 9 | } + | ^^ + 10 | " +`; + +exports[`function.ts [babel-ts] format 1`] = ` +"Leading decorators must be attached to a class declaration (4:1) + 2 | + 3 | @decorator() +> 4 | function foo( ){} + | ^ + 5 | " +`; + +exports[`function.ts [typescript] format 1`] = ` +"Leading decorators must be attached to a class declaration (3:1) + 1 | // https://github.com/typescript-eslint/typescript-eslint/pull/2375 + 2 | +> 3 | @decorator() + | ^^^^^^^^^^^^ +> 4 | function foo( ){} + | ^^^^^^^^^^^^^^^^^^^^^^^ + 5 | " +`; + +exports[`interface.ts [babel-ts] format 1`] = ` +"Leading decorators must be attached to a class declaration (5:1) + 3 | + 4 | @hello() +> 5 | interface MyInterface {id: string; + | ^ + 6 | } + 7 | " +`; + +exports[`interface.ts [typescript] format 1`] = ` +"Leading decorators must be attached to a class declaration (4:1) + 2 | // #4632 + 3 | +> 4 | @hello() + | ^^^^^^^^ +> 5 | interface MyInterface {id: string; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +> 6 | } + | ^^ + 7 | " +`; diff --git a/tests/typescript/conformance/types/decorator/decorator.ts b/tests/misc/errors/invalid-typescript-decorators/decorator.ts similarity index 100% rename from tests/typescript/conformance/types/decorator/decorator.ts rename to tests/misc/errors/invalid-typescript-decorators/decorator.ts diff --git a/tests/misc/errors/invalid-typescript-decorators/enums.ts b/tests/misc/errors/invalid-typescript-decorators/enums.ts new file mode 100644 index 000000000..6db307060 --- /dev/null +++ b/tests/misc/errors/invalid-typescript-decorators/enums.ts @@ -0,0 +1,9 @@ +// https://github.com/typescript-eslint/typescript-eslint/pull/2375 + +@decorator() +enum Direction { + Up = 1, + Down, + Left, + Right +} diff --git a/tests/misc/errors/invalid-typescript-decorators/function.ts b/tests/misc/errors/invalid-typescript-decorators/function.ts new file mode 100644 index 000000000..038ebafbc --- /dev/null +++ b/tests/misc/errors/invalid-typescript-decorators/function.ts @@ -0,0 +1,4 @@ +// https://github.com/typescript-eslint/typescript-eslint/pull/2375 + +@decorator() +function foo( ){} diff --git a/tests/typescript/decorators/interface.ts b/tests/misc/errors/invalid-typescript-decorators/interface.ts similarity index 55% rename from tests/typescript/decorators/interface.ts rename to tests/misc/errors/invalid-typescript-decorators/interface.ts index de7bb11c0..ffd85a50a 100644 --- a/tests/typescript/decorators/interface.ts +++ b/tests/misc/errors/invalid-typescript-decorators/interface.ts @@ -1,6 +1,6 @@ // invalid place but shouldn't be removed +// #4632 @hello() -interface MyInterface { - id: string; +interface MyInterface {id: string; } diff --git a/tests/misc/errors/invalid-typescript-decorators/jsfmt.spec.js b/tests/misc/errors/invalid-typescript-decorators/jsfmt.spec.js new file mode 100644 index 000000000..aff59cd2f --- /dev/null +++ b/tests/misc/errors/invalid-typescript-decorators/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, ["typescript", "babel-ts"]); diff --git a/tests/typescript/conformance/types/decorator/__snapshots__/jsfmt.spec.js.snap b/tests/typescript/conformance/types/decorator/__snapshots__/jsfmt.spec.js.snap deleted file mode 100644 index 38c86cce3..000000000 --- a/tests/typescript/conformance/types/decorator/__snapshots__/jsfmt.spec.js.snap +++ /dev/null @@ -1,30 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`decorator.ts [babel-ts] format 1`] = ` -"Leading decorators must be attached to a class declaration (4:1) - 2 | - 3 | @dec -> 4 | enum E {} - | ^ - 5 | " -`; - -exports[`decorator.ts format 1`] = ` -====================================options===================================== -parsers: ["typescript"] -printWidth: 80 - | printWidth -=====================================input====================================== -declare function dec(target: T): T; - -@dec -enum E {} - -=====================================output===================================== -declare function dec(target: T): T; - -@dec -enum E {} - -================================================================================ -`; diff --git a/tests/typescript/conformance/types/decorator/jsfmt.spec.js b/tests/typescript/conformance/types/decorator/jsfmt.spec.js deleted file mode 100644 index 4c48f7a81..000000000 --- a/tests/typescript/conformance/types/decorator/jsfmt.spec.js +++ /dev/null @@ -1 +0,0 @@ -run_spec(__dirname, ["typescript"], { errors: { "babel-ts": true } }); diff --git a/tests/typescript/decorators/__snapshots__/jsfmt.spec.js.snap b/tests/typescript/decorators/__snapshots__/jsfmt.spec.js.snap index e0d418a98..2d5808521 100644 --- a/tests/typescript/decorators/__snapshots__/jsfmt.spec.js.snap +++ b/tests/typescript/decorators/__snapshots__/jsfmt.spec.js.snap @@ -395,38 +395,3 @@ class MyContainerComponent { ================================================================================ `; - -exports[`interface.ts [babel-ts] format 1`] = ` -"Leading decorators must be attached to a class declaration (4:1) - 2 | - 3 | @hello() -> 4 | interface MyInterface { - | ^ - 5 | id: string; - 6 | } - 7 | " -`; - -exports[`interface.ts format 1`] = ` -====================================options===================================== -parsers: ["typescript"] -printWidth: 80 - | printWidth -=====================================input====================================== -// invalid place but shouldn't be removed - -@hello() -interface MyInterface { - id: string; -} - -=====================================output===================================== -// invalid place but shouldn't be removed - -@hello() -interface MyInterface { - id: string; -} - -================================================================================ -`; diff --git a/tests/typescript/decorators/jsfmt.spec.js b/tests/typescript/decorators/jsfmt.spec.js index ac047e1b5..2ea3bb6eb 100644 --- a/tests/typescript/decorators/jsfmt.spec.js +++ b/tests/typescript/decorators/jsfmt.spec.js @@ -1,3 +1 @@ -run_spec(__dirname, ["typescript"], { - errors: { "babel-ts": ["interface.ts"] }, -}); +run_spec(__dirname, ["typescript"]); diff --git a/tests/typescript/key-remapping-in-mapped-types/__snapshots__/jsfmt.spec.js.snap b/tests/typescript/key-remapping-in-mapped-types/__snapshots__/jsfmt.spec.js.snap index b46fb4526..6d6725530 100644 --- a/tests/typescript/key-remapping-in-mapped-types/__snapshots__/jsfmt.spec.js.snap +++ b/tests/typescript/key-remapping-in-mapped-types/__snapshots__/jsfmt.spec.js.snap @@ -1,15 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`key-remapping.ts [typescript] format 1`] = ` -"']' expected. (2:17) - 1 | type MappedTypeWithNewKeys = { -> 2 | [K in keyof T as NewKeyType]: T[K] - | ^ - 3 | }; - 4 | - 5 | type RemoveKindField = {" -`; - exports[`key-remapping.ts format 1`] = ` ====================================options===================================== parsers: ["babel-ts", "typescript"] diff --git a/tests/typescript/key-remapping-in-mapped-types/jsfmt.spec.js b/tests/typescript/key-remapping-in-mapped-types/jsfmt.spec.js index 1b122de11..92b81c22b 100644 --- a/tests/typescript/key-remapping-in-mapped-types/jsfmt.spec.js +++ b/tests/typescript/key-remapping-in-mapped-types/jsfmt.spec.js @@ -1,3 +1 @@ -run_spec(__dirname, ["babel-ts", "typescript"], { - errors: { typescript: true }, -}); +run_spec(__dirname, ["babel-ts", "typescript"]); diff --git a/tests/typescript/template-literal-types/__snapshots__/jsfmt.spec.js.snap b/tests/typescript/template-literal-types/__snapshots__/jsfmt.spec.js.snap index de4070dd9..8c4448154 100644 --- a/tests/typescript/template-literal-types/__snapshots__/jsfmt.spec.js.snap +++ b/tests/typescript/template-literal-types/__snapshots__/jsfmt.spec.js.snap @@ -1,14 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`template-literal-types.ts [typescript] format 1`] = ` -"Type expected. (1:8) -> 1 | let x: \`foo-\${infer bar}\`; - | ^ - 2 | type HelloWorld = \`\${Hello}, \${World}\` - 3 | type SeussFish = \`\${Quantity | Color} fish\`; - 4 | declare function setAlignment(value: \`\${VerticalAlignment}-\${HorizontalAlignment}\`): void;" -`; - exports[`template-literal-types.ts format 1`] = ` ====================================options===================================== parsers: ["babel-ts", "typescript"] diff --git a/tests/typescript/template-literal-types/jsfmt.spec.js b/tests/typescript/template-literal-types/jsfmt.spec.js index 1b122de11..92b81c22b 100644 --- a/tests/typescript/template-literal-types/jsfmt.spec.js +++ b/tests/typescript/template-literal-types/jsfmt.spec.js @@ -1,3 +1 @@ -run_spec(__dirname, ["babel-ts", "typescript"], { - errors: { typescript: true }, -}); +run_spec(__dirname, ["babel-ts", "typescript"]); diff --git a/tests/typescript/typeparams/consistent/__snapshots__/jsfmt.spec.js.snap b/tests/typescript/typeparams/consistent/__snapshots__/jsfmt.spec.js.snap index bc59c79cf..7a227a5e0 100644 --- a/tests/typescript/typeparams/consistent/__snapshots__/jsfmt.spec.js.snap +++ b/tests/typescript/typeparams/consistent/__snapshots__/jsfmt.spec.js.snap @@ -71,6 +71,41 @@ const foo12: Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ================================================================================ `; +exports[`template-literal-types.ts [babel] format 1`] = ` +"Unexpected token (1:84) +> 1 | const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<\`Hello, \${keyof World}\`> = a; + | ^ + 2 | " +`; + +exports[`template-literal-types.ts [babel-flow] format 1`] = ` +"Unexpected token (1:84) +> 1 | const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<\`Hello, \${keyof World}\`> = a; + | ^ + 2 | " +`; + +exports[`template-literal-types.ts [flow] format 1`] = ` +"Unexpected token \`\`\` (1:84) +> 1 | const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<\`Hello, \${keyof World}\`> = a; + | ^ + 2 | " +`; + +exports[`template-literal-types.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript", "flow", "babel-flow", "babel"] +printWidth: 80 + | printWidth +=====================================input====================================== +const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<\`Hello, \${keyof World}\`> = a; + +=====================================output===================================== +const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<\`Hello, \${keyof World}\`> = a; + +================================================================================ +`; + exports[`typescript-only.ts format 1`] = ` ====================================options===================================== parsers: ["typescript", "flow", "babel-flow", "babel"] @@ -81,6 +116,7 @@ const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo const foo2: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; const foo3: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; const foo4: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; + =====================================output===================================== const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; const foo2: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; diff --git a/tests/typescript/typeparams/consistent/jsfmt.spec.js b/tests/typescript/typeparams/consistent/jsfmt.spec.js index 61cd597f9..9990099dc 100644 --- a/tests/typescript/typeparams/consistent/jsfmt.spec.js +++ b/tests/typescript/typeparams/consistent/jsfmt.spec.js @@ -1 +1,7 @@ -run_spec(__dirname, ["typescript", "flow", "babel-flow", "babel"]); +run_spec(__dirname, ["typescript", "flow", "babel-flow", "babel"], { + errors: { + flow: ["template-literal-types.ts"], + "babel-flow": ["template-literal-types.ts"], + babel: ["template-literal-types.ts"], + }, +}); diff --git a/tests/typescript/typeparams/consistent/template-literal-types.ts b/tests/typescript/typeparams/consistent/template-literal-types.ts new file mode 100644 index 000000000..06c888eee --- /dev/null +++ b/tests/typescript/typeparams/consistent/template-literal-types.ts @@ -0,0 +1 @@ +const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<`Hello, ${keyof World}`> = a; diff --git a/tests/typescript/typeparams/consistent/typescript-only.ts b/tests/typescript/typeparams/consistent/typescript-only.ts index fcea89f2a..68a5b3628 100644 --- a/tests/typescript/typeparams/consistent/typescript-only.ts +++ b/tests/typescript/typeparams/consistent/typescript-only.ts @@ -1,4 +1,4 @@ const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; const foo2: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; const foo3: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; -const foo4: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; \ No newline at end of file +const foo4: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; diff --git a/yarn.lock b/yarn.lock index 192bbf370..34783333d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1465,19 +1465,10 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.0.1.tgz#1cf72582f764931f085cb8230ff215980fe467b2" integrity sha512-S+gD3fgbkZYW2rnbjugNMqibm9HpEjqZBZkTiI3PwbbNGWmAcxolWIUwZ0SKeG4Dy2ktpKKaI/6+HGYVH8Qrlg== -"@typescript-eslint/typescript-estree@3.10.1": - version "3.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz#fd0061cc38add4fad45136d654408569f365b853" - integrity sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w== - dependencies: - "@typescript-eslint/types" "3.10.1" - "@typescript-eslint/visitor-keys" "3.10.1" - debug "^4.1.1" - glob "^7.1.6" - is-glob "^4.0.1" - lodash "^4.17.15" - semver "^7.3.2" - tsutils "^3.17.1" +"@typescript-eslint/types@4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.8.1.tgz#23829c73c5fc6f4fcd5346a7780b274f72fee222" + integrity sha512-ave2a18x2Y25q5K05K/U3JQIe2Av4+TNi/2YuzyaXLAsDx6UZkz1boZ7nR/N6Wwae2PpudTZmHFXqu7faXfHmA== "@typescript-eslint/typescript-estree@4.0.1": version "4.0.1" @@ -1493,12 +1484,19 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/visitor-keys@3.10.1": - version "3.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz#cd4274773e3eb63b2e870ac602274487ecd1e931" - integrity sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ== +"@typescript-eslint/typescript-estree@4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.8.1.tgz#7307e3f2c9e95df7daa8dc0a34b8c43b7ec0dd32" + integrity sha512-bJ6Fn/6tW2g7WIkCWh3QRlaSU7CdUUK52shx36/J7T5oTQzANvi6raoTsbwGM11+7eBbeem8hCCKbyvAc0X3sQ== dependencies: - eslint-visitor-keys "^1.1.0" + "@typescript-eslint/types" "4.8.1" + "@typescript-eslint/visitor-keys" "4.8.1" + debug "^4.1.1" + globby "^11.0.1" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" "@typescript-eslint/visitor-keys@4.0.1": version "4.0.1" @@ -1508,6 +1506,14 @@ "@typescript-eslint/types" "4.0.1" eslint-visitor-keys "^2.0.0" +"@typescript-eslint/visitor-keys@4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.8.1.tgz#794f68ee292d1b2e3aa9690ebedfcb3a8c90e3c3" + integrity sha512-3nrwXFdEYALQh/zW8rFwP4QltqsanCDz4CwWMPiIZmwlk9GlvBeueEIbq05SEq4ganqM0g9nh02xXgv5XI3PeQ== + dependencies: + "@typescript-eslint/types" "4.8.1" + eslint-visitor-keys "^2.0.0" + "@webassemblyjs/ast@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" @@ -7165,10 +7171,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.5.tgz#ae9dddfd1069f1cb5beb3ef3b2170dd7c1332389" - integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ== +typescript@4.1.1-rc: + version "4.1.1-rc" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.1-rc.tgz#4a335244b9b2754995849ca4b607c74d6ee73719" + integrity sha512-tgNcFrLIjlaMWEc7bKC0bxLNIt8BIAauY/HLUOQDyTP75HGskETtXOt46x4EKAHRKhWVLMc7yM02puTHa/yhCA== unherit@^1.0.4: version "1.1.3" From f2b4965a6ac84626349774e57dba5e38c43a8c7a Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Wed, 18 Nov 2020 13:45:44 +0900 Subject: [PATCH 049/299] Add clean-changelog-unreleased step to release script (#9682) --- ...ost-intro.md => BLOG_POST_INTRO_TEMPLATE.md} | 0 scripts/clean-changelog-unreleased.js | 17 +++++++++++++++++ scripts/draft-blog-post.js | 7 +++++++ scripts/lint-changelog.js | 4 +++- 4 files changed, 27 insertions(+), 1 deletion(-) rename changelog_unreleased/{blog-post-intro.md => BLOG_POST_INTRO_TEMPLATE.md} (100%) create mode 100644 scripts/clean-changelog-unreleased.js diff --git a/changelog_unreleased/blog-post-intro.md b/changelog_unreleased/BLOG_POST_INTRO_TEMPLATE.md similarity index 100% rename from changelog_unreleased/blog-post-intro.md rename to changelog_unreleased/BLOG_POST_INTRO_TEMPLATE.md diff --git a/scripts/clean-changelog-unreleased.js b/scripts/clean-changelog-unreleased.js new file mode 100644 index 000000000..9a8b02c47 --- /dev/null +++ b/scripts/clean-changelog-unreleased.js @@ -0,0 +1,17 @@ +#!/usr/bin/env node + +"use strict"; + +const fs = require("fs"); +const path = require("path"); +const globby = require("globby"); + +const changelogUnreleasedDir = path.join(__dirname, "../changelog_unreleased"); + +const files = globby.sync(["blog-post-intro.md", "*/*.md"], { + cwd: changelogUnreleasedDir, + absolute: true, +}); +for (const file of files) { + fs.unlinkSync(file); +} diff --git a/scripts/draft-blog-post.js b/scripts/draft-blog-post.js index 2477a35d1..2a3daad2a 100644 --- a/scripts/draft-blog-post.js +++ b/scripts/draft-blog-post.js @@ -9,7 +9,14 @@ const semver = require("semver"); const changelogUnreleasedDir = path.join(__dirname, "../changelog_unreleased"); const blogDir = path.join(__dirname, "../website/blog"); +const introTemplateFile = path.join( + changelogUnreleasedDir, + "BLOG_POST_INTRO_TEMPLATE.md" +); const introFile = path.join(changelogUnreleasedDir, "blog-post-intro.md"); +if (!fs.existsSync(introFile)) { + fs.copyFileSync(introTemplateFile, introFile); +} const previousVersion = require("prettier/package.json").version; const version = require("../package.json").version.replace(/-.+/, ""); const postGlob = path.join(blogDir, `????-??-??-${version}.md`); diff --git a/scripts/lint-changelog.js b/scripts/lint-changelog.js index fbb1a78e5..401cbf494 100644 --- a/scripts/lint-changelog.js +++ b/scripts/lint-changelog.js @@ -6,6 +6,7 @@ const { outdent } = require("outdent"); const CHANGELOG_DIR = "changelog_unreleased"; const TEMPLATE_FILE = "TEMPLATE.md"; +const BLOG_POST_INTRO_TEMPLATE_FILE = "BLOG_POST_INTRO_TEMPLATE.md"; const BLOG_POST_INTRO_FILE = "blog-post-intro.md"; const CHANGELOG_CATEGORIES = [ "angular", @@ -38,6 +39,7 @@ for (const file of files) { if ( file !== TEMPLATE_FILE && file !== BLOG_POST_INTRO_FILE && + file !== BLOG_POST_INTRO_TEMPLATE_FILE && !CHANGELOG_CATEGORIES.includes(file) ) { showErrorMessage(`Please remove "${file}" from "${CHANGELOG_DIR}".`); @@ -45,7 +47,7 @@ for (const file of files) { } for (const file of [ TEMPLATE_FILE, - BLOG_POST_INTRO_FILE, + BLOG_POST_INTRO_TEMPLATE_FILE, ...CHANGELOG_CATEGORIES, ]) { if (!files.includes(file)) { From f512cd4737789aa9ef074b622d5e8a137941ce28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Nov 2020 14:43:02 +0800 Subject: [PATCH 050/299] Build(deps-dev): Bump webpack from 5.4.0 to 5.5.0 (#9706) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index fd5977015..2498a62a4 100644 --- a/package.json +++ b/package.json @@ -130,7 +130,7 @@ "synchronous-promise": "2.0.15", "tempy": "1.0.0", "terser-webpack-plugin": "5.0.3", - "webpack": "5.4.0" + "webpack": "5.5.0" }, "scripts": { "prepublishOnly": "echo \"Error: must publish from dist/\" && exit 1", diff --git a/yarn.lock b/yarn.lock index 34783333d..dfc6ea430 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7452,10 +7452,10 @@ webpack-sources@^2.1.1: source-list-map "^2.0.1" source-map "^0.6.1" -webpack@5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.4.0.tgz#4fdc6ec8a0ff9160701fb8f2eb8d06b33ecbae0f" - integrity sha512-udpYTyqz8toTTdaOsL2QKPLeZLt2IEm9qY7yTXuFEQhKu5bk0yQD9BtAdVQksmz4jFbbWOiWmm3NHarO0zr/ng== +webpack@5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.5.0.tgz#250b3fdc1d876c7e58269d1406e7f9790af04f06" + integrity sha512-gyr7VE8zXJP81ZvS8+5dDphS2kaE0r8bpVWX6SxkBlzlX3hYfBS96kaltuf2cYK/BKJlUw5Aex/fKC34HUn+hA== dependencies: "@types/eslint-scope" "^3.7.0" "@types/estree" "^0.0.45" From 2f0062234cbc527406e79e44bc8f686416befd57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Nov 2020 14:43:29 +0800 Subject: [PATCH 051/299] Build(deps-dev): Bump webpack from 5.4.0 to 5.5.0 in /website (#9705) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- website/package.json | 2 +- website/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/website/package.json b/website/package.json index a9c58a5ce..ddd455db6 100644 --- a/website/package.json +++ b/website/package.json @@ -23,7 +23,7 @@ "docusaurus": "1.14.6", "js-yaml": "3.14.0", "svgo": "1.3.2", - "webpack": "5.4.0", + "webpack": "5.5.0", "webpack-cli": "4.2.0" } } diff --git a/website/yarn.lock b/website/yarn.lock index d8a0305ba..f82c822c7 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -7373,10 +7373,10 @@ webpack-sources@^2.1.1: source-list-map "^2.0.1" source-map "^0.6.1" -webpack@5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.4.0.tgz#4fdc6ec8a0ff9160701fb8f2eb8d06b33ecbae0f" - integrity sha512-udpYTyqz8toTTdaOsL2QKPLeZLt2IEm9qY7yTXuFEQhKu5bk0yQD9BtAdVQksmz4jFbbWOiWmm3NHarO0zr/ng== +webpack@5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.5.0.tgz#250b3fdc1d876c7e58269d1406e7f9790af04f06" + integrity sha512-gyr7VE8zXJP81ZvS8+5dDphS2kaE0r8bpVWX6SxkBlzlX3hYfBS96kaltuf2cYK/BKJlUw5Aex/fKC34HUn+hA== dependencies: "@types/eslint-scope" "^3.7.0" "@types/estree" "^0.0.45" From 35a484ec1dca767147e2a88588284e56bab33d8f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Nov 2020 15:22:34 +0800 Subject: [PATCH 052/299] Build(deps-dev): Bump cspell from 4.2.0 to 4.2.2 (#9708) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 58 ++++++++++++++++++++++++++-------------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index 2498a62a4..104ad156d 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "benchmark": "2.1.4", "builtin-modules": "3.1.0", "cross-env": "7.0.2", - "cspell": "4.2.0", + "cspell": "4.2.2", "eslint": "7.13.0", "eslint-config-prettier": "6.15.0", "eslint-formatter-friendly": "7.0.0", diff --git a/yarn.lock b/yarn.lock index dfc6ea430..91bf0a870 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2665,25 +2665,25 @@ cspell-dict-typescript@^1.0.12: dependencies: configstore "^5.0.1" -cspell-glob@^0.1.23: - version "0.1.23" - resolved "https://registry.yarnpkg.com/cspell-glob/-/cspell-glob-0.1.23.tgz#63256b384ca2f010f02a8039a8e5f4b8c2e38156" - integrity sha512-Q6iBxMvxXtPB358jvw3sMSC9AcNecZcQ2aD3oYhmgXYJRxX3TDij/3iXMrDkTAKcZx8V2BBZQJo/aJxkYnP0/A== +cspell-glob@^0.1.25: + version "0.1.25" + resolved "https://registry.yarnpkg.com/cspell-glob/-/cspell-glob-0.1.25.tgz#5d55b03ac5e7a379d435ebd5685178806b0c372f" + integrity sha512-/XaSHrGBpMJa+duFz3GKOWfrijrfdHT7a/XGgIcq3cymCSpOH+DPho42sl0jLI/hjM+8yv2m8aEoxRT8yVSnlg== dependencies: micromatch "^4.0.2" -cspell-io@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/cspell-io/-/cspell-io-4.1.4.tgz#945b527c7e8f06c3c0329991bdcf63b6d04400b2" - integrity sha512-qWVBUpu/+HzWwyjBiAxYGgv/w5w5290kYBtT5D42qQ9x/GxTjrq3AILCeWOOh/JtU4XmpiI2QUuyWEsxLSldZw== +cspell-io@^4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/cspell-io/-/cspell-io-4.1.6.tgz#d3300a08fc4ebcd87748b620f4cfdcbc6f238aa5" + integrity sha512-S8Fk1uBrZGt9vcztKQkMIi2qpGT1R0eqTZ+5v5++nZDkryKkix8iTkNldH7cxIvqTQU9Tr7afFI/0RXSEEn8Eg== dependencies: iconv-lite "^0.6.2" iterable-to-stream "^1.0.1" -cspell-lib@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/cspell-lib/-/cspell-lib-4.3.4.tgz#471048dac762eb712c5390073ec7f61bf74690c0" - integrity sha512-ykbrrAiOwh8Q0X4H5tFuTvtKg+L2nthPgN/5eiw7y1SM8DU8/LVGavDI47qcJ4HJSwuSwZ4RH60Ol1Q5zwqh/Q== +cspell-lib@^4.3.6: + version "4.3.6" + resolved "https://registry.yarnpkg.com/cspell-lib/-/cspell-lib-4.3.6.tgz#fd06b8a85204ea2d35d837ac1385c231c1baa889" + integrity sha512-Bm7AEdbjy5rNqGdOulTZVV/P6eUweDivYIZss29T3j3dUFu99spG73zGmKVxTddB7RNdb4MsfLwtnZvWXr98IA== dependencies: comment-json "^4.1.0" configstore "^5.0.1" @@ -2720,37 +2720,37 @@ cspell-lib@^4.3.4: cspell-dict-scala "^1.0.17" cspell-dict-software-terms "^1.0.19" cspell-dict-typescript "^1.0.12" - cspell-io "^4.1.4" - cspell-trie-lib "^4.2.4" - cspell-util-bundle "^4.1.6" + cspell-io "^4.1.6" + cspell-trie-lib "^4.2.6" + cspell-util-bundle "^4.1.8" fs-extra "^9.0.1" gensequence "^3.1.1" minimatch "^3.0.4" resolve-from "^5.0.0" vscode-uri "^2.1.2" -cspell-trie-lib@^4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/cspell-trie-lib/-/cspell-trie-lib-4.2.4.tgz#4a2f6368b63317ece6ad5cec33fc4fe404c44dfd" - integrity sha512-a+jknY90yav3yGndN9PDQLUeo9nFiGZ2a8j9NSiMkieRnFCHmH7iHOwwoXxiMJ6x4+0zeyhSYF1pXuNA7eE2pw== +cspell-trie-lib@^4.2.6: + version "4.2.6" + resolved "https://registry.yarnpkg.com/cspell-trie-lib/-/cspell-trie-lib-4.2.6.tgz#48e0abee2702400ab15998a55a79d4484e5ecaaa" + integrity sha512-glf6Yk1PxRxTFpQIkBk5G4ljpGUBzJORJe1yFHuiZ29mY5gHL0D7+i5rULa2dFU/5WJ24SFojHUXd1fLCBjUOQ== dependencies: gensequence "^3.1.1" -cspell-util-bundle@^4.1.6: - version "4.1.6" - resolved "https://registry.yarnpkg.com/cspell-util-bundle/-/cspell-util-bundle-4.1.6.tgz#6bc54fe8e73e282f4dbe2e7683cc43e339cf9029" - integrity sha512-wpCmiZRNRZ1fEXuColE2qeX15qicfhgwibSt5zNm77PZYhgkSLam52nIgGlnzSQCCFtOp8iaUeUQy40lJ0V+3Q== +cspell-util-bundle@^4.1.8: + version "4.1.8" + resolved "https://registry.yarnpkg.com/cspell-util-bundle/-/cspell-util-bundle-4.1.8.tgz#c57ffb8fc87f57852a2302553e54a5da94a28ca4" + integrity sha512-Cm9fG7dsdveKEtWAN8TgljhW8OU7OQX4vX3ZFg6o9FQfo6rNoX8nwyxXRq60YjbKNBf1d6/ZSozsqS4vq2uLzQ== -cspell@4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/cspell/-/cspell-4.2.0.tgz#01fffa15dc7d102315edc67fa0b385decd4ee2d1" - integrity sha512-5hKiPYapirbSoCuPpTXnDLA47c4vMV3U+ScFP56YF4lhQiz7yAJnNrgK31RiMHkv/pIUIlnuaKZYDD/7fgEgxg== +cspell@4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/cspell/-/cspell-4.2.2.tgz#cecc6b82c733fb859444a04f9d8df0dd652f692e" + integrity sha512-NqObIP0ljFs/f//pA4D8rwqC9XHW2TY3CMNunp0nPQzVk/GanIqTEtMDZEZrVG1wnxHEndUIHlw05+rEYejkQg== dependencies: chalk "^4.1.0" commander "^6.1.0" comment-json "^4.0.6" - cspell-glob "^0.1.23" - cspell-lib "^4.3.4" + cspell-glob "^0.1.25" + cspell-lib "^4.3.6" fs-extra "^9.0.1" gensequence "^3.1.1" get-stdin "^8.0.0" From bb60b08f9e438ae3a5f6996166c16239ffeb9e9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Nov 2020 08:35:32 +0000 Subject: [PATCH 053/299] Build(deps-dev): Bump @typescript-eslint/types from 3.10.1 to 4.8.1 (#9707) --- package.json | 2 +- src/language-js/types/estree.d.ts | 10 ++-------- yarn.lock | 5 ----- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 104ad156d..ffe071e62 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "@rollup/plugin-replace": "2.3.4", "@types/estree": "0.0.45", "@types/node": "14.14.0", - "@typescript-eslint/types": "3.10.1", + "@typescript-eslint/types": "4.8.1", "babel-jest": "26.6.3", "babel-loader": "8.2.1", "benchmark": "2.1.4", diff --git a/src/language-js/types/estree.d.ts b/src/language-js/types/estree.d.ts index 9c19b8866..9690345a4 100644 --- a/src/language-js/types/estree.d.ts +++ b/src/language-js/types/estree.d.ts @@ -43,10 +43,7 @@ export type CallExpression = ( ) & AdditionalFields; -export type OptionalCallExpression = ( - | Babel.OptionalCallExpression - | TSESTree.OptionalCallExpression -) & +export type OptionalCallExpression = Babel.OptionalCallExpression & AdditionalFields; export type MemberExpression = ( @@ -56,10 +53,7 @@ export type MemberExpression = ( ) & AdditionalFields; -export type OptionalMemberExpression = ( - | Babel.OptionalMemberExpression - | TSESTree.OptionalMemberExpression -) & +export type OptionalMemberExpression = Babel.OptionalMemberExpression & AdditionalFields; export type Expression = ( diff --git a/yarn.lock b/yarn.lock index 91bf0a870..927ebfbeb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1455,11 +1455,6 @@ "@typescript-eslint/types" "4.0.1" "@typescript-eslint/visitor-keys" "4.0.1" -"@typescript-eslint/types@3.10.1": - version "3.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727" - integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ== - "@typescript-eslint/types@4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.0.1.tgz#1cf72582f764931f085cb8230ff215980fe467b2" From 9d06174d55b9826fe9133c041d0f0104fef45624 Mon Sep 17 00:00:00 2001 From: Dang Mai Date: Wed, 18 Nov 2020 05:58:46 -0500 Subject: [PATCH 054/299] Fix #9702 - Flush line suffix contents at the end of document (#9703) * Failing test case for flushing line-suffix contents * Flush remaining line-suffix contents at the end of document --- src/document/doc-printer.js | 7 ++++++ .../__tests__/plugin-flush-line-suffix.js | 14 +++++++++++ .../plugins/flushLineSuffix/file.foo | 1 + .../plugins/flushLineSuffix/plugin.js | 25 +++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 tests_integration/__tests__/plugin-flush-line-suffix.js create mode 100644 tests_integration/plugins/flushLineSuffix/file.foo create mode 100644 tests_integration/plugins/flushLineSuffix/plugin.js diff --git a/src/document/doc-printer.js b/src/document/doc-printer.js index 1886571aa..541063c49 100644 --- a/src/document/doc-printer.js +++ b/src/document/doc-printer.js @@ -526,6 +526,13 @@ function printDocToString(doc, options) { default: } } + + // Flush remaining line-suffix contents at the end of the document, in case + // there is no new line after the line-suffix. + if (cmds.length === 0 && lineSuffix.length) { + cmds.push(...lineSuffix.reverse()); + lineSuffix = []; + } } const cursorPlaceholderIndex = out.indexOf(cursor.placeholder); diff --git a/tests_integration/__tests__/plugin-flush-line-suffix.js b/tests_integration/__tests__/plugin-flush-line-suffix.js new file mode 100644 index 000000000..e60ab5adb --- /dev/null +++ b/tests_integration/__tests__/plugin-flush-line-suffix.js @@ -0,0 +1,14 @@ +"use strict"; + +const runPrettier = require("../runPrettier"); + +describe("flush all line-suffix content", () => { + runPrettier("plugins/flushLineSuffix", ["*.foo", "--plugin=./plugin"], { + ignoreLineEndings: true, + }).test({ + stdout: "contents", + stderr: "", + status: 0, + write: [], + }); +}); diff --git a/tests_integration/plugins/flushLineSuffix/file.foo b/tests_integration/plugins/flushLineSuffix/file.foo new file mode 100644 index 000000000..12f00e90b --- /dev/null +++ b/tests_integration/plugins/flushLineSuffix/file.foo @@ -0,0 +1 @@ +contents diff --git a/tests_integration/plugins/flushLineSuffix/plugin.js b/tests_integration/plugins/flushLineSuffix/plugin.js new file mode 100644 index 000000000..4690948ab --- /dev/null +++ b/tests_integration/plugins/flushLineSuffix/plugin.js @@ -0,0 +1,25 @@ +"use strict"; + +const prettier = require("prettier-local"); +const { lineSuffix } = prettier.doc.builders; + +module.exports = { + languages: [ + { + name: "foo", + parsers: ["foo-parser"], + extensions: [".foo"] + } + ], + parsers: { + "foo-parser": { + parse: text => ({ text }), + astFormat: "foo-ast" + } + }, + printers: { + "foo-ast": { + print: path => lineSuffix(path.getValue().text.trim()) + } + } +}; From c74420ec1c91c6e876555fdb74b0228100b084db Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Wed, 18 Nov 2020 19:03:52 +0800 Subject: [PATCH 055/299] Refactor: Improve location compare (#9709) --- src/main/comments.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/comments.js b/src/main/comments.js index 98209cc3b..3d362d160 100644 --- a/src/main/comments.js +++ b/src/main/comments.js @@ -93,6 +93,8 @@ function getSortedChildNodes(node, options, resultArray) { // least one of which is guaranteed to be defined. function decorateComment(node, comment, options) { const { locStart, locEnd } = options; + const commentStart = locStart(comment); + const commentEnd = locEnd(comment); const childNodes = getSortedChildNodes(node, options); let precedingNode; @@ -103,11 +105,10 @@ function decorateComment(node, comment, options) { while (left < right) { const middle = (left + right) >> 1; const child = childNodes[middle]; + const start = locStart(child); + const end = locEnd(child); - if ( - locStart(child) - locStart(comment) <= 0 && - locEnd(comment) - locEnd(child) <= 0 - ) { + if (start <= commentStart && commentEnd <= end) { // The comment is completely contained by this child node. comment.enclosingNode = child; @@ -115,7 +116,7 @@ function decorateComment(node, comment, options) { return; // Abandon the binary search at this level. } - if (locEnd(child) - locStart(comment) <= 0) { + if (start <= commentStart) { // This child node falls completely before the comment. // Because we will never consider this node or any nodes // before it again, this node must be the closest preceding @@ -125,7 +126,7 @@ function decorateComment(node, comment, options) { continue; } - if (locEnd(comment) - locStart(child) <= 0) { + if (commentEnd <= start) { // This child node falls completely after the comment. // Because we will never consider this node or any nodes after // it again, this node must be the closest following node we From 693b9a1f6f8105b1a11d4e371bd4b6a445c12c8b Mon Sep 17 00:00:00 2001 From: Benny Neugebauer Date: Wed, 18 Nov 2020 12:04:37 +0100 Subject: [PATCH 056/299] Fix link to GitHub profile (#9712) --- website/blog/2020-08-24-2.1.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/blog/2020-08-24-2.1.0.md b/website/blog/2020-08-24-2.1.0.md index b164a5a23..215b2102c 100644 --- a/website/blog/2020-08-24-2.1.0.md +++ b/website/blog/2020-08-24-2.1.0.md @@ -12,7 +12,7 @@ This release adds a new `--embedded-language-formatting` option, supports new Ja ### API -#### Add --embedded-language-formatting={auto,off} option ([#7875](https://github.com/prettier/prettier/pull/7875) by [@bakkot](https://github.com/bakkot), [#8825](https://github.com/prettier/prettier/pull/8825) by [@fisker](https://github.com/fiskers)) +#### Add --embedded-language-formatting={auto,off} option ([#7875](https://github.com/prettier/prettier/pull/7875) by [@bakkot](https://github.com/bakkot), [#8825](https://github.com/prettier/prettier/pull/8825) by [@fisker](https://github.com/fisker)) When Prettier identifies cases where it looks like you've placed some code it knows how to format within a string in another file, like in a tagged template in JavaScript with a tag named `html` or in code blocks in Markdown, it will try to format that code by default. From 1064b55f23ce900d9ed33bcf97e0ec959c924cfc Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Wed, 18 Nov 2020 19:51:45 +0800 Subject: [PATCH 057/299] Remove unused parenStart (#9699) --- src/language-js/parse-postprocess.js | 6 +----- src/language-js/types/estree.d.ts | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/language-js/parse-postprocess.js b/src/language-js/parse-postprocess.js index 9aa82f603..0d8c34733 100644 --- a/src/language-js/parse-postprocess.js +++ b/src/language-js/parse-postprocess.js @@ -96,11 +96,7 @@ function postprocess(ast, options) { const start = locStart(node); if (!startOffsetsOfTypeCastedNodes.has(start)) { - if (!expression.extra) { - expression.extra = {}; - } - expression.extra.parenthesized = true; - expression.extra.parenStart = start; + expression.extra = { ...expression.extra, parenthesized: true }; return expression; } } diff --git a/src/language-js/types/estree.d.ts b/src/language-js/types/estree.d.ts index 9690345a4..e3f9b3d3b 100644 --- a/src/language-js/types/estree.d.ts +++ b/src/language-js/types/estree.d.ts @@ -7,7 +7,6 @@ import * as NGTree from "angular-estree-parser/lib/types"; type AdditionalFields = { extra?: { parenthesized?: boolean; - parenStart?: number; raw?: string; }; comments?: Comment[]; From f532bf2b495a19540e45d9ed32a6693fca8bceea Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 19 Nov 2020 08:58:56 +0800 Subject: [PATCH 058/299] Refactor: Module releated format (#9691) --- src/language-js/print/module.js | 232 +++++++++++++++++- src/language-js/printer-estree.js | 151 ++---------- .../comments/__snapshots__/jsfmt.spec.js.snap | 12 +- 3 files changed, 241 insertions(+), 154 deletions(-) diff --git a/src/language-js/print/module.js b/src/language-js/print/module.js index 107677341..b1b23a6b0 100644 --- a/src/language-js/print/module.js +++ b/src/language-js/print/module.js @@ -1,28 +1,181 @@ "use strict"; const { - builders: { concat, softline, group, indent, join, line, ifBreak }, + builders: { concat, softline, group, indent, join, line, ifBreak, hardline }, } = require("../../document"); +const { printDanglingComments } = require("../../main/comments"); -const { shouldPrintComma } = require("../utils"); +const { + hasDanglingComments, + shouldPrintComma, + needsHardlineAfterDanglingComment, +} = require("../utils"); +const { locStart, hasSameLoc } = require("../loc"); /** * @typedef {import("../../document").Doc} Doc */ +function printImportDeclaration(path, options, print) { + const node = path.getValue(); + const semi = options.semi ? ";" : ""; + /** @type{Doc[]} */ + const parts = []; + + const { importKind } = node; + + parts.push("import"); + + if (importKind && importKind !== "value") { + parts.push(" ", importKind); + } + + parts.push( + printModuleSpecifiers(path, options, print), + printModuleSource(path, options, print), + printImportAssertions(path, options, print) + ); + + parts.push(semi); + + return concat(parts); +} + +function printExportDeclaration(path, options, print) { + const node = path.getValue(); + /** @type{Doc[]} */ + const parts = []; + + const { type, exportKind, declaration } = node; + if (type === "DeclareExportDeclaration") { + parts.push("declare "); + } + + parts.push("export"); + + const isDefaultExport = node.default || type === "ExportDefaultDeclaration"; + if (isDefaultExport) { + parts.push(" default"); + } + + if (hasDanglingComments(node)) { + parts.push( + " ", + printDanglingComments(path, options, /* sameIndent */ true) + ); + + if (needsHardlineAfterDanglingComment(node)) { + parts.push(hardline); + } + } + + if (declaration) { + parts.push(" ", path.call(print, "declaration")); + } else { + parts.push( + exportKind === "type" ? " type" : "", + printModuleSpecifiers(path, options, print), + printModuleSource(path, options, print), + printImportAssertions(path, options, print) + ); + } + + if (shouldExportDeclarationPrintSemi(node, options)) { + parts.push(";"); + } + + return concat(parts); +} + +function printExportAllDeclaration(path, options, print) { + const node = path.getValue(); + let semi = options.semi ? ";" : ""; + /** @type{Doc[]} */ + const parts = []; + + const { type, exportKind, exported } = node; + if (type === "DeclareExportAllDeclaration") { + parts.push("declare "); + semi = ""; + } + + parts.push("export"); + + if (exportKind === "type") { + parts.push(" type"); + } + + parts.push(" *"); + + if (exported) { + parts.push(" as ", path.call(print, "exported")); + } + + parts.push( + printModuleSource(path, options, print), + printImportAssertions(path, options, print), + semi + ); + + return concat(parts); +} + +function shouldExportDeclarationPrintSemi(node, options) { + if (!options.semi) { + return false; + } + + const { type, declaration } = node; + const isDefaultExport = node.default || type === "ExportDefaultDeclaration"; + if (!declaration) { + return true; + } + + const { type: declarationType } = declaration; + if ( + isDefaultExport && + declarationType !== "ClassDeclaration" && + declarationType !== "FunctionDeclaration" && + declarationType !== "TSInterfaceDeclaration" && + declarationType !== "DeclareClass" && + declarationType !== "DeclareFunction" && + declarationType !== "TSDeclareFunction" && + declarationType !== "EnumDeclaration" + ) { + return true; + } + return false; +} + function printModuleSource(path, options, print) { const node = path.getValue(); - return node.source ? concat([" from ", path.call(print, "source")]) : ""; + + if (!node.source) { + return ""; + } + + /** @type{Doc[]} */ + const parts = []; + if (!shouldNotPrintSpecifiers(node, options)) { + parts.push(" from"); + } + parts.push(" ", path.call(print, "source")); + + return concat(parts); } function printModuleSpecifiers(path, options, print) { const node = path.getValue(); + if (shouldNotPrintSpecifiers(node, options)) { + return ""; + } + /** @type{Doc[]} */ - const parts = [node.type === "ImportDeclaration" ? " " : ""]; + const parts = [" "]; if (node.specifiers && node.specifiers.length > 0) { - const standalonesSpecifiers = []; + const standaloneSpecifiers = []; const groupedSpecifiers = []; path.each((specifierPath) => { @@ -33,7 +186,7 @@ function printModuleSpecifiers(path, options, print) { specifierType === "ImportNamespaceSpecifier" || specifierType === "ImportDefaultSpecifier" ) { - standalonesSpecifiers.push(print(specifierPath)); + standaloneSpecifiers.push(print(specifierPath)); } else if ( specifierType === "ExportSpecifier" || specifierType === "ImportSpecifier" @@ -47,16 +200,16 @@ function printModuleSpecifiers(path, options, print) { } }, "specifiers"); - parts.push(join(", ", standalonesSpecifiers)); + parts.push(join(", ", standaloneSpecifiers)); if (groupedSpecifiers.length !== 0) { - if (standalonesSpecifiers.length !== 0) { + if (standaloneSpecifiers.length !== 0) { parts.push(", "); } const canBreak = groupedSpecifiers.length > 1 || - standalonesSpecifiers.length > 0 || + standaloneSpecifiers.length > 0 || node.specifiers.some((node) => node.comments); if (canBreak) { @@ -94,6 +247,23 @@ function printModuleSpecifiers(path, options, print) { return concat(parts); } +function shouldNotPrintSpecifiers(node, options) { + const { type, importKind, source, specifiers } = node; + + if ( + type !== "ImportDeclaration" || + (Array.isArray(specifiers) && specifiers.length > 0) || + importKind === "type" + ) { + return false; + } + + // TODO: check tokens + return !/{\s*}/.test( + options.originalText.slice(locStart(node), locStart(source)) + ); +} + function printImportAssertions(path, options, print) { const node = path.getNode(); if (Array.isArray(node.assertions) && node.assertions.length !== 0) { @@ -108,8 +278,46 @@ function printImportAssertions(path, options, print) { return ""; } +function printModuleSpecifier(path, options, print) { + const node = path.getNode(); + + const { type, importKind } = node; + /** @type{Doc[]} */ + const parts = []; + if (type === "ImportSpecifier" && importKind) { + parts.push(importKind, " "); + } + + const isImport = type.startsWith("Import"); + const leftSideProperty = isImport ? "imported" : "local"; + const rightSideProperty = isImport ? "local" : "exported"; + let left = ""; + let right = ""; + if ( + type === "ExportNamespaceSpecifier" || + type === "ImportNamespaceSpecifier" + ) { + left = "*"; + } else if (node[leftSideProperty]) { + left = path.call(print, leftSideProperty); + } + + if ( + node[rightSideProperty] && + (!node[leftSideProperty] || + // import {a as a} from '.' + !hasSameLoc(node[leftSideProperty], node[rightSideProperty])) + ) { + right = path.call(print, rightSideProperty); + } + + parts.push(left, left && right ? " as " : "", right); + return concat(parts); +} + module.exports = { - printModuleSource, - printModuleSpecifiers, - printImportAssertions, + printImportDeclaration, + printExportDeclaration, + printExportAllDeclaration, + printModuleSpecifier, }; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 4657fa348..44065793b 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -103,7 +103,7 @@ const { shouldFlatten, startsWithNoLookaheadToken, } = require("./utils"); -const { locStart, locEnd, hasSameLoc } = require("./loc"); +const { locStart, locEnd } = require("./loc"); const printMemberChain = require("./print/member-chain"); const printCallArguments = require("./print/call-arguments"); @@ -114,9 +114,10 @@ const { printBindExpressionCallee, } = require("./print/misc"); const { - printModuleSource, - printModuleSpecifiers, - printImportAssertions, + printImportDeclaration, + printExportDeclaration, + printExportAllDeclaration, + printModuleSpecifier, } = require("./print/module"); const printTernaryOperator = require("./print/ternary"); const { @@ -807,93 +808,24 @@ function printPathNoParens(path, options, print, args) { } return concat(parts); } - case "ImportSpecifier": - if (n.importKind) { - parts.push(path.call(print, "importKind"), " "); - } - - parts.push(path.call(print, "imported")); - - if (n.local && !hasSameLoc(n.local, n.imported)) { - parts.push(" as ", path.call(print, "local")); - } - - return concat(parts); - case "ExportSpecifier": { - parts.push(path.call(print, "local")); - - if (n.exported && !hasSameLoc(n.local, n.exported)) { - parts.push(" as ", path.call(print, "exported")); - } - - return concat(parts); - } - case "ImportNamespaceSpecifier": - parts.push("* as "); - parts.push(path.call(print, "local")); - return concat(parts); - case "ImportDefaultSpecifier": - return path.call(print, "local"); case "TSExportAssignment": return concat(["export = ", path.call(print, "expression"), semi]); case "ExportDefaultDeclaration": case "ExportNamedDeclaration": - return printExportDeclaration(path, options, print); case "DeclareExportDeclaration": - return concat(["declare ", printExportDeclaration(path, options, print)]); + return printExportDeclaration(path, options, print); case "ExportAllDeclaration": - parts.push("export"); - - if (n.exportKind === "type") { - parts.push(" type"); - } - - parts.push(" *"); - - if (n.exported) { - parts.push(" as ", path.call(print, "exported")); - } - - parts.push( - printModuleSource(path, options, print), - printImportAssertions(path, options, print), - semi - ); - - return concat(parts); - + case "DeclareExportAllDeclaration": + return printExportAllDeclaration(path, options, print); + case "ImportDeclaration": + return printImportDeclaration(path, options, print); + case "ImportSpecifier": + case "ExportSpecifier": + case "ImportNamespaceSpecifier": case "ExportNamespaceSpecifier": - return concat(["* as ", path.call(print, "exported")]); + case "ImportDefaultSpecifier": case "ExportDefaultSpecifier": - return path.call(print, "exported"); - case "ImportDeclaration": { - parts.push("import"); - - if (n.importKind && n.importKind !== "value") { - parts.push(" ", n.importKind); - } - - if (n.specifiers && n.specifiers.length > 0) { - parts.push(printModuleSpecifiers(path, options, print)); - parts.push(printModuleSource(path, options, print)); - } else if ( - (n.importKind && n.importKind === "type") || - // import {} from 'x' - /{\s*}/.test( - options.originalText.slice(locStart(n), locStart(n.source)) - ) - ) { - parts.push(" {}", printModuleSource(path, options, print)); - } else { - parts.push(" ", path.call(print, "source")); - } - - parts.push(printImportAssertions(path, options, print)); - - parts.push(semi); - - return concat(parts); - } + return printModuleSpecifier(path, options, print); case "ImportAttribute": return concat([path.call(print, "key"), ": ", path.call(print, "value")]); case "Import": @@ -2350,11 +2282,6 @@ function printPathNoParens(path, options, print, args) { ]); case "DeclareVariable": return printFlowDeclaration(path, ["var ", path.call(print, "id"), semi]); - case "DeclareExportAllDeclaration": - return concat([ - "declare export *", - printModuleSource(path, options, print), - ]); case "DeclareOpaqueType": case "OpaqueType": { parts.push( @@ -3808,54 +3735,6 @@ function printReturnType(path, print, options) { return concat(parts); } -function printExportDeclaration(path, options, print) { - const decl = path.getValue(); - - const semi = options.semi ? ";" : ""; - - /** @type{Doc[]} */ - const parts = ["export "]; - - const isDefault = decl.default || decl.type === "ExportDefaultDeclaration"; - - if (isDefault) { - parts.push("default "); - } - - parts.push( - comments.printDanglingComments(path, options, /* sameIndent */ true) - ); - - if (needsHardlineAfterDanglingComment(decl)) { - parts.push(hardline); - } - - if (decl.declaration) { - parts.push(path.call(print, "declaration")); - - if ( - isDefault && - decl.declaration.type !== "ClassDeclaration" && - decl.declaration.type !== "FunctionDeclaration" && - decl.declaration.type !== "TSInterfaceDeclaration" && - decl.declaration.type !== "DeclareClass" && - decl.declaration.type !== "DeclareFunction" && - decl.declaration.type !== "TSDeclareFunction" && - decl.declaration.type !== "EnumDeclaration" - ) { - parts.push(semi); - } - } else { - parts.push(decl.exportKind === "type" ? "type " : ""); - parts.push(printModuleSpecifiers(path, options, print)); - parts.push(printModuleSource(path, options, print)); - parts.push(printImportAssertions(path, options, print)); - parts.push(semi); - } - - return concat(parts); -} - function printFlowDeclaration(path, parts) { const parentExportDecl = getParentExportDeclaration(path); diff --git a/tests/js/comments/__snapshots__/jsfmt.spec.js.snap b/tests/js/comments/__snapshots__/jsfmt.spec.js.snap index 46bb3bfb7..aec6bbbce 100644 --- a/tests/js/comments/__snapshots__/jsfmt.spec.js.snap +++ b/tests/js/comments/__snapshots__/jsfmt.spec.js.snap @@ -1175,7 +1175,7 @@ function d() { } new Thing(/* dangling */) Thing(/* dangling */) -export /* dangling */{} +export /* dangling */ {} ================================================================================ `; @@ -1213,7 +1213,7 @@ function d() { } new Thing(/* dangling */); Thing(/* dangling */); -export /* dangling */{}; +export /* dangling */ {}; ================================================================================ `; @@ -1476,9 +1476,9 @@ export { =====================================output===================================== export //comment -{} + {} -export /* comment */{} +export /* comment */ {} const foo = "" export { @@ -1532,9 +1532,9 @@ export { =====================================output===================================== export //comment -{}; + {}; -export /* comment */{}; +export /* comment */ {}; const foo = ""; export { From dcd92726d23a0c68a086f04b1568bb30c5a549e0 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 19 Nov 2020 08:59:25 +0800 Subject: [PATCH 059/299] Extract array and object print (#9698) --- src/language-js/print/array.js | 132 ++++++++ src/language-js/print/object.js | 239 ++++++++++++++ src/language-js/print/type-annotation.js | 68 ++++ src/language-js/printer-estree.js | 403 +---------------------- 4 files changed, 450 insertions(+), 392 deletions(-) create mode 100644 src/language-js/print/array.js create mode 100644 src/language-js/print/object.js create mode 100644 src/language-js/print/type-annotation.js diff --git a/src/language-js/print/array.js b/src/language-js/print/array.js new file mode 100644 index 000000000..0ce6db81b --- /dev/null +++ b/src/language-js/print/array.js @@ -0,0 +1,132 @@ +"use strict"; + +const { printDanglingComments } = require("../../main/comments"); +const { + builders: { concat, line, softline, group, indent, ifBreak }, +} = require("../../document"); +const { getLast, isNextLineEmpty } = require("../../common/util"); +const { hasDanglingComments, shouldPrintComma } = require("../utils"); +const { locEnd } = require("../loc"); + +const { printOptionalToken } = require("./misc"); +const { printTypeAnnotation } = require("./type-annotation"); + +/** @typedef {import("../../document").Doc} Doc */ + +function printArray(path, options, print) { + const n = path.getValue(); + /** @type{Doc[]} */ + const parts = []; + + const openBracket = n.type === "TupleExpression" ? "#[" : "["; + const closeBracket = "]"; + if (n.elements.length === 0) { + if (!hasDanglingComments(n)) { + parts.push(openBracket, closeBracket); + } else { + parts.push( + group( + concat([ + openBracket, + printDanglingComments(path, options), + softline, + closeBracket, + ]) + ) + ); + } + } else { + const lastElem = getLast(n.elements); + const canHaveTrailingComma = !(lastElem && lastElem.type === "RestElement"); + + // JavaScript allows you to have empty elements in an array which + // changes its length based on the number of commas. The algorithm + // is that if the last argument is null, we need to force insert + // a comma to ensure JavaScript recognizes it. + // [,].length === 1 + // [1,].length === 1 + // [1,,].length === 2 + // + // Note that getLast returns null if the array is empty, but + // we already check for an empty array just above so we are safe + const needsForcedTrailingComma = canHaveTrailingComma && lastElem === null; + + const shouldBreak = + !options.__inJestEach && + n.elements.length > 1 && + n.elements.every((element, i, elements) => { + const elementType = element && element.type; + if ( + elementType !== "ArrayExpression" && + elementType !== "ObjectExpression" + ) { + return false; + } + + const nextElement = elements[i + 1]; + if (nextElement && elementType !== nextElement.type) { + return false; + } + + const itemsKey = + elementType === "ArrayExpression" ? "elements" : "properties"; + + return element[itemsKey] && element[itemsKey].length > 1; + }); + + parts.push( + group( + concat([ + openBracket, + indent( + concat([ + softline, + printArrayItems(path, options, "elements", print), + ]) + ), + needsForcedTrailingComma ? "," : "", + ifBreak( + canHaveTrailingComma && + !needsForcedTrailingComma && + shouldPrintComma(options) + ? "," + : "" + ), + printDanglingComments(path, options, /* sameIndent */ true), + softline, + closeBracket, + ]), + { shouldBreak } + ) + ); + } + + parts.push( + printOptionalToken(path), + printTypeAnnotation(path, options, print) + ); + + return concat(parts); +} + +function printArrayItems(path, options, printPath, print) { + const printedElements = []; + let separatorParts = []; + + path.each((childPath) => { + printedElements.push(concat(separatorParts)); + printedElements.push(group(print(childPath))); + + separatorParts = [",", line]; + if ( + childPath.getValue() && + isNextLineEmpty(options.originalText, childPath.getValue(), locEnd) + ) { + separatorParts.push(softline); + } + }, printPath); + + return concat(printedElements); +} + +module.exports = { printArray, printArrayItems }; diff --git a/src/language-js/print/object.js b/src/language-js/print/object.js new file mode 100644 index 000000000..e6f949e6c --- /dev/null +++ b/src/language-js/print/object.js @@ -0,0 +1,239 @@ +"use strict"; + +const { printDanglingComments } = require("../../main/comments"); +const { + builders: { concat, line, softline, group, indent, ifBreak, hardline }, +} = require("../../document"); +const { + getLast, + isNextLineEmpty, + hasNewlineInRange, + hasNewline, +} = require("../../common/util"); +const { + hasDanglingComments, + shouldPrintComma, + hasNodeIgnoreComment, + isBlockComment, +} = require("../utils"); +const { locStart, locEnd } = require("../loc"); + +const { printOptionalToken } = require("./misc"); +const { shouldHugFunctionParameters } = require("./function-parameters"); +const { printTypeAnnotation, shouldHugType } = require("./type-annotation"); + +/** @typedef {import("../../document").Doc} Doc */ + +function printObject(path, options, print) { + const semi = options.semi ? ";" : ""; + const n = path.getValue(); + + let propertiesField; + + if (n.type === "TSTypeLiteral") { + propertiesField = "members"; + } else if (n.type === "TSInterfaceBody") { + propertiesField = "body"; + } else { + propertiesField = "properties"; + } + + const isTypeAnnotation = n.type === "ObjectTypeAnnotation"; + const fields = []; + if (isTypeAnnotation) { + fields.push("indexers", "callProperties", "internalSlots"); + } + fields.push(propertiesField); + + const firstProperty = fields + .map((field) => n[field][0]) + .sort((a, b) => locStart(a) - locStart(b))[0]; + + const parent = path.getParentNode(0); + const isFlowInterfaceLikeBody = + isTypeAnnotation && + parent && + (parent.type === "InterfaceDeclaration" || + parent.type === "DeclareInterface" || + parent.type === "DeclareClass") && + path.getName() === "body"; + const shouldBreak = + n.type === "TSInterfaceBody" || + isFlowInterfaceLikeBody || + (n.type === "ObjectPattern" && + parent.type !== "FunctionDeclaration" && + parent.type !== "FunctionExpression" && + parent.type !== "ArrowFunctionExpression" && + parent.type !== "ObjectMethod" && + parent.type !== "ClassMethod" && + parent.type !== "ClassPrivateMethod" && + parent.type !== "AssignmentPattern" && + parent.type !== "CatchClause" && + n.properties.some( + (property) => + property.value && + (property.value.type === "ObjectPattern" || + property.value.type === "ArrayPattern") + )) || + (n.type !== "ObjectPattern" && + firstProperty && + hasNewlineInRange( + options.originalText, + locStart(n), + locStart(firstProperty) + )); + + const separator = isFlowInterfaceLikeBody + ? ";" + : n.type === "TSInterfaceBody" || n.type === "TSTypeLiteral" + ? ifBreak(semi, ";") + : ","; + const leftBrace = n.type === "RecordExpression" ? "#{" : n.exact ? "{|" : "{"; + const rightBrace = n.exact ? "|}" : "}"; + + // Unfortunately, things are grouped together in the ast can be + // interleaved in the source code. So we need to reorder them before + // printing them. + const propsAndLoc = []; + fields.forEach((field) => { + path.each((childPath) => { + const node = childPath.getValue(); + propsAndLoc.push({ + node, + printed: print(childPath), + loc: locStart(node), + }); + }, field); + }); + + let separatorParts = []; + const props = propsAndLoc + .sort((a, b) => a.loc - b.loc) + .map((prop) => { + const result = concat(separatorParts.concat(group(prop.printed))); + separatorParts = [separator, line]; + if ( + (prop.node.type === "TSPropertySignature" || + prop.node.type === "TSMethodSignature" || + prop.node.type === "TSConstructSignatureDeclaration") && + hasNodeIgnoreComment(prop.node) + ) { + separatorParts.shift(); + } + if (isNextLineEmpty(options.originalText, prop.node, locEnd)) { + separatorParts.push(hardline); + } + return result; + }); + + if (n.inexact) { + let printed; + if (hasDanglingComments(n)) { + const hasLineComments = !n.comments.every((comment) => + isBlockComment(comment) + ); + const printedDanglingComments = printDanglingComments( + path, + options, + /* sameIndent */ true + ); + printed = concat([ + printedDanglingComments, + hasLineComments || + hasNewline( + options.originalText, + locEnd(n.comments[n.comments.length - 1]) + ) + ? hardline + : line, + "...", + ]); + } else { + printed = "..."; + } + props.push(concat(separatorParts.concat(printed))); + } + + const lastElem = getLast(n[propertiesField]); + + const canHaveTrailingSeparator = !( + n.inexact || + (lastElem && lastElem.type === "RestElement") || + (lastElem && + (lastElem.type === "TSPropertySignature" || + lastElem.type === "TSCallSignatureDeclaration" || + lastElem.type === "TSMethodSignature" || + lastElem.type === "TSConstructSignatureDeclaration") && + hasNodeIgnoreComment(lastElem)) + ); + + let content; + if (props.length === 0) { + if (!hasDanglingComments(n)) { + return concat([ + leftBrace, + rightBrace, + printTypeAnnotation(path, options, print), + ]); + } + + content = group( + concat([ + leftBrace, + printDanglingComments(path, options), + softline, + rightBrace, + printOptionalToken(path), + printTypeAnnotation(path, options, print), + ]) + ); + } else { + content = concat([ + leftBrace, + indent(concat([options.bracketSpacing ? line : softline, concat(props)])), + ifBreak( + canHaveTrailingSeparator && + (separator !== "," || shouldPrintComma(options)) + ? separator + : "" + ), + concat([options.bracketSpacing ? line : softline, rightBrace]), + printOptionalToken(path), + printTypeAnnotation(path, options, print), + ]); + } + + // If we inline the object as first argument of the parent, we don't want + // to create another group so that the object breaks before the return + // type + if ( + path.match( + (node) => node.type === "ObjectPattern" && !node.decorators, + (node, name, number) => + shouldHugFunctionParameters(node) && + (name === "params" || + name === "parameters" || + name === "this" || + name === "rest") && + number === 0 + ) || + path.match( + shouldHugType, + (node, name) => name === "typeAnnotation", + (node, name) => name === "typeAnnotation", + (node, name, number) => + shouldHugFunctionParameters(node) && + (name === "params" || + name === "parameters" || + name === "this" || + name === "rest") && + number === 0 + ) + ) { + return content; + } + + return group(content, { shouldBreak }); +} + +module.exports = { printObject }; diff --git a/src/language-js/print/type-annotation.js b/src/language-js/print/type-annotation.js new file mode 100644 index 000000000..483a447bb --- /dev/null +++ b/src/language-js/print/type-annotation.js @@ -0,0 +1,68 @@ +"use strict"; +const { + builders: { concat }, +} = require("../../document"); +const { + isFlowAnnotationComment, + isSimpleType, + isObjectType, +} = require("../utils"); + +function printTypeAnnotation(path, options, print) { + const node = path.getValue(); + if (!node.typeAnnotation) { + return ""; + } + + const parentNode = path.getParentNode(); + const isDefinite = + node.definite || + (parentNode && + parentNode.type === "VariableDeclarator" && + parentNode.definite); + + const isFunctionDeclarationIdentifier = + parentNode.type === "DeclareFunction" && parentNode.id === node; + + if (isFlowAnnotationComment(options.originalText, node.typeAnnotation)) { + return concat([" /*: ", path.call(print, "typeAnnotation"), " */"]); + } + + return concat([ + isFunctionDeclarationIdentifier ? "" : isDefinite ? "!: " : ": ", + path.call(print, "typeAnnotation"), + ]); +} + +function shouldHugType(node) { + if (isSimpleType(node) || isObjectType(node)) { + return true; + } + + if (node.type === "UnionTypeAnnotation" || node.type === "TSUnionType") { + const voidCount = node.types.filter( + (n) => + n.type === "VoidTypeAnnotation" || + n.type === "TSVoidKeyword" || + n.type === "NullLiteralTypeAnnotation" || + n.type === "TSNullKeyword" + ).length; + + const hasObject = node.types.some( + (n) => + n.type === "ObjectTypeAnnotation" || + n.type === "TSTypeLiteral" || + // This is a bit aggressive but captures Array<{x}> + n.type === "GenericTypeAnnotation" || + n.type === "TSTypeReference" + ); + + if (node.types.length - 1 === voidCount && hasObject) { + return true; + } + } + + return false; +} + +module.exports = { printTypeAnnotation, shouldHugType }; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 44065793b..073cc6bad 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -64,7 +64,6 @@ const { hasPrettierIgnore, hasTrailingComment, hasTrailingLineComment, - hasNodeIgnoreComment, hasIgnoreComment, identity, isBinaryish, @@ -85,7 +84,6 @@ const { isNumericLiteral, isObjectType, isObjectTypePropertyAFunction, - isSimpleType, isSimpleNumber, isStringLiteral, isStringPropSafeToUnquote, @@ -120,11 +118,14 @@ const { printModuleSpecifier, } = require("./print/module"); const printTernaryOperator = require("./print/ternary"); -const { - printFunctionParameters, - shouldHugFunctionParameters, -} = require("./print/function-parameters"); +const { printFunctionParameters } = require("./print/function-parameters"); const { printTemplateLiteral } = require("./print/template-literal"); +const { printArray, printArrayItems } = require("./print/array"); +const { printObject } = require("./print/object"); +const { + printTypeAnnotation, + shouldHugType, +} = require("./print/type-annotation"); const needsQuoteProps = new WeakMap(); @@ -997,217 +998,8 @@ function printPathNoParens(path, options, print, args) { case "ObjectTypeAnnotation": case "TSInterfaceBody": case "TSTypeLiteral": - case "RecordExpression": { - let propertiesField; - - if (n.type === "TSTypeLiteral") { - propertiesField = "members"; - } else if (n.type === "TSInterfaceBody") { - propertiesField = "body"; - } else { - propertiesField = "properties"; - } - - const isTypeAnnotation = n.type === "ObjectTypeAnnotation"; - const fields = []; - if (isTypeAnnotation) { - fields.push("indexers", "callProperties", "internalSlots"); - } - fields.push(propertiesField); - - const firstProperty = fields - .map((field) => n[field][0]) - .sort((a, b) => locStart(a) - locStart(b))[0]; - - const parent = path.getParentNode(0); - const isFlowInterfaceLikeBody = - isTypeAnnotation && - parent && - (parent.type === "InterfaceDeclaration" || - parent.type === "DeclareInterface" || - parent.type === "DeclareClass") && - path.getName() === "body"; - const shouldBreak = - n.type === "TSInterfaceBody" || - isFlowInterfaceLikeBody || - (n.type === "ObjectPattern" && - parent.type !== "FunctionDeclaration" && - parent.type !== "FunctionExpression" && - parent.type !== "ArrowFunctionExpression" && - parent.type !== "ObjectMethod" && - parent.type !== "ClassMethod" && - parent.type !== "ClassPrivateMethod" && - parent.type !== "AssignmentPattern" && - parent.type !== "CatchClause" && - n.properties.some( - (property) => - property.value && - (property.value.type === "ObjectPattern" || - property.value.type === "ArrayPattern") - )) || - (n.type !== "ObjectPattern" && - firstProperty && - hasNewlineInRange( - options.originalText, - locStart(n), - locStart(firstProperty) - )); - - const separator = isFlowInterfaceLikeBody - ? ";" - : n.type === "TSInterfaceBody" || n.type === "TSTypeLiteral" - ? ifBreak(semi, ";") - : ","; - const leftBrace = - n.type === "RecordExpression" ? "#{" : n.exact ? "{|" : "{"; - const rightBrace = n.exact ? "|}" : "}"; - - // Unfortunately, things are grouped together in the ast can be - // interleaved in the source code. So we need to reorder them before - // printing them. - const propsAndLoc = []; - fields.forEach((field) => { - path.each((childPath) => { - const node = childPath.getValue(); - propsAndLoc.push({ - node, - printed: print(childPath), - loc: locStart(node), - }); - }, field); - }); - - let separatorParts = []; - const props = propsAndLoc - .sort((a, b) => a.loc - b.loc) - .map((prop) => { - const result = concat(separatorParts.concat(group(prop.printed))); - separatorParts = [separator, line]; - if ( - (prop.node.type === "TSPropertySignature" || - prop.node.type === "TSMethodSignature" || - prop.node.type === "TSConstructSignatureDeclaration") && - hasNodeIgnoreComment(prop.node) - ) { - separatorParts.shift(); - } - if (isNextLineEmpty(options.originalText, prop.node, locEnd)) { - separatorParts.push(hardline); - } - return result; - }); - - if (n.inexact) { - let printed; - if (hasDanglingComments(n)) { - const hasLineComments = !n.comments.every((comment) => - isBlockComment(comment) - ); - const printedDanglingComments = comments.printDanglingComments( - path, - options, - /* sameIndent */ true - ); - printed = concat([ - printedDanglingComments, - hasLineComments || - hasNewline( - options.originalText, - locEnd(n.comments[n.comments.length - 1]) - ) - ? hardline - : line, - "...", - ]); - } else { - printed = "..."; - } - props.push(concat(separatorParts.concat(printed))); - } - - const lastElem = getLast(n[propertiesField]); - - const canHaveTrailingSeparator = !( - n.inexact || - (lastElem && lastElem.type === "RestElement") || - (lastElem && - (lastElem.type === "TSPropertySignature" || - lastElem.type === "TSCallSignatureDeclaration" || - lastElem.type === "TSMethodSignature" || - lastElem.type === "TSConstructSignatureDeclaration") && - hasNodeIgnoreComment(lastElem)) - ); - - let content; - if (props.length === 0) { - if (!hasDanglingComments(n)) { - return concat([ - leftBrace, - rightBrace, - printTypeAnnotation(path, options, print), - ]); - } - - content = group( - concat([ - leftBrace, - comments.printDanglingComments(path, options), - softline, - rightBrace, - printOptionalToken(path), - printTypeAnnotation(path, options, print), - ]) - ); - } else { - content = concat([ - leftBrace, - indent( - concat([options.bracketSpacing ? line : softline, concat(props)]) - ), - ifBreak( - canHaveTrailingSeparator && - (separator !== "," || shouldPrintComma(options)) - ? separator - : "" - ), - concat([options.bracketSpacing ? line : softline, rightBrace]), - printOptionalToken(path), - printTypeAnnotation(path, options, print), - ]); - } - - // If we inline the object as first argument of the parent, we don't want - // to create another group so that the object breaks before the return - // type - if ( - path.match( - (node) => node.type === "ObjectPattern" && !node.decorators, - (node, name, number) => - shouldHugFunctionParameters(node) && - (name === "params" || - name === "parameters" || - name === "this" || - name === "rest") && - number === 0 - ) || - path.match( - shouldHugType, - (node, name) => name === "typeAnnotation", - (node, name) => name === "typeAnnotation", - (node, name, number) => - shouldHugFunctionParameters(node) && - (name === "params" || - name === "parameters" || - name === "this" || - name === "rest") && - number === 0 - ) - ) { - return content; - } - - return group(content, { shouldBreak }); - } + case "RecordExpression": + return printObject(path, options, print); // Babel 6 case "ObjectProperty": // Non-standard AST node type. case "Property": @@ -1262,104 +1054,8 @@ function printPathNoParens(path, options, print, args) { ]); case "ArrayExpression": case "ArrayPattern": - case "TupleExpression": { - const openBracket = n.type === "TupleExpression" ? "#[" : "["; - const closeBracket = "]"; - if (n.elements.length === 0) { - if (!hasDanglingComments(n)) { - parts.push(openBracket, closeBracket); - } else { - parts.push( - group( - concat([ - openBracket, - comments.printDanglingComments(path, options), - softline, - closeBracket, - ]) - ) - ); - } - } else { - const lastElem = getLast(n.elements); - const canHaveTrailingComma = !( - lastElem && lastElem.type === "RestElement" - ); - - // JavaScript allows you to have empty elements in an array which - // changes its length based on the number of commas. The algorithm - // is that if the last argument is null, we need to force insert - // a comma to ensure JavaScript recognizes it. - // [,].length === 1 - // [1,].length === 1 - // [1,,].length === 2 - // - // Note that getLast returns null if the array is empty, but - // we already check for an empty array just above so we are safe - const needsForcedTrailingComma = - canHaveTrailingComma && lastElem === null; - - const shouldBreak = - !options.__inJestEach && - n.elements.length > 1 && - n.elements.every((element, i, elements) => { - const elementType = element && element.type; - if ( - elementType !== "ArrayExpression" && - elementType !== "ObjectExpression" - ) { - return false; - } - - const nextElement = elements[i + 1]; - if (nextElement && elementType !== nextElement.type) { - return false; - } - - const itemsKey = - elementType === "ArrayExpression" ? "elements" : "properties"; - - return element[itemsKey] && element[itemsKey].length > 1; - }); - - parts.push( - group( - concat([ - openBracket, - indent( - concat([ - softline, - printArrayItems(path, options, "elements", print), - ]) - ), - needsForcedTrailingComma ? "," : "", - ifBreak( - canHaveTrailingComma && - !needsForcedTrailingComma && - shouldPrintComma(options) - ? "," - : "" - ), - comments.printDanglingComments( - path, - options, - /* sameIndent */ true - ), - softline, - closeBracket, - ]), - { shouldBreak } - ) - ); - } - - parts.push( - printOptionalToken(path), - printTypeAnnotation(path, options, print) - ); - - return concat(parts); - } + case "TupleExpression": + return printArray(path, options, print); case "SequenceExpression": { const parent = path.getParentNode(0); if ( @@ -3619,32 +3315,6 @@ function printMethodInternal(path, options, print) { return concat(parts); } -function printTypeAnnotation(path, options, print) { - const node = path.getValue(); - if (!node.typeAnnotation) { - return ""; - } - - const parentNode = path.getParentNode(); - const isDefinite = - node.definite || - (parentNode && - parentNode.type === "VariableDeclarator" && - parentNode.definite); - - const isFunctionDeclarationIdentifier = - parentNode.type === "DeclareFunction" && parentNode.id === node; - - if (isFlowAnnotationComment(options.originalText, node.typeAnnotation)) { - return concat([" /*: ", path.call(print, "typeAnnotation"), " */"]); - } - - return concat([ - isFunctionDeclarationIdentifier ? "" : isDefinite ? "!: " : ": ", - path.call(print, "typeAnnotation"), - ]); -} - function shouldPrintParamsWithoutParens(path, options) { if (options.arrowParens === "always") { return false; @@ -4673,57 +4343,6 @@ function stmtNeedsASIProtection(path, options) { ); } -function shouldHugType(node) { - if (isSimpleType(node) || isObjectType(node)) { - return true; - } - - if (node.type === "UnionTypeAnnotation" || node.type === "TSUnionType") { - const voidCount = node.types.filter( - (n) => - n.type === "VoidTypeAnnotation" || - n.type === "TSVoidKeyword" || - n.type === "NullLiteralTypeAnnotation" || - n.type === "TSNullKeyword" - ).length; - - const hasObject = node.types.some( - (n) => - n.type === "ObjectTypeAnnotation" || - n.type === "TSTypeLiteral" || - // This is a bit aggressive but captures Array<{x}> - n.type === "GenericTypeAnnotation" || - n.type === "TSTypeReference" - ); - - if (node.types.length - 1 === voidCount && hasObject) { - return true; - } - } - - return false; -} - -function printArrayItems(path, options, printPath, print) { - const printedElements = []; - let separatorParts = []; - - path.each((childPath) => { - printedElements.push(concat(separatorParts)); - printedElements.push(group(print(childPath))); - - separatorParts = [",", line]; - if ( - childPath.getValue() && - isNextLineEmpty(options.originalText, childPath.getValue(), locEnd) - ) { - separatorParts.push(softline); - } - }, printPath); - - return concat(printedElements); -} - function printReturnAndThrowArgument(path, options, print) { const node = path.getValue(); const semi = options.semi ? ";" : ""; From 91690a376ef72aea14da459bbab0b14aa60def04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Nov 2020 16:09:25 +0800 Subject: [PATCH 060/299] Build(deps-dev): Bump webpack from 5.5.0 to 5.5.1 (#9718) Bumps [webpack](https://github.com/webpack/webpack) from 5.5.0 to 5.5.1. - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.5.0...v5.5.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ffe071e62..89995e309 100644 --- a/package.json +++ b/package.json @@ -130,7 +130,7 @@ "synchronous-promise": "2.0.15", "tempy": "1.0.0", "terser-webpack-plugin": "5.0.3", - "webpack": "5.5.0" + "webpack": "5.5.1" }, "scripts": { "prepublishOnly": "echo \"Error: must publish from dist/\" && exit 1", diff --git a/yarn.lock b/yarn.lock index 927ebfbeb..a564456ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7447,10 +7447,10 @@ webpack-sources@^2.1.1: source-list-map "^2.0.1" source-map "^0.6.1" -webpack@5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.5.0.tgz#250b3fdc1d876c7e58269d1406e7f9790af04f06" - integrity sha512-gyr7VE8zXJP81ZvS8+5dDphS2kaE0r8bpVWX6SxkBlzlX3hYfBS96kaltuf2cYK/BKJlUw5Aex/fKC34HUn+hA== +webpack@5.5.1: + version "5.5.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.5.1.tgz#d6537f85554a0e59f15e6e683af11befdd0476aa" + integrity sha512-v4RzZP9BG2xxMLhxcFIo89M+nyIqGjh35Bhm5EE+I2N8y3dc9jT5OSb1HewUMkzMPyyDscOkVD6pSn6EMtTwNQ== dependencies: "@types/eslint-scope" "^3.7.0" "@types/estree" "^0.0.45" From ca9aac8997eb1221c6a91505e8d7a2945284d8d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Nov 2020 16:36:21 +0800 Subject: [PATCH 061/299] Build(deps-dev): Bump webpack from 5.5.0 to 5.5.1 in /website (#9716) Bumps [webpack](https://github.com/webpack/webpack) from 5.5.0 to 5.5.1. - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.5.0...v5.5.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- website/package.json | 2 +- website/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/website/package.json b/website/package.json index ddd455db6..6c50b1157 100644 --- a/website/package.json +++ b/website/package.json @@ -23,7 +23,7 @@ "docusaurus": "1.14.6", "js-yaml": "3.14.0", "svgo": "1.3.2", - "webpack": "5.5.0", + "webpack": "5.5.1", "webpack-cli": "4.2.0" } } diff --git a/website/yarn.lock b/website/yarn.lock index f82c822c7..f25f1d395 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -7373,10 +7373,10 @@ webpack-sources@^2.1.1: source-list-map "^2.0.1" source-map "^0.6.1" -webpack@5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.5.0.tgz#250b3fdc1d876c7e58269d1406e7f9790af04f06" - integrity sha512-gyr7VE8zXJP81ZvS8+5dDphS2kaE0r8bpVWX6SxkBlzlX3hYfBS96kaltuf2cYK/BKJlUw5Aex/fKC34HUn+hA== +webpack@5.5.1: + version "5.5.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.5.1.tgz#d6537f85554a0e59f15e6e683af11befdd0476aa" + integrity sha512-v4RzZP9BG2xxMLhxcFIo89M+nyIqGjh35Bhm5EE+I2N8y3dc9jT5OSb1HewUMkzMPyyDscOkVD6pSn6EMtTwNQ== dependencies: "@types/eslint-scope" "^3.7.0" "@types/estree" "^0.0.45" From 7acaa554e92330fabae038b73048efc5384df65f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Nov 2020 16:37:30 +0800 Subject: [PATCH 062/299] Build(deps-dev): Bump rollup from 2.33.2 to 2.33.3 (#9717) Bumps [rollup](https://github.com/rollup/rollup) from 2.33.2 to 2.33.3. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v2.33.2...v2.33.3) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 89995e309..1638c07b0 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "path-browserify": "1.0.1", "prettier": "2.1.2", "rimraf": "3.0.2", - "rollup": "2.33.2", + "rollup": "2.33.3", "rollup-plugin-node-globals": "1.4.0", "rollup-plugin-terser": "7.0.2", "shelljs": "0.8.4", diff --git a/yarn.lock b/yarn.lock index a564456ed..69e5adab4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6374,10 +6374,10 @@ rollup-pluginutils@^2.3.1: dependencies: estree-walker "^0.6.1" -rollup@2.33.2: - version "2.33.2" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.33.2.tgz#c4c76cd405a7605e6ebe90976398c46d4c2ea166" - integrity sha512-QPQ6/fWCrzHtSXkI269rhKaC7qXGghYBwXU04b1JsDZ6ibZa3DJ9D1SFAYRMgx1inDg0DaTbb3N4Z1NK/r3fhw== +rollup@2.33.3: + version "2.33.3" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.33.3.tgz#ae72ce31f992b09a580072951bfea76e9df17342" + integrity sha512-RpayhPTe4Gu/uFGCmk7Gp5Z9Qic2VsqZ040G+KZZvsZYdcuWaJg678JeDJJvJeEQXminu24a2au+y92CUWVd+w== optionalDependencies: fsevents "~2.1.2" From b12e869333b6361a766d4e4bc8c94299040c0936 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 19 Nov 2020 18:33:50 +0800 Subject: [PATCH 063/299] Extract JSX related print functions (#9714) --- src/language-js/comments.js | 32 ++ src/language-js/print/jsx.js | 721 +++++++++++++++++++++++++++++ src/language-js/printer-estree.js | 730 ++---------------------------- 3 files changed, 781 insertions(+), 702 deletions(-) create mode 100644 src/language-js/print/jsx.js diff --git a/src/language-js/comments.js b/src/language-js/comments.js index 6dd6b85a6..ea999d16b 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -15,6 +15,10 @@ const { isBlockComment, getFunctionParameters, isPrettierIgnoreComment, + isJSXNode, + hasFlowShorthandAnnotationComment, + hasFlowAnnotationComment, + hasIgnoreComment, } = require("./utils"); const { locStart, locEnd } = require("./loc"); @@ -857,6 +861,33 @@ function isTypeCastComment(comment) { ); } +function willPrintOwnComments(path /*, options */) { + const node = path.getValue(); + const parent = path.getParentNode(); + + return ( + ((node && + (isJSXNode(node) || + hasFlowShorthandAnnotationComment(node) || + (parent && + (parent.type === "CallExpression" || + parent.type === "OptionalCallExpression") && + (hasFlowAnnotationComment(node.leadingComments) || + hasFlowAnnotationComment(node.trailingComments))))) || + (parent && + (parent.type === "JSXSpreadAttribute" || + parent.type === "JSXSpreadChild" || + parent.type === "UnionTypeAnnotation" || + parent.type === "TSUnionType" || + ((parent.type === "ClassDeclaration" || + parent.type === "ClassExpression") && + parent.superClass === node)))) && + (!hasIgnoreComment(path) || + parent.type === "UnionTypeAnnotation" || + parent.type === "TSUnionType") + ); +} + module.exports = { handleOwnLineComment, handleEndOfLineComment, @@ -865,4 +896,5 @@ module.exports = { isTypeCastComment, getGapRegex, getCommentChildNodes, + willPrintOwnComments, }; diff --git a/src/language-js/print/jsx.js b/src/language-js/print/jsx.js new file mode 100644 index 000000000..4c21a063e --- /dev/null +++ b/src/language-js/print/jsx.js @@ -0,0 +1,721 @@ +"use strict"; + +const { printComments, printDanglingComments } = require("../../main/comments"); +const { + builders: { + concat, + line, + hardline, + softline, + group, + indent, + conditionalGroup, + fill, + ifBreak, + lineSuffixBoundary, + }, + utils: { willBreak, isLineNext, isEmpty }, +} = require("../../document"); + +const { getLast, getPreferredQuote } = require("../../common/util"); +const { + hasTrailingComment, + isEmptyJSXElement, + isJSXWhitespaceExpression, + isJSXNode, + isMeaningfulJSXText, + matchJsxWhitespaceRegex, + rawText, + isLiteral, + isCallOrOptionalCallExpression, + isStringLiteral, + isBinaryish, + isBlockComment, +} = require("../utils"); +const pathNeedsParens = require("../needs-parens"); +const { willPrintOwnComments } = require("../comments"); + +// JSX expands children from the inside-out, instead of the outside-in. +// This is both to break children before attributes, +// and to ensure that when children break, their parents do as well. +// +// Any element that is written without any newlines and fits on a single line +// is left that way. +// Not only that, any user-written-line containing multiple JSX siblings +// should also be kept on one line if possible, +// so each user-written-line is wrapped in its own group. +// +// Elements that contain newlines or don't fit on a single line (recursively) +// are fully-split, using hardline and shouldBreak: true. +// +// To support that case properly, all leading and trailing spaces +// are stripped from the list of children, and replaced with a single hardline. +function printJsxElementInternal(path, options, print) { + const n = path.getValue(); + + if (n.type === "JSXElement" && isEmptyJSXElement(n)) { + return concat([ + path.call(print, "openingElement"), + path.call(print, "closingElement"), + ]); + } + + const openingLines = + n.type === "JSXElement" + ? path.call(print, "openingElement") + : path.call(print, "openingFragment"); + const closingLines = + n.type === "JSXElement" + ? path.call(print, "closingElement") + : path.call(print, "closingFragment"); + + if ( + n.children.length === 1 && + n.children[0].type === "JSXExpressionContainer" && + (n.children[0].expression.type === "TemplateLiteral" || + n.children[0].expression.type === "TaggedTemplateExpression") + ) { + return concat([ + openingLines, + concat(path.map(print, "children")), + closingLines, + ]); + } + + // Convert `{" "}` to text nodes containing a space. + // 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)) { + return { + type: "JSXText", + value: " ", + raw: " ", + }; + } + return child; + }); + + const containsTag = n.children.filter(isJSXNode).length > 0; + const containsMultipleExpressions = + n.children.filter((child) => child.type === "JSXExpressionContainer") + .length > 1; + const containsMultipleAttributes = + n.type === "JSXElement" && n.openingElement.attributes.length > 1; + + // Record any breaks. Should never go from true to false, only false to true. + let forcedBreak = + willBreak(openingLines) || + containsTag || + containsMultipleAttributes || + containsMultipleExpressions; + + const isMdxBlock = path.getParentNode().rootMarker === "mdx"; + + const rawJsxWhitespace = options.singleQuote ? "{' '}" : '{" "}'; + const jsxWhitespace = isMdxBlock + ? concat([" "]) + : ifBreak(concat([rawJsxWhitespace, softline]), " "); + + const isFacebookTranslationTag = + n.openingElement && + n.openingElement.name && + n.openingElement.name.name === "fbt"; + + const children = printJSXChildren( + path, + options, + print, + jsxWhitespace, + isFacebookTranslationTag + ); + + const containsText = n.children.some((child) => isMeaningfulJSXText(child)); + + // We can end up we multiple whitespace elements with empty string + // content between them. + // We need to remove empty whitespace and softlines before JSX whitespace + // to get the correct output. + for (let i = children.length - 2; i >= 0; i--) { + const isPairOfEmptyStrings = children[i] === "" && children[i + 1] === ""; + const isPairOfHardlines = + children[i] === hardline && + children[i + 1] === "" && + children[i + 2] === hardline; + const isLineFollowedByJSXWhitespace = + (children[i] === softline || children[i] === hardline) && + children[i + 1] === "" && + children[i + 2] === jsxWhitespace; + const isJSXWhitespaceFollowedByLine = + children[i] === jsxWhitespace && + children[i + 1] === "" && + (children[i + 2] === softline || children[i + 2] === hardline); + const isDoubleJSXWhitespace = + children[i] === jsxWhitespace && + children[i + 1] === "" && + children[i + 2] === jsxWhitespace; + const isPairOfHardOrSoftLines = + (children[i] === softline && + children[i + 1] === "" && + children[i + 2] === hardline) || + (children[i] === hardline && + children[i + 1] === "" && + children[i + 2] === softline); + + if ( + (isPairOfHardlines && containsText) || + isPairOfEmptyStrings || + isLineFollowedByJSXWhitespace || + isDoubleJSXWhitespace || + isPairOfHardOrSoftLines + ) { + children.splice(i, 2); + } else if (isJSXWhitespaceFollowedByLine) { + children.splice(i + 1, 2); + } + } + + // Trim trailing lines (or empty strings) + while ( + children.length && + (isLineNext(getLast(children)) || isEmpty(getLast(children))) + ) { + children.pop(); + } + + // Trim leading lines (or empty strings) + while ( + children.length && + (isLineNext(children[0]) || isEmpty(children[0])) && + (isLineNext(children[1]) || isEmpty(children[1])) + ) { + children.shift(); + children.shift(); + } + + // Tweak how we format children if outputting this element over multiple lines. + // Also detect whether we will force this element to output over multiple lines. + const multilineChildren = []; + children.forEach((child, i) => { + // There are a number of situations where we need to ensure we display + // whitespace as `{" "}` when outputting this element over multiple lines. + if (child === jsxWhitespace) { + if (i === 1 && children[i - 1] === "") { + if (children.length === 2) { + // Solitary whitespace + multilineChildren.push(rawJsxWhitespace); + return; + } + // Leading whitespace + multilineChildren.push(concat([rawJsxWhitespace, hardline])); + return; + } else if (i === children.length - 1) { + // Trailing whitespace + multilineChildren.push(rawJsxWhitespace); + return; + } else if (children[i - 1] === "" && children[i - 2] === hardline) { + // Whitespace after line break + multilineChildren.push(rawJsxWhitespace); + return; + } + } + + multilineChildren.push(child); + + if (willBreak(child)) { + forcedBreak = true; + } + }); + + // If there is text we use `fill` to fit as much onto each line as possible. + // When there is no text (just tags and expressions) we use `group` + // to output each on a separate line. + const content = containsText + ? fill(multilineChildren) + : group(concat(multilineChildren), { shouldBreak: true }); + + if (isMdxBlock) { + return content; + } + + const multiLineElem = group( + concat([ + openingLines, + indent(concat([hardline, content])), + hardline, + closingLines, + ]) + ); + + if (forcedBreak) { + return multiLineElem; + } + + return conditionalGroup([ + group(concat([openingLines, concat(children), closingLines])), + multiLineElem, + ]); +} + +// JSX Children are strange, mostly for two reasons: +// 1. JSX reads newlines into string values, instead of skipping them like JS +// 2. up to one whitespace between elements within a line is significant, +// but not between lines. +// +// Leading, trailing, and lone whitespace all need to +// turn themselves into the rather ugly `{' '}` when breaking. +// +// We print JSX using the `fill` doc primitive. +// This requires that we give it an array of alternating +// content and whitespace elements. +// To ensure this we add dummy `""` content elements as needed. +function printJSXChildren( + path, + options, + print, + jsxWhitespace, + isFacebookTranslationTag +) { + const n = path.getValue(); + const children = []; + + path.each((childPath, i) => { + const child = childPath.getValue(); + if (isLiteral(child)) { + const text = rawText(child); + + // Contains a non-whitespace character + if (isMeaningfulJSXText(child)) { + const words = text.split(matchJsxWhitespaceRegex); + + // Starts with whitespace + if (words[0] === "") { + children.push(""); + words.shift(); + if (/\n/.test(words[0])) { + const next = n.children[i + 1]; + children.push( + separatorWithWhitespace( + isFacebookTranslationTag, + words[1], + child, + next + ) + ); + } else { + children.push(jsxWhitespace); + } + words.shift(); + } + + let endWhitespace; + // Ends with whitespace + if (getLast(words) === "") { + words.pop(); + endWhitespace = words.pop(); + } + + // This was whitespace only without a new line. + if (words.length === 0) { + return; + } + + words.forEach((word, i) => { + if (i % 2 === 1) { + children.push(line); + } else { + children.push(word); + } + }); + + if (endWhitespace !== undefined) { + if (/\n/.test(endWhitespace)) { + const next = n.children[i + 1]; + children.push( + separatorWithWhitespace( + isFacebookTranslationTag, + getLast(children), + child, + next + ) + ); + } else { + children.push(jsxWhitespace); + } + } else { + const next = n.children[i + 1]; + children.push( + separatorNoWhitespace( + isFacebookTranslationTag, + getLast(children), + child, + next + ) + ); + } + } else if (/\n/.test(text)) { + // Keep (up to one) blank line between tags/expressions/text. + // Note: We don't keep blank lines between text elements. + if (text.match(/\n/g).length > 1) { + children.push(""); + children.push(hardline); + } + } else { + children.push(""); + children.push(jsxWhitespace); + } + } else { + const printedChild = print(childPath); + children.push(printedChild); + + const next = n.children[i + 1]; + const directlyFollowedByMeaningfulText = + next && isMeaningfulJSXText(next); + if (directlyFollowedByMeaningfulText) { + const firstWord = rawText(next) + .trim() + .split(matchJsxWhitespaceRegex)[0]; + children.push( + separatorNoWhitespace( + isFacebookTranslationTag, + firstWord, + child, + next + ) + ); + } else { + children.push(hardline); + } + } + }, "children"); + + return children; +} + +function separatorNoWhitespace( + isFacebookTranslationTag, + child, + childNode, + nextNode +) { + if (isFacebookTranslationTag) { + return ""; + } + + if ( + (childNode.type === "JSXElement" && !childNode.closingElement) || + (nextNode && nextNode.type === "JSXElement" && !nextNode.closingElement) + ) { + return child.length === 1 ? softline : hardline; + } + + return softline; +} + +function separatorWithWhitespace( + isFacebookTranslationTag, + child, + childNode, + nextNode +) { + if (isFacebookTranslationTag) { + return hardline; + } + + if (child.length === 1) { + return (childNode.type === "JSXElement" && !childNode.closingElement) || + (nextNode && nextNode.type === "JSXElement" && !nextNode.closingElement) + ? hardline + : softline; + } + + return hardline; +} + +function maybeWrapJSXElementInParens(path, elem, options) { + const parent = path.getParentNode(); + /* istanbul ignore next */ + if (!parent) { + return elem; + } + + const NO_WRAP_PARENTS = { + ArrayExpression: true, + JSXAttribute: true, + JSXElement: true, + JSXExpressionContainer: true, + JSXFragment: true, + ExpressionStatement: true, + CallExpression: true, + OptionalCallExpression: true, + ConditionalExpression: true, + JsExpressionRoot: true, + }; + if (NO_WRAP_PARENTS[parent.type]) { + return elem; + } + + const shouldBreak = path.match( + undefined, + (node) => node.type === "ArrowFunctionExpression", + isCallOrOptionalCallExpression, + (node) => node.type === "JSXExpressionContainer" + ); + + const needsParens = pathNeedsParens(path, options); + + return group( + concat([ + needsParens ? "" : ifBreak("("), + indent(concat([softline, elem])), + softline, + needsParens ? "" : ifBreak(")"), + ]), + { shouldBreak } + ); +} + +function printJsxAttribute(path, options, print) { + const n = path.getValue(); + const parts = []; + parts.push(path.call(print, "name")); + + if (n.value) { + let res; + if (isStringLiteral(n.value)) { + const raw = rawText(n.value); + // Unescape all quotes so we get an accurate preferred quote + let final = raw.replace(/'/g, "'").replace(/"/g, '"'); + const quote = getPreferredQuote( + final, + options.jsxSingleQuote ? "'" : '"' + ); + const escape = quote === "'" ? "'" : """; + final = final.slice(1, -1).replace(new RegExp(quote, "g"), escape); + res = concat([quote, final, quote]); + } else { + res = path.call(print, "value"); + } + parts.push("=", res); + } + + return concat(parts); +} + +function printJsxExpressionContainer(path, options, print) { + const n = path.getValue(); + const parent = path.getParentNode(0); + + const hasComments = n.expression.comments && n.expression.comments.length > 0; + + const shouldInline = + n.expression.type === "JSXEmptyExpression" || + (!hasComments && + (n.expression.type === "ArrayExpression" || + n.expression.type === "ObjectExpression" || + n.expression.type === "ArrowFunctionExpression" || + n.expression.type === "CallExpression" || + n.expression.type === "OptionalCallExpression" || + n.expression.type === "FunctionExpression" || + n.expression.type === "TemplateLiteral" || + n.expression.type === "TaggedTemplateExpression" || + n.expression.type === "DoExpression" || + (isJSXNode(parent) && + (n.expression.type === "ConditionalExpression" || + isBinaryish(n.expression))))); + + if (shouldInline) { + return group( + concat(["{", path.call(print, "expression"), lineSuffixBoundary, "}"]) + ); + } + + return group( + concat([ + "{", + indent(concat([softline, path.call(print, "expression")])), + softline, + lineSuffixBoundary, + "}", + ]) + ); +} + +function printJsxOpeningElement(path, options, print) { + const n = path.getValue(); + + const nameHasComments = + (n.name && n.name.comments && n.name.comments.length > 0) || + (n.typeParameters && + n.typeParameters.comments && + n.typeParameters.comments.length > 0); + + // Don't break self-closing elements with no attributes and no comments + if (n.selfClosing && !n.attributes.length && !nameHasComments) { + return concat([ + "<", + path.call(print, "name"), + path.call(print, "typeParameters"), + " />", + ]); + } + + // don't break up opening elements with a single long text attribute + if ( + n.attributes && + n.attributes.length === 1 && + n.attributes[0].value && + isStringLiteral(n.attributes[0].value) && + !n.attributes[0].value.value.includes("\n") && + // We should break for the following cases: + //
+ //
+ !nameHasComments && + (!n.attributes[0].comments || !n.attributes[0].comments.length) + ) { + return group( + concat([ + "<", + path.call(print, "name"), + path.call(print, "typeParameters"), + " ", + concat(path.map(print, "attributes")), + n.selfClosing ? " />" : ">", + ]) + ); + } + + const lastAttrHasTrailingComments = + n.attributes.length && hasTrailingComment(getLast(n.attributes)); + + const bracketSameLine = + // Simple tags (no attributes and no comment in tag name) should be + // kept unbroken regardless of `jsxBracketSameLine` + (!n.attributes.length && !nameHasComments) || + (options.jsxBracketSameLine && + // We should print the bracket in a new line for the following cases: + //
+ //
+ (!nameHasComments || n.attributes.length) && + !lastAttrHasTrailingComments); + + // We should print the opening element expanded if any prop value is a + // string literal with newlines + const shouldBreak = + n.attributes && + n.attributes.some( + (attr) => + attr.value && + isStringLiteral(attr.value) && + attr.value.value.includes("\n") + ); + + return group( + concat([ + "<", + path.call(print, "name"), + path.call(print, "typeParameters"), + concat([ + indent( + concat(path.map((attr) => concat([line, print(attr)]), "attributes")) + ), + n.selfClosing ? line : bracketSameLine ? ">" : softline, + ]), + n.selfClosing ? "/>" : bracketSameLine ? "" : ">", + ]), + { shouldBreak } + ); +} + +function printJsxClosingElement(path, options, print) { + return concat([""]); +} + +function printJsxOpeningClosingFragment(path, options /*, print*/) { + const n = path.getValue(); + const hasComment = n.comments && n.comments.length; + const hasOwnLineComment = + hasComment && !n.comments.every((comment) => isBlockComment(comment)); + const isOpeningFragment = n.type === "JSXOpeningFragment"; + return concat([ + isOpeningFragment ? "<" : "", + ]); +} + +function printJsxElement(path, options, print) { + const elem = printComments( + path, + () => printJsxElementInternal(path, options, print), + options + ); + return maybeWrapJSXElementInParens(path, elem, options); +} + +function printJsxEmptyExpression(path, options /*, print*/) { + const n = path.getValue(); + const requiresHardline = + n.comments && !n.comments.every((comment) => isBlockComment(comment)); + + return concat([ + printDanglingComments(path, options, /* sameIndent */ !requiresHardline), + requiresHardline ? hardline : "", + ]); +} + +// `JSXSpreadAttribute` and `JSXSpreadChild` +function printJsxSpreadAttribute(path, options, print) { + const n = path.getValue(); + return concat([ + "{", + path.call( + (p) => { + const printed = concat(["...", print(p)]); + const n = p.getValue(); + if (!n.comments || !n.comments.length || !willPrintOwnComments(p)) { + return printed; + } + return concat([ + indent(concat([softline, printComments(p, () => printed, options)])), + softline, + ]); + }, + n.type === "JSXSpreadAttribute" ? "argument" : "expression" + ), + "}", + ]); +} + +module.exports = { + printJsxElement, + printJsxAttribute, + printJsxOpeningElement, + printJsxClosingElement, + printJsxOpeningClosingFragment, + printJsxExpressionContainer, + printJsxEmptyExpression, + printJsxSpreadAttribute, + // Alias + printJsxSpreadChild: printJsxSpreadAttribute, +}; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 073cc6bad..f254c19b2 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -13,7 +13,6 @@ const { getLast, printString, printNumber, - getPreferredQuote, isNextLineEmpty, getNextNonSpaceNonCommentCharacterIndex, } = require("../common/util"); @@ -29,11 +28,9 @@ const { indent, align, conditionalGroup, - fill, ifBreak, - lineSuffixBoundary, }, - utils: { willBreak, isLineNext, isEmpty, normalizeParts }, + utils: { isEmpty, normalizeParts }, } = require("../document"); const embed = require("./embed"); const clean = require("./clean"); @@ -64,20 +61,16 @@ const { hasPrettierIgnore, hasTrailingComment, hasTrailingLineComment, - hasIgnoreComment, identity, isBinaryish, isCallOrOptionalCallExpression, - isEmptyJSXElement, isExportDeclaration, isFlowAnnotationComment, isFunctionNotation, isGetterOrSetter, isJSXNode, - isJSXWhitespaceExpression, isLastStatement, isLiteral, - isMeaningfulJSXText, isMemberExpressionChain, isMemberish, isNgForOf, @@ -93,7 +86,6 @@ const { isTSXFile, isBlockComment, isLineComment, - matchJsxWhitespaceRegex, needsHardlineAfterDanglingComment, rawText, returnArgumentHasLeadingComment, @@ -126,6 +118,17 @@ const { printTypeAnnotation, shouldHugType, } = require("./print/type-annotation"); +const { + printJsxElement, + printJsxAttribute, + printJsxOpeningElement, + printJsxClosingElement, + printJsxOpeningClosingFragment, + printJsxExpressionContainer, + printJsxEmptyExpression, + printJsxSpreadAttribute, + printJsxSpreadChild, +} = require("./print/jsx"); const needsQuoteProps = new WeakMap(); @@ -1536,28 +1539,7 @@ function printPathNoParens(path, options, print, args) { case "DebuggerStatement": return concat(["debugger", semi]); case "JSXAttribute": - parts.push(path.call(print, "name")); - - if (n.value) { - let res; - if (isStringLiteral(n.value)) { - const raw = rawText(n.value); - // Unescape all quotes so we get an accurate preferred quote - let final = raw.replace(/'/g, "'").replace(/"/g, '"'); - const quote = getPreferredQuote( - final, - options.jsxSingleQuote ? "'" : '"' - ); - const escape = quote === "'" ? "'" : """; - final = final.slice(1, -1).replace(new RegExp(quote, "g"), escape); - res = concat([quote, final, quote]); - } else { - res = path.call(print, "value"); - } - parts.push("=", res); - } - - return concat(parts); + return printJsxAttribute(path, options, print); case "JSXIdentifier": return "" + n.name; case "JSXNamespacedName": @@ -1573,215 +1555,26 @@ function printPathNoParens(path, options, print, args) { case "TSQualifiedName": return join(".", [path.call(print, "left"), path.call(print, "right")]); case "JSXSpreadAttribute": - case "JSXSpreadChild": { - return concat([ - "{", - path.call( - (p) => { - const printed = concat(["...", print(p)]); - const n = p.getValue(); - if (!n.comments || !n.comments.length || !willPrintOwnComments(p)) { - return printed; - } - return concat([ - indent( - concat([ - softline, - comments.printComments(p, () => printed, options), - ]) - ), - softline, - ]); - }, - n.type === "JSXSpreadAttribute" ? "argument" : "expression" - ), - "}", - ]); - } - case "JSXExpressionContainer": { - const parent = path.getParentNode(0); - - const hasComments = - n.expression.comments && n.expression.comments.length > 0; - - const shouldInline = - n.expression.type === "JSXEmptyExpression" || - (!hasComments && - (n.expression.type === "ArrayExpression" || - n.expression.type === "ObjectExpression" || - n.expression.type === "ArrowFunctionExpression" || - n.expression.type === "CallExpression" || - n.expression.type === "OptionalCallExpression" || - n.expression.type === "FunctionExpression" || - n.expression.type === "TemplateLiteral" || - n.expression.type === "TaggedTemplateExpression" || - n.expression.type === "DoExpression" || - (isJSXNode(parent) && - (n.expression.type === "ConditionalExpression" || - isBinaryish(n.expression))))); - - if (shouldInline) { - return group( - concat(["{", path.call(print, "expression"), lineSuffixBoundary, "}"]) - ); - } - - return group( - concat([ - "{", - indent(concat([softline, path.call(print, "expression")])), - softline, - lineSuffixBoundary, - "}", - ]) - ); - } + return printJsxSpreadAttribute(path, options, print); + case "JSXSpreadChild": + return printJsxSpreadChild(path, options, print); + case "JSXExpressionContainer": + return printJsxExpressionContainer(path, options, print); case "JSXFragment": - case "JSXElement": { - const elem = comments.printComments( - path, - () => printJSXElement(path, options, print), - options - ); - return maybeWrapJSXElementInParens(path, elem, options); - } - case "JSXOpeningElement": { - const n = path.getValue(); - - const nameHasComments = - (n.name && n.name.comments && n.name.comments.length > 0) || - (n.typeParameters && - n.typeParameters.comments && - n.typeParameters.comments.length > 0); - - // Don't break self-closing elements with no attributes and no comments - if (n.selfClosing && !n.attributes.length && !nameHasComments) { - return concat([ - "<", - path.call(print, "name"), - path.call(print, "typeParameters"), - " />", - ]); - } - - // don't break up opening elements with a single long text attribute - if ( - n.attributes && - n.attributes.length === 1 && - n.attributes[0].value && - isStringLiteral(n.attributes[0].value) && - !n.attributes[0].value.value.includes("\n") && - // We should break for the following cases: - //
- //
- !nameHasComments && - (!n.attributes[0].comments || !n.attributes[0].comments.length) - ) { - return group( - concat([ - "<", - path.call(print, "name"), - path.call(print, "typeParameters"), - " ", - concat(path.map(print, "attributes")), - n.selfClosing ? " />" : ">", - ]) - ); - } - - const lastAttrHasTrailingComments = - n.attributes.length && hasTrailingComment(getLast(n.attributes)); - - const bracketSameLine = - // Simple tags (no attributes and no comment in tag name) should be - // kept unbroken regardless of `jsxBracketSameLine` - (!n.attributes.length && !nameHasComments) || - (options.jsxBracketSameLine && - // We should print the bracket in a new line for the following cases: - //
- //
- (!nameHasComments || n.attributes.length) && - !lastAttrHasTrailingComments); - - // We should print the opening element expanded if any prop value is a - // string literal with newlines - const shouldBreak = - n.attributes && - n.attributes.some( - (attr) => - attr.value && - isStringLiteral(attr.value) && - attr.value.value.includes("\n") - ); - - return group( - concat([ - "<", - path.call(print, "name"), - path.call(print, "typeParameters"), - concat([ - indent( - concat( - path.map((attr) => concat([line, print(attr)]), "attributes") - ) - ), - n.selfClosing ? line : bracketSameLine ? ">" : softline, - ]), - n.selfClosing ? "/>" : bracketSameLine ? "" : ">", - ]), - { shouldBreak } - ); - } + case "JSXElement": + return printJsxElement(path, options, print); + case "JSXOpeningElement": + return printJsxOpeningElement(path, options, print); case "JSXClosingElement": - return concat([""]); + return printJsxClosingElement(path, options, print); case "JSXOpeningFragment": - case "JSXClosingFragment": { - const hasComment = n.comments && n.comments.length; - const hasOwnLineComment = - hasComment && !n.comments.every((comment) => isBlockComment(comment)); - const isOpeningFragment = n.type === "JSXOpeningFragment"; - return concat([ - isOpeningFragment ? "<" : "", - ]); - } + case "JSXClosingFragment": + return printJsxOpeningClosingFragment(path, options /*, print*/); case "JSXText": /* istanbul ignore next */ throw new Error("JSXTest should be handled by JSXElement"); - case "JSXEmptyExpression": { - const requiresHardline = - n.comments && !n.comments.every((comment) => isBlockComment(comment)); - - return concat([ - comments.printDanglingComments( - path, - options, - /* sameIndent */ !requiresHardline - ), - requiresHardline ? hardline : "", - ]); - } + case "JSXEmptyExpression": + return printJsxEmptyExpression(path, options /*, print*/); case "ClassBody": if (!n.comments && n.body.length === 0) { return "{}"; @@ -3634,446 +3427,6 @@ function printClass(path, options, print) { return parts; } -function separatorNoWhitespace( - isFacebookTranslationTag, - child, - childNode, - nextNode -) { - if (isFacebookTranslationTag) { - return ""; - } - - if ( - (childNode.type === "JSXElement" && !childNode.closingElement) || - (nextNode && nextNode.type === "JSXElement" && !nextNode.closingElement) - ) { - return child.length === 1 ? softline : hardline; - } - - return softline; -} - -function separatorWithWhitespace( - isFacebookTranslationTag, - child, - childNode, - nextNode -) { - if (isFacebookTranslationTag) { - return hardline; - } - - if (child.length === 1) { - return (childNode.type === "JSXElement" && !childNode.closingElement) || - (nextNode && nextNode.type === "JSXElement" && !nextNode.closingElement) - ? hardline - : softline; - } - - return hardline; -} - -// JSX Children are strange, mostly for two reasons: -// 1. JSX reads newlines into string values, instead of skipping them like JS -// 2. up to one whitespace between elements within a line is significant, -// but not between lines. -// -// Leading, trailing, and lone whitespace all need to -// turn themselves into the rather ugly `{' '}` when breaking. -// -// We print JSX using the `fill` doc primitive. -// This requires that we give it an array of alternating -// content and whitespace elements. -// To ensure this we add dummy `""` content elements as needed. -function printJSXChildren( - path, - options, - print, - jsxWhitespace, - isFacebookTranslationTag -) { - const n = path.getValue(); - const children = []; - - path.each((childPath, i) => { - const child = childPath.getValue(); - if (isLiteral(child)) { - const text = rawText(child); - - // Contains a non-whitespace character - if (isMeaningfulJSXText(child)) { - const words = text.split(matchJsxWhitespaceRegex); - - // Starts with whitespace - if (words[0] === "") { - children.push(""); - words.shift(); - if (/\n/.test(words[0])) { - const next = n.children[i + 1]; - children.push( - separatorWithWhitespace( - isFacebookTranslationTag, - words[1], - child, - next - ) - ); - } else { - children.push(jsxWhitespace); - } - words.shift(); - } - - let endWhitespace; - // Ends with whitespace - if (getLast(words) === "") { - words.pop(); - endWhitespace = words.pop(); - } - - // This was whitespace only without a new line. - if (words.length === 0) { - return; - } - - words.forEach((word, i) => { - if (i % 2 === 1) { - children.push(line); - } else { - children.push(word); - } - }); - - if (endWhitespace !== undefined) { - if (/\n/.test(endWhitespace)) { - const next = n.children[i + 1]; - children.push( - separatorWithWhitespace( - isFacebookTranslationTag, - getLast(children), - child, - next - ) - ); - } else { - children.push(jsxWhitespace); - } - } else { - const next = n.children[i + 1]; - children.push( - separatorNoWhitespace( - isFacebookTranslationTag, - getLast(children), - child, - next - ) - ); - } - } else if (/\n/.test(text)) { - // Keep (up to one) blank line between tags/expressions/text. - // Note: We don't keep blank lines between text elements. - if (text.match(/\n/g).length > 1) { - children.push(""); - children.push(hardline); - } - } else { - children.push(""); - children.push(jsxWhitespace); - } - } else { - const printedChild = print(childPath); - children.push(printedChild); - - const next = n.children[i + 1]; - const directlyFollowedByMeaningfulText = - next && isMeaningfulJSXText(next); - if (directlyFollowedByMeaningfulText) { - const firstWord = rawText(next) - .trim() - .split(matchJsxWhitespaceRegex)[0]; - children.push( - separatorNoWhitespace( - isFacebookTranslationTag, - firstWord, - child, - next - ) - ); - } else { - children.push(hardline); - } - } - }, "children"); - - return children; -} - -// JSX expands children from the inside-out, instead of the outside-in. -// This is both to break children before attributes, -// and to ensure that when children break, their parents do as well. -// -// Any element that is written without any newlines and fits on a single line -// is left that way. -// Not only that, any user-written-line containing multiple JSX siblings -// should also be kept on one line if possible, -// so each user-written-line is wrapped in its own group. -// -// Elements that contain newlines or don't fit on a single line (recursively) -// are fully-split, using hardline and shouldBreak: true. -// -// To support that case properly, all leading and trailing spaces -// are stripped from the list of children, and replaced with a single hardline. -function printJSXElement(path, options, print) { - const n = path.getValue(); - - if (n.type === "JSXElement" && isEmptyJSXElement(n)) { - return concat([ - path.call(print, "openingElement"), - path.call(print, "closingElement"), - ]); - } - - const openingLines = - n.type === "JSXElement" - ? path.call(print, "openingElement") - : path.call(print, "openingFragment"); - const closingLines = - n.type === "JSXElement" - ? path.call(print, "closingElement") - : path.call(print, "closingFragment"); - - if ( - n.children.length === 1 && - n.children[0].type === "JSXExpressionContainer" && - (n.children[0].expression.type === "TemplateLiteral" || - n.children[0].expression.type === "TaggedTemplateExpression") - ) { - return concat([ - openingLines, - concat(path.map(print, "children")), - closingLines, - ]); - } - - // Convert `{" "}` to text nodes containing a space. - // 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)) { - return { - type: "JSXText", - value: " ", - raw: " ", - }; - } - return child; - }); - - const containsTag = n.children.filter(isJSXNode).length > 0; - const containsMultipleExpressions = - n.children.filter((child) => child.type === "JSXExpressionContainer") - .length > 1; - const containsMultipleAttributes = - n.type === "JSXElement" && n.openingElement.attributes.length > 1; - - // Record any breaks. Should never go from true to false, only false to true. - let forcedBreak = - willBreak(openingLines) || - containsTag || - containsMultipleAttributes || - containsMultipleExpressions; - - const isMdxBlock = path.getParentNode().rootMarker === "mdx"; - - const rawJsxWhitespace = options.singleQuote ? "{' '}" : '{" "}'; - const jsxWhitespace = isMdxBlock - ? concat([" "]) - : ifBreak(concat([rawJsxWhitespace, softline]), " "); - - const isFacebookTranslationTag = - n.openingElement && - n.openingElement.name && - n.openingElement.name.name === "fbt"; - - const children = printJSXChildren( - path, - options, - print, - jsxWhitespace, - isFacebookTranslationTag - ); - - const containsText = n.children.some((child) => isMeaningfulJSXText(child)); - - // We can end up we multiple whitespace elements with empty string - // content between them. - // We need to remove empty whitespace and softlines before JSX whitespace - // to get the correct output. - for (let i = children.length - 2; i >= 0; i--) { - const isPairOfEmptyStrings = children[i] === "" && children[i + 1] === ""; - const isPairOfHardlines = - children[i] === hardline && - children[i + 1] === "" && - children[i + 2] === hardline; - const isLineFollowedByJSXWhitespace = - (children[i] === softline || children[i] === hardline) && - children[i + 1] === "" && - children[i + 2] === jsxWhitespace; - const isJSXWhitespaceFollowedByLine = - children[i] === jsxWhitespace && - children[i + 1] === "" && - (children[i + 2] === softline || children[i + 2] === hardline); - const isDoubleJSXWhitespace = - children[i] === jsxWhitespace && - children[i + 1] === "" && - children[i + 2] === jsxWhitespace; - const isPairOfHardOrSoftLines = - (children[i] === softline && - children[i + 1] === "" && - children[i + 2] === hardline) || - (children[i] === hardline && - children[i + 1] === "" && - children[i + 2] === softline); - - if ( - (isPairOfHardlines && containsText) || - isPairOfEmptyStrings || - isLineFollowedByJSXWhitespace || - isDoubleJSXWhitespace || - isPairOfHardOrSoftLines - ) { - children.splice(i, 2); - } else if (isJSXWhitespaceFollowedByLine) { - children.splice(i + 1, 2); - } - } - - // Trim trailing lines (or empty strings) - while ( - children.length && - (isLineNext(getLast(children)) || isEmpty(getLast(children))) - ) { - children.pop(); - } - - // Trim leading lines (or empty strings) - while ( - children.length && - (isLineNext(children[0]) || isEmpty(children[0])) && - (isLineNext(children[1]) || isEmpty(children[1])) - ) { - children.shift(); - children.shift(); - } - - // Tweak how we format children if outputting this element over multiple lines. - // Also detect whether we will force this element to output over multiple lines. - const multilineChildren = []; - children.forEach((child, i) => { - // There are a number of situations where we need to ensure we display - // whitespace as `{" "}` when outputting this element over multiple lines. - if (child === jsxWhitespace) { - if (i === 1 && children[i - 1] === "") { - if (children.length === 2) { - // Solitary whitespace - multilineChildren.push(rawJsxWhitespace); - return; - } - // Leading whitespace - multilineChildren.push(concat([rawJsxWhitespace, hardline])); - return; - } else if (i === children.length - 1) { - // Trailing whitespace - multilineChildren.push(rawJsxWhitespace); - return; - } else if (children[i - 1] === "" && children[i - 2] === hardline) { - // Whitespace after line break - multilineChildren.push(rawJsxWhitespace); - return; - } - } - - multilineChildren.push(child); - - if (willBreak(child)) { - forcedBreak = true; - } - }); - - // If there is text we use `fill` to fit as much onto each line as possible. - // When there is no text (just tags and expressions) we use `group` - // to output each on a separate line. - const content = containsText - ? fill(multilineChildren) - : group(concat(multilineChildren), { shouldBreak: true }); - - if (isMdxBlock) { - return content; - } - - const multiLineElem = group( - concat([ - openingLines, - indent(concat([hardline, content])), - hardline, - closingLines, - ]) - ); - - if (forcedBreak) { - return multiLineElem; - } - - return conditionalGroup([ - group(concat([openingLines, concat(children), closingLines])), - multiLineElem, - ]); -} - -function maybeWrapJSXElementInParens(path, elem, options) { - const parent = path.getParentNode(); - /* istanbul ignore next */ - if (!parent) { - return elem; - } - - const NO_WRAP_PARENTS = { - ArrayExpression: true, - JSXAttribute: true, - JSXElement: true, - JSXExpressionContainer: true, - JSXFragment: true, - ExpressionStatement: true, - CallExpression: true, - OptionalCallExpression: true, - ConditionalExpression: true, - JsExpressionRoot: true, - }; - if (NO_WRAP_PARENTS[parent.type]) { - return elem; - } - - const shouldBreak = path.match( - undefined, - (node) => node.type === "ArrowFunctionExpression", - isCallOrOptionalCallExpression, - (node) => node.type === "JSXExpressionContainer" - ); - - const needsParens = pathNeedsParens(path, options); - - return group( - concat([ - needsParens ? "" : ifBreak("("), - indent(concat([softline, elem])), - softline, - needsParens ? "" : ifBreak(")"), - ]), - { shouldBreak } - ); -} - function shouldInlineLogicalExpression(node) { if (node.type !== "LogicalExpression") { return false; @@ -4399,33 +3752,6 @@ function printReturnAndThrowArgument(path, options, print) { return concat(parts); } -function willPrintOwnComments(path /*, options */) { - const node = path.getValue(); - const parent = path.getParentNode(); - - return ( - ((node && - (isJSXNode(node) || - hasFlowShorthandAnnotationComment(node) || - (parent && - (parent.type === "CallExpression" || - parent.type === "OptionalCallExpression") && - (hasFlowAnnotationComment(node.leadingComments) || - hasFlowAnnotationComment(node.trailingComments))))) || - (parent && - (parent.type === "JSXSpreadAttribute" || - parent.type === "JSXSpreadChild" || - parent.type === "UnionTypeAnnotation" || - parent.type === "TSUnionType" || - ((parent.type === "ClassDeclaration" || - parent.type === "ClassExpression") && - parent.superClass === node)))) && - (!hasIgnoreComment(path) || - parent.type === "UnionTypeAnnotation" || - parent.type === "TSUnionType") - ); -} - function canAttachComment(node) { return ( node.type && @@ -4509,7 +3835,7 @@ module.exports = { insertPragma, massageAstNode: clean, hasPrettierIgnore, - willPrintOwnComments, + willPrintOwnComments: handleComments.willPrintOwnComments, canAttachComment, printComment, isBlockComment, From 87dab58b3ac41d57ae9232187490085d37cb660e Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 19 Nov 2020 18:52:35 +0800 Subject: [PATCH 064/299] Extract printClass and printTypeParameters (#9713) --- src/language-js/print/class.js | 143 ++++++++++++ src/language-js/print/type-parameters.js | 100 ++++++++ src/language-js/printer-estree.js | 280 ++++------------------- 3 files changed, 288 insertions(+), 235 deletions(-) create mode 100644 src/language-js/print/class.js create mode 100644 src/language-js/print/type-parameters.js diff --git a/src/language-js/print/class.js b/src/language-js/print/class.js new file mode 100644 index 000000000..f5b44069e --- /dev/null +++ b/src/language-js/print/class.js @@ -0,0 +1,143 @@ +"use strict"; + +const { printComments, printDanglingComments } = require("../../main/comments"); +const { + builders: { concat, join, line, hardline, softline, group, indent, ifBreak }, +} = require("../../document"); +const { hasTrailingComment, hasTrailingLineComment } = require("../utils"); +const { getTypeParametersGroupId } = require("./type-parameters"); + +function printClass(path, options, print) { + const n = path.getValue(); + const parts = []; + + if (n.abstract) { + parts.push("abstract "); + } + + parts.push("class"); + + // Keep old behaviour of extends in same line + // If there is only on extends and there are not comments + const groupMode = + (n.id && hasTrailingComment(n.id)) || + (n.superClass && + n.superClass.comments && + n.superClass.comments.length !== 0) || + (n.extends && n.extends.length !== 0) || // DeclareClass + (n.mixins && n.mixins.length !== 0) || + (n.implements && n.implements.length !== 0); + + const partsGroup = []; + const extendsParts = []; + + if (n.id) { + partsGroup.push(" ", path.call(print, "id")); + } + + partsGroup.push(path.call(print, "typeParameters")); + + if (n.superClass) { + const printed = concat([ + "extends ", + printSuperClass(path, options, print), + path.call(print, "superTypeParameters"), + ]); + const printedWithComments = path.call( + (superClass) => printComments(superClass, () => printed, options), + "superClass" + ); + if (groupMode) { + extendsParts.push(line, group(printedWithComments)); + } else { + extendsParts.push(" ", printedWithComments); + } + } else { + extendsParts.push(printList(path, options, print, "extends")); + } + + extendsParts.push(printList(path, options, print, "mixins")); + extendsParts.push(printList(path, options, print, "implements")); + + if (groupMode) { + const printedExtends = concat(extendsParts); + if (shouldIndentOnlyHeritageClauses(n)) { + parts.push( + group( + concat( + partsGroup.concat(ifBreak(indent(printedExtends), printedExtends)) + ) + ) + ); + } else { + parts.push(group(indent(concat(partsGroup.concat(printedExtends))))); + } + } else { + parts.push(...partsGroup, ...extendsParts); + } + + parts.push(" ", path.call(print, "body")); + + return concat(parts); +} + +function hasMultipleHeritage(node) { + return ( + ["superClass", "extends", "mixins", "implements"].filter( + (key) => !!node[key] + ).length > 1 + ); +} + +function shouldIndentOnlyHeritageClauses(node) { + return ( + node.typeParameters && + !hasTrailingLineComment(node.typeParameters) && + !hasMultipleHeritage(node) + ); +} + +function printList(path, options, print, listName) { + const n = path.getValue(); + if (!n[listName] || n[listName].length === 0) { + return ""; + } + + const printedLeadingComments = printDanglingComments( + path, + options, + /* sameIndent */ true, + ({ marker }) => marker === listName + ); + return concat([ + shouldIndentOnlyHeritageClauses(n) + ? ifBreak(" ", line, { + groupId: getTypeParametersGroupId(n.typeParameters), + }) + : line, + printedLeadingComments, + printedLeadingComments && hardline, + listName, + group( + indent( + concat([line, join(concat([",", line]), path.map(print, listName))]) + ) + ), + ]); +} + +function printSuperClass(path, options, print) { + const printed = path.call(print, "superClass"); + const parent = path.getParentNode(); + if (parent && parent.type === "AssignmentExpression") { + return concat([ + ifBreak("("), + indent(concat([softline, printed])), + softline, + ifBreak(")"), + ]); + } + return printed; +} + +module.exports = { printClass }; diff --git a/src/language-js/print/type-parameters.js b/src/language-js/print/type-parameters.js new file mode 100644 index 000000000..f4c53039f --- /dev/null +++ b/src/language-js/print/type-parameters.js @@ -0,0 +1,100 @@ +"use strict"; + +const { printDanglingComments } = require("../../main/comments"); +const { + builders: { concat, join, line, hardline, softline, group, indent, ifBreak }, +} = require("../../document"); +const { + hasDanglingComments, + isTestCall, + isBlockComment, + shouldPrintComma, +} = require("../utils"); +const { shouldHugType } = require("./type-annotation"); + +const typeParametersGroupIds = new WeakMap(); +function getTypeParametersGroupId(node) { + if (!typeParametersGroupIds.has(node)) { + typeParametersGroupIds.set(node, Symbol("typeParameters")); + } + return typeParametersGroupIds.get(node); +} + +function printTypeParameters(path, options, print, paramsKey) { + const n = path.getValue(); + + if (!n[paramsKey]) { + return ""; + } + + // for TypeParameterDeclaration typeParameters is a single node + if (!Array.isArray(n[paramsKey])) { + return path.call(print, paramsKey); + } + + const grandparent = path.getNode(2); + const isParameterInTestCall = grandparent != null && isTestCall(grandparent); + + const shouldInline = + isParameterInTestCall || + n[paramsKey].length === 0 || + (n[paramsKey].length === 1 && + (shouldHugType(n[paramsKey][0]) || + (n[paramsKey][0].type === "GenericTypeAnnotation" && + shouldHugType(n[paramsKey][0].id)) || + (n[paramsKey][0].type === "TSTypeReference" && + shouldHugType(n[paramsKey][0].typeName)) || + n[paramsKey][0].type === "NullableTypeAnnotation")); + + if (shouldInline) { + return concat([ + "<", + join(", ", path.map(print, paramsKey)), + printDanglingCommentsForInline(path, options), + ">", + ]); + } + + return group( + concat([ + "<", + indent( + concat([ + softline, + join(concat([",", line]), path.map(print, paramsKey)), + ]) + ), + ifBreak( + options.parser !== "typescript" && + options.parser !== "babel-ts" && + shouldPrintComma(options, "all") + ? "," + : "" + ), + softline, + ">", + ]), + { id: getTypeParametersGroupId(n) } + ); +} + +function printDanglingCommentsForInline(path, options) { + const n = path.getValue(); + if (!hasDanglingComments(n)) { + return ""; + } + const hasOnlyBlockComments = n.comments.every((comment) => + isBlockComment(comment) + ); + const printed = printDanglingComments( + path, + options, + /* sameIndent */ hasOnlyBlockComments + ); + if (hasOnlyBlockComments) { + return printed; + } + return concat([printed, hardline]); +} + +module.exports = { printTypeParameters, getTypeParametersGroupId }; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index f254c19b2..cdfde7259 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -129,6 +129,11 @@ const { printJsxSpreadAttribute, printJsxSpreadChild, } = require("./print/jsx"); +const { printClass } = require("./print/class"); +const { + printTypeParameters, + getTypeParametersGroupId, +} = require("./print/type-parameters"); const needsQuoteProps = new WeakMap(); @@ -1646,7 +1651,7 @@ function printPathNoParens(path, options, print, args) { if (n.declare) { parts.push("declare "); } - parts.push(concat(printClass(path, options, print))); + parts.push(printClass(path, options, print)); return concat(parts); case "TSInterfaceHeritage": case "TSExpressionWithTypeArguments": // Babel AST @@ -1748,29 +1753,41 @@ function printPathNoParens(path, options, print, args) { semi, ]); case "DeclareFunction": - return printFlowDeclaration(path, [ - "function ", - path.call(print, "id"), - n.predicate ? " " : "", - path.call(print, "predicate"), - semi, - ]); + return printFlowDeclaration( + path, + concat([ + "function ", + path.call(print, "id"), + n.predicate ? " " : "", + path.call(print, "predicate"), + semi, + ]) + ); case "DeclareModule": - return printFlowDeclaration(path, [ - "module ", - path.call(print, "id"), - " ", - path.call(print, "body"), - ]); + return printFlowDeclaration( + path, + concat([ + "module ", + path.call(print, "id"), + " ", + path.call(print, "body"), + ]) + ); case "DeclareModuleExports": - return printFlowDeclaration(path, [ - "module.exports", - ": ", - path.call(print, "typeAnnotation"), - semi, - ]); + return printFlowDeclaration( + path, + concat([ + "module.exports", + ": ", + path.call(print, "typeAnnotation"), + semi, + ]) + ); case "DeclareVariable": - return printFlowDeclaration(path, ["var ", path.call(print, "id"), semi]); + return printFlowDeclaration( + path, + concat(["var ", path.call(print, "id"), semi]) + ); case "DeclareOpaqueType": case "OpaqueType": { parts.push( @@ -1790,7 +1807,7 @@ function printPathNoParens(path, options, print, args) { parts.push(semi); if (n.type === "DeclareOpaqueType") { - return printFlowDeclaration(path, parts); + return printFlowDeclaration(path, concat(parts)); } return concat(parts); @@ -3198,19 +3215,18 @@ function printReturnType(path, print, options) { return concat(parts); } -function printFlowDeclaration(path, parts) { +function printFlowDeclaration(path, printed) { const parentExportDecl = getParentExportDeclaration(path); if (parentExportDecl) { assert.strictEqual(parentExportDecl.type, "DeclareExportDeclaration"); - } else { - // If the parent node has type DeclareExportDeclaration, then it - // will be responsible for printing the "declare" token. Otherwise - // it needs to be printed with this non-exported declaration node. - parts.unshift("declare "); + return printed; } - return concat(parts); + // If the parent node has type DeclareExportDeclaration, then it + // will be responsible for printing the "declare" token. Otherwise + // it needs to be printed with this non-exported declaration node. + return concat(["declare ", printed]); } function printTypeScriptModifiers(path, options, print) { @@ -3221,212 +3237,6 @@ function printTypeScriptModifiers(path, options, print) { return concat([join(" ", path.map(print, "modifiers")), " "]); } -const typeParametersGroupIds = new WeakMap(); -function getTypeParametersGroupId(node) { - if (!typeParametersGroupIds.has(node)) { - typeParametersGroupIds.set(node, Symbol("typeParameters")); - } - return typeParametersGroupIds.get(node); -} - -function printTypeParameters(path, options, print, paramsKey) { - const n = path.getValue(); - - if (!n[paramsKey]) { - return ""; - } - - // for TypeParameterDeclaration typeParameters is a single node - if (!Array.isArray(n[paramsKey])) { - return path.call(print, paramsKey); - } - - const grandparent = path.getNode(2); - const isParameterInTestCall = grandparent != null && isTestCall(grandparent); - - const shouldInline = - isParameterInTestCall || - n[paramsKey].length === 0 || - (n[paramsKey].length === 1 && - (shouldHugType(n[paramsKey][0]) || - (n[paramsKey][0].type === "GenericTypeAnnotation" && - shouldHugType(n[paramsKey][0].id)) || - (n[paramsKey][0].type === "TSTypeReference" && - shouldHugType(n[paramsKey][0].typeName)) || - n[paramsKey][0].type === "NullableTypeAnnotation")); - - function printDanglingCommentsForInline(n) { - if (!hasDanglingComments(n)) { - return ""; - } - const hasOnlyBlockComments = n.comments.every((comment) => - isBlockComment(comment) - ); - const printed = comments.printDanglingComments( - path, - options, - /* sameIndent */ hasOnlyBlockComments - ); - if (hasOnlyBlockComments) { - return printed; - } - return concat([printed, hardline]); - } - - if (shouldInline) { - return concat([ - "<", - join(", ", path.map(print, paramsKey)), - printDanglingCommentsForInline(n), - ">", - ]); - } - - return group( - concat([ - "<", - indent( - concat([ - softline, - join(concat([",", line]), path.map(print, paramsKey)), - ]) - ), - ifBreak( - options.parser !== "typescript" && - options.parser !== "babel-ts" && - shouldPrintComma(options, "all") - ? "," - : "" - ), - softline, - ">", - ]), - { id: getTypeParametersGroupId(n) } - ); -} - -function printClass(path, options, print) { - const n = path.getValue(); - const parts = []; - - if (n.abstract) { - parts.push("abstract "); - } - - parts.push("class"); - - // Keep old behaviour of extends in same line - // If there is only on extends and there are not comments - const groupMode = - (n.id && hasTrailingComment(n.id)) || - (n.superClass && - n.superClass.comments && - n.superClass.comments.length !== 0) || - (n.extends && n.extends.length !== 0) || // DeclareClass - (n.mixins && n.mixins.length !== 0) || - (n.implements && n.implements.length !== 0); - - const partsGroup = []; - const extendsParts = []; - - if (n.id) { - partsGroup.push(" ", path.call(print, "id")); - } - - partsGroup.push(path.call(print, "typeParameters")); - - const hasMultipleHeritage = - ["superClass", "extends", "mixins", "implements"].filter((key) => !!n[key]) - .length > 1; - const shouldIndentOnlyHeritageClauses = - n.typeParameters && - !hasTrailingLineComment(n.typeParameters) && - !hasMultipleHeritage; - - function printList(listName) { - if (n[listName] && n[listName].length !== 0) { - const printedLeadingComments = comments.printDanglingComments( - path, - options, - /* sameIndent */ true, - ({ marker }) => marker === listName - ); - extendsParts.push( - shouldIndentOnlyHeritageClauses - ? ifBreak(" ", line, { - groupId: getTypeParametersGroupId(n.typeParameters), - }) - : line, - printedLeadingComments, - printedLeadingComments && hardline, - listName, - group( - indent( - concat([line, join(concat([",", line]), path.map(print, listName))]) - ) - ) - ); - } - } - - if (n.superClass) { - const printSuperClass = (path) => { - const printed = path.call(print, "superClass"); - const parent = path.getParentNode(); - if (parent && parent.type === "AssignmentExpression") { - return concat([ - ifBreak("("), - indent(concat([softline, printed])), - softline, - ifBreak(")"), - ]); - } - return printed; - }; - const printed = concat([ - "extends ", - printSuperClass(path), - path.call(print, "superTypeParameters"), - ]); - const printedWithComments = path.call( - (superClass) => - comments.printComments(superClass, () => printed, options), - "superClass" - ); - if (groupMode) { - extendsParts.push(line, group(printedWithComments)); - } else { - extendsParts.push(" ", printedWithComments); - } - } else { - printList("extends"); - } - - printList("mixins"); - printList("implements"); - - if (groupMode) { - const printedExtends = concat(extendsParts); - if (shouldIndentOnlyHeritageClauses) { - parts.push( - group( - concat( - partsGroup.concat(ifBreak(indent(printedExtends), printedExtends)) - ) - ) - ); - } else { - parts.push(group(indent(concat(partsGroup.concat(printedExtends))))); - } - } else { - parts.push(...partsGroup, ...extendsParts); - } - - parts.push(" ", path.call(print, "body")); - - return parts; -} - function shouldInlineLogicalExpression(node) { if (node.type !== "LogicalExpression") { return false; From c03a38e8de078eaa50385842258969a2ceeb2986 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 19 Nov 2020 23:27:58 +0800 Subject: [PATCH 065/299] Extract function related functions (#9721) --- src/language-js/print/class.js | 26 +- src/language-js/print/function.js | 354 +++++++++++++++++++++++ src/language-js/print/misc.js | 14 +- src/language-js/print/property.js | 100 +++++++ src/language-js/printer-estree.js | 455 +----------------------------- 5 files changed, 507 insertions(+), 442 deletions(-) create mode 100644 src/language-js/print/function.js create mode 100644 src/language-js/print/property.js diff --git a/src/language-js/print/class.js b/src/language-js/print/class.js index f5b44069e..2e48dfeb1 100644 --- a/src/language-js/print/class.js +++ b/src/language-js/print/class.js @@ -6,6 +6,8 @@ const { } = require("../../document"); const { hasTrailingComment, hasTrailingLineComment } = require("../utils"); const { getTypeParametersGroupId } = require("./type-parameters"); +const { printMethod } = require("./function"); +const { printDecorators } = require("./misc"); function printClass(path, options, print) { const n = path.getValue(); @@ -140,4 +142,26 @@ function printSuperClass(path, options, print) { return printed; } -module.exports = { printClass }; +function printClassMethod(path, options, print) { + const n = path.getValue(); + const parts = []; + + if (n.decorators && n.decorators.length !== 0) { + parts.push(printDecorators(path, options, print)); + } + if (n.accessibility) { + parts.push(n.accessibility + " "); + } + if (n.static) { + parts.push("static "); + } + if (n.type === "TSAbstractMethodDefinition" || n.abstract) { + parts.push("abstract "); + } + + parts.push(printMethod(path, options, print)); + + return concat(parts); +} + +module.exports = { printClass, printClassMethod }; diff --git a/src/language-js/print/function.js b/src/language-js/print/function.js new file mode 100644 index 000000000..94f247e3d --- /dev/null +++ b/src/language-js/print/function.js @@ -0,0 +1,354 @@ +"use strict"; + +/** @type {import("assert")} */ +const assert = require("assert"); +const { printDanglingComments } = require("../../main/comments"); +const { + getNextNonSpaceNonCommentCharacterIndex, +} = require("../../common/util"); +const { + builders: { concat, line, softline, group, indent, ifBreak, hardline }, +} = require("../../document"); +const { + getFunctionParameters, + hasDanglingComments, + hasLeadingOwnLineComment, + isFlowAnnotationComment, + isJSXNode, + isTemplateOnItsOwnLine, + shouldPrintComma, + startsWithNoLookaheadToken, + returnArgumentHasLeadingComment, + isBinaryish, + isLineComment, +} = require("../utils"); +const { locEnd } = require("../loc"); +const { printFunctionParameters } = require("./function-parameters"); +const { printPropertyKey } = require("./property"); +const { printFunctionTypeParameters } = require("./misc"); + +function printFunctionDeclaration(path, print, options, expandArg) { + const n = path.getValue(); + const parts = []; + + if (n.async) { + parts.push("async "); + } + + if (n.generator) { + parts.push("function* "); + } else { + parts.push("function "); + } + + if (n.id) { + parts.push(path.call(print, "id")); + } + + parts.push( + printFunctionTypeParameters(path, options, print), + group( + concat([ + printFunctionParameters(path, print, options, expandArg), + printReturnType(path, print, options), + ]) + ), + n.body ? " " : "", + path.call(print, "body") + ); + + return concat(parts); +} + +function printMethod(path, options, print) { + const node = path.getNode(); + const { kind } = node; + const value = node.value || node; + const parts = []; + + if (!kind || kind === "init" || kind === "method" || kind === "constructor") { + if (value.async) { + parts.push("async "); + } + } else { + assert.ok(kind === "get" || kind === "set"); + + parts.push(kind, " "); + } + + // A `getter`/`setter` can't be a generator, but it's recoverable + if (value.generator) { + parts.push("*"); + } + + parts.push( + printPropertyKey(path, options, print), + node.optional || node.key.optional ? "?" : "", + node === value + ? printMethodInternal(path, options, print) + : path.call((path) => printMethodInternal(path, options, print), "value") + ); + + return concat(parts); +} + +function printMethodInternal(path, options, print) { + const parts = [ + printFunctionTypeParameters(path, options, print), + group( + concat([ + printFunctionParameters(path, print, options), + printReturnType(path, print, options), + ]) + ), + ]; + + if (path.getNode().body) { + parts.push(" ", path.call(print, "body")); + } else { + parts.push(options.semi ? ";" : ""); + } + + return concat(parts); +} + +function printArrowFunctionExpression(path, options, print, args) { + const n = path.getValue(); + const parts = []; + + if (n.async) { + parts.push("async "); + } + + if (shouldPrintParamsWithoutParens(path, options)) { + parts.push(path.call(print, "params", 0)); + } else { + parts.push( + group( + concat([ + printFunctionParameters( + path, + print, + options, + /* expandLast */ args && + (args.expandLastArg || args.expandFirstArg), + /* printTypeParams */ true + ), + printReturnType(path, print, options), + ]) + ) + ); + } + + const dangling = printDanglingComments( + path, + options, + /* sameIndent */ true, + (comment) => { + const nextCharacter = getNextNonSpaceNonCommentCharacterIndex( + options.originalText, + comment, + locEnd + ); + return ( + nextCharacter !== false && + options.originalText.slice(nextCharacter, nextCharacter + 2) === "=>" + ); + } + ); + if (dangling) { + parts.push(" ", dangling); + } + + parts.push(" =>"); + + const body = path.call((bodyPath) => print(bodyPath, args), "body"); + + // We want to always keep these types of nodes on the same line + // as the arrow. + if ( + !hasLeadingOwnLineComment(options.originalText, n.body) && + (n.body.type === "ArrayExpression" || + n.body.type === "ObjectExpression" || + n.body.type === "BlockStatement" || + isJSXNode(n.body) || + isTemplateOnItsOwnLine(n.body, options.originalText) || + n.body.type === "ArrowFunctionExpression" || + n.body.type === "DoExpression") + ) { + return group(concat([concat(parts), " ", body])); + } + + // We handle sequence expressions as the body of arrows specially, + // so that the required parentheses end up on their own lines. + if (n.body.type === "SequenceExpression") { + return group( + concat([ + concat(parts), + group(concat([" (", indent(concat([softline, body])), softline, ")"])), + ]) + ); + } + + // if the arrow function is expanded as last argument, we are adding a + // level of indentation and need to add a softline to align the closing ) + // with the opening (, or if it's inside a JSXExpression (e.g. an attribute) + // we should align the expression's closing } with the line with the opening {. + const shouldAddSoftLine = + ((args && args.expandLastArg) || + path.getParentNode().type === "JSXExpressionContainer") && + !(n.comments && n.comments.length); + + const printTrailingComma = + args && args.expandLastArg && shouldPrintComma(options, "all"); + + // In order to avoid confusion between + // a => a ? a : a + // a <= a ? a : a + const shouldAddParens = + n.body.type === "ConditionalExpression" && + !startsWithNoLookaheadToken(n.body, /* forbidFunctionAndClass */ false); + + return group( + concat([ + concat(parts), + group( + concat([ + indent( + concat([ + line, + shouldAddParens ? ifBreak("", "(") : "", + body, + shouldAddParens ? ifBreak("", ")") : "", + ]) + ), + shouldAddSoftLine + ? concat([ifBreak(printTrailingComma ? "," : ""), softline]) + : "", + ]) + ), + ]) + ); +} + +function canPrintParamsWithoutParens(node) { + const parameters = getFunctionParameters(node); + return ( + parameters.length === 1 && + !node.typeParameters && + !hasDanglingComments(node) && + parameters[0].type === "Identifier" && + !parameters[0].typeAnnotation && + !parameters[0].comments && + !parameters[0].optional && + !node.predicate && + !node.returnType + ); +} + +function shouldPrintParamsWithoutParens(path, options) { + if (options.arrowParens === "always") { + return false; + } + + if (options.arrowParens === "avoid") { + const node = path.getValue(); + return canPrintParamsWithoutParens(node); + } + + // Fallback default; should be unreachable + /* istanbul ignore next */ + return false; +} + +function printReturnType(path, print, options) { + const n = path.getValue(); + const returnType = path.call(print, "returnType"); + + if ( + n.returnType && + isFlowAnnotationComment(options.originalText, n.returnType) + ) { + return concat([" /*: ", returnType, " */"]); + } + + const parts = [returnType]; + + // prepend colon to TypeScript type annotation + if (n.returnType && n.returnType.typeAnnotation) { + parts.unshift(": "); + } + + if (n.predicate) { + // The return type will already add the colon, but otherwise we + // need to do it ourselves + parts.push(n.returnType ? " " : ": ", path.call(print, "predicate")); + } + + return concat(parts); +} + +// `ReturnStatement` and `ThrowStatement` +function printReturnAndThrowArgument(path, options, print) { + const node = path.getValue(); + const semi = options.semi ? ";" : ""; + const parts = []; + + if (node.argument) { + if (returnArgumentHasLeadingComment(options, node.argument)) { + parts.push( + concat([ + " (", + indent(concat([hardline, path.call(print, "argument")])), + hardline, + ")", + ]) + ); + } else if ( + isBinaryish(node.argument) || + node.argument.type === "SequenceExpression" + ) { + parts.push( + group( + concat([ + ifBreak(" (", " "), + indent(concat([softline, path.call(print, "argument")])), + softline, + ifBreak(")"), + ]) + ) + ); + } else { + parts.push(" ", path.call(print, "argument")); + } + } + + const lastComment = + Array.isArray(node.comments) && node.comments[node.comments.length - 1]; + const isLastCommentLine = lastComment && isLineComment(lastComment); + + if (isLastCommentLine) { + parts.push(semi); + } + + if (hasDanglingComments(node)) { + parts.push( + " ", + printDanglingComments(path, options, /* sameIndent */ true) + ); + } + + if (!isLastCommentLine) { + parts.push(semi); + } + + return concat(parts); +} + +module.exports = { + printFunctionDeclaration, + printArrowFunctionExpression, + printMethod, + printReturnAndThrowArgument, + shouldPrintParamsWithoutParens, +}; diff --git a/src/language-js/print/misc.js b/src/language-js/print/misc.js index ac74bbce8..488ff3a14 100644 --- a/src/language-js/print/misc.js +++ b/src/language-js/print/misc.js @@ -3,8 +3,9 @@ const { isNumericLiteral } = require("../utils"); const { - builders: { concat, softline, group, indent }, + builders: { concat, softline, group, indent, join, line, hardline }, } = require("../../document"); +const { hasNewlineBetweenOrAfterDecorators } = require("../utils"); function printOptionalToken(path) { const node = path.getValue(); @@ -58,9 +59,20 @@ function printBindExpressionCallee(path, options, print) { return concat(["::", path.call(print, "callee")]); } +function printDecorators(path, options, print) { + const node = path.getValue(); + return group( + concat([ + join(line, path.map(print, "decorators")), + hasNewlineBetweenOrAfterDecorators(node, options) ? hardline : line, + ]) + ); +} + module.exports = { printOptionalToken, printFunctionTypeParameters, printMemberLookup, printBindExpressionCallee, + printDecorators, }; diff --git a/src/language-js/print/property.js b/src/language-js/print/property.js new file mode 100644 index 000000000..722880b2e --- /dev/null +++ b/src/language-js/print/property.js @@ -0,0 +1,100 @@ +"use strict"; + +const { printComments } = require("../../main/comments"); +const { printString, printNumber } = require("../../common/util"); +const { + builders: { concat }, +} = require("../../document"); +const { + isNumericLiteral, + isSimpleNumber, + isStringLiteral, + isStringPropSafeToUnquote, + rawText, +} = require("../utils"); + +const needsQuoteProps = new WeakMap(); + +function printPropertyKey(path, options, print) { + const node = path.getNode(); + + if (node.computed) { + return concat(["[", path.call(print, "key"), "]"]); + } + + const parent = path.getParentNode(); + const { key } = node; + + if ( + node.type === "ClassPrivateProperty" && + // flow has `Identifier` key, and babel has `PrivateName` key + key.type === "Identifier" + ) { + return concat(["#", path.call(print, "key")]); + } + + if (options.quoteProps === "consistent" && !needsQuoteProps.has(parent)) { + const objectHasStringProp = ( + parent.properties || + parent.body || + parent.members + ).some( + (prop) => + !prop.computed && + prop.key && + isStringLiteral(prop.key) && + !isStringPropSafeToUnquote(prop, options) + ); + needsQuoteProps.set(parent, objectHasStringProp); + } + + if ( + (key.type === "Identifier" || + (isNumericLiteral(key) && + isSimpleNumber(printNumber(rawText(key))) && + // Avoid converting 999999999999999999999 to 1e+21, 0.99999999999999999 to 1 and 1.0 to 1. + String(key.value) === printNumber(rawText(key)) && + // Quoting number keys is safe in JS and Flow, but not in TypeScript (as + // mentioned in `isStringPropSafeToUnquote`). + !(options.parser === "typescript" || options.parser === "babel-ts"))) && + (options.parser === "json" || + (options.quoteProps === "consistent" && needsQuoteProps.get(parent))) + ) { + // a -> "a" + // 1 -> "1" + // 1.5 -> "1.5" + const prop = printString( + JSON.stringify( + key.type === "Identifier" ? key.name : key.value.toString() + ), + options + ); + return path.call( + (keyPath) => printComments(keyPath, () => prop, options), + "key" + ); + } + + if ( + isStringPropSafeToUnquote(node, options) && + (options.quoteProps === "as-needed" || + (options.quoteProps === "consistent" && !needsQuoteProps.get(parent))) + ) { + // 'a' -> a + // '1' -> 1 + // '1.5' -> 1.5 + return path.call( + (keyPath) => + printComments( + keyPath, + () => (/^\d/.test(key.value) ? printNumber(key.value) : key.value), + options + ), + "key" + ); + } + + return path.call(print, "key"); +} + +module.exports = { printPropertyKey }; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index cdfde7259..261457b6a 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -14,7 +14,6 @@ const { printString, printNumber, isNextLineEmpty, - getNextNonSpaceNonCommentCharacterIndex, } = require("../common/util"); const { builders: { @@ -65,7 +64,6 @@ const { isBinaryish, isCallOrOptionalCallExpression, isExportDeclaration, - isFlowAnnotationComment, isFunctionNotation, isGetterOrSetter, isJSXNode, @@ -74,12 +72,9 @@ const { isMemberExpressionChain, isMemberish, isNgForOf, - isNumericLiteral, isObjectType, isObjectTypePropertyAFunction, - isSimpleNumber, isStringLiteral, - isStringPropSafeToUnquote, isTemplateOnItsOwnLine, isTestCall, isTheOnlyJSXElementInMarkdown, @@ -88,10 +83,8 @@ const { isLineComment, needsHardlineAfterDanglingComment, rawText, - returnArgumentHasLeadingComment, shouldPrintComma, shouldFlatten, - startsWithNoLookaheadToken, } = require("./utils"); const { locStart, locEnd } = require("./loc"); @@ -102,6 +95,7 @@ const { printFunctionTypeParameters, printMemberLookup, printBindExpressionCallee, + printDecorators, } = require("./print/misc"); const { printImportDeclaration, @@ -129,13 +123,19 @@ const { printJsxSpreadAttribute, printJsxSpreadChild, } = require("./print/jsx"); -const { printClass } = require("./print/class"); +const { printClass, printClassMethod } = require("./print/class"); const { printTypeParameters, getTypeParametersGroupId, } = require("./print/type-parameters"); - -const needsQuoteProps = new WeakMap(); +const { printPropertyKey } = require("./print/property"); +const { + printFunctionDeclaration, + printArrowFunctionExpression, + printMethod, + printReturnAndThrowArgument, + shouldPrintParamsWithoutParens, +} = require("./print/function"); let uid = 0; @@ -247,16 +247,6 @@ function genericPrint(path, options, printPath, args) { return concat(parts); } -function printDecorators(path, options, print) { - const node = path.getValue(); - return group( - concat([ - join(line, path.map(print, "decorators")), - hasNewlineBetweenOrAfterDecorators(node, options) ? hardline : line, - ]) - ); -} - function printPathNoParens(path, options, print, args) { const n = path.getValue(); const semi = options.semi ? ";" : ""; @@ -668,124 +658,8 @@ function printPathNoParens(path, options, print, args) { parts.push(semi); } return concat(parts); - case "ArrowFunctionExpression": { - if (n.async) { - parts.push("async "); - } - - if (shouldPrintParamsWithoutParens(path, options)) { - parts.push(path.call(print, "params", 0)); - } else { - parts.push( - group( - concat([ - printFunctionParameters( - path, - print, - options, - /* expandLast */ args && - (args.expandLastArg || args.expandFirstArg), - /* printTypeParams */ true - ), - printReturnType(path, print, options), - ]) - ) - ); - } - - const dangling = comments.printDanglingComments( - path, - options, - /* sameIndent */ true, - (comment) => { - const nextCharacter = getNextNonSpaceNonCommentCharacterIndex( - options.originalText, - comment, - locEnd - ); - return ( - nextCharacter !== false && - options.originalText.slice(nextCharacter, nextCharacter + 2) === - "=>" - ); - } - ); - if (dangling) { - parts.push(" ", dangling); - } - - parts.push(" =>"); - - const body = path.call((bodyPath) => print(bodyPath, args), "body"); - - // We want to always keep these types of nodes on the same line - // as the arrow. - if ( - !hasLeadingOwnLineComment(options.originalText, n.body) && - (n.body.type === "ArrayExpression" || - n.body.type === "ObjectExpression" || - n.body.type === "BlockStatement" || - isJSXNode(n.body) || - isTemplateOnItsOwnLine(n.body, options.originalText) || - n.body.type === "ArrowFunctionExpression" || - n.body.type === "DoExpression") - ) { - return group(concat([concat(parts), " ", body])); - } - - // We handle sequence expressions as the body of arrows specially, - // so that the required parentheses end up on their own lines. - if (n.body.type === "SequenceExpression") { - return group( - concat([ - concat(parts), - group( - concat([" (", indent(concat([softline, body])), softline, ")"]) - ), - ]) - ); - } - - // if the arrow function is expanded as last argument, we are adding a - // level of indentation and need to add a softline to align the closing ) - // with the opening (, or if it's inside a JSXExpression (e.g. an attribute) - // we should align the expression's closing } with the line with the opening {. - const shouldAddSoftLine = - ((args && args.expandLastArg) || - path.getParentNode().type === "JSXExpressionContainer") && - !(n.comments && n.comments.length); - - const printTrailingComma = - args && args.expandLastArg && shouldPrintComma(options, "all"); - - // In order to avoid confusion between - // a => a ? a : a - // a <= a ? a : a - const shouldAddParens = - n.body.type === "ConditionalExpression" && - !startsWithNoLookaheadToken(n.body, /* forbidFunctionAndClass */ false); - - return group( - concat([ - concat(parts), - group( - concat([ - indent( - concat([ - line, - shouldAddParens ? ifBreak("", "(") : "", - body, - shouldAddParens ? ifBreak("", ")") : "", - ]) - ), - shouldAddSoftLine - ? concat([ifBreak(printTrailingComma ? "," : ""), softline]) - : "", - ]) - ), - ]) - ); - } + case "ArrowFunctionExpression": + return printArrowFunctionExpression(path, options, print, args); case "YieldExpression": parts.push("yield"); @@ -900,9 +774,10 @@ function printPathNoParens(path, options, print, args) { return concat(parts); } + case "ThrowStatement": case "ReturnStatement": return concat([ - "return", + n.type === "ReturnStatement" ? "return" : "throw", printReturnAndThrowArgument(path, options, print), ]); case "NewExpression": @@ -1036,22 +911,7 @@ function printPathNoParens(path, options, print, args) { case "MethodDefinition": case "TSAbstractMethodDefinition": case "TSDeclareMethod": - if (n.decorators && n.decorators.length !== 0) { - parts.push(printDecorators(path, options, print)); - } - if (n.accessibility) { - parts.push(n.accessibility + " "); - } - if (n.static) { - parts.push("static "); - } - if (n.type === "TSAbstractMethodDefinition" || n.abstract) { - parts.push("abstract "); - } - - parts.push(printMethod(path, options, print)); - - return concat(parts); + return printClassMethod(path, options, print); case "ObjectMethod": return printMethod(path, options, print); case "Decorator": @@ -1475,11 +1335,6 @@ function printPathNoParens(path, options, print, args) { } return concat(["catch ", path.call(print, "body")]); - case "ThrowStatement": - return concat([ - "throw", - printReturnAndThrowArgument(path, options, print), - ]); // Note: ignoring n.lexical because it has no printing consequences. case "SwitchStatement": return concat([ @@ -2991,230 +2846,6 @@ function printStatementSequence(path, options, print) { return join(hardline, printed); } -function printPropertyKey(path, options, print) { - const node = path.getNode(); - - if (node.computed) { - return concat(["[", path.call(print, "key"), "]"]); - } - - const parent = path.getParentNode(); - const { key } = node; - - if ( - node.type === "ClassPrivateProperty" && - // flow has `Identifier` key, and babel has `PrivateName` key - key.type === "Identifier" - ) { - return concat(["#", path.call(print, "key")]); - } - - if (options.quoteProps === "consistent" && !needsQuoteProps.has(parent)) { - const objectHasStringProp = ( - parent.properties || - parent.body || - parent.members - ).some( - (prop) => - !prop.computed && - prop.key && - isStringLiteral(prop.key) && - !isStringPropSafeToUnquote(prop, options) - ); - needsQuoteProps.set(parent, objectHasStringProp); - } - - if ( - (key.type === "Identifier" || - (isNumericLiteral(key) && - isSimpleNumber(printNumber(rawText(key))) && - // Avoid converting 999999999999999999999 to 1e+21, 0.99999999999999999 to 1 and 1.0 to 1. - String(key.value) === printNumber(rawText(key)) && - // Quoting number keys is safe in JS and Flow, but not in TypeScript (as - // mentioned in `isStringPropSafeToUnquote`). - !(options.parser === "typescript" || options.parser === "babel-ts"))) && - (options.parser === "json" || - (options.quoteProps === "consistent" && needsQuoteProps.get(parent))) - ) { - // a -> "a" - // 1 -> "1" - // 1.5 -> "1.5" - const prop = printString( - JSON.stringify( - key.type === "Identifier" ? key.name : key.value.toString() - ), - options - ); - return path.call( - (keyPath) => comments.printComments(keyPath, () => prop, options), - "key" - ); - } - - if ( - isStringPropSafeToUnquote(node, options) && - (options.quoteProps === "as-needed" || - (options.quoteProps === "consistent" && !needsQuoteProps.get(parent))) - ) { - // 'a' -> a - // '1' -> 1 - // '1.5' -> 1.5 - return path.call( - (keyPath) => - comments.printComments( - keyPath, - () => (/^\d/.test(key.value) ? printNumber(key.value) : key.value), - options - ), - "key" - ); - } - - return path.call(print, "key"); -} - -function printMethod(path, options, print) { - const node = path.getNode(); - const { kind } = node; - const value = node.value || node; - const parts = []; - - if (!kind || kind === "init" || kind === "method" || kind === "constructor") { - if (value.async) { - parts.push("async "); - } - } else { - assert.ok(kind === "get" || kind === "set"); - - parts.push(kind, " "); - } - - // A `getter`/`setter` can't be a generator, but it's recoverable - if (value.generator) { - parts.push("*"); - } - - parts.push( - printPropertyKey(path, options, print), - node.optional || node.key.optional ? "?" : "", - node === value - ? printMethodInternal(path, options, print) - : path.call((path) => printMethodInternal(path, options, print), "value") - ); - - return concat(parts); -} - -function printMethodInternal(path, options, print) { - const parts = [ - printFunctionTypeParameters(path, options, print), - group( - concat([ - printFunctionParameters(path, print, options), - printReturnType(path, print, options), - ]) - ), - ]; - - if (path.getNode().body) { - parts.push(" ", path.call(print, "body")); - } else { - parts.push(options.semi ? ";" : ""); - } - - return concat(parts); -} - -function shouldPrintParamsWithoutParens(path, options) { - if (options.arrowParens === "always") { - return false; - } - - if (options.arrowParens === "avoid") { - const node = path.getValue(); - return canPrintParamsWithoutParens(node); - } - - // Fallback default; should be unreachable - /* istanbul ignore next */ - return false; -} - -function canPrintParamsWithoutParens(node) { - const parameters = getFunctionParameters(node); - return ( - parameters.length === 1 && - !node.typeParameters && - !hasDanglingComments(node) && - parameters[0].type === "Identifier" && - !parameters[0].typeAnnotation && - !parameters[0].comments && - !parameters[0].optional && - !node.predicate && - !node.returnType - ); -} - -function printFunctionDeclaration(path, print, options, expandArg) { - const n = path.getValue(); - const parts = []; - - if (n.async) { - parts.push("async "); - } - - if (n.generator) { - parts.push("function* "); - } else { - parts.push("function "); - } - - if (n.id) { - parts.push(path.call(print, "id")); - } - - parts.push( - printFunctionTypeParameters(path, options, print), - group( - concat([ - printFunctionParameters(path, print, options, expandArg), - printReturnType(path, print, options), - ]) - ), - n.body ? " " : "", - path.call(print, "body") - ); - - return concat(parts); -} - -function printReturnType(path, print, options) { - const n = path.getValue(); - const returnType = path.call(print, "returnType"); - - if ( - n.returnType && - isFlowAnnotationComment(options.originalText, n.returnType) - ) { - return concat([" /*: ", returnType, " */"]); - } - - const parts = [returnType]; - - // prepend colon to TypeScript type annotation - if (n.returnType && n.returnType.typeAnnotation) { - parts.unshift(": "); - } - - if (n.predicate) { - // The return type will already add the colon, but otherwise we - // need to do it ourselves - parts.push(n.returnType ? " " : ": ", path.call(print, "predicate")); - } - - return concat(parts); -} - function printFlowDeclaration(path, printed) { const parentExportDecl = getParentExportDeclaration(path); @@ -3506,62 +3137,6 @@ function stmtNeedsASIProtection(path, options) { ); } -function printReturnAndThrowArgument(path, options, print) { - const node = path.getValue(); - const semi = options.semi ? ";" : ""; - const parts = []; - - if (node.argument) { - if (returnArgumentHasLeadingComment(options, node.argument)) { - parts.push( - concat([ - " (", - indent(concat([hardline, path.call(print, "argument")])), - hardline, - ")", - ]) - ); - } else if ( - isBinaryish(node.argument) || - node.argument.type === "SequenceExpression" - ) { - parts.push( - group( - concat([ - ifBreak(" (", " "), - indent(concat([softline, path.call(print, "argument")])), - softline, - ifBreak(")"), - ]) - ) - ); - } else { - parts.push(" ", path.call(print, "argument")); - } - } - - const lastComment = - Array.isArray(node.comments) && node.comments[node.comments.length - 1]; - const isLastCommentLine = lastComment && isLineComment(lastComment); - - if (isLastCommentLine) { - parts.push(semi); - } - - if (hasDanglingComments(node)) { - parts.push( - " ", - comments.printDanglingComments(path, options, /* sameIndent */ true) - ); - } - - if (!isLastCommentLine) { - parts.push(semi); - } - - return concat(parts); -} - function canAttachComment(node) { return ( node.type && From 05236cf64dca26a308dc4f928c61713e0b5e7dc5 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 19 Nov 2020 23:46:51 +0800 Subject: [PATCH 066/299] Extract printInterface and printCallExpression (#9715) --- src/language-js/print/call-expression.js | 103 +++++++++++++ src/language-js/print/interface.js | 83 +++++++++++ src/language-js/print/misc.js | 16 +- src/language-js/printer-estree.js | 180 +---------------------- 4 files changed, 207 insertions(+), 175 deletions(-) create mode 100644 src/language-js/print/call-expression.js create mode 100644 src/language-js/print/interface.js diff --git a/src/language-js/print/call-expression.js b/src/language-js/print/call-expression.js new file mode 100644 index 000000000..11d683863 --- /dev/null +++ b/src/language-js/print/call-expression.js @@ -0,0 +1,103 @@ +"use strict"; + +const { + builders: { concat, join, group }, +} = require("../../document"); +const pathNeedsParens = require("../needs-parens"); +const { + getCallArguments, + hasFlowAnnotationComment, + isCallOrOptionalCallExpression, + isMemberish, + isTemplateOnItsOwnLine, + isTestCall, + iterateCallArgumentsPath, +} = require("../utils"); +const printMemberChain = require("./member-chain"); +const printCallArguments = require("./call-arguments"); +const { printOptionalToken, printFunctionTypeParameters } = require("./misc"); + +function printCallExpression(path, options, print) { + const n = path.getValue(); + const isNew = n.type === "NewExpression"; + const isDynamicImport = n.type === "ImportExpression"; + + const optional = printOptionalToken(path); + const args = getCallArguments(n); + if ( + // Dangling comments not handled, all these special cases should has argument #9668 + args.length > 0 && + // We want to keep CommonJS- and AMD-style require calls, and AMD-style + // define calls, as a unit. + // e.g. `define(["some/lib", (lib) => {` + ((!isDynamicImport && + !isNew && + n.callee.type === "Identifier" && + (n.callee.name === "require" || n.callee.name === "define")) || + // Template literals as single arguments + (args.length === 1 && + isTemplateOnItsOwnLine(args[0], options.originalText)) || + // Keep test declarations on a single line + // e.g. `it('long name', () => {` + (!isNew && isTestCall(n, path.getParentNode()))) + ) { + const printed = []; + iterateCallArgumentsPath(path, (argPath) => { + printed.push(print(argPath)); + }); + return concat([ + isNew ? "new " : "", + path.call(print, "callee"), + optional, + printFunctionTypeParameters(path, options, print), + concat(["(", join(", ", printed), ")"]), + ]); + } + + // Inline Flow annotation comments following Identifiers in Call nodes need to + // stay with the Identifier. For example: + // + // foo /*:: */(bar); + // + // Here, we ensure that such comments stay between the Identifier and the Callee. + const isIdentifierWithFlowAnnotation = + (options.parser === "babel" || options.parser === "babel-flow") && + n.callee && + n.callee.type === "Identifier" && + hasFlowAnnotationComment(n.callee.trailingComments); + if (isIdentifierWithFlowAnnotation) { + n.callee.trailingComments[0].printed = true; + } + + // We detect calls on member lookups and possibly print them in a + // special chain format. See `printMemberChain` for more info. + if ( + !isDynamicImport && + !isNew && + isMemberish(n.callee) && + !path.call((path) => pathNeedsParens(path, options), "callee") + ) { + return printMemberChain(path, options, print); + } + + const contents = concat([ + isNew ? "new " : "", + isDynamicImport ? "import" : path.call(print, "callee"), + optional, + isIdentifierWithFlowAnnotation + ? `/*:: ${n.callee.trailingComments[0].value.slice(2).trim()} */` + : "", + printFunctionTypeParameters(path, options, print), + printCallArguments(path, options, print), + ]); + + // We group here when the callee is itself a call expression. + // See `isLongCurriedCallExpression` for more info. + if (isDynamicImport || isCallOrOptionalCallExpression(n.callee)) { + return group(contents); + } + + return contents; +} + +module.exports = { printCallExpression }; diff --git a/src/language-js/print/interface.js b/src/language-js/print/interface.js new file mode 100644 index 000000000..17b6164b1 --- /dev/null +++ b/src/language-js/print/interface.js @@ -0,0 +1,83 @@ +"use strict"; + +const { + builders: { concat, join, line, group, indent, ifBreak }, +} = require("../../document"); +const { + hasTrailingComment, + hasTrailingLineComment, + identity, +} = require("../utils"); +const { getTypeParametersGroupId } = require("./type-parameters"); +const { printTypeScriptModifiers } = require("./misc"); + +function printInterface(path, options, print) { + const n = path.getValue(); + const parts = []; + if (n.type === "DeclareInterface" || n.declare) { + parts.push("declare "); + } + + if (n.type === "TSInterfaceDeclaration") { + parts.push( + n.abstract ? "abstract " : "", + printTypeScriptModifiers(path, options, print) + ); + } + + parts.push("interface"); + + const partsGroup = []; + const extendsParts = []; + + if (n.type !== "InterfaceTypeAnnotation") { + partsGroup.push( + " ", + path.call(print, "id"), + path.call(print, "typeParameters") + ); + } + + const shouldIndentOnlyHeritageClauses = + n.typeParameters && !hasTrailingLineComment(n.typeParameters); + + if (n.extends && n.extends.length !== 0) { + extendsParts.push( + shouldIndentOnlyHeritageClauses + ? ifBreak(" ", line, { + groupId: getTypeParametersGroupId(n.typeParameters), + }) + : line, + "extends ", + (n.extends.length === 1 ? identity : indent)( + join(concat([",", line]), path.map(print, "extends")) + ) + ); + } + + if ( + (n.id && hasTrailingComment(n.id)) || + (n.extends && n.extends.length !== 0) + ) { + const printedExtends = concat(extendsParts); + if (shouldIndentOnlyHeritageClauses) { + parts.push( + group( + concat( + partsGroup.concat(ifBreak(indent(printedExtends), printedExtends)) + ) + ) + ); + } else { + parts.push(group(indent(concat(partsGroup.concat(printedExtends))))); + } + } else { + parts.push(...partsGroup, ...extendsParts); + } + + parts.push(" ", path.call(print, "body")); + + return group(concat(parts)); +} + +module.exports = { printInterface }; diff --git a/src/language-js/print/misc.js b/src/language-js/print/misc.js index 488ff3a14..11cc31df7 100644 --- a/src/language-js/print/misc.js +++ b/src/language-js/print/misc.js @@ -1,11 +1,12 @@ "use strict"; -const { isNumericLiteral } = require("../utils"); - const { builders: { concat, softline, group, indent, join, line, hardline }, } = require("../../document"); -const { hasNewlineBetweenOrAfterDecorators } = require("../utils"); +const { + hasNewlineBetweenOrAfterDecorators, + isNumericLiteral, +} = require("../utils"); function printOptionalToken(path) { const node = path.getValue(); @@ -59,6 +60,14 @@ function printBindExpressionCallee(path, options, print) { return concat(["::", path.call(print, "callee")]); } +function printTypeScriptModifiers(path, options, print) { + const n = path.getValue(); + if (!n.modifiers || !n.modifiers.length) { + return ""; + } + return concat([join(" ", path.map(print, "modifiers")), " "]); +} + function printDecorators(path, options, print) { const node = path.getValue(); return group( @@ -74,5 +83,6 @@ module.exports = { printFunctionTypeParameters, printMemberLookup, printBindExpressionCallee, + printTypeScriptModifiers, printDecorators, }; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 261457b6a..69f214f35 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -46,12 +46,10 @@ const { classPropMayCauseASIProblems, getFunctionParameters, getCallArguments, - iterateCallArgumentsPath, getLeftSidePathName, getParentExportDeclaration, getTypeScriptMappedTypeModifier, hasDanglingComments, - hasFlowAnnotationComment, hasFlowShorthandAnnotationComment, hasLeadingOwnLineComment, hasNakedLeftSide, @@ -60,9 +58,7 @@ const { hasPrettierIgnore, hasTrailingComment, hasTrailingLineComment, - identity, isBinaryish, - isCallOrOptionalCallExpression, isExportDeclaration, isFunctionNotation, isGetterOrSetter, @@ -70,13 +66,10 @@ const { isLastStatement, isLiteral, isMemberExpressionChain, - isMemberish, isNgForOf, isObjectType, isObjectTypePropertyAFunction, isStringLiteral, - isTemplateOnItsOwnLine, - isTestCall, isTheOnlyJSXElementInMarkdown, isTSXFile, isBlockComment, @@ -88,13 +81,11 @@ const { } = require("./utils"); const { locStart, locEnd } = require("./loc"); -const printMemberChain = require("./print/member-chain"); -const printCallArguments = require("./print/call-arguments"); const { printOptionalToken, - printFunctionTypeParameters, printMemberLookup, printBindExpressionCallee, + printTypeScriptModifiers, printDecorators, } = require("./print/misc"); const { @@ -124,10 +115,7 @@ const { printJsxSpreadChild, } = require("./print/jsx"); const { printClass, printClassMethod } = require("./print/class"); -const { - printTypeParameters, - getTypeParametersGroupId, -} = require("./print/type-parameters"); +const { printTypeParameters } = require("./print/type-parameters"); const { printPropertyKey } = require("./print/property"); const { printFunctionDeclaration, @@ -136,6 +124,8 @@ const { printReturnAndThrowArgument, shouldPrintParamsWithoutParens, } = require("./print/function"); +const { printCallExpression } = require("./print/call-expression"); +const { printInterface } = require("./print/interface"); let uid = 0; @@ -783,88 +773,8 @@ function printPathNoParens(path, options, print, args) { case "NewExpression": case "ImportExpression": case "OptionalCallExpression": - case "CallExpression": { - const isNew = n.type === "NewExpression"; - const isDynamicImport = n.type === "ImportExpression"; - - const optional = printOptionalToken(path); - const args = getCallArguments(n); - if ( - // Dangling comments not handled, all these special cases should has argument #9668 - args.length > 0 && - // We want to keep CommonJS- and AMD-style require calls, and AMD-style - // define calls, as a unit. - // e.g. `define(["some/lib", (lib) => {` - ((!isDynamicImport && - !isNew && - n.callee.type === "Identifier" && - (n.callee.name === "require" || n.callee.name === "define")) || - // Template literals as single arguments - (args.length === 1 && - isTemplateOnItsOwnLine(args[0], options.originalText)) || - // Keep test declarations on a single line - // e.g. `it('long name', () => {` - (!isNew && isTestCall(n, path.getParentNode()))) - ) { - const printed = []; - iterateCallArgumentsPath(path, (argPath) => { - printed.push(print(argPath)); - }); - return concat([ - isNew ? "new " : "", - path.call(print, "callee"), - optional, - printFunctionTypeParameters(path, options, print), - concat(["(", join(", ", printed), ")"]), - ]); - } - - // Inline Flow annotation comments following Identifiers in Call nodes need to - // stay with the Identifier. For example: - // - // foo /*:: */(bar); - // - // Here, we ensure that such comments stay between the Identifier and the Callee. - const isIdentifierWithFlowAnnotation = - (options.parser === "babel" || options.parser === "babel-flow") && - n.callee && - n.callee.type === "Identifier" && - hasFlowAnnotationComment(n.callee.trailingComments); - if (isIdentifierWithFlowAnnotation) { - n.callee.trailingComments[0].printed = true; - } - - // We detect calls on member lookups and possibly print them in a - // special chain format. See `printMemberChain` for more info. - if ( - !isDynamicImport && - !isNew && - isMemberish(n.callee) && - !path.call((path) => pathNeedsParens(path, options), "callee") - ) { - return printMemberChain(path, options, print); - } - - const contents = concat([ - isNew ? "new " : "", - isDynamicImport ? "import" : path.call(print, "callee"), - optional, - isIdentifierWithFlowAnnotation - ? `/*:: ${n.callee.trailingComments[0].value.slice(2).trim()} */` - : "", - printFunctionTypeParameters(path, options, print), - printCallArguments(path, options, print), - ]); - - // We group here when the callee is itself a call expression. - // See `isLongCurriedCallExpression` for more info. - if (isDynamicImport || isCallOrOptionalCallExpression(n.callee)) { - return group(contents); - } - - return contents; - } - + case "CallExpression": + return printCallExpression(path, options, print); case "ObjectTypeInternalSlot": return concat([ n.static ? "static " : "", @@ -1842,74 +1752,8 @@ function printPathNoParens(path, options, print, args) { case "DeclareInterface": case "InterfaceDeclaration": case "InterfaceTypeAnnotation": - case "TSInterfaceDeclaration": { - if (n.type === "DeclareInterface" || n.declare) { - parts.push("declare "); - } - - if (n.type === "TSInterfaceDeclaration") { - parts.push( - n.abstract ? "abstract " : "", - printTypeScriptModifiers(path, options, print) - ); - } - - parts.push("interface"); - - const partsGroup = []; - const extendsParts = []; - - if (n.type !== "InterfaceTypeAnnotation") { - partsGroup.push( - " ", - path.call(print, "id"), - path.call(print, "typeParameters") - ); - } - - const shouldIndentOnlyHeritageClauses = - n.typeParameters && !hasTrailingLineComment(n.typeParameters); - - if (n.extends && n.extends.length !== 0) { - extendsParts.push( - shouldIndentOnlyHeritageClauses - ? ifBreak(" ", line, { - groupId: getTypeParametersGroupId(n.typeParameters), - }) - : line, - "extends ", - (n.extends.length === 1 ? identity : indent)( - join(concat([",", line]), path.map(print, "extends")) - ) - ); - } - - if ( - (n.id && hasTrailingComment(n.id)) || - (n.extends && n.extends.length !== 0) - ) { - const printedExtends = concat(extendsParts); - if (shouldIndentOnlyHeritageClauses) { - parts.push( - group( - concat( - partsGroup.concat( - ifBreak(indent(printedExtends), printedExtends) - ) - ) - ) - ); - } else { - parts.push(group(indent(concat(partsGroup.concat(printedExtends))))); - } - } else { - parts.push(...partsGroup, ...extendsParts); - } - - parts.push(" ", path.call(print, "body")); - - return group(concat(parts)); - } + case "TSInterfaceDeclaration": + return printInterface(path, options, print); case "ClassImplements": case "InterfaceExtends": return concat([ @@ -2860,14 +2704,6 @@ function printFlowDeclaration(path, printed) { return concat(["declare ", printed]); } -function printTypeScriptModifiers(path, options, print) { - const n = path.getValue(); - if (!n.modifiers || !n.modifiers.length) { - return ""; - } - return concat([join(" ", path.map(print, "modifiers")), " "]); -} - function shouldInlineLogicalExpression(node) { if (node.type !== "LogicalExpression") { return false; From 92d31d1b30ceeda381164dc1ae26b5bc0eefe8a5 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Fri, 20 Nov 2020 00:36:48 +0800 Subject: [PATCH 067/299] Extract `printAssignment`, `printBinaryishExpression`, and `printComment` (#9722) --- src/language-js/print/assignment.js | 95 ++++++ src/language-js/print/binaryish.js | 308 +++++++++++++++++++ src/language-js/print/comment.js | 74 +++++ src/language-js/print/misc.js | 18 ++ src/language-js/printer-estree.js | 462 +--------------------------- 5 files changed, 510 insertions(+), 447 deletions(-) create mode 100644 src/language-js/print/assignment.js create mode 100644 src/language-js/print/binaryish.js create mode 100644 src/language-js/print/comment.js diff --git a/src/language-js/print/assignment.js b/src/language-js/print/assignment.js new file mode 100644 index 000000000..5088c610a --- /dev/null +++ b/src/language-js/print/assignment.js @@ -0,0 +1,95 @@ +"use strict"; + +const { + builders: { concat, line, group, indent }, +} = require("../../document"); +const { + hasLeadingOwnLineComment, + isBinaryish, + isMemberExpressionChain, + isStringLiteral, +} = require("../utils"); +const { shouldInlineLogicalExpression } = require("./binaryish"); + +function printAssignment( + leftNode, + printedLeft, + operator, + rightNode, + printedRight, + options +) { + if (!rightNode) { + return printedLeft; + } + + const printed = printAssignmentRight( + leftNode, + rightNode, + printedRight, + options + ); + + return group(concat([printedLeft, operator, printed])); +} + +function printAssignmentExpression(path, options, print) { + const n = path.getValue(); + return printAssignment( + n.left, + path.call(print, "left"), + concat([" ", n.operator]), + n.right, + path.call(print, "right"), + options + ); +} + +function printVariableDeclarator(path, options, print) { + const n = path.getValue(); + return printAssignment( + n.id, + path.call(print, "id"), + " =", + n.init, + n.init && path.call(print, "init"), + options + ); +} + +function printAssignmentRight(leftNode, rightNode, printedRight, options) { + if (hasLeadingOwnLineComment(options.originalText, rightNode)) { + return indent(concat([line, printedRight])); + } + + const canBreak = + (isBinaryish(rightNode) && !shouldInlineLogicalExpression(rightNode)) || + (rightNode.type === "ConditionalExpression" && + isBinaryish(rightNode.test) && + !shouldInlineLogicalExpression(rightNode.test)) || + rightNode.type === "StringLiteralTypeAnnotation" || + (rightNode.type === "ClassExpression" && + rightNode.decorators && + rightNode.decorators.length) || + ((leftNode.type === "Identifier" || + isStringLiteral(leftNode) || + leftNode.type === "MemberExpression") && + (isStringLiteral(rightNode) || isMemberExpressionChain(rightNode)) && + // do not put values on a separate line from the key in json + options.parser !== "json" && + options.parser !== "json5") || + rightNode.type === "SequenceExpression"; + + if (canBreak) { + return group(indent(concat([line, printedRight]))); + } + + return concat([" ", printedRight]); +} + +module.exports = { + printVariableDeclarator, + printAssignmentExpression, + printAssignment, + printAssignmentRight, +}; diff --git a/src/language-js/print/binaryish.js b/src/language-js/print/binaryish.js new file mode 100644 index 000000000..f6edc26a5 --- /dev/null +++ b/src/language-js/print/binaryish.js @@ -0,0 +1,308 @@ +"use strict"; + +const { printComments } = require("../../main/comments"); +const { getLast } = require("../../common/util"); +const { + builders: { concat, join, line, softline, group, indent, align, ifBreak }, + utils: { normalizeParts }, +} = require("../../document"); +const { + hasLeadingOwnLineComment, + hasTrailingLineComment, + isBinaryish, + isJSXNode, + shouldFlatten, +} = require("../utils"); + +/** @typedef {import("../../document").Doc} Doc */ + +let uid = 0; +function printBinaryishExpression(path, options, print) { + const n = path.getValue(); + const parent = path.getParentNode(); + const parentParent = path.getParentNode(1); + const isInsideParenthesis = + n !== parent.body && + (parent.type === "IfStatement" || + parent.type === "WhileStatement" || + parent.type === "SwitchStatement" || + parent.type === "DoWhileStatement"); + + const parts = printBinaryishExpressions( + path, + print, + options, + /* isNested */ false, + isInsideParenthesis + ); + + // if ( + // this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft + // ) { + // + // looks super weird, we want to break the children if the parent breaks + // + // if ( + // this.hasPlugin("dynamicImports") && + // this.lookahead().type === tt.parenLeft + // ) { + if (isInsideParenthesis) { + return concat(parts); + } + + // Break between the parens in + // unaries or in a member or specific call expression, i.e. + // + // ( + // a && + // b && + // c + // ).call() + if ( + ((parent.type === "CallExpression" || + parent.type === "OptionalCallExpression") && + parent.callee === n) || + parent.type === "UnaryExpression" || + ((parent.type === "MemberExpression" || + parent.type === "OptionalMemberExpression") && + !parent.computed) + ) { + return group(concat([indent(concat([softline, concat(parts)])), softline])); + } + + // Avoid indenting sub-expressions in some cases where the first sub-expression is already + // indented accordingly. We should indent sub-expressions where the first case isn't indented. + const shouldNotIndent = + parent.type === "ReturnStatement" || + parent.type === "ThrowStatement" || + (parent.type === "JSXExpressionContainer" && + parentParent.type === "JSXAttribute") || + (n.operator !== "|" && parent.type === "JsExpressionRoot") || + (n.type !== "NGPipeExpression" && + ((parent.type === "NGRoot" && options.parser === "__ng_binding") || + (parent.type === "NGMicrosyntaxExpression" && + parentParent.type === "NGMicrosyntax" && + parentParent.body.length === 1))) || + (n === parent.body && parent.type === "ArrowFunctionExpression") || + (n !== parent.body && parent.type === "ForStatement") || + (parent.type === "ConditionalExpression" && + parentParent.type !== "ReturnStatement" && + parentParent.type !== "ThrowStatement" && + parentParent.type !== "CallExpression" && + parentParent.type !== "OptionalCallExpression") || + parent.type === "TemplateLiteral"; + + const shouldIndentIfInlining = + parent.type === "AssignmentExpression" || + parent.type === "VariableDeclarator" || + parent.type === "ClassProperty" || + parent.type === "FieldDefinition" || + parent.type === "TSAbstractClassProperty" || + parent.type === "ClassPrivateProperty" || + parent.type === "ObjectProperty" || + parent.type === "Property"; + + const samePrecedenceSubExpression = + isBinaryish(n.left) && shouldFlatten(n.operator, n.left.operator); + + if ( + shouldNotIndent || + (shouldInlineLogicalExpression(n) && !samePrecedenceSubExpression) || + (!shouldInlineLogicalExpression(n) && shouldIndentIfInlining) + ) { + return group(concat(parts)); + } + + if (parts.length === 0) { + return ""; + } + + // If the right part is a JSX node, we include it in a separate group to + // prevent it breaking the whole chain, so we can print the expression like: + // + // foo && bar && ( + // + // + // + // ) + + const hasJSX = isJSXNode(n.right); + + const firstGroupIndex = parts.findIndex( + (part) => typeof part !== "string" && part.type === "group" + ); + + // Separate the leftmost expression, possibly with its leading comments. + const headParts = parts.slice( + 0, + firstGroupIndex === -1 ? 1 : firstGroupIndex + 1 + ); + + const rest = concat(parts.slice(headParts.length, hasJSX ? -1 : undefined)); + + const groupId = Symbol("logicalChain-" + ++uid); + + const chain = group( + concat([ + // Don't include the initial expression in the indentation + // level. The first item is guaranteed to be the first + // left-most expression. + ...headParts, + indent(rest), + ]), + { id: groupId } + ); + + if (!hasJSX) { + return chain; + } + + const jsxPart = getLast(parts); + return group(concat([chain, ifBreak(indent(jsxPart), jsxPart, { groupId })])); +} + +// For binary expressions to be consistent, we need to group +// subsequent operators with the same precedence level under a single +// group. Otherwise they will be nested such that some of them break +// onto new lines but not all. Operators with the same precedence +// level should either all break or not. Because we group them by +// precedence level and the AST is structured based on precedence +// level, things are naturally broken up correctly, i.e. `&&` is +// broken before `+`. +function printBinaryishExpressions( + path, + print, + options, + isNested, + isInsideParenthesis +) { + /** @type{Doc[]} */ + let parts = []; + + const node = path.getValue(); + + // We treat BinaryExpression and LogicalExpression nodes the same. + if (isBinaryish(node)) { + // Put all operators with the same precedence level in the same + // group. The reason we only need to do this with the `left` + // expression is because given an expression like `1 + 2 - 3`, it + // is always parsed like `((1 + 2) - 3)`, meaning the `left` side + // is where the rest of the expression will exist. Binary + // expressions on the right side mean they have a difference + // precedence level and should be treated as a separate group, so + // print them normally. (This doesn't hold for the `**` operator, + // which is unique in that it is right-associative.) + if (shouldFlatten(node.operator, node.left.operator)) { + // Flatten them out by recursively calling this function. + parts = parts.concat( + path.call( + (left) => + printBinaryishExpressions( + left, + print, + options, + /* isNested */ true, + isInsideParenthesis + ), + "left" + ) + ); + } else { + parts.push(group(path.call(print, "left"))); + } + + const shouldInline = shouldInlineLogicalExpression(node); + const lineBeforeOperator = + (node.operator === "|>" || + node.type === "NGPipeExpression" || + (node.operator === "|" && options.parser === "__vue_expression")) && + !hasLeadingOwnLineComment(options.originalText, node.right); + + const operator = node.type === "NGPipeExpression" ? "|" : node.operator; + const rightSuffix = + node.type === "NGPipeExpression" && node.arguments.length !== 0 + ? group( + indent( + concat([ + softline, + ": ", + join( + concat([softline, ":", ifBreak(" ")]), + path + .map(print, "arguments") + .map((arg) => align(2, group(arg))) + ), + ]) + ) + ) + : ""; + + const right = shouldInline + ? concat([operator, " ", path.call(print, "right"), rightSuffix]) + : concat([ + lineBeforeOperator ? line : "", + operator, + lineBeforeOperator ? " " : line, + path.call(print, "right"), + rightSuffix, + ]); + + // If there's only a single binary expression, we want to create a group + // in order to avoid having a small right part like -1 be on its own line. + const parent = path.getParentNode(); + const shouldBreak = hasTrailingLineComment(node.left); + const shouldGroup = + shouldBreak || + (!(isInsideParenthesis && node.type === "LogicalExpression") && + parent.type !== node.type && + node.left.type !== node.type && + node.right.type !== node.type); + + parts.push( + lineBeforeOperator ? "" : " ", + shouldGroup ? group(right, { shouldBreak }) : right + ); + + // 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 && node.comments) { + parts = normalizeParts( + printComments(path, () => concat(parts), options).parts + ); + } + } else { + // Our stopping case. Simply print the node normally. + parts.push(group(path.call(print))); + } + + return parts; +} + +function shouldInlineLogicalExpression(node) { + if (node.type !== "LogicalExpression") { + return false; + } + + if ( + node.right.type === "ObjectExpression" && + node.right.properties.length !== 0 + ) { + return true; + } + + if ( + node.right.type === "ArrayExpression" && + node.right.elements.length !== 0 + ) { + return true; + } + + if (isJSXNode(node.right)) { + return true; + } + + return false; +} + +module.exports = { printBinaryishExpression, shouldInlineLogicalExpression }; diff --git a/src/language-js/print/comment.js b/src/language-js/print/comment.js new file mode 100644 index 000000000..b41b1236c --- /dev/null +++ b/src/language-js/print/comment.js @@ -0,0 +1,74 @@ +"use strict"; + +const { hasNewline } = require("../../common/util"); +const { + builders: { concat, join, hardline }, +} = require("../../document"); + +const { isLineComment, isBlockComment } = require("../utils"); +const { locStart, locEnd } = require("../loc"); + +function printComment(commentPath, options) { + const comment = commentPath.getValue(); + + if (isLineComment(comment)) { + // Supports `//`, `#!`, `` + return options.originalText + .slice(locStart(comment), locEnd(comment)) + .trimEnd(); + } + + if (isBlockComment(comment)) { + if (isIndentableBlockComment(comment)) { + const printed = printIndentableBlockComment(comment); + // We need to prevent an edge case of a previous trailing comment + // printed as a `lineSuffix` which causes the comments to be + // interleaved. See https://github.com/prettier/prettier/issues/4412 + if ( + comment.trailing && + !hasNewline(options.originalText, locStart(comment), { + backwards: true, + }) + ) { + return concat([hardline, printed]); + } + return printed; + } + + const commentEnd = locEnd(comment); + const isInsideFlowComment = + options.originalText.slice(commentEnd - 3, commentEnd) === "*-/"; + return "/*" + comment.value + (isInsideFlowComment ? "*-/" : "*/"); + } + + /* istanbul ignore next */ + throw new Error("Not a comment: " + JSON.stringify(comment)); +} + +function isIndentableBlockComment(comment) { + // If the comment has multiple lines and every line starts with a star + // we can fix the indentation of each line. The stars in the `/*` and + // `*/` delimiters are not included in the comment value, so add them + // back first. + const lines = `*${comment.value}*`.split("\n"); + return lines.length > 1 && lines.every((line) => line.trim()[0] === "*"); +} + +function printIndentableBlockComment(comment) { + const lines = comment.value.split("\n"); + + return concat([ + "/*", + join( + hardline, + lines.map((line, index) => + index === 0 + ? line.trimEnd() + : " " + (index < lines.length - 1 ? line.trim() : line.trimStart()) + ) + ), + "*/", + ]); +} + +module.exports = { printComment }; diff --git a/src/language-js/print/misc.js b/src/language-js/print/misc.js index 11cc31df7..2a8ccbdfe 100644 --- a/src/language-js/print/misc.js +++ b/src/language-js/print/misc.js @@ -1,11 +1,14 @@ "use strict"; +/** @type {import("assert")} */ +const assert = require("assert"); const { builders: { concat, softline, group, indent, join, line, hardline }, } = require("../../document"); const { hasNewlineBetweenOrAfterDecorators, isNumericLiteral, + getParentExportDeclaration, } = require("../utils"); function printOptionalToken(path) { @@ -78,6 +81,20 @@ function printDecorators(path, options, print) { ); } +function printFlowDeclaration(path, printed) { + const parentExportDecl = getParentExportDeclaration(path); + + if (parentExportDecl) { + assert.strictEqual(parentExportDecl.type, "DeclareExportDeclaration"); + return printed; + } + + // If the parent node has type DeclareExportDeclaration, then it + // will be responsible for printing the "declare" token. Otherwise + // it needs to be printed with this non-exported declaration node. + return concat(["declare ", printed]); +} + module.exports = { printOptionalToken, printFunctionTypeParameters, @@ -85,4 +102,5 @@ module.exports = { printBindExpressionCallee, printTypeScriptModifiers, printDecorators, + printFlowDeclaration, }; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 69f214f35..c5e7825f7 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -29,7 +29,7 @@ const { conditionalGroup, ifBreak, }, - utils: { isEmpty, normalizeParts }, + utils: { isEmpty }, } = require("../document"); const embed = require("./embed"); const clean = require("./clean"); @@ -57,27 +57,21 @@ const { hasNgSideEffect, hasPrettierIgnore, hasTrailingComment, - hasTrailingLineComment, - isBinaryish, isExportDeclaration, isFunctionNotation, isGetterOrSetter, isJSXNode, isLastStatement, isLiteral, - isMemberExpressionChain, isNgForOf, isObjectType, isObjectTypePropertyAFunction, - isStringLiteral, isTheOnlyJSXElementInMarkdown, isTSXFile, isBlockComment, - isLineComment, needsHardlineAfterDanglingComment, rawText, shouldPrintComma, - shouldFlatten, } = require("./utils"); const { locStart, locEnd } = require("./loc"); @@ -87,6 +81,7 @@ const { printBindExpressionCallee, printTypeScriptModifiers, printDecorators, + printFlowDeclaration, } = require("./print/misc"); const { printImportDeclaration, @@ -126,8 +121,14 @@ const { } = require("./print/function"); const { printCallExpression } = require("./print/call-expression"); const { printInterface } = require("./print/interface"); - -let uid = 0; +const { + printVariableDeclarator, + printAssignmentExpression, + printAssignment, + printAssignmentRight, +} = require("./print/assignment"); +const { printBinaryishExpression } = require("./print/binaryish"); +const { printComment } = require("./print/comment"); function genericPrint(path, options, printPath, args) { const node = path.getValue(); @@ -357,164 +358,13 @@ function printPathNoParens(path, options, print, args) { ); } case "AssignmentExpression": - return printAssignment( - n.left, - path.call(print, "left"), - concat([" ", n.operator]), - n.right, - path.call(print, "right"), - options - ); + return printAssignmentExpression(path, options, print); + case "VariableDeclarator": + return printVariableDeclarator(path, options, print); case "BinaryExpression": case "LogicalExpression": - case "NGPipeExpression": { - const parent = path.getParentNode(); - const parentParent = path.getParentNode(1); - const isInsideParenthesis = - n !== parent.body && - (parent.type === "IfStatement" || - parent.type === "WhileStatement" || - parent.type === "SwitchStatement" || - parent.type === "DoWhileStatement"); - - const parts = printBinaryishExpressions( - path, - print, - options, - /* isNested */ false, - isInsideParenthesis - ); - - // if ( - // this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft - // ) { - // - // looks super weird, we want to break the children if the parent breaks - // - // if ( - // this.hasPlugin("dynamicImports") && - // this.lookahead().type === tt.parenLeft - // ) { - if (isInsideParenthesis) { - return concat(parts); - } - - // Break between the parens in - // unaries or in a member or specific call expression, i.e. - // - // ( - // a && - // b && - // c - // ).call() - if ( - ((parent.type === "CallExpression" || - parent.type === "OptionalCallExpression") && - parent.callee === n) || - parent.type === "UnaryExpression" || - ((parent.type === "MemberExpression" || - parent.type === "OptionalMemberExpression") && - !parent.computed) - ) { - return group( - concat([indent(concat([softline, concat(parts)])), softline]) - ); - } - - // Avoid indenting sub-expressions in some cases where the first sub-expression is already - // indented accordingly. We should indent sub-expressions where the first case isn't indented. - const shouldNotIndent = - parent.type === "ReturnStatement" || - parent.type === "ThrowStatement" || - (parent.type === "JSXExpressionContainer" && - parentParent.type === "JSXAttribute") || - (n.operator !== "|" && parent.type === "JsExpressionRoot") || - (n.type !== "NGPipeExpression" && - ((parent.type === "NGRoot" && options.parser === "__ng_binding") || - (parent.type === "NGMicrosyntaxExpression" && - parentParent.type === "NGMicrosyntax" && - parentParent.body.length === 1))) || - (n === parent.body && parent.type === "ArrowFunctionExpression") || - (n !== parent.body && parent.type === "ForStatement") || - (parent.type === "ConditionalExpression" && - parentParent.type !== "ReturnStatement" && - parentParent.type !== "ThrowStatement" && - parentParent.type !== "CallExpression" && - parentParent.type !== "OptionalCallExpression") || - parent.type === "TemplateLiteral"; - - const shouldIndentIfInlining = - parent.type === "AssignmentExpression" || - parent.type === "VariableDeclarator" || - parent.type === "ClassProperty" || - parent.type === "FieldDefinition" || - parent.type === "TSAbstractClassProperty" || - parent.type === "ClassPrivateProperty" || - parent.type === "ObjectProperty" || - parent.type === "Property"; - - const samePrecedenceSubExpression = - isBinaryish(n.left) && shouldFlatten(n.operator, n.left.operator); - - if ( - shouldNotIndent || - (shouldInlineLogicalExpression(n) && !samePrecedenceSubExpression) || - (!shouldInlineLogicalExpression(n) && shouldIndentIfInlining) - ) { - return group(concat(parts)); - } - - if (parts.length === 0) { - return ""; - } - - // If the right part is a JSX node, we include it in a separate group to - // prevent it breaking the whole chain, so we can print the expression like: - // - // foo && bar && ( - // - // - // - // ) - - const hasJSX = isJSXNode(n.right); - - const firstGroupIndex = parts.findIndex( - (part) => typeof part !== "string" && part.type === "group" - ); - - // Separate the leftmost expression, possibly with its leading comments. - const headParts = parts.slice( - 0, - firstGroupIndex === -1 ? 1 : firstGroupIndex + 1 - ); - - const rest = concat( - parts.slice(headParts.length, hasJSX ? -1 : undefined) - ); - - const groupId = Symbol("logicalChain-" + ++uid); - - const chain = group( - concat([ - // Don't include the initial expression in the indentation - // level. The first item is guaranteed to be the first - // left-most expression. - ...headParts, - indent(rest), - ]), - { id: groupId } - ); - - if (!hasJSX) { - return chain; - } - - const jsxPart = getLast(parts); - return group( - concat([chain, ifBreak(indent(jsxPart), jsxPart, { groupId })]) - ); - } + case "NGPipeExpression": + return printBinaryishExpression(path, options, print); case "AssignmentPattern": return concat([ path.call(print, "left"), @@ -1002,15 +852,6 @@ function printPathNoParens(path, options, print, args) { return group(concat(parts)); } - case "VariableDeclarator": - return printAssignment( - n.id, - path.call(print, "id"), - " =", - n.init, - n.init && path.call(print, "init"), - options - ); case "WithStatement": return group( concat([ @@ -2690,216 +2531,6 @@ function printStatementSequence(path, options, print) { return join(hardline, printed); } -function printFlowDeclaration(path, printed) { - const parentExportDecl = getParentExportDeclaration(path); - - if (parentExportDecl) { - assert.strictEqual(parentExportDecl.type, "DeclareExportDeclaration"); - return printed; - } - - // If the parent node has type DeclareExportDeclaration, then it - // will be responsible for printing the "declare" token. Otherwise - // it needs to be printed with this non-exported declaration node. - return concat(["declare ", printed]); -} - -function shouldInlineLogicalExpression(node) { - if (node.type !== "LogicalExpression") { - return false; - } - - if ( - node.right.type === "ObjectExpression" && - node.right.properties.length !== 0 - ) { - return true; - } - - if ( - node.right.type === "ArrayExpression" && - node.right.elements.length !== 0 - ) { - return true; - } - - if (isJSXNode(node.right)) { - return true; - } - - return false; -} - -// For binary expressions to be consistent, we need to group -// subsequent operators with the same precedence level under a single -// group. Otherwise they will be nested such that some of them break -// onto new lines but not all. Operators with the same precedence -// level should either all break or not. Because we group them by -// precedence level and the AST is structured based on precedence -// level, things are naturally broken up correctly, i.e. `&&` is -// broken before `+`. -function printBinaryishExpressions( - path, - print, - options, - isNested, - isInsideParenthesis -) { - /** @type{Doc[]} */ - let parts = []; - - const node = path.getValue(); - - // We treat BinaryExpression and LogicalExpression nodes the same. - if (isBinaryish(node)) { - // Put all operators with the same precedence level in the same - // group. The reason we only need to do this with the `left` - // expression is because given an expression like `1 + 2 - 3`, it - // is always parsed like `((1 + 2) - 3)`, meaning the `left` side - // is where the rest of the expression will exist. Binary - // expressions on the right side mean they have a difference - // precedence level and should be treated as a separate group, so - // print them normally. (This doesn't hold for the `**` operator, - // which is unique in that it is right-associative.) - if (shouldFlatten(node.operator, node.left.operator)) { - // Flatten them out by recursively calling this function. - parts = parts.concat( - path.call( - (left) => - printBinaryishExpressions( - left, - print, - options, - /* isNested */ true, - isInsideParenthesis - ), - "left" - ) - ); - } else { - parts.push(group(path.call(print, "left"))); - } - - const shouldInline = shouldInlineLogicalExpression(node); - const lineBeforeOperator = - (node.operator === "|>" || - node.type === "NGPipeExpression" || - (node.operator === "|" && options.parser === "__vue_expression")) && - !hasLeadingOwnLineComment(options.originalText, node.right); - - const operator = node.type === "NGPipeExpression" ? "|" : node.operator; - const rightSuffix = - node.type === "NGPipeExpression" && node.arguments.length !== 0 - ? group( - indent( - concat([ - softline, - ": ", - join( - concat([softline, ":", ifBreak(" ")]), - path - .map(print, "arguments") - .map((arg) => align(2, group(arg))) - ), - ]) - ) - ) - : ""; - - const right = shouldInline - ? concat([operator, " ", path.call(print, "right"), rightSuffix]) - : concat([ - lineBeforeOperator ? line : "", - operator, - lineBeforeOperator ? " " : line, - path.call(print, "right"), - rightSuffix, - ]); - - // If there's only a single binary expression, we want to create a group - // in order to avoid having a small right part like -1 be on its own line. - const parent = path.getParentNode(); - const shouldBreak = hasTrailingLineComment(node.left); - const shouldGroup = - shouldBreak || - (!(isInsideParenthesis && node.type === "LogicalExpression") && - parent.type !== node.type && - node.left.type !== node.type && - node.right.type !== node.type); - - parts.push( - lineBeforeOperator ? "" : " ", - shouldGroup ? group(right, { shouldBreak }) : right - ); - - // 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 && node.comments) { - parts = normalizeParts( - comments.printComments(path, () => concat(parts), options).parts - ); - } - } else { - // Our stopping case. Simply print the node normally. - parts.push(group(path.call(print))); - } - - return parts; -} - -function printAssignmentRight(leftNode, rightNode, printedRight, options) { - if (hasLeadingOwnLineComment(options.originalText, rightNode)) { - return indent(concat([line, printedRight])); - } - - const canBreak = - (isBinaryish(rightNode) && !shouldInlineLogicalExpression(rightNode)) || - (rightNode.type === "ConditionalExpression" && - isBinaryish(rightNode.test) && - !shouldInlineLogicalExpression(rightNode.test)) || - rightNode.type === "StringLiteralTypeAnnotation" || - (rightNode.type === "ClassExpression" && - rightNode.decorators && - rightNode.decorators.length) || - ((leftNode.type === "Identifier" || - isStringLiteral(leftNode) || - leftNode.type === "MemberExpression") && - (isStringLiteral(rightNode) || isMemberExpressionChain(rightNode)) && - // do not put values on a separate line from the key in json - options.parser !== "json" && - options.parser !== "json5") || - rightNode.type === "SequenceExpression"; - - if (canBreak) { - return group(indent(concat([line, printedRight]))); - } - - return concat([" ", printedRight]); -} - -function printAssignment( - leftNode, - printedLeft, - operator, - rightNode, - printedRight, - options -) { - if (!rightNode) { - return printedLeft; - } - - const printed = printAssignmentRight( - leftNode, - rightNode, - printedRight, - options - ); - - return group(concat([printedLeft, operator, printed])); -} - function adjustClause(node, clause, forceSpace) { if (node.type === "EmptyStatement") { return ";"; @@ -2986,69 +2617,6 @@ function canAttachComment(node) { ); } -function printComment(commentPath, options) { - const comment = commentPath.getValue(); - - if (isLineComment(comment)) { - // Supports `//`, `#!`, `` - return options.originalText - .slice(locStart(comment), locEnd(comment)) - .trimEnd(); - } - - if (isBlockComment(comment)) { - if (isIndentableBlockComment(comment)) { - const printed = printIndentableBlockComment(comment); - // We need to prevent an edge case of a previous trailing comment - // printed as a `lineSuffix` which causes the comments to be - // interleaved. See https://github.com/prettier/prettier/issues/4412 - if ( - comment.trailing && - !hasNewline(options.originalText, locStart(comment), { - backwards: true, - }) - ) { - return concat([hardline, printed]); - } - return printed; - } - - const commentEnd = locEnd(comment); - const isInsideFlowComment = - options.originalText.slice(commentEnd - 3, commentEnd) === "*-/"; - return "/*" + comment.value + (isInsideFlowComment ? "*-/" : "*/"); - } - - /* istanbul ignore next */ - throw new Error("Not a comment: " + JSON.stringify(comment)); -} - -function isIndentableBlockComment(comment) { - // If the comment has multiple lines and every line starts with a star - // we can fix the indentation of each line. The stars in the `/*` and - // `*/` delimiters are not included in the comment value, so add them - // back first. - const lines = `*${comment.value}*`.split("\n"); - return lines.length > 1 && lines.every((line) => line.trim()[0] === "*"); -} - -function printIndentableBlockComment(comment) { - const lines = comment.value.split("\n"); - - return concat([ - "/*", - join( - hardline, - lines.map((line, index) => - index === 0 - ? line.trimEnd() - : " " + (index < lines.length - 1 ? line.trim() : line.trimStart()) - ) - ), - "*/", - ]); -} - module.exports = { preprocess, print: genericPrint, From 002dc6c45fd3f57d29e3f051e4a6362d32a8842f Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Fri, 20 Nov 2020 02:02:46 +0800 Subject: [PATCH 068/299] Extract `printStatementSequence`, `printMemberExpression`, and `printBlock` (#9723) --- src/language-js/print/block.js | 76 ++++++++ src/language-js/print/member-chain.js | 2 +- src/language-js/print/member.js | 67 ++++++++ src/language-js/print/misc.js | 35 ++-- src/language-js/print/statement.js | 151 ++++++++++++++++ src/language-js/printer-estree.js | 239 +------------------------- 6 files changed, 316 insertions(+), 254 deletions(-) create mode 100644 src/language-js/print/block.js create mode 100644 src/language-js/print/member.js create mode 100644 src/language-js/print/statement.js diff --git a/src/language-js/print/block.js b/src/language-js/print/block.js new file mode 100644 index 000000000..b4a7f5051 --- /dev/null +++ b/src/language-js/print/block.js @@ -0,0 +1,76 @@ +"use strict"; + +const { printDanglingComments } = require("../../main/comments"); +const { isNextLineEmpty } = require("../../common/util"); +const { + builders: { concat, hardline, indent }, +} = require("../../document"); +const { hasDanglingComments } = require("../utils"); +const { locEnd } = require("../loc"); + +const { printStatementSequence } = require("./statement"); + +/** @typedef {import("../../document").Doc} Doc */ + +function printBlock(path, options, print) { + const n = path.getValue(); + const parts = []; + const semi = options.semi ? ";" : ""; + const naked = path.call((bodyPath) => { + return printStatementSequence(bodyPath, options, print); + }, "body"); + + if (n.type === "StaticBlock") { + parts.push("static "); + } + + const hasContent = n.body.some((node) => node.type !== "EmptyStatement"); + const hasDirectives = n.directives && n.directives.length > 0; + + const parent = path.getParentNode(); + const parentParent = path.getParentNode(1); + if ( + !hasContent && + !hasDirectives && + !hasDanglingComments(n) && + (parent.type === "ArrowFunctionExpression" || + parent.type === "FunctionExpression" || + parent.type === "FunctionDeclaration" || + parent.type === "ObjectMethod" || + parent.type === "ClassMethod" || + parent.type === "ClassPrivateMethod" || + parent.type === "ForStatement" || + parent.type === "WhileStatement" || + parent.type === "DoWhileStatement" || + parent.type === "DoExpression" || + (parent.type === "CatchClause" && !parentParent.finalizer) || + parent.type === "TSModuleDeclaration" || + parent.type === "TSDeclareFunction" || + n.type === "StaticBlock") + ) { + return concat([...parts, "{}"]); + } + + parts.push("{"); + + // Babel 6 + if (hasDirectives) { + path.each((childPath) => { + parts.push(indent(concat([hardline, print(childPath), semi]))); + if (isNextLineEmpty(options.originalText, childPath.getValue(), locEnd)) { + parts.push(hardline); + } + }, "directives"); + } + + if (hasContent) { + parts.push(indent(concat([hardline, naked]))); + } + + parts.push(printDanglingComments(path, options)); + parts.push(hardline, "}"); + + return concat(parts); +} + +module.exports = { printBlock }; diff --git a/src/language-js/print/member-chain.js b/src/language-js/print/member-chain.js index 9bb2333dd..16247fdb3 100644 --- a/src/language-js/print/member-chain.js +++ b/src/language-js/print/member-chain.js @@ -35,10 +35,10 @@ const { utils: { willBreak }, } = require("../../document"); const printCallArguments = require("./call-arguments"); +const { printMemberLookup } = require("./member"); const { printOptionalToken, printFunctionTypeParameters, - printMemberLookup, printBindExpressionCallee, } = require("./misc"); diff --git a/src/language-js/print/member.js b/src/language-js/print/member.js new file mode 100644 index 000000000..78201b27f --- /dev/null +++ b/src/language-js/print/member.js @@ -0,0 +1,67 @@ +"use strict"; + +const { + builders: { concat, softline, group, indent }, +} = require("../../document"); +const { isNumericLiteral } = require("../utils"); +const { printOptionalToken } = require("./misc"); + +function printMemberExpression(path, options, print) { + const n = path.getValue(); + + const parent = path.getParentNode(); + let firstNonMemberParent; + let i = 0; + do { + firstNonMemberParent = path.getParentNode(i); + i++; + } while ( + firstNonMemberParent && + (firstNonMemberParent.type === "MemberExpression" || + firstNonMemberParent.type === "OptionalMemberExpression" || + firstNonMemberParent.type === "TSNonNullExpression") + ); + + const shouldInline = + (firstNonMemberParent && + (firstNonMemberParent.type === "NewExpression" || + firstNonMemberParent.type === "BindExpression" || + (firstNonMemberParent.type === "VariableDeclarator" && + firstNonMemberParent.id.type !== "Identifier") || + (firstNonMemberParent.type === "AssignmentExpression" && + firstNonMemberParent.left.type !== "Identifier"))) || + n.computed || + (n.object.type === "Identifier" && + n.property.type === "Identifier" && + parent.type !== "MemberExpression" && + parent.type !== "OptionalMemberExpression"); + + return concat([ + path.call(print, "object"), + shouldInline + ? printMemberLookup(path, options, print) + : group( + indent(concat([softline, printMemberLookup(path, options, print)])) + ), + ]); +} + +function printMemberLookup(path, options, print) { + const property = path.call(print, "property"); + const n = path.getValue(); + const optional = printOptionalToken(path); + + if (!n.computed) { + return concat([optional, ".", property]); + } + + if (!n.property || isNumericLiteral(n.property)) { + return concat([optional, "[", property, "]"]); + } + + return group( + concat([optional, "[", indent(concat([softline, property])), softline, "]"]) + ); +} + +module.exports = { printMemberExpression, printMemberLookup }; diff --git a/src/language-js/print/misc.js b/src/language-js/print/misc.js index 2a8ccbdfe..4d30c8889 100644 --- a/src/language-js/print/misc.js +++ b/src/language-js/print/misc.js @@ -3,11 +3,10 @@ /** @type {import("assert")} */ const assert = require("assert"); const { - builders: { concat, softline, group, indent, join, line, hardline }, + builders: { concat, group, indent, join, line, hardline }, } = require("../../document"); const { hasNewlineBetweenOrAfterDecorators, - isNumericLiteral, getParentExportDeclaration, } = require("../utils"); @@ -41,24 +40,6 @@ function printFunctionTypeParameters(path, options, print) { return ""; } -function printMemberLookup(path, options, print) { - const property = path.call(print, "property"); - const n = path.getValue(); - const optional = printOptionalToken(path); - - if (!n.computed) { - return concat([optional, ".", property]); - } - - if (!n.property || isNumericLiteral(n.property)) { - return concat([optional, "[", property, "]"]); - } - - return group( - concat([optional, "[", indent(concat([softline, property])), softline, "]"]) - ); -} - function printBindExpressionCallee(path, options, print) { return concat(["::", path.call(print, "callee")]); } @@ -95,12 +76,24 @@ function printFlowDeclaration(path, printed) { return concat(["declare ", printed]); } +function adjustClause(node, clause, forceSpace) { + if (node.type === "EmptyStatement") { + return ";"; + } + + if (node.type === "BlockStatement" || forceSpace) { + return concat([" ", clause]); + } + + return indent(concat([line, clause])); +} + module.exports = { printOptionalToken, printFunctionTypeParameters, - printMemberLookup, printBindExpressionCallee, printTypeScriptModifiers, printDecorators, printFlowDeclaration, + adjustClause, }; diff --git a/src/language-js/print/statement.js b/src/language-js/print/statement.js new file mode 100644 index 000000000..a4a95c909 --- /dev/null +++ b/src/language-js/print/statement.js @@ -0,0 +1,151 @@ +"use strict"; + +const { isNextLineEmpty } = require("../../common/util"); +const { + builders: { concat, join, hardline }, +} = require("../../document"); +const pathNeedsParens = require("../needs-parens"); +const { + classChildNeedsASIProtection, + classPropMayCauseASIProblems, + getLeftSidePathName, + hasNakedLeftSide, + isJSXNode, + isLastStatement, + isTheOnlyJSXElementInMarkdown, +} = require("../utils"); +const { locEnd } = require("../loc"); +const { shouldPrintParamsWithoutParens } = require("./function"); + +/** @typedef {import("../../document").Doc} Doc */ + +function printStatement({ path, index, bodyNode, isClass }, options, print) { + const node = path.getValue(); + + // Just in case the AST has been modified to contain falsy + // "statements," it's safer simply to skip them. + /* istanbul ignore if */ + if (!node) { + return; + } + + // Skip printing EmptyStatement nodes to avoid leaving stray + // semicolons lying around. + if (node.type === "EmptyStatement") { + return; + } + + const printed = print(path); + const text = options.originalText; + const parts = []; + + // in no-semi mode, prepend statement with semicolon if it might break ASI + // don't prepend the only JSX element in a program with semicolon + if ( + !options.semi && + !isClass && + !isTheOnlyJSXElementInMarkdown(options, path) && + statementNeedsASIProtection(path, options) + ) { + if (node.comments && node.comments.some((comment) => comment.leading)) { + parts.push(print(path, { needsSemi: true })); + } else { + parts.push(";", printed); + } + } else { + parts.push(printed); + } + + if (!options.semi && isClass) { + if (classPropMayCauseASIProblems(path)) { + parts.push(";"); + } else if ( + node.type === "ClassProperty" || + node.type === "FieldDefinition" + ) { + const nextChild = bodyNode.body[index + 1]; + if (classChildNeedsASIProtection(nextChild)) { + parts.push(";"); + } + } + } + + if (isNextLineEmpty(text, node, locEnd) && !isLastStatement(path)) { + parts.push(hardline); + } + + return concat(parts); +} + +function printStatementSequence(path, options, print) { + const bodyNode = path.getNode(); + const isClass = bodyNode.type === "ClassBody"; + + const printed = path + .map((statementPath, index) => + printStatement( + { + path, + index, + bodyNode, + isClass, + }, + options, + print + ) + ) + .filter(Boolean); + + return join(hardline, printed); +} + +function statementNeedsASIProtection(path, options) { + const node = path.getNode(); + + if (node.type !== "ExpressionStatement") { + return false; + } + + return path.call( + (childPath) => expressionNeedsASIProtection(childPath, options), + "expression" + ); +} + +function expressionNeedsASIProtection(path, options) { + const node = path.getValue(); + + const maybeASIProblem = + pathNeedsParens(path, options) || + node.type === "ParenthesizedExpression" || + node.type === "TypeCastExpression" || + (node.type === "ArrowFunctionExpression" && + !shouldPrintParamsWithoutParens(path, options)) || + node.type === "ArrayExpression" || + node.type === "ArrayPattern" || + (node.type === "UnaryExpression" && + node.prefix && + (node.operator === "+" || node.operator === "-")) || + node.type === "TemplateLiteral" || + node.type === "TemplateElement" || + isJSXNode(node) || + (node.type === "BindExpression" && !node.object) || + node.type === "RegExpLiteral" || + (node.type === "Literal" && node.pattern) || + (node.type === "Literal" && node.regex); + + if (maybeASIProblem) { + return true; + } + + if (!hasNakedLeftSide(node)) { + return false; + } + + return path.call( + (childPath) => expressionNeedsASIProtection(childPath, options), + ...getLeftSidePathName(path, node) + ); +} + +module.exports = { printStatementSequence }; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index c5e7825f7..025e7775e 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -42,17 +42,13 @@ const { } = require("./html-binding"); const preprocess = require("./print-preprocess"); const { - classChildNeedsASIProtection, - classPropMayCauseASIProblems, getFunctionParameters, getCallArguments, - getLeftSidePathName, getParentExportDeclaration, getTypeScriptMappedTypeModifier, hasDanglingComments, hasFlowShorthandAnnotationComment, hasLeadingOwnLineComment, - hasNakedLeftSide, hasNewlineBetweenOrAfterDecorators, hasNgSideEffect, hasPrettierIgnore, @@ -60,8 +56,6 @@ const { isExportDeclaration, isFunctionNotation, isGetterOrSetter, - isJSXNode, - isLastStatement, isLiteral, isNgForOf, isObjectType, @@ -77,11 +71,11 @@ const { locStart, locEnd } = require("./loc"); const { printOptionalToken, - printMemberLookup, printBindExpressionCallee, printTypeScriptModifiers, printDecorators, printFlowDeclaration, + adjustClause, } = require("./print/misc"); const { printImportDeclaration, @@ -117,7 +111,6 @@ const { printArrowFunctionExpression, printMethod, printReturnAndThrowArgument, - shouldPrintParamsWithoutParens, } = require("./print/function"); const { printCallExpression } = require("./print/call-expression"); const { printInterface } = require("./print/interface"); @@ -128,6 +121,9 @@ const { printAssignmentRight, } = require("./print/assignment"); const { printBinaryishExpression } = require("./print/binaryish"); +const { printStatementSequence } = require("./print/statement"); +const { printMemberExpression } = require("./print/member"); +const { printBlock } = require("./print/block"); const { printComment } = require("./print/comment"); function genericPrint(path, options, printPath, args) { @@ -404,43 +400,7 @@ function printPathNoParens(path, options, print, args) { } case "OptionalMemberExpression": case "MemberExpression": { - const parent = path.getParentNode(); - let firstNonMemberParent; - let i = 0; - do { - firstNonMemberParent = path.getParentNode(i); - i++; - } while ( - firstNonMemberParent && - (firstNonMemberParent.type === "MemberExpression" || - firstNonMemberParent.type === "OptionalMemberExpression" || - firstNonMemberParent.type === "TSNonNullExpression") - ); - - const shouldInline = - (firstNonMemberParent && - (firstNonMemberParent.type === "NewExpression" || - firstNonMemberParent.type === "BindExpression" || - (firstNonMemberParent.type === "VariableDeclarator" && - firstNonMemberParent.id.type !== "Identifier") || - (firstNonMemberParent.type === "AssignmentExpression" && - firstNonMemberParent.left.type !== "Identifier"))) || - n.computed || - (n.object.type === "Identifier" && - n.property.type === "Identifier" && - parent.type !== "MemberExpression" && - parent.type !== "OptionalMemberExpression"); - - return concat([ - path.call(print, "object"), - shouldInline - ? printMemberLookup(path, options, print) - : group( - indent( - concat([softline, printMemberLookup(path, options, print)]) - ) - ), - ]); + return printMemberExpression(path, options, print); } case "MetaProperty": return concat([ @@ -555,65 +515,8 @@ function printPathNoParens(path, options, print, args) { return "import"; case "TSModuleBlock": case "BlockStatement": - case "StaticBlock": { - const naked = path.call((bodyPath) => { - return printStatementSequence(bodyPath, options, print); - }, "body"); - - if (n.type === "StaticBlock") { - parts.push("static "); - } - - const hasContent = n.body.some((node) => node.type !== "EmptyStatement"); - const hasDirectives = n.directives && n.directives.length > 0; - - const parent = path.getParentNode(); - const parentParent = path.getParentNode(1); - if ( - !hasContent && - !hasDirectives && - !hasDanglingComments(n) && - (parent.type === "ArrowFunctionExpression" || - parent.type === "FunctionExpression" || - parent.type === "FunctionDeclaration" || - parent.type === "ObjectMethod" || - parent.type === "ClassMethod" || - parent.type === "ClassPrivateMethod" || - parent.type === "ForStatement" || - parent.type === "WhileStatement" || - parent.type === "DoWhileStatement" || - parent.type === "DoExpression" || - (parent.type === "CatchClause" && !parentParent.finalizer) || - parent.type === "TSModuleDeclaration" || - parent.type === "TSDeclareFunction" || - n.type === "StaticBlock") - ) { - return concat([...parts, "{}"]); - } - - parts.push("{"); - - // Babel 6 - if (hasDirectives) { - path.each((childPath) => { - parts.push(indent(concat([hardline, print(childPath), semi]))); - if ( - isNextLineEmpty(options.originalText, childPath.getValue(), locEnd) - ) { - parts.push(hardline); - } - }, "directives"); - } - - if (hasContent) { - parts.push(indent(concat([hardline, naked]))); - } - - parts.push(comments.printDanglingComments(path, options)); - parts.push(hardline, "}"); - - return concat(parts); - } + case "StaticBlock": + return printBlock(path, options, print); case "ThrowStatement": case "ReturnStatement": return concat([ @@ -2464,85 +2367,6 @@ function printPathNoParens(path, options, print, args) { } } -function printStatementSequence(path, options, print) { - const printed = []; - - const bodyNode = path.getNode(); - const isClass = bodyNode.type === "ClassBody"; - - path.each((stmtPath, i) => { - const stmt = stmtPath.getValue(); - - // Just in case the AST has been modified to contain falsy - // "statements," it's safer simply to skip them. - /* istanbul ignore if */ - if (!stmt) { - return; - } - - // Skip printing EmptyStatement nodes to avoid leaving stray - // semicolons lying around. - if (stmt.type === "EmptyStatement") { - return; - } - - const stmtPrinted = print(stmtPath); - const text = options.originalText; - const parts = []; - - // in no-semi mode, prepend statement with semicolon if it might break ASI - // don't prepend the only JSX element in a program with semicolon - if ( - !options.semi && - !isClass && - !isTheOnlyJSXElementInMarkdown(options, stmtPath) && - stmtNeedsASIProtection(stmtPath, options) - ) { - if (stmt.comments && stmt.comments.some((comment) => comment.leading)) { - parts.push(print(stmtPath, { needsSemi: true })); - } else { - parts.push(";", stmtPrinted); - } - } else { - parts.push(stmtPrinted); - } - - if (!options.semi && isClass) { - if (classPropMayCauseASIProblems(stmtPath)) { - parts.push(";"); - } else if ( - stmt.type === "ClassProperty" || - stmt.type === "FieldDefinition" - ) { - const nextChild = bodyNode.body[i + 1]; - if (classChildNeedsASIProtection(nextChild)) { - parts.push(";"); - } - } - } - - if (isNextLineEmpty(text, stmt, locEnd) && !isLastStatement(stmtPath)) { - parts.push(hardline); - } - - printed.push(concat(parts)); - }); - - return join(hardline, printed); -} - -function adjustClause(node, clause, forceSpace) { - if (node.type === "EmptyStatement") { - return ";"; - } - - if (node.type === "BlockStatement" || forceSpace) { - return concat([" ", clause]); - } - - return indent(concat([line, clause])); -} - function nodeStr(node, options, isFlowOrTypeScriptDirectiveLiteral) { const raw = rawText(node); const isDirectiveLiteral = @@ -2555,55 +2379,6 @@ function printRegex(node) { return `/${node.pattern}/${flags}`; } -function exprNeedsASIProtection(path, options) { - const node = path.getValue(); - - const maybeASIProblem = - pathNeedsParens(path, options) || - node.type === "ParenthesizedExpression" || - node.type === "TypeCastExpression" || - (node.type === "ArrowFunctionExpression" && - !shouldPrintParamsWithoutParens(path, options)) || - node.type === "ArrayExpression" || - node.type === "ArrayPattern" || - (node.type === "UnaryExpression" && - node.prefix && - (node.operator === "+" || node.operator === "-")) || - node.type === "TemplateLiteral" || - node.type === "TemplateElement" || - isJSXNode(node) || - (node.type === "BindExpression" && !node.object) || - node.type === "RegExpLiteral" || - (node.type === "Literal" && node.pattern) || - (node.type === "Literal" && node.regex); - - if (maybeASIProblem) { - return true; - } - - if (!hasNakedLeftSide(node)) { - return false; - } - - return path.call( - (childPath) => exprNeedsASIProtection(childPath, options), - ...getLeftSidePathName(path, node) - ); -} - -function stmtNeedsASIProtection(path, options) { - const node = path.getNode(); - - if (node.type !== "ExpressionStatement") { - return false; - } - - return path.call( - (childPath) => exprNeedsASIProtection(childPath, options), - "expression" - ); -} - function canAttachComment(node) { return ( node.type && From 9bc90cfe7d2b1531ae1249baffe43ed318bd12a4 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Fri, 20 Nov 2020 11:35:29 +0900 Subject: [PATCH 069/299] Update to typescript 4.1.2 (#9725) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1638c07b0..1047d267e 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "resolve": "1.19.0", "semver": "7.3.2", "string-width": "4.2.0", - "typescript": "4.1.1-rc", + "typescript": "4.1.2", "unicode-regex": "3.0.0", "unified": "9.2.0", "vnopts": "1.0.2", diff --git a/yarn.lock b/yarn.lock index 69e5adab4..76319a93c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7166,10 +7166,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@4.1.1-rc: - version "4.1.1-rc" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.1-rc.tgz#4a335244b9b2754995849ca4b607c74d6ee73719" - integrity sha512-tgNcFrLIjlaMWEc7bKC0bxLNIt8BIAauY/HLUOQDyTP75HGskETtXOt46x4EKAHRKhWVLMc7yM02puTHa/yhCA== +typescript@4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.2.tgz#6369ef22516fe5e10304aae5a5c4862db55380e9" + integrity sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ== unherit@^1.0.4: version "1.1.3" From 42b2195e713236f2d43dd95add7301d63f7f6b0c Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Fri, 20 Nov 2020 13:44:18 +0900 Subject: [PATCH 070/299] Release 2.2.0 --- .github/ISSUE_TEMPLATE/formatting.md | 2 +- .github/ISSUE_TEMPLATE/integration.md | 2 +- CHANGELOG.md | 6 +++++ docs/browser.md | 12 ++++----- package.json | 2 +- .../versioned_docs/version-stable/browser.md | 25 +++++++++++-------- .../versioned_docs/version-stable/options.md | 1 + .../versioned_docs/version-stable/plugins.md | 10 +++++++- .../version-stable/precommit.md | 2 -- 9 files changed, 40 insertions(+), 22 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/formatting.md b/.github/ISSUE_TEMPLATE/formatting.md index ba91ba43f..af8efd889 100644 --- a/.github/ISSUE_TEMPLATE/formatting.md +++ b/.github/ISSUE_TEMPLATE/formatting.md @@ -26,7 +26,7 @@ Tip! Don't write this stuff manually. --> -**Prettier 2.1.2** +**Prettier 2.2.0** [Playground link](https://prettier.io/playground/#.....) ```sh diff --git a/.github/ISSUE_TEMPLATE/integration.md b/.github/ISSUE_TEMPLATE/integration.md index 73e97d703..eea91394d 100644 --- a/.github/ISSUE_TEMPLATE/integration.md +++ b/.github/ISSUE_TEMPLATE/integration.md @@ -20,7 +20,7 @@ BEFORE SUBMITTING AN ISSUE: **Environments:** -- Prettier Version: 2.1.2 +- Prettier Version: 2.2.0 - Running Prettier via: - Runtime: - Operating System: diff --git a/CHANGELOG.md b/CHANGELOG.md index 6270e1b7c..b1d3f6130 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 2.2.0 + +[diff](https://github.com/prettier/prettier/compare/2.1.2...2.2.0) + +🔗 [Release Notes](https://prettier.io/blog/2020/11/20/2.2.0.html) + # 2.1.2 [diff](https://github.com/prettier/prettier/compare/2.1.1...2.1.2) diff --git a/docs/browser.md b/docs/browser.md index 96d81c1a6..92f7a67a7 100644 --- a/docs/browser.md +++ b/docs/browser.md @@ -23,8 +23,8 @@ See [Usage](#usage) below for examples. ### Global ```html - - + + - + + + + + + + + + + + + + + +``` + +### Handlebars (alpha) + +#### Fix unstable newlines after `