112
| {kind: 'reactive'; name: string; value: ReactiveFunction}
113
| {kind: 'debug'; name: string; value: string};
114
115
-export function* run(
115
+function run(
116
func: NodePath<
117
t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression
118
>,
122
logger: Logger | null,
123
filename: string | null,
124
code: string | null,
125
-): Generator<CompilerPipelineValue, CodegenFunction> {
125
+): CodegenFunction {
126
const contextIdentifiers = findContextIdentifiers(func);
127
const env = new Environment(
128
func.scope,
134
code,
135
useMemoCacheIdentifier,
136
);
137
- yield log({
137
+ env.logger?.debugLogIRs?.({
138
+ kind: 'debug',
139
+ name: 'EnvironmentConfig',
140
+ value: prettyFormat(env.config),
141
+ });
142
+ printLog({
143
kind: 'debug',
144
name: 'EnvironmentConfig',
145
value: prettyFormat(env.config),
146
});
142
- const ast = yield* runWithEnvironment(func, env);
147
+ const ast = runWithEnvironment(func, env);
148
return ast;
149
}
150
152
* Note: this is split from run() to make `config` out of scope, so that all
153
* access to feature flags has to be through the Environment for consistency.
154
*/
150
-function* runWithEnvironment(
155
+function runWithEnvironment(
156
func: NodePath<
157
t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression
158
>,
159
env: Environment,
155
-): Generator<CompilerPipelineValue, CodegenFunction> {
160
+): CodegenFunction {
161
+ const log = (value: CompilerPipelineValue): CompilerPipelineValue => {
162
+ printLog(value);
163
+ env.logger?.debugLogIRs?.(value);
164
+ return value;
165
+ };
166
const hir = lower(func, env).unwrap();
157
- yield log({kind: 'hir', name: 'HIR', value: hir});
167
+ log({kind: 'hir', name: 'HIR', value: hir});
168
169
pruneMaybeThrows(hir);
160
- yield log({kind: 'hir', name: 'PruneMaybeThrows', value: hir});
170
+ log({kind: 'hir', name: 'PruneMaybeThrows', value: hir});
171
172
validateContextVariableLValues(hir);
173
validateUseMemo(hir);
178
!env.config.enableChangeDetectionForDebugging
179
) {
180
dropManualMemoization(hir);
171
- yield log({kind: 'hir', name: 'DropManualMemoization', value: hir});
181
+ log({kind: 'hir', name: 'DropManualMemoization', value: hir});
182
}
183
184
inlineImmediatelyInvokedFunctionExpressions(hir);
175
- yield log({
185
+ log({
186
kind: 'hir',
187
name: 'InlineImmediatelyInvokedFunctionExpressions',
188
value: hir,
189
});
190
191
mergeConsecutiveBlocks(hir);
182
- yield log({kind: 'hir', name: 'MergeConsecutiveBlocks', value: hir});
192
+ log({kind: 'hir', name: 'MergeConsecutiveBlocks', value: hir});
193
194
assertConsistentIdentifiers(hir);
195
assertTerminalSuccessorsExist(hir);
196
197
enterSSA(hir);
188
- yield log({kind: 'hir', name: 'SSA', value: hir});
198
+ log({kind: 'hir', name: 'SSA', value: hir});
199
200
eliminateRedundantPhi(hir);
191
- yield log({kind: 'hir', name: 'EliminateRedundantPhi', value: hir});
201
+ log({kind: 'hir', name: 'EliminateRedundantPhi', value: hir});
202
203
assertConsistentIdentifiers(hir);
204
205
constantPropagation(hir);
196
- yield log({kind: 'hir', name: 'ConstantPropagation', value: hir});
206
+ log({kind: 'hir', name: 'ConstantPropagation', value: hir});
207
208
inferTypes(hir);
199
- yield log({kind: 'hir', name: 'InferTypes', value: hir});
209
+ log({kind: 'hir', name: 'InferTypes', value: hir});
210
211
if (env.config.validateHooksUsage) {
212
validateHooksUsage(hir);
221
}
222
223
optimizePropsMethodCalls(hir);
214
- yield log({kind: 'hir', name: 'OptimizePropsMethodCalls', value: hir});
224
+ log({kind: 'hir', name: 'OptimizePropsMethodCalls', value: hir});
225
226
analyseFunctions(hir);
217
- yield log({kind: 'hir', name: 'AnalyseFunctions', value: hir});
227
+ log({kind: 'hir', name: 'AnalyseFunctions', value: hir});
228
229
inferReferenceEffects(hir);
220
- yield log({kind: 'hir', name: 'InferReferenceEffects', value: hir});
230
+ log({kind: 'hir', name: 'InferReferenceEffects', value: hir});
231
232
validateLocalsNotReassignedAfterRender(hir);
233
234
// Note: Has to come after infer reference effects because "dead" code may still affect inference
235
deadCodeElimination(hir);
226
- yield log({kind: 'hir', name: 'DeadCodeElimination', value: hir});
236
+ log({kind: 'hir', name: 'DeadCodeElimination', value: hir});
237
238
if (env.config.enableInstructionReordering) {
239
instructionReordering(hir);
230
- yield log({kind: 'hir', name: 'InstructionReordering', value: hir});
240
+ log({kind: 'hir', name: 'InstructionReordering', value: hir});
241
}
242
243
pruneMaybeThrows(hir);
234
- yield log({kind: 'hir', name: 'PruneMaybeThrows', value: hir});
244
+ log({kind: 'hir', name: 'PruneMaybeThrows', value: hir});
245
246
inferMutableRanges(hir);
237
- yield log({kind: 'hir', name: 'InferMutableRanges', value: hir});
247
+ log({kind: 'hir', name: 'InferMutableRanges', value: hir});
248
249
if (env.config.assertValidMutableRanges) {
250
assertValidMutableRanges(hir);
267
}
268
269
inferReactivePlaces(hir);
260
- yield log({kind: 'hir', name: 'InferReactivePlaces', value: hir});
270
+ log({kind: 'hir', name: 'InferReactivePlaces', value: hir});
271
272
rewriteInstructionKindsBasedOnReassignment(hir);
263
- yield log({
273
+ log({
274
kind: 'hir',
275
name: 'RewriteInstructionKindsBasedOnReassignment',
276
value: hir,
277
});
278
279
propagatePhiTypes(hir);
270
- yield log({
280
+ log({
281
kind: 'hir',
282
name: 'PropagatePhiTypes',
283
value: hir,
284
});
285
286
inferReactiveScopeVariables(hir);
277
- yield log({kind: 'hir', name: 'InferReactiveScopeVariables', value: hir});
287
+ log({kind: 'hir', name: 'InferReactiveScopeVariables', value: hir});
288
289
const fbtOperands = memoizeFbtAndMacroOperandsInSameScope(hir);
280
- yield log({
290
+ log({
291
kind: 'hir',
292
name: 'MemoizeFbtAndMacroOperandsInSameScope',
293
value: hir,
299
300
if (env.config.enableFunctionOutlining) {
301
outlineFunctions(hir, fbtOperands);
292
- yield log({kind: 'hir', name: 'OutlineFunctions', value: hir});
302
+ log({kind: 'hir', name: 'OutlineFunctions', value: hir});
303
}
304
305
alignMethodCallScopes(hir);
296
- yield log({
306
+ log({
307
kind: 'hir',
308
name: 'AlignMethodCallScopes',
309
value: hir,
310
});
311
312
alignObjectMethodScopes(hir);
303
- yield log({
313
+ log({
314
kind: 'hir',
315
name: 'AlignObjectMethodScopes',
316
value: hir,
317
});
318
319
pruneUnusedLabelsHIR(hir);
310
- yield log({
320
+ log({
321
kind: 'hir',
322
name: 'PruneUnusedLabelsHIR',
323
value: hir,
324
});
325
326
alignReactiveScopesToBlockScopesHIR(hir);
317
- yield log({
327
+ log({
328
kind: 'hir',
329
name: 'AlignReactiveScopesToBlockScopesHIR',
330
value: hir,
331
});
332
333
mergeOverlappingReactiveScopesHIR(hir);
324
- yield log({
334
+ log({
335
kind: 'hir',
336
name: 'MergeOverlappingReactiveScopesHIR',
337
value: hir,
339
assertValidBlockNesting(hir);
340
341
buildReactiveScopeTerminalsHIR(hir);
332
- yield log({
342
+ log({
343
kind: 'hir',
344
name: 'BuildReactiveScopeTerminalsHIR',
345
value: hir,
348
assertValidBlockNesting(hir);
349
350
flattenReactiveLoopsHIR(hir);
341
- yield log({
351
+ log({
352
kind: 'hir',
353
name: 'FlattenReactiveLoopsHIR',
354
value: hir,
355
});
356
357
flattenScopesWithHooksOrUseHIR(hir);
348
- yield log({
358
+ log({
359
kind: 'hir',
360
name: 'FlattenScopesWithHooksOrUseHIR',
361
value: hir,
363
assertTerminalSuccessorsExist(hir);
364
assertTerminalPredsExist(hir);
365
propagateScopeDependenciesHIR(hir);
356
- yield log({
366
+ log({
367
kind: 'hir',
368
name: 'PropagateScopeDependenciesHIR',
369
value: hir,
375
376
if (env.config.inlineJsxTransform) {
377
inlineJsxTransform(hir, env.config.inlineJsxTransform);
368
- yield log({
378
+ log({
379
kind: 'hir',
380
name: 'inlineJsxTransform',
381
value: hir,
383
}
384
385
const reactiveFunction = buildReactiveFunction(hir);
376
- yield log({
386
+ log({
387
kind: 'reactive',
388
name: 'BuildReactiveFunction',
389
value: reactiveFunction,
392
assertWellFormedBreakTargets(reactiveFunction);
393
394
pruneUnusedLabels(reactiveFunction);
385
- yield log({
395
+ log({
396
kind: 'reactive',
397
name: 'PruneUnusedLabels',
398
value: reactiveFunction,
400
assertScopeInstructionsWithinScopes(reactiveFunction);
401
402
pruneNonEscapingScopes(reactiveFunction);
393
- yield log({
403
+ log({
404
kind: 'reactive',
405
name: 'PruneNonEscapingScopes',
406
value: reactiveFunction,
407
});
408
409
pruneNonReactiveDependencies(reactiveFunction);
400
- yield log({
410
+ log({
411
kind: 'reactive',
412
name: 'PruneNonReactiveDependencies',
413
value: reactiveFunction,
414
});
415
416
pruneUnusedScopes(reactiveFunction);
407
- yield log({
417
+ log({
418
kind: 'reactive',
419
name: 'PruneUnusedScopes',
420
value: reactiveFunction,
421
});
422
423
mergeReactiveScopesThatInvalidateTogether(reactiveFunction);
414
- yield log({
424
+ log({
425
kind: 'reactive',
426
name: 'MergeReactiveScopesThatInvalidateTogether',
427
value: reactiveFunction,
428
});
429
430
pruneAlwaysInvalidatingScopes(reactiveFunction);
421
- yield log({
431
+ log({
432
kind: 'reactive',
433
name: 'PruneAlwaysInvalidatingScopes',
434
value: reactiveFunction,
436
437
if (env.config.enableChangeDetectionForDebugging != null) {
438
pruneInitializationDependencies(reactiveFunction);
429
- yield log({
439
+ log({
440
kind: 'reactive',
441
name: 'PruneInitializationDependencies',
442
value: reactiveFunction,
444
}
445
446
propagateEarlyReturns(reactiveFunction);
437
- yield log({
447
+ log({
448
kind: 'reactive',
449
name: 'PropagateEarlyReturns',
450
value: reactiveFunction,
451
});
452
453
pruneUnusedLValues(reactiveFunction);
444
- yield log({
454
+ log({
455
kind: 'reactive',
456
name: 'PruneUnusedLValues',
457
value: reactiveFunction,
458
});
459
460
promoteUsedTemporaries(reactiveFunction);
451
- yield log({
461
+ log({
462
kind: 'reactive',
463
name: 'PromoteUsedTemporaries',
464
value: reactiveFunction,
465
});
466
467
extractScopeDeclarationsFromDestructuring(reactiveFunction);
458
- yield log({
468
+ log({
469
kind: 'reactive',
470
name: 'ExtractScopeDeclarationsFromDestructuring',
471
value: reactiveFunction,
472
});
473
474
stabilizeBlockIds(reactiveFunction);
465
- yield log({
475
+ log({
476
kind: 'reactive',
477
name: 'StabilizeBlockIds',
478
value: reactiveFunction,
479
});
480
481
const uniqueIdentifiers = renameVariables(reactiveFunction);
472
- yield log({
482
+ log({
483
kind: 'reactive',
484
name: 'RenameVariables',
485
value: reactiveFunction,
486
});
487
488
pruneHoistedContexts(reactiveFunction);
479
- yield log({
489
+ log({
490
kind: 'reactive',
491
name: 'PruneHoistedContexts',
492
value: reactiveFunction,
507
uniqueIdentifiers,
508
fbtOperands,
509
}).unwrap();
500
- yield log({kind: 'ast', name: 'Codegen', value: ast});
510
+ log({kind: 'ast', name: 'Codegen', value: ast});
511
for (const outlined of ast.outlined) {
502
- yield log({kind: 'ast', name: 'Codegen (outlined)', value: outlined.fn});
512
+ log({kind: 'ast', name: 'Codegen (outlined)', value: outlined.fn});
513
}
514
515
/**
535
filename: string | null,
536
code: string | null,
537
): CodegenFunction {
528
- let generator = run(
538
+ return run(
539
func,
540
config,
541
fnType,
544
filename,
545
code,
546
);
537
- while (true) {
538
- const next = generator.next();
539
- if (next.done) {
540
- return next.value;
541
- }
542
- }
547
}
548
545
-export function log(value: CompilerPipelineValue): CompilerPipelineValue {
549
+function printLog(value: CompilerPipelineValue): CompilerPipelineValue {
550
switch (value.kind) {
551
case 'ast': {
552
logCodegenFunction(value.name, value.value);
570
}
571
return value;
572
}
569
-
570
-export function* runPlayground(
571
- func: NodePath<
572
- t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression
573
- >,
574
- config: EnvironmentConfig,
575
- fnType: ReactFunctionType,
576
-): Generator<CompilerPipelineValue, CodegenFunction> {
577
- const ast = yield* run(func, config, fnType, '_c', null, null, null);
578
- return ast;
579
-}