Mark hoisted react constant elements as #__PURE__ (#7372)

This commit is contained in:
Mateusz Burzyński 2018-02-21 18:58:56 +01:00 committed by GitHub
parent d75a6b8468
commit d283324f8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 180 additions and 57 deletions

View File

@ -4,7 +4,9 @@ function action() {
return _action.apply(this, arguments);
}
var _ref = React.createElement(Contact, {
var _ref =
/*#__PURE__*/
React.createElement(Contact, {
title: title
});

View File

@ -8,6 +8,9 @@
"keywords": [
"babel-plugin"
],
"dependencies": {
"@babel/helper-annotate-as-pure": "7.0.0-beta.40"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.40"
},

View File

@ -1,4 +1,5 @@
import { types as t } from "@babel/core";
import annotateAsPure from "@babel/helper-annotate-as-pure";
export default function transformReactConstantElement(api, options) {
const { allowMutablePropsOnTags } = options;
@ -101,7 +102,11 @@ export default function transformReactConstantElement(api, options) {
path.traverse(immutabilityVisitor, state);
if (state.isImmutable) {
path.hoist();
const hoisted = path.hoist();
if (hoisted) {
annotateAsPure(hoisted);
}
}
},
},

View File

@ -1,10 +1,14 @@
var _ref = <div>child</div>;
var _ref =
/*#__PURE__*/
<div>child</div>;
const AppItem = () => {
return _ref;
};
var _ref2 = <div>
var _ref2 =
/*#__PURE__*/
<div>
<p>Parent</p>
<AppItem />
</div>;

View File

@ -1,6 +1,10 @@
var _ref2 = <div>child</div>;
var _ref2 =
/*#__PURE__*/
<div>child</div>;
var _ref3 = <p>Parent</p>;
var _ref3 =
/*#__PURE__*/
<p>Parent</p>;
(function () {
class App extends React.Component {
@ -13,7 +17,9 @@ var _ref3 = <p>Parent</p>;
const AppItem = () => {
return _ref2;
},
_ref = <div>
_ref =
/*#__PURE__*/
<div>
{_ref3}
<AppItem />
</div>;

View File

@ -1,13 +1,19 @@
var _ref = <div>child</div>;
var _ref =
/*#__PURE__*/
<div>child</div>;
var _ref3 = <p>Parent</p>;
var _ref3 =
/*#__PURE__*/
<p>Parent</p>;
(function () {
const AppItem = () => {
return _ref;
};
var _ref2 = <div>
var _ref2 =
/*#__PURE__*/
<div>
{_ref3}
<AppItem />
</div>;

View File

@ -5,12 +5,16 @@ export default class App extends React.Component {
}
var _ref2 = <div>child</div>;
var _ref2 =
/*#__PURE__*/
<div>child</div>;
const AppItem = () => {
return _ref2;
},
_ref = <div>
_ref =
/*#__PURE__*/
<div>
<p>Parent</p>
<AppItem />
</div>;

View File

@ -1,4 +1,6 @@
var _ref = <span />;
var _ref =
/*#__PURE__*/
<span />;
var Foo = React.createClass({
render: function () {

View File

@ -1,6 +1,8 @@
import React from 'react'; // Regression test for https://github.com/babel/babel/issues/5552
var _ref = <div />;
var _ref =
/*#__PURE__*/
<div />;
class BugReport extends React.Component {
constructor(...args) {

View File

@ -1,9 +1,13 @@
import React from 'react';
import Loader from 'loader';
var _ref = <Loader className="full-height" />;
var _ref =
/*#__PURE__*/
<Loader className="full-height" />;
var _ref2 = <Loader className="p-y-5" />;
var _ref2 =
/*#__PURE__*/
<Loader className="p-y-5" />;
const errorComesHere = () => _ref,
thisWorksFine = () => _ref2;

View File

@ -1,6 +1,8 @@
var Foo = require("Foo");
var _ref = <Foo />;
var _ref =
/*#__PURE__*/
<Foo />;
function render() {
return _ref;

View File

@ -1,6 +1,10 @@
var _ref = <b></b>;
var _ref =
/*#__PURE__*/
<b></b>;
var _ref2 = <span></span>;
var _ref2 =
/*#__PURE__*/
<span></span>;
function render() {
var children = _ref;

View File

@ -4,11 +4,15 @@ const Parent = ({}) => _ref;
export default Parent;
var _ref2 = <div className="child">
var _ref2 =
/*#__PURE__*/
<div className="child">
ChildTextContent
</div>;
let Child = () => _ref2,
_ref = <div className="parent">
_ref =
/*#__PURE__*/
<div className="parent">
<Child />
</div>;

View File

@ -1,6 +1,8 @@
function render() {
const bar = "bar",
_ref = <foo bar={bar} />,
_ref =
/*#__PURE__*/
<foo bar={bar} />,
renderFoo = () => _ref;
return renderFoo();
@ -10,7 +12,9 @@ function render() {
const bar = "bar",
renderFoo = () => _ref2,
baz = "baz",
_ref2 = <foo bar={bar} baz={baz} />;
_ref2 =
/*#__PURE__*/
<foo bar={bar} baz={baz} />;
return renderFoo();
}

View File

@ -1,7 +1,9 @@
function render() {
var title = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var _ref = <Component title={title} />;
var _ref =
/*#__PURE__*/
<Component title={title} />;
return () => _ref;
}

View File

@ -1,6 +1,8 @@
function render(Component) {
var text = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '',
_ref = <Component text={text} />;
_ref =
/*#__PURE__*/
<Component text={text} />;
return function () {
return _ref;

View File

@ -6,7 +6,9 @@ const Parent = ({}) => _ref;
export default Parent;
var _ref2 = <div className="child">
var _ref2 =
/*#__PURE__*/
<div className="child">
ChildTextContent
</div>;
@ -14,6 +16,8 @@ let Child = () => _ref2;
Child = HOC(Child);
var _ref = <div className="parent">
var _ref =
/*#__PURE__*/
<div className="parent">
<Child />
</div>;

View File

@ -1,5 +1,7 @@
function render(text) {
var _ref = <foo>{text}</foo>;
var _ref =
/*#__PURE__*/
<foo>{text}</foo>;
return function () {
return _ref;
@ -9,7 +11,9 @@ function render(text) {
var Foo2 = require("Foo");
function createComponent(text) {
var _ref2 = <Foo2>{text}</Foo2>;
var _ref2 =
/*#__PURE__*/
<Foo2>{text}</Foo2>;
return function render() {
return _ref2;

View File

@ -1,4 +1,6 @@
var _ref = <div foo={notDeclared}></div>;
var _ref =
/*#__PURE__*/
<div foo={notDeclared}></div>;
var Foo = React.createClass({
render: function render() {

View File

@ -1,10 +1,14 @@
var _ref = <foo />;
var _ref =
/*#__PURE__*/
<foo />;
function render() {
return _ref;
}
var _ref2 = <div className="foo"><input type="checkbox" checked={true} /></div>;
var _ref2 =
/*#__PURE__*/
<div className="foo"><input type="checkbox" checked={true} /></div>;
function render() {
return _ref2;

View File

@ -2,7 +2,9 @@ var REACT_ELEMENT_TYPE;
function _jsx(type, props, key, children) { if (!REACT_ELEMENT_TYPE) { REACT_ELEMENT_TYPE = typeof Symbol === "function" && Symbol.for && Symbol.for("react.element") || 0xeac7; } var defaultProps = type && type.defaultProps; var childrenLength = arguments.length - 3; if (!props && childrenLength !== 0) { props = { children: void 0 }; } if (props && defaultProps) { for (var propName in defaultProps) { if (props[propName] === void 0) { props[propName] = defaultProps[propName]; } } } else if (!props) { props = defaultProps || {}; } if (childrenLength === 1) { props.children = children; } else if (childrenLength > 1) { var childArray = new Array(childrenLength); for (var i = 0; i < childrenLength; i++) { childArray[i] = arguments[i + 3]; } props.children = childArray; } return { $$typeof: REACT_ELEMENT_TYPE, type: type, key: key === undefined ? null : '' + key, ref: null, props: props, _owner: null }; }
var _ref = _jsx("foo", {});
var _ref =
/*#__PURE__*/
_jsx("foo", {});
function render() {
return _ref;
@ -11,7 +13,9 @@ function render() {
function render() {
var text = getText();
var _ref2 = _jsx("foo", {}, void 0, text);
var _ref2 =
/*#__PURE__*/
_jsx("foo", {}, void 0, text);
return function () {
return _ref2;

View File

@ -1,7 +1,9 @@
function render() {
var text = getText();
var _ref = <foo>{text}</foo>;
var _ref =
/*#__PURE__*/
<foo>{text}</foo>;
return function () {
return _ref;

View File

@ -1,7 +1,9 @@
function render() {
this.component = "div";
var _ref = <this.component />;
var _ref =
/*#__PURE__*/
<this.component />;
return () => _ref;
}

View File

@ -1,10 +1,14 @@
var _ref = <span>Sub Component</span>;
var _ref =
/*#__PURE__*/
<span>Sub Component</span>;
class Component extends React.Component {
constructor(...args) {
var _temp;
var _ref2 = <this.subComponent />;
var _ref2 =
/*#__PURE__*/
<this.subComponent />;
return _temp = super(...args), this.subComponent = () => _ref, this.render = () => _ref2, _temp;
}

View File

@ -1,10 +1,14 @@
var _ref = <span>Sub Component</span>;
var _ref =
/*#__PURE__*/
<span>Sub Component</span>;
const els = {
subComponent: () => _ref
};
var _ref2 = <els.subComponent />;
var _ref2 =
/*#__PURE__*/
<els.subComponent />;
class Component extends React.Component {
constructor(...args) {

View File

@ -1,6 +1,8 @@
function fn(Component, obj) {
var data = obj.data,
_ref = <Component prop={data} />;
_ref =
/*#__PURE__*/
<Component prop={data} />;
return () => _ref;
}

View File

@ -3,7 +3,9 @@ function render(_ref) {
className = _ref.className,
id = _ref.id;
var _ref2 = <Component text={text} className={className} id={id} />;
var _ref2 =
/*#__PURE__*/
<Component text={text} className={className} id={id} />;
return () => _ref2;
}

View File

@ -4,7 +4,9 @@ function render(_ref) {
id = _ref.id,
props = babelHelpers.objectWithoutProperties(_ref, ["text", "className", "id"]);
var _ref2 = <Component text={text} className={className} id={id} />;
var _ref2 =
/*#__PURE__*/
<Component text={text} className={className} id={id} />;
// intentionally ignoring props
return () => _ref2;

View File

@ -1,7 +1,9 @@
function render(_ref) {
let text = _ref.text;
var _ref2 = <Component text={text} />;
var _ref2 =
/*#__PURE__*/
<Component text={text} />;
return () => _ref2;
}

View File

@ -1,5 +1,7 @@
function render(text) {
var _ref = <div>{text}</div>;
var _ref =
/*#__PURE__*/
<div>{text}</div>;
return function () {
return _ref;

View File

@ -1,5 +1,7 @@
function render(offset) {
var _ref = <div tabIndex={offset + 1} />;
var _ref =
/*#__PURE__*/
<div tabIndex={offset + 1} />;
return function () {
return _ref;

View File

@ -1,6 +1,8 @@
const OFFSET = 3;
var _ref = <div tabIndex={OFFSET + 1} />;
var _ref =
/*#__PURE__*/
<div tabIndex={OFFSET + 1} />;
var Foo = React.createClass({
render: function () {

View File

@ -1,6 +1,8 @@
import Intl from 'react-intl';
var _ref = <Intl.FormattedMessage id="someMessage.foo" defaultMessage={"Some text, " + "and some more too. {someValue}"} description="A test message for babel." values={{
var _ref =
/*#__PURE__*/
<Intl.FormattedMessage id="someMessage.foo" defaultMessage={"Some text, " + "and some more too. {someValue}"} description="A test message for babel." values={{
someValue: "A value."
}} />;

View File

@ -1,4 +1,6 @@
var _ref = <FormattedMessage id="someMessage.foo" defaultMessage={"Some text, " + "and some more too. {someValue}"} description="A test message for babel." values={{
var _ref =
/*#__PURE__*/
<FormattedMessage id="someMessage.foo" defaultMessage={"Some text, " + "and some more too. {someValue}"} description="A test message for babel." values={{
someValue: "A value."
}} />;

View File

@ -1,4 +1,6 @@
var _ref = <div data-text={"Some text, " + "and some more too."} />;
var _ref =
/*#__PURE__*/
<div data-text={"Some text, " + "and some more too."} />;
var Foo = React.createClass({
render: function () {

View File

@ -1,7 +1,9 @@
function render(text) {
text += "yes";
var _ref = <div>{text}</div>;
var _ref =
/*#__PURE__*/
<div>{text}</div>;
return function () {
return _ref;

View File

@ -7,4 +7,6 @@ class A {
export default class B {}
var _ref = React.createElement(B, null);
var _ref =
/*#__PURE__*/
React.createElement(B, null);

View File

@ -7,4 +7,6 @@ class A {
export class B {}
var _ref = React.createElement(B, null);
var _ref =
/*#__PURE__*/
React.createElement(B, null);

View File

@ -1,4 +1,6 @@
var _ref = <div className="class-name">
var _ref =
/*#__PURE__*/
<div className="class-name">
Text
</div>;

View File

@ -1,6 +1,8 @@
function fn(Component) {
var data = "prop",
_ref = <Component prop={data} />;
_ref =
/*#__PURE__*/
<Component prop={data} />;
return () => _ref;
}

View File

@ -1,4 +1,6 @@
var _ref = <div className="navbar-header">
var _ref =
/*#__PURE__*/
<div className="navbar-header">
<a className="navbar-brand" href="/">
<img src="/img/logo/logo-96x36.png" />
</a>

View File

@ -206,10 +206,11 @@ export default class PathHoister {
// generate declaration and insert it to our point
let uid = attachTo.scope.generateUidIdentifier("ref");
const declarator = t.variableDeclarator(uid, this.path.node);
const insertFn = this.attachAfter ? "insertAfter" : "insertBefore";
attachTo[insertFn]([
const [attached] = attachTo[insertFn]([
attachTo.isVariableDeclarator()
? declarator
: t.variableDeclaration("var", [declarator]),
@ -223,5 +224,9 @@ export default class PathHoister {
}
this.path.replaceWith(t.cloneNode(uid));
return attachTo.isVariableDeclarator()
? attached.get("init")
: attached.get("declarations.0.init");
}
}