Skip to content

Commit 82d8ade

Browse files
committed
Ensure left is evaluated before right
1 parent dbcd7f0 commit 82d8ade

File tree

9 files changed

+88
-41
lines changed

9 files changed

+88
-41
lines changed

packages/babel-plugin-transform-pipeline-operator/src/index.js

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,40 @@ export default function({ types: t }) {
66

77
visitor: {
88
BinaryExpression(path) {
9-
const { operator, left, right } = path.node;
9+
const { scope, parentPath } = path;
10+
const { node } = path;
11+
const { operator, left, right } = node;
1012
if (operator !== "|>") return;
1113

12-
if (
14+
// Why do I have to fix this here?!
15+
if (parentPath.isArrowFunctionExpression({ body: node })) {
16+
path.replaceWith(t.blockStatement([t.returnStatement(node)]));
17+
return;
18+
}
19+
20+
const optimizeArrow =
1321
t.isArrowFunctionExpression(right) &&
1422
right.params.length === 1 &&
1523
t.isIdentifier(right.params[0]) &&
16-
t.isExpression(right.body)
17-
) {
18-
//
19-
// Optimize away arrow function!
20-
//
21-
// Converts:
22-
// arg |> x => x + x;
23-
// To:
24-
// (_x = arg, _x + _x);
25-
//
26-
const paramName = right.params[0].name;
27-
const placeholder = path.scope.generateDeclaredUidIdentifier(
28-
paramName,
29-
);
24+
t.isExpression(right.body);
3025

31-
path.get("right").scope.rename(paramName, placeholder.name);
32-
path.replaceWith(
33-
t.sequenceExpression([
34-
t.assignmentExpression("=", placeholder, left),
35-
right.body,
36-
]),
37-
);
38-
} else {
39-
//
40-
// Simple invocation.
41-
//
42-
// Converts:
43-
// x |> obj.f;
44-
// To:
45-
// obj.f(x);
46-
//
47-
path.replaceWith(t.callExpression(right, [left]));
26+
const param = optimizeArrow ? right.params[0] : left;
27+
const placeholder = scope.generateUidIdentifierBasedOnNode(param);
28+
scope.push({ id: placeholder });
29+
30+
if (optimizeArrow) {
31+
path.get("right").scope.rename(param.name, placeholder.name);
4832
}
33+
34+
const call = optimizeArrow
35+
? right.body
36+
: t.callExpression(right, [placeholder]);
37+
path.replaceWith(
38+
t.sequenceExpression([
39+
t.assignmentExpression("=", placeholder, left),
40+
call,
41+
]),
42+
);
4943
},
5044
},
5145
};
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
var _2, _3, _sum;
1+
var _ref, _ref2, _sum;
22

3-
var result = (_2 = [5, 10], (_3 = _2.map(x => x * 2), (_sum = _3.reduce((a, b) => a + b), _sum + 1)));
3+
var result = (_ref = [5, 10], (_ref2 = _ref.map(x => x * 2), (_sum = _ref2.reduce((a, b) => a + b), _sum + 1)));
44
assert.equal(result, 31);
55

66
var inc = x => x + 1;
77

88
var double = x => x * 2;
99

10-
var result2 = [4, 9].map(x => double(inc(x)));
10+
var result2 = [4, 9].map(x => {
11+
var _ref3, _x;
12+
13+
return _ref3 = (_x = x, inc(_x)), double(_ref3);
14+
});
1115
assert.deepEqual(result2, [10, 20]);
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
var _;
2+
13
var inc = x => x + 1;
24

3-
assert.equal(inc(10), 11);
5+
assert.equal((_ = 10, inc(_)), 11);
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
var _ref, _;
2+
13
var inc = x => x + 1;
24

35
var double = x => x * 2;
46

5-
assert.equal(double(inc(10)), 22);
7+
assert.equal((_ref = (_ = 10, inc(_)), double(_ref)), 22);
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
var _ref;
2+
13
var map = fn => array => array.map(fn);
24

3-
var result = map(x => x * 20)([10, 20]);
5+
var result = (_ref = [10, 20], map(x => x * 20)(_ref));
46
assert.deepEqual(result, [200, 400]);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
var obj = {
2+
get prop() {
3+
return this._prop = 1;
4+
},
5+
6+
get method() {
7+
if (!this._prop) throw new Error('invalid evaluation order');
8+
return (v) => v;
9+
}
10+
}
11+
12+
var result = obj.prop |> obj.method;
13+
assert.equal(result, 1);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
var obj = {
2+
get prop() {
3+
return this._prop = 1;
4+
},
5+
6+
get method() {
7+
if (!this._prop) throw new Error('invalid evaluation order');
8+
return (v) => v;
9+
}
10+
}
11+
12+
var result = obj.prop |> obj.method;
13+
assert.equal(result, 1);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
var _obj$prop;
2+
3+
var obj = {
4+
get prop() {
5+
return this._prop = 1;
6+
},
7+
8+
get method() {
9+
if (!this._prop) throw new Error('invalid evaluation order');
10+
return v => v;
11+
}
12+
13+
};
14+
var result = (_obj$prop = obj.prop, obj.method(_obj$prop));
15+
assert.equal(result, 1);
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
var _ref, _ref2, _;
2+
13
var inc = x => x + 1;
24

3-
var result = inc(4 || 9);
5+
var result = (_ref = 4 || 9, inc(_ref));
46
assert.equal(result, 5);
57

68
var f = x => x + 10;
79

810
var h = x => x + 20;
911

10-
var result2 = inc((f || h)(10));
12+
var result2 = (_ref2 = (_ = 10, (f || h)(_)), inc(_ref2));
1113
assert.equal(result2, 21);

0 commit comments

Comments
 (0)