| 21 | } |
| 22 | |
| 23 | pub fn expand(input: &mut Config) -> Result<TokenStream> { |
| 24 | let mut src = match input.opts.generate(&mut input.resolve, input.world) { |
| 25 | Ok(s) => s, |
| 26 | Err(e) => return Err(Error::new(Span::call_site(), e.to_string())), |
| 27 | }; |
| 28 | |
| 29 | if input.opts.stringify { |
| 30 | return Ok(quote::quote!(#src)); |
| 31 | } |
| 32 | |
| 33 | // If a magical `WASMTIME_DEBUG_BINDGEN` environment variable is set then |
| 34 | // place a formatted version of the expanded code into a file. This file |
| 35 | // will then show up in rustc error messages for any codegen issues and can |
| 36 | // be inspected manually. |
| 37 | if input.include_generated_code_from_file |
| 38 | || input.opts.debug |
| 39 | || std::env::var("WASMTIME_DEBUG_BINDGEN").is_ok() |
| 40 | { |
| 41 | static INVOCATION: AtomicUsize = AtomicUsize::new(0); |
| 42 | let root = Path::new(env!("DEBUG_OUTPUT_DIR")); |
| 43 | let world_name = &input.resolve.worlds[input.world].name; |
| 44 | let n = INVOCATION.fetch_add(1, Relaxed); |
| 45 | let path = root.join(format!("{world_name}{n}.rs")); |
| 46 | |
| 47 | std::fs::write(&path, &src).unwrap(); |
| 48 | |
| 49 | // optimistically format the code but don't require success |
| 50 | drop( |
| 51 | std::process::Command::new("rustfmt") |
| 52 | .arg(&path) |
| 53 | .arg("--edition=2021") |
| 54 | .output(), |
| 55 | ); |
| 56 | |
| 57 | src = format!("include!({path:?});"); |
| 58 | } |
| 59 | let mut contents = src.parse::<TokenStream>().unwrap(); |
| 60 | |
| 61 | // Include a dummy `include_bytes!` for any files we read so rustc knows that |
| 62 | // we depend on the contents of those files. |
| 63 | for file in input.files.iter() { |
| 64 | contents.extend( |
| 65 | format!( |
| 66 | "const _: &[u8] = include_bytes!(r#\"{}\"#);\n", |
| 67 | file.display() |
| 68 | ) |
| 69 | .parse::<TokenStream>() |
| 70 | .unwrap(), |
| 71 | ); |
| 72 | } |
| 73 | |
| 74 | Ok(contents) |
| 75 | } |
| 76 | |
| 77 | impl Parse for Config { |
| 78 | fn parse(input: ParseStream<'_>) -> Result<Self> { |