mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-09-11 14:46:37 +03:00
Support logical operator unfolding in React reconcilation (#2091)
Summary: Release notes: React compiler supports unfolding && and || logical expressions This adds support for `&&` and `||` logical abstract value unfolding. Closes https://github.com/facebook/prepack/pull/2091 Differential Revision: D8386493 Pulled By: trueadm fbshipit-source-id: 3def85ac912906ada087a99c27f91ad80897c55e
This commit is contained in:
parent
9c11ec9a5e
commit
3bd3ecc072
@ -1704,6 +1704,36 @@ ReactStatistics {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, JSX output Functional component folding Component type change 11 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Foo",
|
||||
"status": "INLINED",
|
||||
},
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Bar",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 2,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, JSX output Functional component folding Component type same 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
@ -2788,6 +2818,107 @@ ReactStatistics {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, JSX output Functional component folding Simple 18 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 1,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 0,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, JSX output Functional component folding Simple 19 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 2,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, JSX output Functional component folding Simple 20 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 2,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, JSX output Functional component folding Simple 21 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 2,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 1,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, JSX output Functional component folding Simple children 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
@ -6434,6 +6565,36 @@ ReactStatistics {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, create-element output Functional component folding Component type change 11 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Foo",
|
||||
"status": "INLINED",
|
||||
},
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Bar",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 2,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, create-element output Functional component folding Component type same 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
@ -7518,6 +7679,107 @@ ReactStatistics {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, create-element output Functional component folding Simple 18 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 1,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 0,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, create-element output Functional component folding Simple 19 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 2,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, create-element output Functional component folding Simple 20 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 2,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, create-element output Functional component folding Simple 21 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 2,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 1,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with JSX input, create-element output Functional component folding Simple children 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
@ -11164,6 +11426,36 @@ ReactStatistics {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, JSX output Functional component folding Component type change 11 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Foo",
|
||||
"status": "INLINED",
|
||||
},
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Bar",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 2,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, JSX output Functional component folding Component type same 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
@ -12248,6 +12540,107 @@ ReactStatistics {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, JSX output Functional component folding Simple 18 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 1,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 0,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, JSX output Functional component folding Simple 19 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 2,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, JSX output Functional component folding Simple 20 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 2,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, JSX output Functional component folding Simple 21 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 2,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 1,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, JSX output Functional component folding Simple children 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
@ -15909,6 +16302,36 @@ ReactStatistics {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, create-element output Functional component folding Component type change 11 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Foo",
|
||||
"status": "INLINED",
|
||||
},
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Bar",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 2,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, create-element output Functional component folding Component type same 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
@ -16993,6 +17416,107 @@ ReactStatistics {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, create-element output Functional component folding Simple 18 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 1,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 0,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, create-element output Functional component folding Simple 19 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 2,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, create-element output Functional component folding Simple 20 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 2,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, create-element output Functional component folding Simple 21 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 2,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "Child",
|
||||
"status": "INLINED",
|
||||
},
|
||||
],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 1,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test React with create-element input, create-element output Functional component folding Simple children 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 3,
|
||||
|
@ -369,6 +369,22 @@ function runTestSuite(outputJsx, shouldTranspileSource) {
|
||||
await runTest(directory, "simple-17.js");
|
||||
});
|
||||
|
||||
it("Simple 18", async () => {
|
||||
await runTest(directory, "simple-18.js");
|
||||
});
|
||||
|
||||
it("Simple 19", async () => {
|
||||
await runTest(directory, "simple-19.js");
|
||||
});
|
||||
|
||||
it("Simple 20", async () => {
|
||||
await runTest(directory, "simple-20.js");
|
||||
});
|
||||
|
||||
it("Simple 21", async () => {
|
||||
await runTest(directory, "simple-21.js");
|
||||
});
|
||||
|
||||
it("Havocing of ReactElements should not result in property assignments", async () => {
|
||||
await runTest(directory, "react-element-havoc.js");
|
||||
});
|
||||
@ -622,6 +638,10 @@ function runTestSuite(outputJsx, shouldTranspileSource) {
|
||||
await runTest(directory, "type-change10.js");
|
||||
});
|
||||
|
||||
it("Component type change 11", async () => {
|
||||
await runTest(directory, "type-change11.js");
|
||||
});
|
||||
|
||||
it("Component type same", async () => {
|
||||
await runTest(directory, "type-same.js");
|
||||
});
|
||||
|
@ -167,6 +167,8 @@ function applyBranchedLogicValue(realm: Realm, value: Value): Value {
|
||||
);
|
||||
}
|
||||
);
|
||||
} else if (value instanceof AbstractValue && (value.kind === "||" || value.kind === "&&")) {
|
||||
invariant(false, "applyBranchedLogicValue encounterted a logical expression (|| or &&), this should never occur");
|
||||
} else {
|
||||
throw new ExpectedBailOut("Unsupported value encountered when applying branched logic to values");
|
||||
}
|
||||
|
@ -926,6 +926,37 @@ export class Reconciler {
|
||||
return value;
|
||||
}
|
||||
|
||||
_resolveAbstractLogicalValue(
|
||||
componentType: Value,
|
||||
value: AbstractValue,
|
||||
context: ObjectValue | AbstractObjectValue,
|
||||
evaluatedNode: ReactEvaluatedNode
|
||||
) {
|
||||
let [leftValue, rightValue] = value.args;
|
||||
let operator = value.kind;
|
||||
|
||||
invariant(leftValue instanceof AbstractValue);
|
||||
if (operator === "||") {
|
||||
return this._resolveAbstractConditionalValue(
|
||||
componentType,
|
||||
leftValue,
|
||||
leftValue,
|
||||
rightValue,
|
||||
context,
|
||||
evaluatedNode
|
||||
);
|
||||
} else {
|
||||
return this._resolveAbstractConditionalValue(
|
||||
componentType,
|
||||
leftValue,
|
||||
rightValue,
|
||||
leftValue,
|
||||
context,
|
||||
evaluatedNode
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_resolveAbstractValue(
|
||||
componentType: Value,
|
||||
value: AbstractValue,
|
||||
@ -946,6 +977,8 @@ export class Reconciler {
|
||||
context,
|
||||
evaluatedNode
|
||||
);
|
||||
} else if (value.kind === "||" || value.kind === "&&") {
|
||||
return this._resolveAbstractLogicalValue(componentType, value, context, evaluatedNode);
|
||||
} else {
|
||||
if (value instanceof AbstractValue && this.realm.react.abstractHints.has(value)) {
|
||||
let reactHint = this.realm.react.abstractHints.get(value);
|
||||
|
29
test/react/functional-components/simple-18.js
Normal file
29
test/react/functional-components/simple-18.js
Normal file
@ -0,0 +1,29 @@
|
||||
var React = require('React');
|
||||
// the JSX transform converts to React, so we need to add it back in
|
||||
this['React'] = React;
|
||||
|
||||
function App(props) {
|
||||
return (
|
||||
<div>
|
||||
{props.x || <div />}
|
||||
{props.y && <span />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
App.getTrials = function(renderer, Root) {
|
||||
let results = [];
|
||||
renderer.update(<Root x={<span />} y={true} />);
|
||||
results.push(['deals with logical expression 1', renderer.toJSON()]);
|
||||
renderer.update(<Root x={false} y={true} />);
|
||||
results.push(['deals with logical expression 2', renderer.toJSON()]);
|
||||
renderer.update(<Root x={false} y={<div />} />);
|
||||
results.push(['deals with logical expression 3', renderer.toJSON()]);
|
||||
return results;
|
||||
};
|
||||
|
||||
if (this.__optimizeReactComponentTree) {
|
||||
__optimizeReactComponentTree(App);
|
||||
}
|
||||
|
||||
module.exports = App;
|
37
test/react/functional-components/simple-19.js
Normal file
37
test/react/functional-components/simple-19.js
Normal file
@ -0,0 +1,37 @@
|
||||
var React = require('React');
|
||||
// the JSX transform converts to React, so we need to add it back in
|
||||
this['React'] = React;
|
||||
|
||||
function Child(props) {
|
||||
var x = Object.assign({}, props, {
|
||||
a: 1,
|
||||
b: 2,
|
||||
});
|
||||
return <span>{x.a}{x.b}{x.c}</span>
|
||||
}
|
||||
|
||||
function App(props) {
|
||||
return (
|
||||
<div>
|
||||
{props.x || <Child {...props} />}
|
||||
{props.y && <Child {...props} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
App.getTrials = function(renderer, Root) {
|
||||
let results = [];
|
||||
renderer.update(<Root x={<span />} y={true} c={3} />);
|
||||
results.push(['deals with logical expression 1', renderer.toJSON()]);
|
||||
renderer.update(<Root x={false} y={true} c={4} />);
|
||||
results.push(['deals with logical expression 2', renderer.toJSON()]);
|
||||
renderer.update(<Root x={false} y={<div />} c={5} />);
|
||||
results.push(['deals with logical expression 3', renderer.toJSON()]);
|
||||
return results;
|
||||
};
|
||||
|
||||
if (this.__optimizeReactComponentTree) {
|
||||
__optimizeReactComponentTree(App);
|
||||
}
|
||||
|
||||
module.exports = App;
|
40
test/react/functional-components/simple-20.js
Normal file
40
test/react/functional-components/simple-20.js
Normal file
@ -0,0 +1,40 @@
|
||||
var React = require('React');
|
||||
// the JSX transform converts to React, so we need to add it back in
|
||||
this['React'] = React;
|
||||
|
||||
function Child(props) {
|
||||
var x = Object.assign({}, props, {
|
||||
a: 1,
|
||||
b: 2,
|
||||
});
|
||||
return <span>{x.a}{x.b}{x.c}</span>
|
||||
}
|
||||
|
||||
function App(props) {
|
||||
var foo = props.x ? props.y : props.z;
|
||||
return (
|
||||
<div>
|
||||
{foo || <Child {...props} />}
|
||||
{foo && <Child {...props} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
App.getTrials = function(renderer, Root) {
|
||||
let results = [];
|
||||
renderer.update(<Root x={true} y={true} z={true} c={3} />);
|
||||
results.push(['deals with logical expression 1', renderer.toJSON()]);
|
||||
renderer.update(<Root x={true} y={true} z={false} c={3} />);
|
||||
results.push(['deals with logical expression 2', renderer.toJSON()]);
|
||||
renderer.update(<Root x={true} y={false} z={true} c={3} />);
|
||||
results.push(['deals with logical expression 3', renderer.toJSON()]);
|
||||
renderer.update(<Root x={false} y={true} z={true} c={3} />);
|
||||
results.push(['deals with logical expression 4', renderer.toJSON()]);
|
||||
return results;
|
||||
};
|
||||
|
||||
if (this.__optimizeReactComponentTree) {
|
||||
__optimizeReactComponentTree(App);
|
||||
}
|
||||
|
||||
module.exports = App;
|
32
test/react/functional-components/simple-21.js
Normal file
32
test/react/functional-components/simple-21.js
Normal file
@ -0,0 +1,32 @@
|
||||
var React = require('React');
|
||||
// the JSX transform converts to React, so we need to add it back in
|
||||
this['React'] = React;
|
||||
|
||||
function Child(props) {
|
||||
return <span>{props.x.toString()}</span>;
|
||||
}
|
||||
|
||||
function App(props) {
|
||||
return (
|
||||
<div>
|
||||
{props.x !== null && <Child {...props} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
App.getTrials = function(renderer, Root) {
|
||||
let results = [];
|
||||
renderer.update(<Root x={null} />);
|
||||
results.push(['deals with logical expression 1', renderer.toJSON()]);
|
||||
renderer.update(<Root x={5} />);
|
||||
results.push(['deals with logical expression 2', renderer.toJSON()]);
|
||||
renderer.update(<Root x={"hello world"} />);
|
||||
results.push(['deals with logical expression 3', renderer.toJSON()]);
|
||||
return results;
|
||||
};
|
||||
|
||||
if (this.__optimizeReactComponentTree) {
|
||||
__optimizeReactComponentTree(App);
|
||||
}
|
||||
|
||||
module.exports = App;
|
50
test/react/functional-components/type-change11.js
Normal file
50
test/react/functional-components/type-change11.js
Normal file
@ -0,0 +1,50 @@
|
||||
var React = require('react');
|
||||
// the JSX transform converts to React, so we need to add it back in
|
||||
this['React'] = React;
|
||||
|
||||
function App(props) {
|
||||
if (props.foo) {
|
||||
return (
|
||||
<div>
|
||||
<Foo callback={props.callback} x={props.x} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Bar callback={props.callback} x={props.x} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Foo(props) {
|
||||
return props.x || <input ref={props.callback} />;
|
||||
}
|
||||
|
||||
function Bar(props) {
|
||||
return props.x && <input ref={props.callback} />;
|
||||
}
|
||||
|
||||
if (this.__optimizeReactComponentTree) {
|
||||
__optimizeReactComponentTree(App);
|
||||
}
|
||||
|
||||
App.getTrials = function(renderer, Root) {
|
||||
let counter = 0;
|
||||
let nodes = [];
|
||||
function callback(node) {
|
||||
nodes.push(node);
|
||||
counter++;
|
||||
}
|
||||
renderer.update(<Root callback={callback} foo={true} x={true} />);
|
||||
renderer.update(<Root callback={callback} foo={true} x={false} />);
|
||||
renderer.update(<Root callback={callback} foo={false} x={false} />);
|
||||
renderer.update(<Root callback={callback} foo={false} x={true} />);
|
||||
|
||||
let results = [];
|
||||
results.push(['ensure refs was called 3 times', counter]);
|
||||
results.push(['ensure refs at 0 is not null', nodes[0] !== null]);
|
||||
return results;
|
||||
};
|
||||
|
||||
module.exports = App;
|
Loading…
Reference in New Issue
Block a user