UNPKG

13 kBSource Map (JSON)View Raw
1{"version":3,"sources":["../../src/react/hoisting.js"],"names":["canHoistObject","realm","object","residualHeapVisitor","visitedValues","canHoistReactElement","propName","properties","prop","canHoistValue","symbol","symbols","canHoistArray","array","intrinsicName","lengthValue","NumberValue","length","value","i","element","canHoistFunction","func","react","hoistableFunctions","has","get","undefined","functionInstance","functionInstances","residualFunctionBindings","Map","residualBindings","declarativeEnvironmentRecord","Value","ECMAScriptSourceFunctionValue","code","$ECMAScriptCode","functionInfos","unbound","size","set","canHoistAbstract","abstract","isPrimitive","StringValue","SymbolValue","BooleanValue","intrinsics","null","add","canHoist","ArrayValue","FunctionValue","ObjectValue","AbstractValue","delete","reactElement","hoistableReactElements","type","ref","key","props","Set","String","isPartialObject","determineIfReactElementCanBeHoisted"],"mappings":"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","sourcesContent":["/**\n * Copyright (c) 2017-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n\n/* @flow */\n\nimport { Realm } from \"../realm.js\";\nimport {\n AbstractValue,\n ArrayValue,\n BooleanValue,\n ECMAScriptSourceFunctionValue,\n FunctionValue,\n NumberValue,\n ObjectValue,\n SymbolValue,\n StringValue,\n Value,\n} from \"../values/index.js\";\nimport { Get } from \"../methods/index.js\";\nimport invariant from \"../invariant.js\";\nimport { isReactElement, getProperty } from \"./utils.js\";\nimport { ResidualHeapVisitor } from \"../serializer/ResidualHeapVisitor.js\";\n\n// a nested object of a React Element should be hoisted where all its properties are known\n// at evaluation time to be safe to hoist (because of the heuristics of a React render)\nfunction canHoistObject(\n realm: Realm,\n object: ObjectValue,\n residualHeapVisitor: ResidualHeapVisitor,\n visitedValues: Set<Value>\n): boolean {\n if (isReactElement(object)) {\n return canHoistReactElement(realm, object, residualHeapVisitor, visitedValues);\n }\n for (let [propName] of object.properties) {\n let prop = Get(realm, object, propName);\n if (!canHoistValue(realm, prop, residualHeapVisitor, visitedValues)) {\n return false;\n }\n }\n for (let [symbol] of object.symbols) {\n let prop = Get(realm, object, symbol);\n if (!canHoistValue(realm, prop, residualHeapVisitor, visitedValues)) {\n return false;\n }\n }\n return true;\n}\n\nfunction canHoistArray(\n realm: Realm,\n array: ArrayValue,\n residualHeapVisitor: ResidualHeapVisitor,\n visitedValues: Set<Value>\n): boolean {\n if (array.intrinsicName) return false;\n let lengthValue = Get(realm, array, \"length\");\n invariant(lengthValue instanceof NumberValue);\n let length = lengthValue.value;\n for (let i = 0; i < length; i++) {\n let element = Get(realm, array, \"\" + i);\n\n if (!canHoistValue(realm, element, residualHeapVisitor, visitedValues)) {\n return false;\n }\n }\n return true;\n}\n\nexport function canHoistFunction(\n realm: Realm,\n func: FunctionValue,\n residualHeapVisitor?: ResidualHeapVisitor,\n visitedValues: Set<Value>\n): boolean {\n if (realm.react.hoistableFunctions.has(func)) {\n // cast because Flow thinks that we may have set a value to be something other than a boolean?\n return ((realm.react.hoistableFunctions.get(func): any): boolean);\n }\n if (residualHeapVisitor === undefined) {\n return false;\n }\n // get the function instance\n let functionInstance = residualHeapVisitor.functionInstances.get(func);\n // we can safely hoist the function if the residual bindings hoistable too\n if (functionInstance !== undefined) {\n invariant(functionInstance.residualFunctionBindings instanceof Map);\n let residualBindings = functionInstance.residualFunctionBindings;\n for (let [, { declarativeEnvironmentRecord, value }] of residualBindings) {\n // if declarativeEnvironmentRecord is null, it's likely a global binding\n // so we can assume that we can still hoist this function\n if (declarativeEnvironmentRecord !== null) {\n if (value === undefined) {\n return false;\n }\n invariant(value instanceof Value);\n if (!canHoistValue(realm, value, residualHeapVisitor, visitedValues)) {\n return false;\n }\n }\n }\n if (func instanceof ECMAScriptSourceFunctionValue) {\n let code = func.$ECMAScriptCode;\n let functionInfos = residualHeapVisitor.functionInfos.get(code);\n if (functionInfos && functionInfos.unbound.size > 0) {\n return false;\n }\n }\n realm.react.hoistableFunctions.set(func, true);\n return true;\n }\n realm.react.hoistableFunctions.set(func, false);\n return false;\n}\n\nfunction canHoistAbstract(realm: Realm, abstract: AbstractValue, residualHeapVisitor: ResidualHeapVisitor): boolean {\n // TODO #1687: add abstract value hoisting\n return false;\n}\n\nfunction isPrimitive(realm: Realm, value: Value) {\n return (\n value instanceof StringValue ||\n value instanceof NumberValue ||\n value instanceof SymbolValue ||\n value instanceof BooleanValue ||\n value === realm.intrinsics.null ||\n value === realm.intrinsics.undefined\n );\n}\n\nfunction canHoistValue(\n realm: Realm,\n value: Value,\n residualHeapVisitor: ResidualHeapVisitor,\n visitedValues: Set<Value>\n): boolean {\n if (visitedValues.has(value)) {\n // If there is a cycle, bail out.\n // TODO: is there some way to *not* bail out in this case?\n // Currently if we don't, the output is broken.\n return false;\n }\n visitedValues.add(value);\n let canHoist = false;\n\n if (value instanceof ArrayValue) {\n canHoist = canHoistArray(realm, value, residualHeapVisitor, visitedValues);\n } else if (value instanceof FunctionValue) {\n canHoist = canHoistFunction(realm, value, residualHeapVisitor, visitedValues);\n } else if (value instanceof ObjectValue) {\n canHoist = canHoistObject(realm, value, residualHeapVisitor, visitedValues);\n } else if (value instanceof AbstractValue) {\n canHoist = canHoistAbstract(realm, value, residualHeapVisitor);\n } else if (isPrimitive) {\n canHoist = true;\n }\n visitedValues.delete(value);\n return canHoist;\n}\n\nexport function canHoistReactElement(\n realm: Realm,\n reactElement: ObjectValue,\n residualHeapVisitor?: ResidualHeapVisitor,\n visitedValues?: Set<Value> | void\n): boolean {\n if (realm.react.hoistableReactElements.has(reactElement)) {\n // cast because Flow thinks that we may have set a value to be something other than a boolean?\n return ((realm.react.hoistableReactElements.get(reactElement): any): boolean);\n }\n if (residualHeapVisitor === undefined) {\n return false;\n }\n let type = getProperty(realm, reactElement, \"type\");\n let ref = getProperty(realm, reactElement, \"ref\");\n let key = getProperty(realm, reactElement, \"key\");\n let props = getProperty(realm, reactElement, \"props\");\n\n if (visitedValues === undefined) {\n visitedValues = new Set();\n visitedValues.add(reactElement);\n }\n if (\n canHoistValue(realm, type, residualHeapVisitor, visitedValues) &&\n // we can't hoist string \"refs\" or if they're abstract, as they might be abstract strings\n !(ref instanceof String || ref instanceof AbstractValue) &&\n canHoistValue(realm, ref, residualHeapVisitor, visitedValues) &&\n canHoistValue(realm, key, residualHeapVisitor, visitedValues) &&\n !props.isPartialObject() &&\n canHoistValue(realm, props, residualHeapVisitor, visitedValues)\n ) {\n realm.react.hoistableReactElements.set(reactElement, true);\n return true;\n }\n realm.react.hoistableReactElements.set(reactElement, false);\n return false;\n}\n\nexport function determineIfReactElementCanBeHoisted(\n realm: Realm,\n reactElement: ObjectValue,\n residualHeapVisitor: ResidualHeapVisitor\n): void {\n canHoistReactElement(realm, reactElement, residualHeapVisitor);\n}\n"],"file":"hoisting.js"}
\No newline at end of file