diff --git a/changelog_unreleased/css/pr-7933.md b/changelog_unreleased/css/pr-7933.md new file mode 100644 index 000000000..16d9f059c --- /dev/null +++ b/changelog_unreleased/css/pr-7933.md @@ -0,0 +1,41 @@ +#### [BREAKING] Add pure css parser ([#7933](https://github.com/prettier/prettier/pull/7933) by [@fisker](https://github.com/fisker)) + +Previously when `--parser=css` passed, we try `postcss-scss`/`postcss-less` to parse content, this cause confusion, and hard to check syntax error. Now `--parser=css` only works on css syntax. + +_If you're setting `parser="css"` for your `.less`/`.scss` file, you'll need update it to correct parser, or let prettier decide._ + + +```less +/* Input */ +/* Less Syntax with `--parser=css` */ +a {.bordered();} + +/* Prettier stable */ +/* Less Syntax with `--parser=css` */ +a { + .bordered(); +} + +/* Prettier master */ +SyntaxError: (postcss) CssSyntaxError Unknown word (2:4) + 1 | /* Less Syntax with `--parser=css` */ +> 2 | a {.bordered();} +``` + + +```scss +/* Input */ +/* Scss Syntax with `--parser=css` */ +::before {content: #{$foo}} + +/* Prettier stable */ +/* Scss Syntax with `--parser=css` */ +::before { + content: #{$foo}; +} + +/* Prettier master */ +SyntaxError: (postcss) CssSyntaxError Unknown word (2:22) + 1 | /* Scss Syntax with `--parser=css` */ +> 2 | ::before {content: #{$foo}} +``` diff --git a/docs/options.md b/docs/options.md index c3be3220c..38d6000ad 100644 --- a/docs/options.md +++ b/docs/options.md @@ -211,9 +211,9 @@ Valid options: - `"babel-ts"` (similar to `"typescript"` but uses Babel and its TypeScript plugin) _First available in v2.0.0_ - `"flow"` (via [flow-parser](https://github.com/facebook/flow/tree/master/src/parser)) - `"typescript"` (via [@typescript-eslint/typescript-estree](https://github.com/typescript-eslint/typescript-eslint)) _First available in v1.4.0_ -- `"css"` (via [postcss-scss](https://github.com/postcss/postcss-scss) and [postcss-less](https://github.com/shellscape/postcss-less), autodetects which to use) _First available in v1.7.1_ -- `"scss"` (same parsers as `"css"`, prefers postcss-scss) _First available in v1.7.1_ -- `"less"` (same parsers as `"css"`, prefers postcss-less) _First available in v1.7.1_ +- `"css"` (via [postcss](https://github.com/postcss/postcss)) _First available in v1.7.1_ +- `"scss"` (via [postcss-scss](https://github.com/postcss/postcss-scss)) _First available in v1.7.1_ +- `"less"` (via [postcss-less](https://github.com/shellscape/postcss-less) _First available in v1.7.1_ - `"json"` (via [@babel/parser parseExpression](https://babeljs.io/docs/en/next/babel-parser.html#babelparserparseexpressioncode-options)) _First available in v1.5.0_ - `"json5"` (same parser as `"json"`, but outputs as [json5](https://json5.org/)) _First available in v1.13.0_ - `"json-stringify"` (same parser as `"json"`, but outputs like `JSON.stringify`) _First available in v1.13.0_ diff --git a/package.json b/package.json index f40ed988f..2a38640b1 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "outdent": "0.7.1", "parse-srcset": "ikatyang/parse-srcset#54eb9c1cb21db5c62b4d0e275d7249516df6f0ee", "please-upgrade-node": "3.2.0", + "postcss": "7.0.30", "postcss-less": "3.1.4", "postcss-media-query-parser": "0.2.3", "postcss-scss": "2.1.1", diff --git a/src/language-css/parser-postcss.js b/src/language-css/parser-postcss.js index e8e503d49..8430cdc08 100644 --- a/src/language-css/parser-postcss.js +++ b/src/language-css/parser-postcss.js @@ -606,26 +606,9 @@ function parseWithParser(parse, text, options) { return result; } -// TODO: make this only work on css function parseCss(text, parsers, options) { - const isSCSSParser = isSCSS(options.parser, text); - const parseFunctions = isSCSSParser - ? [parseScss, parseLess] - : [parseLess, parseScss]; - - let error; - for (const parse of parseFunctions) { - try { - return parse(text, parsers, options); - } catch (parseError) { - error = error || parseError; - } - } - - /* istanbul ignore next */ - if (error) { - throw error; - } + const { parse } = require("postcss"); + return parseWithParser(parse, text, options); } function parseLess(text, parsers, options) { diff --git a/tests/misc/errors/css/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/css/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..36d3dad90 --- /dev/null +++ b/tests/misc/errors/css/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`less-syntax.css error test 1`] = ` +"(postcss) CssSyntaxError Unknown word (1:4) +> 1 | a {.bordered();} + | ^ + 2 | " +`; + +exports[`scss-syntax.css error test 1`] = ` +"(postcss) CssSyntaxError Unknown word (1:15) +> 1 | a {content: #{$foo}} + | ^ + 2 | " +`; diff --git a/tests/misc/errors/css/jsfmt.spec.js b/tests/misc/errors/css/jsfmt.spec.js new file mode 100644 index 000000000..7d3726c81 --- /dev/null +++ b/tests/misc/errors/css/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, ["css"]); diff --git a/tests/misc/errors/css/less-syntax.css b/tests/misc/errors/css/less-syntax.css new file mode 100644 index 000000000..c093b5027 --- /dev/null +++ b/tests/misc/errors/css/less-syntax.css @@ -0,0 +1 @@ +a {.bordered();} diff --git a/tests/misc/errors/css/scss-syntax.css b/tests/misc/errors/css/scss-syntax.css new file mode 100644 index 000000000..b3d023332 --- /dev/null +++ b/tests/misc/errors/css/scss-syntax.css @@ -0,0 +1 @@ +a {content: #{$foo}} diff --git a/tests/misc/errors/less/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/less/__snapshots__/jsfmt.spec.js.snap index e113e898d..2897e4871 100644 --- a/tests/misc/errors/less/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/less/__snapshots__/jsfmt.spec.js.snap @@ -28,3 +28,10 @@ exports[`open-sigle-quote.less error test 1`] = ` 3 | } 4 | " `; + +exports[`scss-syntax.css error test 1`] = ` +"(postcss) CssSyntaxError Unknown word (1:15) +> 1 | a {content: #{$foo}} + | ^ + 2 | " +`; diff --git a/tests/misc/errors/less/scss-syntax.css b/tests/misc/errors/less/scss-syntax.css new file mode 100644 index 000000000..b3d023332 --- /dev/null +++ b/tests/misc/errors/less/scss-syntax.css @@ -0,0 +1 @@ +a {content: #{$foo}} diff --git a/tests/misc/errors/scss/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/scss/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..cd42dd081 --- /dev/null +++ b/tests/misc/errors/scss/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,8 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`less-syntax.css error test 1`] = ` +"(postcss) CssSyntaxError Unknown word (1:4) +> 1 | a {.bordered();} + | ^ + 2 | " +`; diff --git a/tests/misc/errors/scss/jsfmt.spec.js b/tests/misc/errors/scss/jsfmt.spec.js new file mode 100644 index 000000000..539bde086 --- /dev/null +++ b/tests/misc/errors/scss/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, ["scss"]); diff --git a/tests/misc/errors/scss/less-syntax.css b/tests/misc/errors/scss/less-syntax.css new file mode 100644 index 000000000..c093b5027 --- /dev/null +++ b/tests/misc/errors/scss/less-syntax.css @@ -0,0 +1 @@ +a {.bordered();} diff --git a/yarn.lock b/yarn.lock index 75c831cfa..4a4bd9217 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6462,6 +6462,15 @@ postcss-values-parser@2.0.1: indexes-of "^1.0.1" uniq "^1.0.1" +postcss@7.0.30: + version "7.0.30" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.30.tgz#cc9378beffe46a02cbc4506a0477d05fcea9a8e2" + integrity sha512-nu/0m+NtIzoubO+xdAlwZl/u5S5vi/y6BCsoL8D+8IxsD3XvBS8X4YEADNIVXKVuQvduiucnRv+vPIqj56EGMQ== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + postcss@^7.0.14, postcss@^7.0.6: version "7.0.32" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d"