From 194092e7290c2a2e50e0263bac67686df418b915 Mon Sep 17 00:00:00 2001 From: Adam Miskiewicz Date: Mon, 8 Feb 2016 15:00:42 -0800 Subject: [PATCH] Adding 'transform-symbol-member' transform to preset. Summary: Turns out, even after discussion that was had in https://github.com/facebook/react-native/pull/5294#issuecomment-174397103, we really do need this transform. I've just included it in the preset...let me know if you all would rather publish to npm. The actual reason why this is necessary is because in the latest sync from FB, fbjs was updated to use the `Symbol.iterator` express in it's isEmpty function: https://github.com/facebook/fbjs/commit/064a484e18b03f988f9eb540255ef8d742301c8d We use this in RN in the ListView...and this change (once #5084 is merged) will cause ListView to break on older JSC context's. This resolves that, and is probably something we should have had all along. Closes https://github.com/facebook/react-native/pull/5824 Reviewed By: svcscm Differential Revision: D2913315 Pulled By: vjeux fb-gh-sync-id: abaf484a9431b3111e8118d01db8d2c0d2dd73ca shipit-source-id: abaf484a9431b3111e8118d01db8d2c0d2dd73ca --- babel-preset/configs/main.js | 1 + babel-preset/package.json | 2 +- .../transforms/transform-symbol-member.js | 61 +++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 babel-preset/transforms/transform-symbol-member.js diff --git a/babel-preset/configs/main.js b/babel-preset/configs/main.js index 204028fbb..3322812bd 100644 --- a/babel-preset/configs/main.js +++ b/babel-preset/configs/main.js @@ -36,6 +36,7 @@ module.exports = { 'transform-react-jsx', 'transform-regenerator', ['transform-es2015-for-of', { loose: true }], + require('../transforms/transform-symbol-member'), ]), retainLines: true, sourceMaps: false, diff --git a/babel-preset/package.json b/babel-preset/package.json index b442ab23c..0ab0579b1 100644 --- a/babel-preset/package.json +++ b/babel-preset/package.json @@ -1,6 +1,6 @@ { "name": "babel-preset-react-native", - "version": "1.2.4", + "version": "1.4.0", "description": "Babel preset for React Native applications", "main": "index.js", "repository": "https://github.com/facebook/react-native/tree/master/babel-preset", diff --git a/babel-preset/transforms/transform-symbol-member.js b/babel-preset/transforms/transform-symbol-member.js new file mode 100644 index 000000000..305eb3c2d --- /dev/null +++ b/babel-preset/transforms/transform-symbol-member.js @@ -0,0 +1,61 @@ +/** + * Copyright 2004-present Facebook. All Rights Reserved. + */ + +'use strict'; + +/*eslint consistent-return: 0*/ + +/** + * Transforms function properties of the `Symbol` into + * the presence check, and fallback string "@@". + * + * Example: + * + * Symbol.iterator; + * + * Transformed to: + * + * typeof Symbol.iterator === 'function' ? Symbol.iterator : '@@iterator'; + */ +module.exports = function symbolMember(babel) { + const t = babel.types; + + return { + visitor: { + MemberExpression(path) { + let node = path.node; + + if (!isAppropriateMember(node)) { + return; + } + + path.replaceWith( + t.conditionalExpression( + t.binaryExpression( + '===', + t.unaryExpression( + 'typeof', + t.identifier('Symbol'), + true + ), + t.stringLiteral('function') + ), + node, + t.stringLiteral(`@@${node.property.name}`) + ) + ); + + // We should stop to avoid infinite recursion, since Babel + // traverses replaced path, and again would hit our transform. + path.stop(); + }, + }, + }; +}; + +function isAppropriateMember(node) { + return node.object.type === 'Identifier' && + node.object.name === 'Symbol' && + node.property.type === 'Identifier'; +}