| 1 | use react_compiler_hir::environment_config::EnvironmentConfig; |
| 2 | use serde::{Deserialize, Serialize}; |
| 3 | |
| 4 | /// Target configuration for the compiler |
| 5 | #[derive(Debug, Clone, Serialize, Deserialize)] |
| 6 | #[serde(untagged)] |
| 7 | pub enum CompilerTarget { |
| 8 | /// Standard React version target |
| 9 | Version(String), // "17", "18", "19" |
| 10 | /// Meta-internal target with custom runtime module |
| 11 | MetaInternal { |
| 12 | kind: String, // "donotuse_meta_internal" |
| 13 | #[serde(rename = "runtimeModule")] |
| 14 | runtime_module: String, |
| 15 | }, |
| 16 | } |
| 17 | |
| 18 | /// Gating configuration |
| 19 | #[derive(Debug, Clone, Serialize, Deserialize)] |
| 20 | pub struct GatingConfig { |
| 21 | pub source: String, |
| 22 | #[serde(rename = "importSpecifierName")] |
| 23 | pub import_specifier_name: String, |
| 24 | } |
| 25 | |
| 26 | /// Dynamic gating configuration |
| 27 | #[derive(Debug, Clone, Serialize, Deserialize)] |
| 28 | pub struct DynamicGatingConfig { |
| 29 | pub source: String, |
| 30 | } |
| 31 | |
| 32 | /// Serializable plugin options, pre-resolved by the JS shim. |
| 33 | /// JS-only values (sources function, logger, etc.) are resolved before |
| 34 | /// being sent to Rust. |
| 35 | #[derive(Debug, Clone, Serialize, Deserialize)] |
| 36 | #[serde(rename_all = "camelCase")] |
| 37 | pub struct PluginOptions { |
| 38 | // Pre-resolved by JS |
| 39 | pub should_compile: bool, |
| 40 | pub enable_reanimated: bool, |
| 41 | pub is_dev: bool, |
| 42 | pub filename: Option<String>, |
| 43 | |
| 44 | // Pass-through options |
| 45 | #[serde(default = "default_compilation_mode")] |
| 46 | pub compilation_mode: String, |
| 47 | #[serde(default = "default_panic_threshold")] |
| 48 | pub panic_threshold: String, |
| 49 | #[serde(default = "default_target")] |
| 50 | pub target: CompilerTarget, |
| 51 | #[serde(default)] |
| 52 | pub gating: Option<GatingConfig>, |
| 53 | #[serde(default)] |
| 54 | pub dynamic_gating: Option<DynamicGatingConfig>, |
| 55 | #[serde(default)] |
| 56 | pub no_emit: bool, |
| 57 | #[serde(default)] |
| 58 | pub output_mode: Option<String>, |
| 59 | #[serde(default)] |
| 60 | pub eslint_suppression_rules: Option<Vec<String>>, |
| 61 | #[serde(default = "default_true")] |
| 62 | pub flow_suppressions: bool, |
| 63 | #[serde(default)] |
| 64 | pub ignore_use_no_forget: bool, |
| 65 | #[serde(default)] |
| 66 | pub custom_opt_out_directives: Option<Vec<String>>, |
| 67 | #[serde(default)] |
| 68 | pub environment: EnvironmentConfig, |
| 69 | |
| 70 | /// Source code of the file being compiled (passed from Babel plugin for fast refresh hash). |
| 71 | #[serde(default, rename = "__sourceCode")] |
| 72 | pub source_code: Option<String>, |
| 73 | |
| 74 | /// Enable profiling timing data collection. |
| 75 | #[serde(default, rename = "__profiling")] |
| 76 | pub profiling: bool, |
| 77 | |
| 78 | /// Enable debug logging (HIR formatting after each pass). |
| 79 | /// Only set to true when a logger with debugLogIRs is configured on the JS side. |
| 80 | #[serde(default, rename = "__debug")] |
| 81 | pub debug: bool, |
| 82 | } |
| 83 | |
| 84 | fn default_compilation_mode() -> String { |
| 85 | "infer".to_string() |
| 86 | } |
| 87 | |
| 88 | fn default_panic_threshold() -> String { |
| 89 | "none".to_string() |
| 90 | } |
| 91 | |
| 92 | fn default_target() -> CompilerTarget { |
| 93 | CompilerTarget::Version("19".to_string()) |
| 94 | } |
| 95 | |
| 96 | fn default_true() -> bool { |
| 97 | true |
| 98 | } |
| 99 | |
| 100 | /// Output mode for the compiler, derived from PluginOptions. |
| 101 | /// Matches the TS `compilerOutputMode` logic in Program.ts. |
| 102 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 103 | pub enum CompilerOutputMode { |
| 104 | Ssr, |
| 105 | Client, |
| 106 | Lint, |
| 107 | } |
| 108 | |
| 109 | impl CompilerOutputMode { |
| 110 | pub fn from_opts(opts: &PluginOptions) -> Self { |
| 111 | match opts.output_mode.as_deref() { |
| 112 | Some("ssr") => Self::Ssr, |
| 113 | Some("lint") => Self::Lint, |
| 114 | _ if opts.no_emit => Self::Lint, |
| 115 | _ => Self::Client, |
| 116 | } |
| 117 | } |
| 118 | } |