compiler/packages/babel-plugin-react-compiler-rust/native/src/lib.rs RUST 138 lines View on github.com → Search inside
1use std::time::Instant;23use napi_derive::napi;4use react_compiler::entrypoint::PluginOptions;5use react_compiler::entrypoint::compile_program;6use react_compiler::timing::TimingEntry;7use react_compiler_ast::File;8use react_compiler_ast::scope::ScopeInfo;9use serde::Deserialize;1011/// Deserialize JSON with no recursion limit (for deeply nested ASTs).12fn from_json_str<'de, T: Deserialize<'de>>(s: &'de str) -> serde_json::Result<T> {13    let mut deserializer = serde_json::Deserializer::from_str(s);14    deserializer.disable_recursion_limit();15    T::deserialize(&mut deserializer)16}1718/// Main entry point for the React Compiler.19///20/// Receives a full program AST, scope information, and resolved options21/// as JSON strings. Returns a JSON string containing the CompileResult.22///23/// This function is called by the JS shim (bridge.ts) via napi-rs.24/// Spawns a dedicated thread with 64MB stack to handle deeply nested ASTs25/// that would overflow the default Node.js thread stack.26#[napi]27pub fn compile(ast_json: String, scope_json: String, options_json: String) -> napi::Result<String> {28    let handle = std::thread::Builder::new()29        .stack_size(64 * 1024 * 1024) // 64MB stack30        .spawn(move || compile_inner(ast_json, scope_json, options_json))31        .map_err(|e| napi::Error::from_reason(format!("Failed to spawn compiler thread: {}", e)))?;3233    match handle.join() {34        Ok(result) => result,35        Err(panic_payload) => {36            let msg = if let Some(s) = panic_payload.downcast_ref::<&str>() {37                format!("Rust compiler panicked: {}", s)38            } else if let Some(s) = panic_payload.downcast_ref::<String>() {39                format!("Rust compiler panicked: {}", s)40            } else {41                "Rust compiler panicked (unknown payload)".to_string()42            };43            Err(napi::Error::from_reason(msg))44        }45    }46}4748fn compile_inner(49    ast_json: String,50    scope_json: String,51    options_json: String,52) -> napi::Result<String> {53    // Check if profiling is enabled by peeking at the options JSON54    let profiling = options_json.contains("\"__profiling\":true");5556    let deser_start = Instant::now();5758    let ast: File = from_json_str(&ast_json)59        .map_err(|e| napi::Error::from_reason(format!("Failed to parse AST JSON: {}", e)))?;6061    let scope: ScopeInfo = from_json_str(&scope_json)62        .map_err(|e| napi::Error::from_reason(format!("Failed to parse scope JSON: {}", e)))?;6364    let opts: PluginOptions = from_json_str(&options_json)65        .map_err(|e| napi::Error::from_reason(format!("Failed to parse options JSON: {}", e)))?;6667    let deser_duration = deser_start.elapsed();6869    let compile_start = Instant::now();70    let mut result = compile_program(ast, scope, opts);71    let compile_duration = compile_start.elapsed();7273    // If profiling is enabled, prepend NAPI deserialization timing and append serialization timing74    if profiling {75        let napi_deser_entry = TimingEntry {76            name: "napi_deserialize".to_string(),77            duration_us: deser_duration.as_micros() as u64,78        };7980        // Insert NAPI timing entries81        match &mut result {82            react_compiler::entrypoint::CompileResult::Success { timing, .. } => {83                timing.insert(0, napi_deser_entry);84            }85            react_compiler::entrypoint::CompileResult::Error { timing, .. } => {86                timing.insert(0, napi_deser_entry);87            }88        }8990        // Add compile_program duration (the total Rust compilation time including pass timing)91        let compile_entry = TimingEntry {92            name: "napi_compile_program".to_string(),93            duration_us: compile_duration.as_micros() as u64,94        };95        match &mut result {96            react_compiler::entrypoint::CompileResult::Success { timing, .. } => {97                timing.push(compile_entry);98            }99            react_compiler::entrypoint::CompileResult::Error { timing, .. } => {100                timing.push(compile_entry);101            }102        }103    }104105    let ser_start = Instant::now();106    let result_json = serde_json::to_string(&result)107        .map_err(|e| napi::Error::from_reason(format!("Failed to serialize result: {}", e)))?;108109    if profiling {110        // We need to inject the serialization timing into the already-serialized JSON.111        // Since timing is a JSON array at the end of the result, we can append to it.112        let ser_duration = ser_start.elapsed();113        let ser_entry = format!(114            r#"{{"name":"napi_serialize","duration_us":{}}}"#,115            ser_duration.as_micros()116        );117118        // Find the timing array in the JSON and append our entry119        if let Some(pos) = result_json.rfind("\"timing\":[") {120            // Find the closing ] of the timing array121            let timing_start = pos + "\"timing\":[".len();122            if let Some(close_bracket) = result_json[timing_start..].rfind(']') {123                let abs_close = timing_start + close_bracket;124                let mut patched = result_json[..abs_close].to_string();125                if abs_close > timing_start {126                    // Array is non-empty, add comma127                    patched.push(',');128                }129                patched.push_str(&ser_entry);130                patched.push_str(&result_json[abs_close..]);131                return Ok(patched);132            }133        }134    }135136    Ok(result_json)137}

Code quality findings 3

Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
if let Some(close_bracket) = result_json[timing_start..].rfind(']') {
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
let mut patched = result_json[..abs_close].to_string();
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
patched.push_str(&result_json[abs_close..]);

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.