Merge branch 'master' into merge-master

# Conflicts:
#	lerna.json
#	packages/babel-cli/package.json
#	packages/babel-core/package.json
#	packages/babel-generator/package.json
#	packages/babel-helper-builder-react-jsx/package.json
#	packages/babel-helper-function-name/package.json
#	packages/babel-helper-optimise-call-expression/package.json
#	packages/babel-helper-replace-supers/package.json
#	packages/babel-helper-transform-fixture-test-runner/package.json
#	packages/babel-helpers/package.json
#	packages/babel-plugin-transform-class-properties/package.json
#	packages/babel-plugin-transform-es2015-block-scoping/package.json
#	packages/babel-plugin-transform-es2015-classes/package.json
#	packages/babel-plugin-transform-es2015-modules-commonjs/package.json
#	packages/babel-plugin-transform-es2015-modules-systemjs/package.json
#	packages/babel-plugin-transform-es2015-modules-umd/package.json
#	packages/babel-plugin-transform-es2015-parameters/package.json
#	packages/babel-plugin-transform-react-jsx/package.json
#	packages/babel-register/package.json
#	packages/babel-template/package.json
#	packages/babel-traverse/package.json
#	packages/babel/package.json
This commit is contained in:
Daniel Tschinder
2017-02-14 12:46:11 +01:00
87 changed files with 830 additions and 256 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "babel-plugin-transform-react-constant-elements",
"version": "6.22.0",
"version": "6.23.0",
"description": "Treat React JSX elements as value types and hoist them to the highest scope",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-constant-elements",
"license": "MIT",

View File

@@ -1,4 +1,4 @@
export default function () {
export default function ({ types: t }) {
const immutabilityVisitor = {
enter(path, state) {
const stop = () => {
@@ -11,15 +11,39 @@ export default function () {
return;
}
// Elements with refs are not safe to hoist.
if (path.isJSXIdentifier({ name: "ref" }) && path.parentPath.isJSXAttribute({ name: path.node })) {
return stop();
}
// Ignore identifiers & JSX expressions.
if (path.isJSXIdentifier() || path.isIdentifier() || path.isJSXMemberExpression()) {
return;
}
if (!path.isImmutable()) stop();
if (!path.isImmutable()) {
// If it's not immutable, it may still be a pure expression, such as string concatenation.
// It is still safe to hoist that, so long as its result is immutable.
// If not, it is not safe to replace as mutable values (like objects) could be mutated after render.
// https://github.com/facebook/react/issues/3226
if (path.isPure()) {
const expressionResult = path.evaluate();
if (expressionResult.confident) {
// We know the result; check its mutability.
const { value } = expressionResult;
const isMutable = (value && typeof value === "object") || (typeof value === "function");
if (!isMutable) {
// It evaluated to an immutable value, so we can hoist it.
return;
}
} else if (t.isIdentifier(expressionResult.deopt)) {
// It's safe to hoist here if the deopt reason is an identifier (e.g. func param).
// The hoister will take care of how high up it can be hoisted.
return;
}
}
stop();
}
}
};

View File

@@ -1,18 +1,19 @@
var _ref = <p>Parent</p>;
var _ref2 = <div>child</div>;
var _ref3 = <p>Parent</p>;
(function () {
class App extends React.Component {
render() {
return <div>
{_ref}
<AppItem />
</div>;
return _ref;
}
}
const AppItem = () => {
return _ref2;
};
});
},
_ref = <div>
{_ref3}
<AppItem />
</div>;
});

View File

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

View File

@@ -0,0 +1,15 @@
import React from "react";
const Parent = ({}) => (
<div className="parent">
<Child/>
</div>
);
export default Parent;
let Child = () => (
<div className="child">
ChildTextContent
</div>
);

View File

@@ -0,0 +1,13 @@
import React from "react";
const Parent = ({}) => _ref;
export default Parent;
let _ref2 = <div className="child">
ChildTextContent
</div>,
Child = () => _ref2,
_ref = <div className="parent">
<Child />
</div>;

View File

@@ -8,8 +8,9 @@ function render() {
function render() {
const bar = "bar",
renderFoo = () => <foo bar={bar} baz={baz} />,
baz = "baz";
renderFoo = () => _ref2,
baz = "baz",
_ref2 = <foo bar={bar} baz={baz} />;
return renderFoo();
}

View File

@@ -0,0 +1,18 @@
import React from "react";
const HOC = component => component;
const Parent = ({}) => (
<div className="parent">
<Child/>
</div>
);
export default Parent;
let Child = () => (
<div className="child">
ChildTextContent
</div>
);
Child = HOC(Child);

View File

@@ -0,0 +1,18 @@
import React from "react";
const HOC = component => component;
const Parent = ({}) => _ref;
export default Parent;
var _ref2 = <div className="child">
ChildTextContent
</div>;
let Child = () => _ref2;
Child = HOC(Child);
var _ref = <div className="parent">
<Child />
</div>;

View File

@@ -1,17 +1,11 @@
function render(flag) {
if (flag) {
var _ret = function () {
var bar = "bar";
var bar = "bar";
[].map(() => bar);
[].map(() => bar);
return {
v: <foo bar={bar} />
};
}();
if (typeof _ret === "object") return _ret.v;
return <foo bar={bar} />;
}
return null;
}
}

View File

@@ -0,0 +1,4 @@
function render() {
this.component = "div";
return () => <this.component />;
}

View File

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

View File

@@ -0,0 +1,5 @@
class Component extends React.Component {
subComponent = () => <span>Sub Component</span>
render = () => <this.subComponent />
}

View File

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

View File

@@ -0,0 +1,3 @@
{
"plugins": ["syntax-jsx", "transform-react-constant-elements", "transform-class-properties"]
}

View File

@@ -0,0 +1,6 @@
const els = {
subComponent: () => <span>Sub Component</span>
};
class Component extends React.Component {
render = () => <els.subComponent />
}

View File

@@ -0,0 +1,16 @@
var _ref = <span>Sub Component</span>;
const els = {
subComponent: () => _ref
};
var _ref2 = <els.subComponent />;
class Component extends React.Component {
constructor(...args) {
var _temp;
return _temp = super(...args), this.render = () => _ref2, _temp;
}
}

View File

@@ -0,0 +1,3 @@
{
"plugins": ["syntax-jsx", "transform-react-constant-elements", "transform-class-properties"]
}

View File

@@ -0,0 +1,5 @@
// https://github.com/facebook/react/issues/3226
// Not safe to reuse because it is mutable
function render() {
return <div style={{ width: 100 }} />;
}

View File

@@ -0,0 +1,5 @@
// https://github.com/facebook/react/issues/3226
// Not safe to reuse because it is mutable
function render() {
return <div style={{ width: 100 }} />;
}

View File

@@ -0,0 +1,5 @@
function render(offset) {
return function () {
return <div tabIndex={offset + 1} />;
};
}

View File

@@ -0,0 +1,8 @@
function render(offset) {
var _ref = <div tabIndex={offset + 1} />;
return function () {
return _ref;
};
}

View File

@@ -0,0 +1,10 @@
const OFFSET = 3;
var Foo = React.createClass({
render: function () {
return (
<div tabIndex={OFFSET + 1} />
);
}
});

View File

@@ -0,0 +1,10 @@
const OFFSET = 3;
var _ref = <div tabIndex={OFFSET + 1} />;
var Foo = React.createClass({
render: function () {
return _ref;
}
});

View File

@@ -0,0 +1,11 @@
var Foo = React.createClass({
render: function () {
return (
<div data-text={
"Some text, " +
"and some more too."
} />
);
}
});

View File

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