Skip to content

Commit

Permalink
Support hack-style pipeline (#11335)
Browse files Browse the repository at this point in the history
* Avoid to conflicts to v8intrinsic plugin

* Support hack-style pipeline

* Update tests for hask-style pipeline

* Update tests 2

* Add changelog

* Update misc tests

* Address reviews

* Fix type error

* Copy plugin array

* Add tests

* Address review

* Add error tests
  • Loading branch information
sosukesuzuki committed Aug 14, 2021
1 parent 83e5ebe commit 53f95f3
Show file tree
Hide file tree
Showing 16 changed files with 382 additions and 330 deletions.
20 changes: 20 additions & 0 deletions changelog_unreleased/javascript/11335.md
@@ -0,0 +1,20 @@
#### Support hack-style pipeline proposal (#11335 by @sosukesuzuki)

Support new [hack-style pipeline proposal](https://github.com/js-choi/proposal-hack-pipes). We chose `%` as the topic token, following the official explainer.

Also, [smart-style pipeline proposal](https://github.com/js-choi/proposal-smart-pipelines) is removed. See https://prettier.io/docs/en/rationale.html#disclaimer-about-non-standard-syntax for the rationale behind this decision.

```js
// Input
const foo = fn() |> fn1(%) |> fn2(%);

// Prettier stable
SyntaxError: Unexpected token (1:25)
> 1 | const foo = fn() |> fn1(%) |> fn2(%);
| ^
2 |

// Prettier main
const foo = fn() |> fn1(%) |> fn(%);

```
16 changes: 13 additions & 3 deletions src/language-js/parse/babel.js
Expand Up @@ -33,7 +33,6 @@ const parseOptions = {
"functionBind",
"functionSent",
"throwExpressions",
"v8intrinsic",
"partialApplication",
["decorators", { decoratorsBeforeExport: false }],
"importAssertions",
Expand All @@ -49,9 +48,12 @@ const parseOptions = {
/** @type {ParserPlugin} */
const recordAndTuplePlugin = ["recordAndTuple", { syntaxType: "hash" }];

/** @type {ParserPlugin} */
const v8intrinsicPlugin = "v8intrinsic";

/** @type {Array<ParserPlugin>} */
const pipelineOperatorPlugins = [
["pipelineOperator", { proposal: "smart" }],
["pipelineOperator", { proposal: "hack", topicToken: "%" }],
["pipelineOperator", { proposal: "minimal" }],
["pipelineOperator", { proposal: "fsharp" }],
];
Expand Down Expand Up @@ -121,12 +123,20 @@ function createParse(parseMethod, ...optionsCombinations) {
);
}

const shouldEnableV8intrinsicPlugin = /%[A-Z]/.test(text);
if (text.includes("|>")) {
combinations = pipelineOperatorPlugins.flatMap((pipelineOperatorPlugin) =>
const conflictsPlugins = shouldEnableV8intrinsicPlugin
? [...pipelineOperatorPlugins, v8intrinsicPlugin]
: pipelineOperatorPlugins;
combinations = conflictsPlugins.flatMap((pipelineOperatorPlugin) =>
combinations.map((options) =>
appendPlugins([pipelineOperatorPlugin], options)
)
);
} else if (shouldEnableV8intrinsicPlugin) {
combinations = combinations.map((options) =>
appendPlugins([v8intrinsicPlugin], options)
);
}

const { result: ast, error } = tryCombinations(
Expand Down
9 changes: 3 additions & 6 deletions src/language-js/printer-estree.js
Expand Up @@ -737,12 +737,9 @@ function printPathNoParens(path, options, print, args) {

return parts;

case "PipelineBareFunction":
return print("callee");
case "PipelineTopicExpression":
return print("expression");
case "PipelinePrimaryTopicReference":
return "#";
// For hack-style pipeline
case "TopicReference":
return "%";

case "ArgumentPlaceholder":
return "?";
Expand Down
108 changes: 48 additions & 60 deletions tests/format/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -1612,6 +1612,54 @@ let newScore = boundScore(0, 100, add(7, double(person.score)));
================================================================================
`;
exports[`pipeline-operator-hack.js [espree] format 1`] = `
"Unexpected token > (5:3)
3 |
4 | return list
> 5 | |> take(prefix.length, %)
| ^
6 | |> equals(%, prefix);
7 |
8 | // (The % token isn't final; it might instead be @ or ? or #.)"
`;
exports[`pipeline-operator-hack.js [meriyah] format 1`] = `
"[5:3]: Unexpected token: '>' (5:3)
3 |
4 | return list
> 5 | |> take(prefix.length, %)
| ^
6 | |> equals(%, prefix);
7 |
8 | // (The % token isn't final; it might instead be @ or ? or #.)"
`;
exports[`pipeline-operator-hack.js format 1`] = `
====================================options=====================================
parsers: ["babel", "babel-ts", "babel-flow"]
printWidth: 80
| printWidth
=====================================input======================================
// https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator
// https://github.com/js-choi/proposal-hack-pipes
return list
|> take(prefix.length, %)
|> equals(%, prefix);
// (The % token isn't final; it might instead be @ or ? or #.)
=====================================output=====================================
// https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator
// https://github.com/js-choi/proposal-hack-pipes
return list |> take(prefix.length, %) |> equals(%, prefix);
// (The % token isn't final; it might instead be @ or ? or #.)
================================================================================
`;
exports[`pipeline-operator-minimal.js [espree] format 1`] = `
"Identifier 'result' has already been declared (7:5)
5 | result //=> \\"Hello, hello!\\"
Expand Down Expand Up @@ -1667,66 +1715,6 @@ result; //=> "Hello, hello!"
================================================================================
`;
exports[`pipeline-operator-smart.js [espree] format 1`] = `
"Unexpected token > (5:2)
3 |
4 | value
> 5 | |> await #
| ^
6 | |> doubleSay(#, ', ')
7 | |> capitalize // This is a function call.
8 | |> # + '!'"
`;
exports[`pipeline-operator-smart.js [meriyah] format 1`] = `
"[5:2]: Unexpected token: '>' (5:2)
3 |
4 | value
> 5 | |> await #
| ^
6 | |> doubleSay(#, ', ')
7 | |> capitalize // This is a function call.
8 | |> # + '!'"
`;
exports[`pipeline-operator-smart.js format 1`] = `
====================================options=====================================
parsers: ["babel", "babel-ts", "babel-flow"]
printWidth: 80
| printWidth
=====================================input======================================
// https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator
// https://github.com/js-choi/proposal-smart-pipelines
value
|> await #
|> doubleSay(#, ', ')
|> capitalize // This is a function call.
|> # + '!'
|> new User.Message(#)
|> await #
|> console.log; // This is a method call.
// (The # token isn't final; it might instead be @ or ? or %.)
=====================================output=====================================
// https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator
// https://github.com/js-choi/proposal-smart-pipelines
value
|> await #
|> doubleSay(#, ", ")
|> capitalize // This is a function call.
|> # + "!"
|> new User.Message(#)
|> await #
|> console.log; // This is a method call.
// (The # token isn't final; it might instead be @ or ? or %.)
================================================================================
`;
exports[`private-fields-in-in.js [espree] format 1`] = `
"Unexpected token #brand (44:12)
42 |
Expand Down
4 changes: 2 additions & 2 deletions tests/format/js/babel-plugins/jsfmt.spec.js
Expand Up @@ -16,7 +16,7 @@ run_spec(__dirname, ["babel", "babel-ts", "babel-flow"], {
"partial-application.js",
"pipeline-operator-fsharp.js",
"pipeline-operator-minimal.js",
"pipeline-operator-smart.js",
"pipeline-operator-hack.js",
"private-fields-in-in.js",
"record-tuple-record.js",
"record-tuple-tuple.js",
Expand All @@ -40,7 +40,7 @@ run_spec(__dirname, ["babel", "babel-ts", "babel-flow"], {
"partial-application.js",
"pipeline-operator-fsharp.js",
"pipeline-operator-minimal.js",
"pipeline-operator-smart.js",
"pipeline-operator-hack.js",
"record-tuple-record.js",
"record-tuple-tuple.js",
"throw-expressions.js",
Expand Down
8 changes: 8 additions & 0 deletions tests/format/js/babel-plugins/pipeline-operator-hack.js
@@ -0,0 +1,8 @@
// https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator
// https://github.com/js-choi/proposal-hack-pipes

return list
|> take(prefix.length, %)
|> equals(%, prefix);

// (The % token isn't final; it might instead be @ or ? or #.)
13 changes: 0 additions & 13 deletions tests/format/js/babel-plugins/pipeline-operator-smart.js

This file was deleted.

0 comments on commit 53f95f3

Please sign in to comment.