Add all React component prototype properties from the prototype chain

Summary:
Release notes: none

Previously, we only took the prototype methods from the parent class prototype, we should actually traverse the entire prototype chain looking for methods to apply. This removes a bunch of bail out cases that are being `console.error` in `react-tests` due to bailing out.
Closes https://github.com/facebook/prepack/pull/1419

Differential Revision: D6940685

Pulled By: trueadm

fbshipit-source-id: fa333902c9dcca300675aeb93582bab75c8a63a7
This commit is contained in:
Dominic Gannaway 2018-02-08 15:33:02 -08:00 committed by Facebook Github Bot
parent 1f8cedeeea
commit baa67cbd44
2 changed files with 26 additions and 11 deletions

View File

@ -10,7 +10,7 @@ ReactStatistics {
exports[`Test React (JSX) Class component folding Inheritance chaining 1`] = `
ReactStatistics {
"inlinedComponents": 0,
"optimizedTrees": 1,
"optimizedTrees": 2,
}
`;
@ -325,7 +325,7 @@ ReactStatistics {
exports[`Test React (create-element) Class component folding Inheritance chaining 1`] = `
ReactStatistics {
"inlinedComponents": 0,
"optimizedTrees": 1,
"optimizedTrees": 2,
}
`;

View File

@ -124,19 +124,19 @@ export function createSimpleClassInstance(
return instance;
}
export function createClassInstance(
function deeplyApplyInstancePrototypeProperties(
realm: Realm,
componentType: ECMAScriptSourceFunctionValue,
props: ObjectValue | AbstractValue,
context: ObjectValue | AbstractValue,
instance: ObjectValue,
componentPrototype: ObjectValue,
classMetadata: ClassComponentMetadata
): AbstractObjectValue {
let componentPrototype = Get(realm, componentType, "prototype");
invariant(componentPrototype instanceof ObjectValue);
) {
let { instanceProperties, instanceSymbols } = classMetadata;
let proto = componentPrototype.$Prototype;
if (proto instanceof ObjectValue && proto !== realm.intrinsics.ObjectPrototype) {
deeplyApplyInstancePrototypeProperties(realm, instance, proto, classMetadata);
}
// create an instance object and disable serialization as we don't want to output the internals we set below
let instance = new ObjectValue(realm, componentPrototype, "this", true);
for (let [name] of componentPrototype.properties) {
// ensure we don't set properties that were defined on the instance
if (name !== "constructor" && !instanceProperties.has(name)) {
@ -149,6 +149,21 @@ export function createClassInstance(
Properties.Set(realm, instance, symbol, Get(realm, componentPrototype, symbol), true);
}
}
}
export function createClassInstance(
realm: Realm,
componentType: ECMAScriptSourceFunctionValue,
props: ObjectValue | AbstractValue,
context: ObjectValue | AbstractValue,
classMetadata: ClassComponentMetadata
): AbstractObjectValue {
let componentPrototype = Get(realm, componentType, "prototype");
invariant(componentPrototype instanceof ObjectValue);
// create an instance object and disable serialization as we don't want to output the internals we set below
let instance = new ObjectValue(realm, componentPrototype, "this", true);
deeplyApplyInstancePrototypeProperties(realm, instance, componentPrototype, classMetadata);
// assign refs
Properties.Set(realm, instance, "refs", AbstractValue.createAbstractObject(realm, "this.refs"), true);
// assign props