diff --git a/doc/playground.md b/doc/playground.md index 2ee2ee9db4..79a3c23540 100644 --- a/doc/playground.md +++ b/doc/playground.md @@ -18,6 +18,7 @@ to5.transform("code", { playground: true }); * [Memoization operator](#memoization-operator) * [Method binding](#method-binding) + * [Pretzel map](#pretzel-map) ### Memoization assignment operator @@ -61,5 +62,16 @@ var fn = obj.method.bind(obj); var fn = obj.method.bind(obj, "foob"); ``` -**NOTE:** Method binding can **only** be used as an **expression** and not as -statement. +### Pretzel map + +```javascript +["foo", "bar"].map(:toUpperCase); // ["FOO", "BAR"] +[1.1234, 23.53245, 3].map(:toFixed(2)); // ["1.12", "23.53", "3.00"] +``` + +equivalent to: + +```javascript +["foo", "bar"].map(function (val) { return val.toUpperCase(); }); +[1.1234, 23.53245, 3].map(function (val) { return val.toFixed(2); }); +``` diff --git a/lib/6to5/generation/generators/playground.js b/lib/6to5/generation/generators/playground.js index 3742aa9f86..cbc57fbc0e 100644 --- a/lib/6to5/generation/generators/playground.js +++ b/lib/6to5/generation/generators/playground.js @@ -1,6 +1,6 @@ var _ = require("lodash"); -_.each(["BindMemberExpression"], function (type) { +_.each(["BindMemberExpression", "PretzelMapExpression"], function (type) { exports[type] = function () { throw new ReferenceError("Trying to render non-standard playground node " + JSON.stringify(type)); }; diff --git a/lib/6to5/patch.js b/lib/6to5/patch.js index a6049df532..d7251fca26 100644 --- a/lib/6to5/patch.js +++ b/lib/6to5/patch.js @@ -38,6 +38,12 @@ def("BindMemberExpression") .field("property", or(def("Identifier"), def("Expression"))) .field("arguments", [def("Expression")]); +def("PretzelMapExpression") + .bases("Expression") + .build("callee", "arguments") + .field("callee", def("Expression")) + .field("arguments", [def("Expression")]); + types.finalize(); var estraverse = require("estraverse"); diff --git a/lib/6to5/transformation/transform.js b/lib/6to5/transformation/transform.js index baf69321e1..ad73d6f8af 100644 --- a/lib/6to5/transformation/transform.js +++ b/lib/6to5/transformation/transform.js @@ -59,6 +59,7 @@ _.each({ // plyground methodBinding: require("./transformers/playground-method-binding"), memoizationOperator: require("./transformers/playground-memoization-operator"), + pretzelMap: require("./transformers/playground-pretzel-map"), _blockHoist: require("./transformers/_block-hoist"), _declarations: require("./transformers/_declarations"), diff --git a/lib/6to5/transformation/transformers/playground-pretzel-map.js b/lib/6to5/transformation/transformers/playground-pretzel-map.js new file mode 100644 index 0000000000..ad224793ea --- /dev/null +++ b/lib/6to5/transformation/transformers/playground-pretzel-map.js @@ -0,0 +1,29 @@ +var t = require("../../types"); +var _ = require("lodash"); + +exports.PretzelMapExpression = function (node, parent, file, scope) { + var buildCall = function (args) { + var param = file.generateUidIdentifier("val", scope); + return t.functionExpression(null, [param], t.blockStatement([ + t.returnStatement(t.callExpression(t.memberExpression(param, node.callee), args)) + ])); + }; + + if (_.find(node.arguments, t.isDynamic)) { + var argsIdName = file.generateUid("args", scope); + var argsId = t.identifier(argsIdName); + scope.push({ + key: argsIdName, + id: argsId + }); + + return t.sequenceExpression([ + t.assignmentExpression("=", argsId, t.arrayExpression(node.arguments)), + buildCall(node.arguments.map(function (node, i) { + return t.memberExpression(argsId, t.literal(i), true); + })) + ]); + } else { + return buildCall(node.arguments); + } +}; diff --git a/lib/6to5/types/visitor-keys.json b/lib/6to5/types/visitor-keys.json index 79a3902c5f..e9f57e15ca 100644 --- a/lib/6to5/types/visitor-keys.json +++ b/lib/6to5/types/visitor-keys.json @@ -44,6 +44,7 @@ "ObjectExpression": ["properties"], "ObjectPattern": ["properties"], "ParenthesizedExpression": ["expression"], + "PretzelMapExpression": ["callee", "arguments"], "Program": ["body"], "Property": ["key", "value"], "ReturnStatement": ["argument"], diff --git a/package.json b/package.json index ea40e9ee1a..7251f7460d 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "chokidar": "0.11.1", "source-map-support": "0.2.8", "esutils": "1.1.6", - "acorn-6to5": "0.9.1-8", + "acorn-6to5": "0.9.1-9", "estraverse": "1.8.0", "private": "0.1.6" }, diff --git a/test/fixtures/transformation/playground/pretzel-map/actual.js b/test/fixtures/transformation/playground/pretzel-map/actual.js new file mode 100644 index 0000000000..8fc19dd7da --- /dev/null +++ b/test/fixtures/transformation/playground/pretzel-map/actual.js @@ -0,0 +1,7 @@ +["foo", "bar"].map(:toUpperCase); +[1.1234, 23.53245, 3].map(:toFixed(2)); + +var get = function () { + return 2; +}; +[1.1234, 23.53245, 3].map(:toFixed(get())); diff --git a/test/fixtures/transformation/playground/pretzel-map/exec.js b/test/fixtures/transformation/playground/pretzel-map/exec.js new file mode 100644 index 0000000000..e9d7e3b836 --- /dev/null +++ b/test/fixtures/transformation/playground/pretzel-map/exec.js @@ -0,0 +1,7 @@ +assert.deepEqual(["foo", "bar"].map(:toUpperCase), ["FOO", "BAR"]); +assert.deepEqual([1.1234, 23.53245, 3].map(:toFixed(2)), ["1.12", "23.53", "3.00"]); + +var get = function () { + return 2; +} +assert.deepEqual([1.1234, 23.53245, 3].map(:toFixed(get())), ["1.12", "23.53", "3.00"]); diff --git a/test/fixtures/transformation/playground/pretzel-map/expected.js b/test/fixtures/transformation/playground/pretzel-map/expected.js new file mode 100644 index 0000000000..9126e9810f --- /dev/null +++ b/test/fixtures/transformation/playground/pretzel-map/expected.js @@ -0,0 +1,16 @@ +"use strict"; + +var _args; +["foo", "bar"].map(function (_val) { + return _val.toUpperCase(); +}); +[1.1234, 23.53245, 3].map(function (_val2) { + return _val2.toFixed(2); +}); + +var get = function () { + return 2; +}; +[1.1234, 23.53245, 3].map((_args = [get()], function (_val3) { + return _val3.toFixed(_args[0]); +}));