diff --git a/tasks/ast_tools/src/codegen.rs b/tasks/ast_tools/src/codegen.rs index 5bf7ad298..0da21c394 100644 --- a/tasks/ast_tools/src/codegen.rs +++ b/tasks/ast_tools/src/codegen.rs @@ -1,18 +1,16 @@ use std::{cell::RefCell, path::PathBuf}; use itertools::Itertools; -use proc_macro2::TokenStream; use rustc_hash::{FxBuildHasher, FxHashMap}; use crate::{ - derives::{Derive, DeriveOutput}, - fmt::pretty_print, - generators::{Generator, GeneratorOutput}, + derives::Derive, + generators::Generator, log, logln, + output::RawOutput, passes::Pass, rust_ast::{self, AstRef}, schema::{lower_ast_types, Schema, TypeDef}, - util::write_all_to, Result, TypeId, }; @@ -20,50 +18,13 @@ use crate::{ pub struct AstCodegen { files: Vec, passes: Vec>>, - generators: Vec>>, - derives: Vec>>, + generators: Vec>>, + derives: Vec, Context = LateCtx>>>, } pub struct AstCodegenResult { pub schema: Schema, - pub outputs: Vec, -} - -pub struct SideEffect { - pub path: PathBuf, - pub content: Vec, -} - -impl SideEffect { - /// Apply the side-effect - pub fn apply(self) -> std::io::Result<()> { - let Self { path, content } = self; - let path = path.into_os_string(); - let path = path.to_str().unwrap(); - write_all_to(&content, path)?; - Ok(()) - } - - pub fn path(&self) -> String { - let path = self.path.to_string_lossy(); - path.replace('\\', "/") - } -} - -impl From<(PathBuf, TokenStream)> for SideEffect { - fn from((path, stream): (PathBuf, TokenStream)) -> Self { - let content = pretty_print(&stream); - Self { path, content: content.into() } - } -} - -impl From for SideEffect { - fn from(output: GeneratorOutput) -> Self { - match output { - GeneratorOutput::Rust { path, tokens } => Self::from((path, tokens)), - GeneratorOutput::Javascript { path, code } => Self { path, content: code.into() }, - } - } + pub outputs: Vec, } pub trait Runner { @@ -162,7 +123,7 @@ impl AstCodegen { #[must_use] pub fn generate(mut self, generator: G) -> Self where - G: Generator + Runner + 'static, + G: Generator + Runner + 'static, { self.generators.push(Box::new(generator)); self @@ -171,7 +132,7 @@ impl AstCodegen { #[must_use] pub fn derive(mut self, derive: D) -> Self where - D: Derive + Runner + 'static, + D: Derive + Runner, Context = LateCtx> + 'static, { self.derives.push(Box::new(derive)); self @@ -213,24 +174,19 @@ impl AstCodegen { } result }) - .map_ok(|output| output.0.into_iter().map(SideEffect::from)) .flatten_ok(); - let outputs = self - .generators - .into_iter() - .map(|mut runner| { - let name = runner.name(); - log!("Generate {name}... "); - let result = runner.run(&ctx); - if result.is_ok() { - logln!("Done!"); - } else { - logln!("Fail!"); - } - result - }) - .map_ok(SideEffect::from); + let outputs = self.generators.into_iter().map(|mut runner| { + let name = runner.name(); + log!("Generate {name}... "); + let result = runner.run(&ctx); + if result.is_ok() { + logln!("Done!"); + } else { + logln!("Fail!"); + } + result + }); let outputs = derives.chain(outputs).collect::>>()?; @@ -242,27 +198,3 @@ impl AstCodegen { pub trait CodegenBase { fn file_path() -> &'static str; } - -/// Creates a generated file warning + required information for a generated file. -pub fn generate_rust_header(file_path: &str) -> TokenStream { - let file_path = file_path.replace('\\', "/"); - - // TODO: Add generation date, AST source hash, etc here. - let edit_comment = format!("@ To edit this generated file you have to edit `{file_path}`"); - quote::quote! { - //!@ Auto-generated code, DO NOT EDIT DIRECTLY! - #![doc = #edit_comment] - //!@@line_break - } -} - -/// Creates a generated file warning + required information for a generated file. -pub fn generate_javascript_header(file_path: &str) -> String { - let file_path = file_path.replace('\\', "/"); - - // TODO: Add generation date, AST source hash, etc here. - format!( - "// Auto-generated code, DO NOT EDIT DIRECTLY!\n\ - // To edit this generated file you have to edit `{file_path}`\n\n" - ) -} diff --git a/tasks/ast_tools/src/derives/mod.rs b/tasks/ast_tools/src/derives/mod.rs index 1986ef825..733594cf9 100644 --- a/tasks/ast_tools/src/derives/mod.rs +++ b/tasks/ast_tools/src/derives/mod.rs @@ -1,12 +1,11 @@ -use std::path::PathBuf; - use convert_case::{Case, Casing}; use itertools::Itertools; use proc_macro2::TokenStream; use rustc_hash::{FxHashMap, FxHashSet}; use crate::{ - codegen::{generate_rust_header, CodegenBase, LateCtx}, + codegen::{CodegenBase, LateCtx}, + output::{output_path, Output, RawOutput}, schema::TypeDef, Result, }; @@ -23,9 +22,6 @@ pub use content_hash::DeriveContentHash; pub use estree::DeriveESTree; pub use get_span::{DeriveGetSpan, DeriveGetSpanMut}; -#[derive(Debug, Clone)] -pub struct DeriveOutput(pub Vec<(PathBuf, TokenStream)>); - pub trait Derive: CodegenBase { // Methods defined by implementer @@ -44,7 +40,6 @@ pub trait Derive: CodegenBase { // Standard methods fn template(module_paths: Vec<&str>, impls: TokenStream) -> TokenStream { - let header = generate_rust_header(Self::file_path()); let prelude = Self::prelude(); // from `x::y::z` to `crate::y::z::*` @@ -63,8 +58,6 @@ pub trait Derive: CodegenBase { }); quote::quote! { - #header - #prelude #(#use_modules)* @@ -74,7 +67,7 @@ pub trait Derive: CodegenBase { } } - fn output(&mut self, ctx: &LateCtx) -> Result { + fn output(&mut self, ctx: &LateCtx) -> Result> { let trait_name = Self::trait_name(); let filename = format!("derive_{}.rs", Self::snake_name()); let output = ctx @@ -102,12 +95,12 @@ pub trait Derive: CodegenBase { let mut modules = Vec::from_iter(modules); modules.sort_unstable(); - acc.push(( - crate::output( + let output = Output::Rust { + path: output_path( format!("crates/{}", path.split("::").next().unwrap()).as_str(), &filename, ), - Self::template( + tokens: Self::template( modules, streams.into_iter().fold(TokenStream::new(), |mut acc, it| { acc.extend(quote::quote! { @@ -117,10 +110,12 @@ pub trait Derive: CodegenBase { acc }), ), - )); + }; + + acc.push(output.output(Self::file_path())); acc }); - Ok(DeriveOutput(output)) + Ok(output) } } @@ -129,7 +124,7 @@ macro_rules! define_derive { const _: () = { use $crate::{ codegen::{CodegenBase, LateCtx, Runner}, - derives::DeriveOutput, + output::RawOutput, Result, }; @@ -141,13 +136,13 @@ macro_rules! define_derive { impl $($lifetime)? Runner for $ident $($lifetime)? { type Context = LateCtx; - type Output = DeriveOutput; + type Output = Vec; fn name(&self) -> &'static str { stringify!($ident) } - fn run(&mut self, ctx: &LateCtx) -> Result { + fn run(&mut self, ctx: &LateCtx) -> Result> { self.output(ctx) } } diff --git a/tasks/ast_tools/src/generators/assert_layouts.rs b/tasks/ast_tools/src/generators/assert_layouts.rs index 0f4d31c3e..a1166d742 100644 --- a/tasks/ast_tools/src/generators/assert_layouts.rs +++ b/tasks/ast_tools/src/generators/assert_layouts.rs @@ -5,10 +5,10 @@ use syn::Type; use super::define_generator; use crate::{ codegen::LateCtx, - output, + output::{output_path, Output}, schema::{FieldDef, ToType, TypeDef}, util::ToIdent, - Generator, GeneratorOutput, + Generator, }; pub struct AssertLayouts; @@ -16,7 +16,7 @@ pub struct AssertLayouts; define_generator!(AssertLayouts); impl Generator for AssertLayouts { - fn generate(&mut self, ctx: &LateCtx) -> GeneratorOutput { + fn generate(&mut self, ctx: &LateCtx) -> Output { let (assertions_64, assertions_32) = ctx .schema() .into_iter() @@ -26,8 +26,8 @@ impl Generator for AssertLayouts { }) .collect::<(Vec, Vec)>(); - GeneratorOutput::Rust { - path: output(crate::AST_CRATE, "assert_layouts.rs"), + Output::Rust { + path: output_path(crate::AST_CRATE, "assert_layouts.rs"), tokens: quote! { use std::mem::{align_of, offset_of, size_of}; diff --git a/tasks/ast_tools/src/generators/ast_builder.rs b/tasks/ast_tools/src/generators/ast_builder.rs index 992c2bbf1..50267cf44 100644 --- a/tasks/ast_tools/src/generators/ast_builder.rs +++ b/tasks/ast_tools/src/generators/ast_builder.rs @@ -11,12 +11,12 @@ use syn::{parse_quote, Ident, Type}; use super::define_generator; use crate::{ codegen::LateCtx, - output, + output::{output_path, Output}, schema::{ EnumDef, FieldDef, GetIdent, InheritDef, StructDef, ToType, TypeDef, TypeName, VariantDef, }, util::{TypeAnalysis, TypeWrapper}, - Generator, GeneratorOutput, + Generator, }; pub struct AstBuilderGenerator; @@ -24,7 +24,7 @@ pub struct AstBuilderGenerator; define_generator!(AstBuilderGenerator); impl Generator for AstBuilderGenerator { - fn generate(&mut self, ctx: &LateCtx) -> GeneratorOutput { + fn generate(&mut self, ctx: &LateCtx) -> Output { let fns = ctx .schema() .into_iter() @@ -32,8 +32,8 @@ impl Generator for AstBuilderGenerator { .map(|it| generate_builder_fn(it, ctx)) .collect_vec(); - GeneratorOutput::Rust { - path: output(crate::AST_CRATE, "ast_builder.rs"), + Output::Rust { + path: output_path(crate::AST_CRATE, "ast_builder.rs"), tokens: quote! { //! AST node factories diff --git a/tasks/ast_tools/src/generators/ast_kind.rs b/tasks/ast_tools/src/generators/ast_kind.rs index cd387df34..c17707789 100644 --- a/tasks/ast_tools/src/generators/ast_kind.rs +++ b/tasks/ast_tools/src/generators/ast_kind.rs @@ -6,9 +6,9 @@ use syn::{parse_quote, Arm, ImplItemFn, Variant}; use super::define_generator; use crate::{ codegen::LateCtx, - output, + output::{output_path, Output}, schema::{GetIdent, ToType}, - Generator, GeneratorOutput, + Generator, }; pub struct AstKindGenerator; @@ -80,7 +80,7 @@ pub const BLACK_LIST: [&str; 61] = [ ]; impl Generator for AstKindGenerator { - fn generate(&mut self, ctx: &LateCtx) -> GeneratorOutput { + fn generate(&mut self, ctx: &LateCtx) -> Output { let have_kinds = ctx .schema() .into_iter() @@ -125,8 +125,8 @@ impl Generator for AstKindGenerator { }) .collect_vec(); - GeneratorOutput::Rust { - path: output(crate::AST_CRATE, "ast_kind.rs"), + Output::Rust { + path: output_path(crate::AST_CRATE, "ast_kind.rs"), tokens: quote! { #![allow(missing_docs)] ///@ FIXME (in ast_tools/src/generators/ast_kind.rs) diff --git a/tasks/ast_tools/src/generators/mod.rs b/tasks/ast_tools/src/generators/mod.rs index 8667af08c..6ecc593c0 100644 --- a/tasks/ast_tools/src/generators/mod.rs +++ b/tasks/ast_tools/src/generators/mod.rs @@ -1,10 +1,6 @@ -use std::path::PathBuf; - -use proc_macro2::TokenStream; -use quote::quote; - use crate::{ - codegen::{generate_javascript_header, generate_rust_header, CodegenBase, LateCtx}, + codegen::{CodegenBase, LateCtx}, + output::{Output, RawOutput}, Result, }; @@ -20,37 +16,16 @@ pub use ast_kind::AstKindGenerator; pub use typescript::TypescriptGenerator; pub use visit::{VisitGenerator, VisitMutGenerator}; -#[derive(Debug, Clone)] -pub enum GeneratorOutput { - Rust { path: PathBuf, tokens: TokenStream }, - Javascript { path: PathBuf, code: String }, -} - pub trait Generator: CodegenBase { // Methods defined by implementer - fn generate(&mut self, ctx: &LateCtx) -> GeneratorOutput; + fn generate(&mut self, ctx: &LateCtx) -> Output; // Standard methods - fn output(&mut self, ctx: &LateCtx) -> Result { - let mut output = self.generate(ctx); - - match &mut output { - GeneratorOutput::Rust { tokens, .. } => { - let header = generate_rust_header(Self::file_path()); - *tokens = quote! { - #header - #tokens - }; - } - GeneratorOutput::Javascript { code: content, .. } => { - let header = generate_javascript_header(Self::file_path()); - *content = format!("{header}{content}"); - } - } - - Ok(output) + fn output(&mut self, ctx: &LateCtx) -> Result { + let output = self.generate(ctx); + Ok(output.output(Self::file_path())) } } @@ -59,7 +34,7 @@ macro_rules! define_generator { const _: () = { use $crate::{ codegen::{CodegenBase, LateCtx, Runner}, - generators::GeneratorOutput, + output::RawOutput, Result, }; @@ -71,13 +46,13 @@ macro_rules! define_generator { impl $($lifetime)? Runner for $ident $($lifetime)? { type Context = LateCtx; - type Output = GeneratorOutput; + type Output = RawOutput; fn name(&self) -> &'static str { stringify!($ident) } - fn run(&mut self, ctx: &LateCtx) -> Result { + fn run(&mut self, ctx: &LateCtx) -> Result { self.output(ctx) } } diff --git a/tasks/ast_tools/src/generators/typescript.rs b/tasks/ast_tools/src/generators/typescript.rs index 56b5cf9ec..bd9107e3c 100644 --- a/tasks/ast_tools/src/generators/typescript.rs +++ b/tasks/ast_tools/src/generators/typescript.rs @@ -1,19 +1,15 @@ use convert_case::{Case, Casing}; use itertools::Itertools; -use std::{ - io::Write, - process::{Command, Stdio}, -}; use super::define_generator; use crate::{ codegen::LateCtx, - output, + output::{output_path, Output}, schema::{ serialize::{enum_variant_name, get_type_tag}, EnumDef, GetIdent, StructDef, TypeDef, TypeName, }, - Generator, GeneratorOutput, + Generator, }; const CUSTOM_TYPESCRIPT: &str = include_str!("../../../../crates/oxc_ast/src/ast/types.d.ts"); @@ -23,7 +19,7 @@ pub struct TypescriptGenerator; define_generator!(TypescriptGenerator); impl Generator for TypescriptGenerator { - fn generate(&mut self, ctx: &LateCtx) -> GeneratorOutput { + fn generate(&mut self, ctx: &LateCtx) -> Output { let mut code = format!("{CUSTOM_TYPESCRIPT}\n"); for def in ctx.schema() { @@ -40,10 +36,7 @@ impl Generator for TypescriptGenerator { code.push_str("\n\n"); } - GeneratorOutput::Javascript { - path: output(crate::TYPESCRIPT_PACKAGE, "types.d.ts"), - code: format_typescript(&code), - } + Output::Javascript { path: output_path(crate::TYPESCRIPT_PACKAGE, "types.d.ts"), code } } } @@ -127,19 +120,3 @@ fn type_to_string(ty: &TypeName) -> String { TypeName::Opt(type_name) => format!("{} | null", type_to_string(type_name)), } } - -fn format_typescript(source_text: &str) -> String { - let mut dprint = Command::new("dprint") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .args(["fmt", "--stdin", "types.d.ts"]) - .spawn() - .expect("Failed to run dprint (is it installed?)"); - - let stdin = dprint.stdin.as_mut().unwrap(); - stdin.write_all(source_text.as_bytes()).unwrap(); - stdin.flush().unwrap(); - - let output = dprint.wait_with_output().unwrap(); - String::from_utf8(output.stdout).unwrap() -} diff --git a/tasks/ast_tools/src/generators/visit.rs b/tasks/ast_tools/src/generators/visit.rs index e31294cc7..270ce96f2 100644 --- a/tasks/ast_tools/src/generators/visit.rs +++ b/tasks/ast_tools/src/generators/visit.rs @@ -12,10 +12,10 @@ use crate::{ codegen::LateCtx, generators::ast_kind::BLACK_LIST as KIND_BLACK_LIST, markers::VisitArg, - output, + output::{output_path, Output}, schema::{EnumDef, GetIdent, StructDef, ToType, TypeDef}, util::{StrExt, TokenStreamExt, TypeWrapper}, - Generator, GeneratorOutput, + Generator, }; pub struct VisitGenerator; @@ -23,9 +23,9 @@ pub struct VisitGenerator; define_generator!(VisitGenerator); impl Generator for VisitGenerator { - fn generate(&mut self, ctx: &LateCtx) -> GeneratorOutput { - GeneratorOutput::Rust { - path: output(crate::AST_CRATE, "visit.rs"), + fn generate(&mut self, ctx: &LateCtx) -> Output { + Output::Rust { + path: output_path(crate::AST_CRATE, "visit.rs"), tokens: generate_visit::(ctx), } } @@ -36,9 +36,9 @@ pub struct VisitMutGenerator; define_generator!(VisitMutGenerator); impl Generator for VisitMutGenerator { - fn generate(&mut self, ctx: &LateCtx) -> GeneratorOutput { - GeneratorOutput::Rust { - path: output(crate::AST_CRATE, "visit_mut.rs"), + fn generate(&mut self, ctx: &LateCtx) -> Output { + Output::Rust { + path: output_path(crate::AST_CRATE, "visit_mut.rs"), tokens: generate_visit::(ctx), } } diff --git a/tasks/ast_tools/src/main.rs b/tasks/ast_tools/src/main.rs index 502ff3fec..ba04f0575 100644 --- a/tasks/ast_tools/src/main.rs +++ b/tasks/ast_tools/src/main.rs @@ -8,10 +8,10 @@ use syn::parse_file; mod codegen; mod derives; -mod fmt; mod generators; mod layout; mod markers; +mod output; mod passes; mod rust_ast; mod schema; @@ -22,11 +22,12 @@ use derives::{ DeriveGetSpanMut, }; use generators::{ - AssertLayouts, AstBuilderGenerator, AstKindGenerator, Generator, GeneratorOutput, - TypescriptGenerator, VisitGenerator, VisitMutGenerator, + AssertLayouts, AstBuilderGenerator, AstKindGenerator, Generator, TypescriptGenerator, + VisitGenerator, VisitMutGenerator, }; +use output::write_all_to; use passes::{CalcLayout, Linker}; -use util::{write_all_to, NormalizeError}; +use util::NormalizeError; static SOURCE_PATHS: &[&str] = &[ "crates/oxc_ast/src/ast/literal.rs", @@ -90,7 +91,7 @@ fn main() -> std::result::Result<(), Box> { .map(|it| { let path = it.path(); log!("Writing {path}..."); - it.apply().unwrap(); + it.write_to_file().unwrap(); logln!(" Done!"); path }) @@ -107,10 +108,6 @@ fn main() -> std::result::Result<(), Box> { Ok(()) } -fn output(krate: &str, path: &str) -> PathBuf { - std::path::PathBuf::from_iter(vec![krate, "src", "generated", path]) -} - fn write_ci_filter( inputs: &[&str], side_effects: Vec, diff --git a/tasks/ast_tools/src/output/javascript.rs b/tasks/ast_tools/src/output/javascript.rs new file mode 100644 index 000000000..2d68f50d3 --- /dev/null +++ b/tasks/ast_tools/src/output/javascript.rs @@ -0,0 +1,39 @@ +use std::{ + io::Write, + process::{Command, Stdio}, +}; + +/// Format Javascript/Typescript code, and add header. +pub fn print_javascript(code: &str, generator_path: &str) -> String { + let header = generate_header(generator_path); + let code = format!("{header}{code}"); + format(&code) +} + +/// Creates a generated file warning + required information for a generated file. +fn generate_header(generator_path: &str) -> String { + let generator_path = generator_path.replace('\\', "/"); + + // TODO: Add generation date, AST source hash, etc here. + format!( + "// Auto-generated code, DO NOT EDIT DIRECTLY!\n\ + // To edit this generated file you have to edit `{generator_path}`\n\n" + ) +} + +/// Format JS/TS code with dprint. +fn format(source_text: &str) -> String { + let mut dprint = Command::new("dprint") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .args(["fmt", "--stdin", "dummy.ts"]) + .spawn() + .expect("Failed to run dprint (is it installed?)"); + + let stdin = dprint.stdin.as_mut().unwrap(); + stdin.write_all(source_text.as_bytes()).unwrap(); + stdin.flush().unwrap(); + + let output = dprint.wait_with_output().unwrap(); + String::from_utf8(output.stdout).unwrap() +} diff --git a/tasks/ast_tools/src/output/mod.rs b/tasks/ast_tools/src/output/mod.rs new file mode 100644 index 000000000..f8e5b0b46 --- /dev/null +++ b/tasks/ast_tools/src/output/mod.rs @@ -0,0 +1,72 @@ +use std::{fs, io::Write, path::PathBuf}; + +use proc_macro2::TokenStream; + +mod javascript; +mod rust; +use javascript::print_javascript; +use rust::print_rust; + +/// An output from codegen. +/// +/// Can be either Rust or Javascript. +pub enum Output { + Rust { path: PathBuf, tokens: TokenStream }, + Javascript { path: PathBuf, code: String }, +} + +impl Output { + pub fn output(self, generator_path: &str) -> RawOutput { + let (path, code) = match self { + Self::Rust { path, tokens } => { + let code = print_rust(&tokens, generator_path); + (path, code) + } + Self::Javascript { path, code } => { + let code = print_javascript(&code, generator_path); + (path, code) + } + }; + RawOutput { path, content: code.into_bytes() } + } +} + +/// A raw output from codegen. +#[derive(Debug)] +pub struct RawOutput { + pub path: PathBuf, + pub content: Vec, +} + +impl RawOutput { + /// Get path of output as a string. + pub fn path(&self) -> String { + let path = self.path.to_string_lossy(); + path.replace('\\', "/") + } + + /// Write output to file + pub fn write_to_file(self) -> std::io::Result<()> { + let Self { path, content } = self; + let path = path.into_os_string(); + let path = path.to_str().unwrap(); + write_all_to(&content, path)?; + Ok(()) + } +} + +/// Get path for an output. +pub fn output_path(krate: &str, path: &str) -> PathBuf { + std::path::PathBuf::from_iter(vec![krate, "src", "generated", path]) +} + +/// Write data to file. +pub fn write_all_to>(data: &[u8], path: S) -> std::io::Result<()> { + let path = path.as_ref(); + if let Some(parent) = path.parent() { + fs::create_dir_all(parent)?; + } + let mut file = fs::File::create(path)?; + file.write_all(data)?; + Ok(()) +} diff --git a/tasks/ast_tools/src/fmt.rs b/tasks/ast_tools/src/output/rust.rs similarity index 68% rename from tasks/ast_tools/src/fmt.rs rename to tasks/ast_tools/src/output/rust.rs index 08e47981d..012869cb4 100644 --- a/tasks/ast_tools/src/fmt.rs +++ b/tasks/ast_tools/src/output/rust.rs @@ -5,17 +5,37 @@ use std::{ use lazy_static::lazy_static; use proc_macro2::TokenStream; +use quote::quote; use regex::{Captures, Regex, Replacer}; use syn::parse_file; -/// Pretty print -pub fn pretty_print(input: &TokenStream) -> String { - let result = prettyplease::unparse(&parse_file(input.to_string().as_str()).unwrap()); +/// Format Rust code, and add header. +pub fn print_rust(tokens: &TokenStream, generator_path: &str) -> String { + let header = generate_header(generator_path); + let tokens = quote! { + #header + #tokens + }; + + let result = prettyplease::unparse(&parse_file(tokens.to_string().as_str()).unwrap()); let result = COMMENT_REGEX.replace_all(&result, CommentReplacer).to_string(); rust_fmt(&result) } -pub fn rust_fmt(source_text: &str) -> String { +/// Creates a generated file warning + required information for a generated file. +fn generate_header(generator_path: &str) -> TokenStream { + let generator_path = generator_path.replace('\\', "/"); + + // TODO: Add generation date, AST source hash, etc here. + let edit_comment = format!("@ To edit this generated file you have to edit `{generator_path}`"); + quote::quote! { + //!@ Auto-generated code, DO NOT EDIT DIRECTLY! + #![doc = #edit_comment] + //!@@line_break + } +} + +fn rust_fmt(source_text: &str) -> String { let mut rustfmt = Command::new("rustfmt") .stdin(Stdio::piped()) .stdout(Stdio::piped()) diff --git a/tasks/ast_tools/src/util.rs b/tasks/ast_tools/src/util.rs index 5be691c34..97e0cb496 100644 --- a/tasks/ast_tools/src/util.rs +++ b/tasks/ast_tools/src/util.rs @@ -309,17 +309,6 @@ where } } -pub fn write_all_to>(data: &[u8], path: S) -> std::io::Result<()> { - use std::{fs, io::Write}; - let path = path.as_ref(); - if let Some(parent) = path.parent() { - fs::create_dir_all(parent)?; - } - let mut file = fs::File::create(path)?; - file.write_all(data)?; - Ok(()) -} - pub fn unexpanded_macro_err(mac: &ItemMacro) -> String { format!("Unexpanded macro: {:?}:{:?}", mac.ident, mac.span()) }