1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.optimizeReactComponentTreeRoot = optimizeReactComponentTreeRoot;
|
7 | exports.applyOptimizedReactComponents = applyOptimizedReactComponents;
|
8 |
|
9 | var _realm = require("../realm.js");
|
10 |
|
11 | var _index = require("../values/index.js");
|
12 |
|
13 | var _utils = require("../serializer/utils.js");
|
14 |
|
15 | var _utils2 = require("./utils.js");
|
16 |
|
17 | var _types = require("../serializer/types.js");
|
18 |
|
19 | var _reconcilation = require("./reconcilation.js");
|
20 |
|
21 | var _errors = require("./errors.js");
|
22 |
|
23 | var _singletons = require("../singletons.js");
|
24 |
|
25 | var _index2 = require("../methods/index.js");
|
26 |
|
27 | var _invariant = _interopRequireDefault(require("../invariant.js"));
|
28 |
|
29 | var _logger = require("../utils/logger.js");
|
30 |
|
31 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | function applyWriteEffectsForOptimizedComponent(realm, componentType, _effects, componentTreeState, evaluatedNode, writeEffects, environmentRecordIdAfterGlobalCode) {
|
44 | let effects = _effects;
|
45 | let additionalFunctionEffects = (0, _utils.createAdditionalEffects)(realm, effects, false, "ReactAdditionalFunctionEffects", environmentRecordIdAfterGlobalCode);
|
46 |
|
47 | if (additionalFunctionEffects === null) {
|
48 | throw new _errors.ReconcilerFatalError(`Failed to optimize React component tree for "${evaluatedNode.name}" due to an unsupported completion`, evaluatedNode);
|
49 | }
|
50 |
|
51 | effects = additionalFunctionEffects.effects;
|
52 | let value = effects.result;
|
53 |
|
54 | if (value === realm.intrinsics.undefined) {
|
55 |
|
56 |
|
57 | return;
|
58 | }
|
59 |
|
60 | if ((0, _utils2.valueIsClassComponent)(realm, componentType)) {
|
61 | if (componentTreeState.status === "SIMPLE") {
|
62 |
|
63 |
|
64 | (0, _utils2.convertSimpleClassComponentToFunctionalComponent)(realm, componentType, additionalFunctionEffects);
|
65 | (0, _utils2.normalizeFunctionalComponentParamaters)(componentType);
|
66 | writeEffects.set(componentType, additionalFunctionEffects);
|
67 | } else {
|
68 | let prototype = (0, _index2.Get)(realm, componentType, "prototype");
|
69 | (0, _invariant.default)(prototype instanceof _index.ObjectValue);
|
70 | let renderMethod = (0, _index2.Get)(realm, prototype, "render");
|
71 | (0, _invariant.default)(renderMethod instanceof _index.ECMAScriptSourceFunctionValue);
|
72 | writeEffects.set(renderMethod, additionalFunctionEffects);
|
73 | }
|
74 | } else {
|
75 | if (componentTreeState.status === "COMPLEX") {
|
76 | (0, _utils2.convertFunctionalComponentToComplexClassComponent)(realm, componentType, componentTreeState.componentType, additionalFunctionEffects);
|
77 | let prototype = (0, _index2.Get)(realm, componentType, "prototype");
|
78 | (0, _invariant.default)(prototype instanceof _index.ObjectValue);
|
79 | let renderMethod = (0, _index2.Get)(realm, prototype, "render");
|
80 | (0, _invariant.default)(renderMethod instanceof _index.ECMAScriptSourceFunctionValue);
|
81 | writeEffects.set(renderMethod, additionalFunctionEffects);
|
82 | } else {
|
83 | (0, _utils2.normalizeFunctionalComponentParamaters)(componentType);
|
84 | writeEffects.set(componentType, additionalFunctionEffects);
|
85 | }
|
86 | }
|
87 |
|
88 |
|
89 | if (componentTreeState.contextTypes.size > 0) {
|
90 | let contextTypes = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype);
|
91 | let noOpFunc = (0, _utils2.createNoopFunction)(realm);
|
92 |
|
93 | for (let key of componentTreeState.contextTypes) {
|
94 | _singletons.Properties.Set(realm, contextTypes, key, noOpFunc, true);
|
95 | }
|
96 |
|
97 | _singletons.Properties.Set(realm, componentType, "contextTypes", contextTypes, true);
|
98 | }
|
99 | }
|
100 |
|
101 | function optimizeReactComponentTreeBranches(realm, reconciler, writeEffects, environmentRecordIdAfterGlobalCode, logger) {
|
102 | if (realm.react.verbose && reconciler.branchedComponentTrees.length > 0) {
|
103 | logger.logInformation(` Evaluating React component tree branches...`);
|
104 | }
|
105 |
|
106 |
|
107 |
|
108 | for (let _ref of reconciler.branchedComponentTrees) {
|
109 | let {
|
110 | rootValue: branchRootValue,
|
111 | evaluatedNode
|
112 | } = _ref;
|
113 | let branchComponentType = (0, _utils2.getComponentTypeFromRootValue)(realm, branchRootValue);
|
114 |
|
115 | if (branchComponentType === null) {
|
116 | evaluatedNode.status = "UNKNOWN_TYPE";
|
117 | continue;
|
118 | }
|
119 |
|
120 |
|
121 | if (reconciler.hasEvaluatedRootNode(branchComponentType, evaluatedNode)) {
|
122 | continue;
|
123 | }
|
124 |
|
125 | reconciler.clearComponentTreeState();
|
126 |
|
127 | if (realm.react.verbose) {
|
128 | logger.logInformation(` Evaluating ${evaluatedNode.name} (branch)`);
|
129 | }
|
130 |
|
131 | let branchEffects = reconciler.resolveReactComponentTree(branchComponentType, null, null, evaluatedNode);
|
132 |
|
133 | if (realm.react.verbose) {
|
134 | logger.logInformation(` ✔ ${evaluatedNode.name} (branch)`);
|
135 | }
|
136 |
|
137 | let branchComponentTreeState = reconciler.componentTreeState;
|
138 | applyWriteEffectsForOptimizedComponent(realm, branchComponentType, branchEffects, branchComponentTreeState, evaluatedNode, writeEffects, environmentRecordIdAfterGlobalCode);
|
139 | }
|
140 | }
|
141 |
|
142 | function optimizeReactNestedClosures(realm, reconciler, writeEffects, environmentRecordIdAfterGlobalCode, logger) {
|
143 | if (realm.react.verbose && reconciler.nestedOptimizedClosures.length > 0) {
|
144 | logger.logInformation(` Evaluating nested closures...`);
|
145 | }
|
146 |
|
147 | for (let _ref2 of reconciler.nestedOptimizedClosures) {
|
148 | let {
|
149 | func,
|
150 | evaluatedNode,
|
151 | nestedEffects,
|
152 | componentType,
|
153 | context
|
154 | } = _ref2;
|
155 |
|
156 | if (reconciler.hasEvaluatedNestedClosure(func)) {
|
157 | continue;
|
158 | }
|
159 |
|
160 | if (func instanceof _index.ECMAScriptSourceFunctionValue && reconciler.hasEvaluatedRootNode(func, evaluatedNode)) {
|
161 | continue;
|
162 | }
|
163 |
|
164 | if (realm.react.verbose) {
|
165 | logger.logInformation(` Evaluating function "${(0, _utils2.getComponentName)(realm, func)}"`);
|
166 | }
|
167 |
|
168 | let closureEffects = reconciler.resolveNestedOptimizedClosure(func, nestedEffects, componentType, context, evaluatedNode);
|
169 |
|
170 | if (realm.react.verbose) {
|
171 | logger.logInformation(` ✔ function "${(0, _utils2.getComponentName)(realm, func)}"`);
|
172 | }
|
173 |
|
174 | let additionalFunctionEffects = (0, _utils.createAdditionalEffects)(realm, closureEffects, true, "ReactNestedAdditionalFunctionEffects", environmentRecordIdAfterGlobalCode);
|
175 | (0, _invariant.default)(additionalFunctionEffects);
|
176 |
|
177 | if (func instanceof _index.BoundFunctionValue) {
|
178 | (0, _invariant.default)(func.$BoundTargetFunction instanceof _index.ECMAScriptSourceFunctionValue);
|
179 | writeEffects.set(func.$BoundTargetFunction, additionalFunctionEffects);
|
180 | } else {
|
181 | writeEffects.set(func, additionalFunctionEffects);
|
182 | }
|
183 | }
|
184 | }
|
185 |
|
186 | function optimizeReactComponentTreeRoot(realm, componentRoot, config, writeEffects, environmentRecordIdAfterGlobalCode, logger, statistics) {
|
187 | let reconciler = new _reconcilation.Reconciler(realm, config, statistics, logger);
|
188 | let componentType = (0, _utils2.getComponentTypeFromRootValue)(realm, componentRoot);
|
189 |
|
190 | if (componentType === null) {
|
191 | return;
|
192 | }
|
193 |
|
194 | let evaluatedRootNode = (0, _utils2.createReactEvaluatedNode)("ROOT", (0, _utils2.getComponentName)(realm, componentType));
|
195 | statistics.evaluatedRootNodes.push(evaluatedRootNode);
|
196 |
|
197 | if (reconciler.hasEvaluatedRootNode(componentType, evaluatedRootNode)) {
|
198 | return;
|
199 | }
|
200 |
|
201 | if (realm.react.verbose) {
|
202 | logger.logInformation(` Evaluating ${evaluatedRootNode.name} (root)`);
|
203 | }
|
204 |
|
205 | let componentTreeEffects = reconciler.resolveReactComponentTree(componentType, null, null, evaluatedRootNode);
|
206 |
|
207 | if (realm.react.verbose) {
|
208 | logger.logInformation(` ✔ ${evaluatedRootNode.name} (root)`);
|
209 | }
|
210 |
|
211 | applyWriteEffectsForOptimizedComponent(realm, componentType, componentTreeEffects, reconciler.componentTreeState, evaluatedRootNode, writeEffects, environmentRecordIdAfterGlobalCode);
|
212 | let startingComponentTreeBranches = 0;
|
213 |
|
214 | do {
|
215 | startingComponentTreeBranches = reconciler.branchedComponentTrees.length;
|
216 | optimizeReactComponentTreeBranches(realm, reconciler, writeEffects, environmentRecordIdAfterGlobalCode, logger);
|
217 |
|
218 | if (realm.react.optimizeNestedFunctions) {
|
219 | optimizeReactNestedClosures(realm, reconciler, writeEffects, environmentRecordIdAfterGlobalCode, logger);
|
220 | }
|
221 | } while (startingComponentTreeBranches !== reconciler.branchedComponentTrees.length);
|
222 | }
|
223 |
|
224 | function applyOptimizedReactComponents(realm, writeEffects, environmentRecordIdAfterGlobalCode) {
|
225 | for (let _ref3 of realm.react.optimizedNestedClosuresToWrite) {
|
226 | let {
|
227 | effects,
|
228 | func
|
229 | } = _ref3;
|
230 | let additionalFunctionEffects = (0, _utils.createAdditionalEffects)(realm, effects, true, "ReactNestedAdditionalFunctionEffects", environmentRecordIdAfterGlobalCode);
|
231 | (0, _invariant.default)(additionalFunctionEffects);
|
232 |
|
233 | if (func instanceof _index.BoundFunctionValue) {
|
234 | (0, _invariant.default)(func.$BoundTargetFunction instanceof _index.ECMAScriptSourceFunctionValue);
|
235 | writeEffects.set(func.$BoundTargetFunction, additionalFunctionEffects);
|
236 | } else {
|
237 | writeEffects.set(func, additionalFunctionEffects);
|
238 | }
|
239 | }
|
240 | }
|
241 |
|
\ | No newline at end of file |