mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-10-26 23:32:02 +03:00
Improve fb-www mocks objectWithoutProperties
value by ensuring we store known values (#2194)
Summary: Release notes: none When the `objectWithoutProperties` mock was originally created, my knowledge of Prepack's internals wasn't as good as it was now. Now that I understand how AbstractObjectValues work, we can safely add the known values in `objectWithoutProperties` to the abstract backing object. The backing object was missing these values before and was an empty empty that was partial. This should give more data and value on our internal bundle, where before the values would be lost unnecessarily. Closes https://github.com/facebook/prepack/pull/2194 Differential Revision: D8716289 Pulled By: trueadm fbshipit-source-id: 451065473ea09943831f75c0bc15490e73c8d947
This commit is contained in:
parent
5159b0d832
commit
67a47fd48f
20299
scripts/__snapshots__/test-react.js.snap
Normal file
20299
scripts/__snapshots__/test-react.js.snap
Normal file
File diff suppressed because it is too large
Load Diff
1171
scripts/test-react.js
Normal file
1171
scripts/test-react.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -10,6 +10,7 @@
|
||||
/* @flow */
|
||||
|
||||
import type { Realm } from "../../realm.js";
|
||||
import { ValuesDomain } from "../../domains/index.js";
|
||||
import {
|
||||
ArrayValue,
|
||||
AbstractValue,
|
||||
@ -81,6 +82,25 @@ function createBabelHelpers(realm: Realm, global: ObjectValue | AbstractObjectVa
|
||||
});
|
||||
inheritsValue.intrinsicName = `babelHelpers.inherits`;
|
||||
|
||||
const createObjectWithoutProperties = (obj: ObjectValue, keys: ArrayValue) => {
|
||||
let removeKeys = new Set();
|
||||
forEachArrayValue(realm, keys, key => {
|
||||
if (key instanceof StringValue || key instanceof NumberValue) {
|
||||
removeKeys.add(key.value);
|
||||
}
|
||||
});
|
||||
let newObject = Create.ObjectCreate(realm, realm.intrinsics.ObjectPrototype);
|
||||
for (let [propName, binding] of obj.properties) {
|
||||
if (!removeKeys.has(propName)) {
|
||||
if (binding && binding.descriptor && binding.descriptor.enumerable) {
|
||||
let value = Get(realm, obj, propName);
|
||||
Properties.Set(realm, newObject, propName, value, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return newObject;
|
||||
};
|
||||
|
||||
//babelHelpers.objectWithoutProperties
|
||||
let objectWithoutPropertiesValue = new NativeFunctionValue(
|
||||
realm,
|
||||
@ -90,38 +110,33 @@ function createBabelHelpers(realm: Realm, global: ObjectValue | AbstractObjectVa
|
||||
(context, [obj, keys]) => {
|
||||
invariant(obj instanceof ObjectValue || obj instanceof AbstractObjectValue || obj instanceof AbstractValue);
|
||||
invariant(keys instanceof ArrayValue);
|
||||
if (obj.isPartialObject() || obj instanceof AbstractObjectValue || obj instanceof AbstractValue) {
|
||||
if (obj.mightBeObject() && ((obj instanceof AbstractValue && obj.values.isTop()) || obj.isPartialObject())) {
|
||||
let temporalArgs = [objectWithoutPropertiesValue, obj, keys];
|
||||
let temporalConfig = { skipInvariant: true, isPure: true };
|
||||
let value = AbstractValue.createTemporalFromBuildFunction(
|
||||
realm,
|
||||
ObjectValue,
|
||||
[objectWithoutPropertiesValue, obj, keys],
|
||||
temporalArgs,
|
||||
([methodNode, objNode, propRemoveNode]) => {
|
||||
return t.callExpression(methodNode, [objNode, propRemoveNode]);
|
||||
},
|
||||
{ skipInvariant: true, isPure: true }
|
||||
temporalConfig
|
||||
);
|
||||
if (value instanceof AbstractObjectValue) {
|
||||
// as we are returning an abstract object, we mark it as simple
|
||||
value.makeSimple();
|
||||
invariant(value instanceof AbstractObjectValue);
|
||||
if (obj instanceof ObjectValue) {
|
||||
let template = createObjectWithoutProperties(obj, keys);
|
||||
value.values = new ValuesDomain(template);
|
||||
}
|
||||
// Store the args for the temporal so we can easily clone
|
||||
// and reconstruct the temporal at another point, rather than
|
||||
// mutate the existing temporal
|
||||
realm.temporalAliasArgs.set(value, temporalArgs);
|
||||
// as we are returning an abstract object, we mark it as simple
|
||||
value.makeSimple();
|
||||
return value;
|
||||
} else {
|
||||
let removeKeys = new Set();
|
||||
forEachArrayValue(realm, keys, key => {
|
||||
if (key instanceof StringValue || key instanceof NumberValue) {
|
||||
removeKeys.add(key.value);
|
||||
}
|
||||
});
|
||||
let newObject = Create.ObjectCreate(realm, realm.intrinsics.ObjectPrototype);
|
||||
for (let [propName, binding] of obj.properties) {
|
||||
if (!removeKeys.has(propName)) {
|
||||
if (binding && binding.descriptor && binding.descriptor.enumerable) {
|
||||
let value = Get(realm, obj, propName);
|
||||
Properties.Set(realm, newObject, propName, value, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return newObject;
|
||||
invariant(obj instanceof ObjectValue);
|
||||
return createObjectWithoutProperties(obj, keys);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -127,6 +127,14 @@ it("fb-www 23", () => {
|
||||
runTest(__dirname + "/FBMocks/fb23.js");
|
||||
});
|
||||
|
||||
it("fb-www 24", () => {
|
||||
runTest(__dirname + "/FBMocks/fb24.js");
|
||||
});
|
||||
|
||||
it("fb-www 25", () => {
|
||||
runTest(__dirname + "/FBMocks/fb25.js");
|
||||
});
|
||||
|
||||
it("repl example", () => {
|
||||
runTest(__dirname + "/FBMocks/repl-example.js");
|
||||
});
|
||||
|
59
test/react/FBMocks/fb24.js
Normal file
59
test/react/FBMocks/fb24.js
Normal file
@ -0,0 +1,59 @@
|
||||
var React = require("react");
|
||||
|
||||
// FB www polyfill
|
||||
if (!this.babelHelpers) {
|
||||
this.babelHelpers = {
|
||||
inherits(subClass, superClass) {
|
||||
Object.assign(subClass, superClass);
|
||||
subClass.prototype = Object.create(superClass && superClass.prototype);
|
||||
subClass.prototype.constructor = subClass;
|
||||
subClass.__superConstructor__ = superClass;
|
||||
return superClass;
|
||||
},
|
||||
_extends: Object.assign,
|
||||
extends: Object.assign,
|
||||
objectWithoutProperties(obj, keys) {
|
||||
var target = {};
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
for (var i in obj) {
|
||||
if (!hasOwn.call(obj, i) || keys.indexOf(i) >= 0) {
|
||||
continue;
|
||||
}
|
||||
target[i] = obj[i];
|
||||
}
|
||||
return target;
|
||||
},
|
||||
taggedTemplateLiteralLoose(strings, raw) {
|
||||
strings.raw = raw;
|
||||
return strings;
|
||||
},
|
||||
bind: Function.prototype.bind,
|
||||
};
|
||||
}
|
||||
|
||||
function App(props) {
|
||||
var data = {};
|
||||
var someProps = Object.assign(data, props, {
|
||||
text: "Text!",
|
||||
})
|
||||
var propsWithout = babelHelpers.objectWithoutProperties(data, []);
|
||||
return <div>{propsWithout.text}</div>
|
||||
}
|
||||
|
||||
App.getTrials = function(renderer, Root, data, isCompiled) {
|
||||
if (isCompiled) {
|
||||
var a = App({});
|
||||
var b = App({});
|
||||
if (a !== b) {
|
||||
throw new Error("The values should be the same!");
|
||||
}
|
||||
}
|
||||
renderer.update(<Root />);
|
||||
return [["fb24", renderer.toJSON()]];
|
||||
};
|
||||
|
||||
if (this.__optimizeReactComponentTree) {
|
||||
__optimizeReactComponentTree(App);
|
||||
}
|
||||
|
||||
module.exports = App;
|
58
test/react/FBMocks/fb25.js
Normal file
58
test/react/FBMocks/fb25.js
Normal file
@ -0,0 +1,58 @@
|
||||
var React = require("react");
|
||||
|
||||
// FB www polyfill
|
||||
if (!this.babelHelpers) {
|
||||
this.babelHelpers = {
|
||||
inherits(subClass, superClass) {
|
||||
Object.assign(subClass, superClass);
|
||||
subClass.prototype = Object.create(superClass && superClass.prototype);
|
||||
subClass.prototype.constructor = subClass;
|
||||
subClass.__superConstructor__ = superClass;
|
||||
return superClass;
|
||||
},
|
||||
_extends: Object.assign,
|
||||
extends: Object.assign,
|
||||
objectWithoutProperties(obj, keys) {
|
||||
var target = {};
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
for (var i in obj) {
|
||||
if (!hasOwn.call(obj, i) || keys.indexOf(i) >= 0) {
|
||||
continue;
|
||||
}
|
||||
target[i] = obj[i];
|
||||
}
|
||||
return target;
|
||||
},
|
||||
taggedTemplateLiteralLoose(strings, raw) {
|
||||
strings.raw = raw;
|
||||
return strings;
|
||||
},
|
||||
bind: Function.prototype.bind,
|
||||
};
|
||||
}
|
||||
|
||||
function App(props) {
|
||||
var someProps = Object.assign({}, props, {
|
||||
text: "Text!",
|
||||
})
|
||||
var propsWithout = babelHelpers.objectWithoutProperties(someProps, []);
|
||||
return <div>{propsWithout.text}</div>
|
||||
}
|
||||
|
||||
App.getTrials = function(renderer, Root, data, isCompiled) {
|
||||
if (isCompiled) {
|
||||
var a = App({});
|
||||
var b = App({});
|
||||
if (a !== b) {
|
||||
throw new Error("The values should be the same!");
|
||||
}
|
||||
}
|
||||
renderer.update(<Root />);
|
||||
return [["fb25", renderer.toJSON()]];
|
||||
};
|
||||
|
||||
if (this.__optimizeReactComponentTree) {
|
||||
__optimizeReactComponentTree(App);
|
||||
}
|
||||
|
||||
module.exports = App;
|
@ -2396,6 +2396,142 @@ ReactStatistics {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`fb-www 24: (JSX => JSX) 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 1,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 0,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`fb-www 24: (JSX => createElement) 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 1,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 0,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`fb-www 24: (createElement => JSX) 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 1,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 0,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`fb-www 24: (createElement => createElement) 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 1,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 0,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`fb-www 25: (JSX => JSX) 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 1,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 0,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`fb-www 25: (JSX => createElement) 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 1,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 0,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`fb-www 25: (createElement => JSX) 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 1,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 0,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`fb-www 25: (createElement => createElement) 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 1,
|
||||
"evaluatedRootNodes": Array [
|
||||
Object {
|
||||
"children": Array [],
|
||||
"message": "",
|
||||
"name": "App",
|
||||
"status": "ROOT",
|
||||
},
|
||||
],
|
||||
"inlinedComponents": 0,
|
||||
"optimizedNestedClosures": 0,
|
||||
"optimizedTrees": 1,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`fb-www: (JSX => JSX) 1`] = `
|
||||
ReactStatistics {
|
||||
"componentsEvaluated": 1,
|
||||
|
Loading…
Reference in New Issue
Block a user