1/**2 * Copyright (c) Meta Platforms, Inc. and affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 */78import type * as BabelCore from '@babel/core';9import {transformFromAstSync} from '@babel/core';10import * as BabelParser from '@babel/parser';11import BabelPluginReactCompiler, {12 ErrorSeverity,13 type CompilerErrorDetailOptions,14 type PluginOptions,15} from 'babel-plugin-react-compiler/src';16import {LoggerEvent as RawLoggerEvent} from 'babel-plugin-react-compiler/src/Entrypoint';17import chalk from 'chalk';1819type LoggerEvent = RawLoggerEvent & {filename: string | null};2021const SucessfulCompilation: Array<LoggerEvent> = [];22const ActionableFailures: Array<LoggerEvent> = [];23const OtherFailures: Array<LoggerEvent> = [];2425const logger = {26 logEvent(filename: string | null, rawEvent: RawLoggerEvent) {27 const event = {...rawEvent, filename};28 switch (event.kind) {29 case 'CompileSuccess': {30 SucessfulCompilation.push(event);31 return;32 }33 case 'CompileError': {34 if (isActionableDiagnostic(event.detail)) {35 ActionableFailures.push(event);36 return;37 }38 OtherFailures.push(event);39 return;40 }41 case 'CompileDiagnostic':42 case 'PipelineError':43 OtherFailures.push(event);44 return;45 }46 },47};4849const COMPILER_OPTIONS: PluginOptions = {50 noEmit: true,51 compilationMode: 'infer',52 panicThreshold: 'critical_errors',53 logger,54};5556function isActionableDiagnostic(detail: CompilerErrorDetailOptions) {57 switch (detail.severity) {58 case ErrorSeverity.InvalidReact:59 case ErrorSeverity.InvalidJS:60 return true;61 case ErrorSeverity.InvalidConfig:62 case ErrorSeverity.Invariant:63 case ErrorSeverity.CannotPreserveMemoization:64 case ErrorSeverity.Todo:65 return false;66 default:67 throw new Error(`Unhandled error severity \`${detail.severity}\``);68 }69}7071function runBabelPluginReactCompiler(72 text: string,73 file: string,74 language: 'flow' | 'typescript',75 options: PluginOptions | null,76): BabelCore.BabelFileResult {77 const ast = BabelParser.parse(text, {78 sourceFilename: file,79 plugins: [language, 'jsx'],80 sourceType: 'module',81 });82 const result = transformFromAstSync(ast, text, {83 filename: file,84 highlightCode: false,85 retainLines: true,86 plugins: [[BabelPluginReactCompiler, options]],87 sourceType: 'module',88 configFile: false,89 babelrc: false,90 });91 if (result?.code == null) {92 throw new Error(93 `Expected BabelPluginReactForget to codegen successfully, got: ${result}`,94 );95 }96 return result;97}9899function compile(sourceCode: string, filename: string) {100 try {101 runBabelPluginReactCompiler(102 sourceCode,103 filename,104 'typescript',105 COMPILER_OPTIONS,106 );107 } catch {}108}109110const JsFileExtensionRE = /(js|ts|jsx|tsx)$/;111112/**113 * Counts unique source locations (filename + function definition location)114 * in source.115 * The compiler currently occasionally emits multiple error events for a116 * single file (e.g. to report multiple rules of react violations in the117 * same pass).118 * TODO: enable non-destructive `CompilerDiagnostic` logging in dev mode,119 * and log a "CompilationStart" event for every function we begin processing.120 */121function countUniqueLocInEvents(events: Array<LoggerEvent>): number {122 const seenLocs = new Set<string>();123 let count = 0;124 for (const e of events) {125 if (e.filename != null && e.fnLoc != null) {126 seenLocs.add(`${e.filename}:${e.fnLoc.start}:${e.fnLoc.end}`);127 } else {128 // failed to dedup due to lack of source locations129 count++;130 }131 }132 return count + seenLocs.size;133}134135export default {136 run(source: string, path: string): void {137 if (JsFileExtensionRE.exec(path) !== null) {138 compile(source, path);139 }140 },141142 report(): void {143 const totalComponents =144 SucessfulCompilation.length +145 countUniqueLocInEvents(OtherFailures) +146 countUniqueLocInEvents(ActionableFailures);147 console.log(148 chalk.green(149 `Successfully compiled ${SucessfulCompilation.length} out of ${totalComponents} components.`,150 ),151 );152 },153};
Findings
✓ No findings reported for this file.