Merge pull request #4940 from appden/fix-react-constant-elements
Fix React constant element bugs
This commit is contained in:
@@ -305,14 +305,14 @@ class BlockScoping {
|
||||
this.remap();
|
||||
}
|
||||
|
||||
this.updateScopeInfo();
|
||||
this.updateScopeInfo(needsClosure);
|
||||
|
||||
if (this.loopLabel && !t.isLabeledStatement(this.loopParent)) {
|
||||
return t.labeledStatement(this.loopLabel, this.loop);
|
||||
}
|
||||
}
|
||||
|
||||
updateScopeInfo() {
|
||||
updateScopeInfo(wrappedInClosure) {
|
||||
let scope = this.scope;
|
||||
let parentScope = scope.getFunctionParent();
|
||||
let letRefs = this.letReferences;
|
||||
@@ -323,7 +323,12 @@ class BlockScoping {
|
||||
if (!binding) continue;
|
||||
if (binding.kind === "let" || binding.kind === "const") {
|
||||
binding.kind = "var";
|
||||
scope.moveBindingTo(ref.name, parentScope);
|
||||
|
||||
if (wrappedInClosure) {
|
||||
scope.removeBinding(ref.name);
|
||||
} else {
|
||||
scope.moveBindingTo(ref.name, parentScope);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
function render() {
|
||||
const bar = "bar", renderFoo = () => <foo bar={bar} />;
|
||||
|
||||
return renderFoo();
|
||||
}
|
||||
|
||||
function render() {
|
||||
const bar = "bar", renderFoo = () => <foo bar={bar} baz={baz} />, baz = "baz";
|
||||
|
||||
return renderFoo();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
function render() {
|
||||
const bar = "bar",
|
||||
_ref = <foo bar={bar} />,
|
||||
renderFoo = () => _ref;
|
||||
|
||||
return renderFoo();
|
||||
}
|
||||
|
||||
function render() {
|
||||
const bar = "bar",
|
||||
renderFoo = () => <foo bar={bar} baz={baz} />,
|
||||
baz = "baz";
|
||||
|
||||
return renderFoo();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
function render(flag) {
|
||||
if (flag) {
|
||||
let bar = "bar";
|
||||
|
||||
[].map(() => bar);
|
||||
|
||||
return <foo bar={bar} />;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
function render(flag) {
|
||||
if (flag) {
|
||||
var _ret = function () {
|
||||
var bar = "bar";
|
||||
|
||||
[].map(() => bar);
|
||||
|
||||
return {
|
||||
v: <foo bar={bar} />
|
||||
};
|
||||
}();
|
||||
|
||||
if (typeof _ret === "object") return _ret.v;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugins": [
|
||||
"syntax-jsx",
|
||||
"transform-es2015-block-scoping",
|
||||
"transform-react-constant-elements"
|
||||
]
|
||||
}
|
||||
@@ -83,7 +83,7 @@ export default class PathHoister {
|
||||
if (binding.kind === "param") continue;
|
||||
|
||||
// if this binding appears after our attachment point then don't hoist it
|
||||
if (binding.path.getStatementParent().key > path.key) return;
|
||||
if (this.getAttachmentParentForPath(binding.path).key > path.key) return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,16 +105,25 @@ export default class PathHoister {
|
||||
return scope.path.get("body").get("body")[0];
|
||||
} else {
|
||||
// doesn't need to be be attached to this scope
|
||||
return this.getNextScopeStatementParent();
|
||||
return this.getNextScopeAttachmentParent();
|
||||
}
|
||||
} else if (scope.path.isProgram()) {
|
||||
return this.getNextScopeStatementParent();
|
||||
return this.getNextScopeAttachmentParent();
|
||||
}
|
||||
}
|
||||
|
||||
getNextScopeStatementParent() {
|
||||
getNextScopeAttachmentParent() {
|
||||
let scope = this.scopes.pop();
|
||||
if (scope) return scope.path.getStatementParent();
|
||||
if (scope) return this.getAttachmentParentForPath(scope.path);
|
||||
}
|
||||
|
||||
getAttachmentParentForPath(path) {
|
||||
do {
|
||||
if (!path.parentPath ||
|
||||
(Array.isArray(path.container) && path.isStatement()) ||
|
||||
(path.isVariableDeclarator() && path.parentPath.node.declarations.length > 1))
|
||||
return path;
|
||||
} while ((path = path.parentPath));
|
||||
}
|
||||
|
||||
hasOwnParamBindings(scope) {
|
||||
@@ -144,10 +153,10 @@ export default class PathHoister {
|
||||
|
||||
// generate declaration and insert it to our point
|
||||
let uid = attachTo.scope.generateUidIdentifier("ref");
|
||||
let declarator = t.variableDeclarator(uid, this.path.node);
|
||||
|
||||
attachTo.insertBefore([
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(uid, this.path.node)
|
||||
])
|
||||
attachTo.isVariableDeclarator() ? declarator : t.variableDeclaration("var", [declarator])
|
||||
]);
|
||||
|
||||
let parent = this.path.parentPath;
|
||||
|
||||
Reference in New Issue
Block a user