diff --git a/tasks/ast_codegen/src/codegen.rs b/tasks/ast_codegen/src/codegen.rs new file mode 100644 index 00000000000000..b3c0f8066bccbd --- /dev/null +++ b/tasks/ast_codegen/src/codegen.rs @@ -0,0 +1,156 @@ +use std::{cell::RefCell, collections::HashMap, path::PathBuf}; + +use itertools::Itertools; + +use crate::{ + generators::{Generator, GeneratorOutput}, + passes::Pass, + rust_ast::{self, AstRef}, + schema::{lower_ast_types, Schema, TypeDef}, + Result, TypeId, +}; + +#[derive(Default)] +pub struct AstCodegen { + files: Vec, + passes: Vec>>, + generators: Vec>>, +} + +pub struct AstCodegenResult { + pub schema: Schema, + pub outputs: Vec<(/* generator name */ &'static str, /* output */ GeneratorOutput)>, +} + +pub trait Runner { + type Context; + type Output; + fn name(&self) -> &'static str; + fn run(&mut self, ctx: &Self::Context) -> Result; +} + +pub struct EarlyCtx { + ty_table: Vec, + ident_table: HashMap, + mods: RefCell>, +} + +impl EarlyCtx { + fn new(mods: Vec) -> Self { + // worst case len + let len = mods.iter().fold(0, |acc, it| acc + it.items.len()); + let adts = mods.iter().flat_map(|it| it.items.iter()); + + let mut ty_table = Vec::with_capacity(len); + let mut ident_table = HashMap::with_capacity(len); + for adt in adts { + if let Some(ident) = adt.borrow().ident() { + let ident = ident.to_string(); + let type_id = ty_table.len(); + ty_table.push(AstRef::clone(adt)); + ident_table.insert(ident, type_id); + } + } + + Self { ty_table, ident_table, mods: RefCell::new(mods) } + } + + pub fn chronological_idents(&self) -> impl Iterator { + self.ident_table.iter().sorted_by_key(|it| it.1).map(|it| it.0) + } + + pub fn mods(&self) -> &RefCell> { + &self.mods + } + + pub fn find(&self, key: &String) -> Option { + self.type_id(key).map(|id| AstRef::clone(&self.ty_table[id])) + } + + pub fn type_id(&self, key: &String) -> Option { + self.ident_table.get(key).copied() + } + + pub fn ast_ref(&self, id: TypeId) -> AstRef { + AstRef::clone(&self.ty_table[id]) + } + + fn into_late_ctx(self) -> LateCtx { + let schema = lower_ast_types(&self); + + LateCtx { schema } + } +} + +pub struct LateCtx { + schema: Schema, +} + +impl LateCtx { + pub fn schema(&self) -> &Schema { + &self.schema + } + + pub fn type_def(&self, id: TypeId) -> Option<&TypeDef> { + self.schema.get(id) + } +} + +impl AstCodegen { + #[must_use] + pub fn add_file

(mut self, path: P) -> Self + where + P: AsRef, + { + self.files.push(path.as_ref().into()); + self + } + + #[must_use] + pub fn pass

(mut self, pass: P) -> Self + where + P: Pass + Runner + 'static, + { + self.passes.push(Box::new(pass)); + self + } + + #[must_use] + pub fn gen(mut self, generator: G) -> Self + where + G: Generator + Runner + 'static, + { + self.generators.push(Box::new(generator)); + self + } + + pub fn generate(self) -> Result { + let modules = self + .files + .into_iter() + .map(rust_ast::Module::from) + .map(rust_ast::Module::load) + .map_ok(rust_ast::Module::expand) + .map_ok(|it| it.map(rust_ast::Module::analyze)) + .collect::>>>>()???; + + // early passes + let ctx = { + let ctx = EarlyCtx::new(modules); + _ = self + .passes + .into_iter() + .map(|mut runner| runner.run(&ctx).map(|res| (runner.name(), res))) + .collect::>>()?; + ctx.into_late_ctx() + }; + + let outputs = self + .generators + .into_iter() + .map(|mut runner| runner.run(&ctx).map(|res| (runner.name(), res))) + .collect::>>()?; + + Ok(AstCodegenResult { outputs, schema: ctx.schema }) + } +} diff --git a/tasks/ast_codegen/src/generators/assert_layouts.rs b/tasks/ast_codegen/src/generators/assert_layouts.rs index d0d8533a3e8ab8..054207b076a53f 100644 --- a/tasks/ast_codegen/src/generators/assert_layouts.rs +++ b/tasks/ast_codegen/src/generators/assert_layouts.rs @@ -3,9 +3,10 @@ use quote::{format_ident, quote}; use syn::Type; use crate::{ + codegen::LateCtx, output, schema::{FieldDef, ToType, TypeDef}, - Generator, GeneratorOutput, LateCtx, + Generator, GeneratorOutput, }; use super::{define_generator, generated_header}; @@ -17,9 +18,8 @@ define_generator! { impl Generator for AssertLayouts { fn generate(&mut self, ctx: &LateCtx) -> GeneratorOutput { let (assertions_64, assertions_32) = ctx - .schema - .definitions - .iter() + .schema() + .into_iter() .map(|def| { let typ = def.to_type_elide(); assert_type(&typ, def) diff --git a/tasks/ast_codegen/src/generators/ast_builder.rs b/tasks/ast_codegen/src/generators/ast_builder.rs index 4d183c05f33267..3718476f183002 100644 --- a/tasks/ast_codegen/src/generators/ast_builder.rs +++ b/tasks/ast_codegen/src/generators/ast_builder.rs @@ -9,13 +9,14 @@ use quote::{format_ident, quote, ToTokens}; use syn::{parse_quote, Ident, Type}; use crate::{ + codegen::LateCtx, generators::generated_header, output, schema::{ EnumDef, FieldDef, GetIdent, InheritDef, StructDef, ToType, TypeDef, TypeName, VariantDef, }, util::{TypeAnalysis, TypeWrapper}, - Generator, GeneratorOutput, LateCtx, + Generator, GeneratorOutput, }; use super::define_generator; @@ -27,9 +28,8 @@ define_generator! { impl Generator for AstBuilderGenerator { fn generate(&mut self, ctx: &LateCtx) -> GeneratorOutput { let fns = ctx - .schema - .definitions - .iter() + .schema() + .into_iter() .filter(|it| it.visitable()) .map(|it| generate_builder_fn(it, ctx)) .collect_vec(); diff --git a/tasks/ast_codegen/src/generators/ast_kind.rs b/tasks/ast_codegen/src/generators/ast_kind.rs index 92281a266134fd..dd1dcf64eaeb44 100644 --- a/tasks/ast_codegen/src/generators/ast_kind.rs +++ b/tasks/ast_codegen/src/generators/ast_kind.rs @@ -3,10 +3,11 @@ use quote::quote; use syn::{parse_quote, Arm, Ident, Type, Variant}; use crate::{ + codegen::LateCtx, output, schema::{GetIdent, ToType, TypeDef}, util::ToIdent, - Generator, GeneratorOutput, LateCtx, + Generator, GeneratorOutput, }; use super::{define_generator, generated_header}; @@ -137,8 +138,8 @@ pub fn process_types(def: &TypeDef, _: &LateCtx) -> Vec<(Ident, Type)> { impl Generator for AstKindGenerator { fn generate(&mut self, ctx: &LateCtx) -> GeneratorOutput { let have_kinds: Vec<(Ident, Type)> = ctx - .schema.definitions - .iter() + .schema() + .into_iter() .filter(|it| it.visitable()) .filter( |maybe_kind| matches!(maybe_kind, kind @ (TypeDef::Enum(_) | TypeDef::Struct(_)) if kind.visitable()) diff --git a/tasks/ast_codegen/src/generators/derive_clone_in.rs b/tasks/ast_codegen/src/generators/derive_clone_in.rs index 1075382f8708d0..db41c58aaf3abf 100644 --- a/tasks/ast_codegen/src/generators/derive_clone_in.rs +++ b/tasks/ast_codegen/src/generators/derive_clone_in.rs @@ -4,9 +4,10 @@ use quote::{format_ident, quote}; use syn::Ident; use crate::{ + codegen::LateCtx, output, schema::{EnumDef, GetIdent, StructDef, TypeDef}, - GeneratorOutput, LateCtx, + GeneratorOutput, }; use super::{define_generator, generated_header, Generator}; @@ -18,9 +19,8 @@ define_generator! { impl Generator for DeriveCloneIn { fn generate(&mut self, ctx: &LateCtx) -> GeneratorOutput { let impls: Vec = ctx - .schema - .definitions - .iter() + .schema() + .into_iter() .filter(|def| def.generates_derive("CloneIn")) .map(|def| match &def { TypeDef::Enum(it) => derive_enum(it), diff --git a/tasks/ast_codegen/src/generators/derive_get_span.rs b/tasks/ast_codegen/src/generators/derive_get_span.rs index d0d7671b2b989b..231823969e0956 100644 --- a/tasks/ast_codegen/src/generators/derive_get_span.rs +++ b/tasks/ast_codegen/src/generators/derive_get_span.rs @@ -3,10 +3,11 @@ use quote::{format_ident, quote}; use syn::Ident; use crate::{ + codegen::LateCtx, output, schema::{EnumDef, GetGenerics, StructDef, ToType, TypeDef}, util::ToIdent, - Generator, GeneratorOutput, LateCtx, + Generator, GeneratorOutput, }; use super::{define_generator, generated_header}; @@ -54,9 +55,8 @@ fn derive( ctx: &LateCtx, ) -> TokenStream { let impls: Vec = ctx - .schema - .definitions - .iter() + .schema() + .into_iter() .filter(|def| def.visitable()) .map(|def| match &def { TypeDef::Enum(def) => derive_enum(def, trait_name, method_name, self_type, result_type), diff --git a/tasks/ast_codegen/src/generators/mod.rs b/tasks/ast_codegen/src/generators/mod.rs index 07dd1e5516fe16..55070d68894dfb 100644 --- a/tasks/ast_codegen/src/generators/mod.rs +++ b/tasks/ast_codegen/src/generators/mod.rs @@ -1,4 +1,8 @@ -use crate::{GeneratorOutput, LateCtx}; +use std::path::PathBuf; + +use proc_macro2::TokenStream; + +use crate::codegen::LateCtx; mod assert_layouts; mod ast_builder; @@ -22,6 +26,102 @@ macro_rules! endl { }; } +pub trait Generator { + fn generate(&mut self, ctx: &LateCtx) -> GeneratorOutput; +} + +pub type GeneratedTokenStream = (/* output path */ PathBuf, TokenStream); +pub type GeneratedDataStream = (/* output path */ PathBuf, Vec); + +// TODO: remove me +#[allow(dead_code)] +#[derive(Debug, Clone)] +pub enum GeneratorOutput { + None, + Info(Vec), + Data(GeneratedDataStream), + Stream(GeneratedTokenStream), +} + +// TODO: remove me +#[allow(dead_code)] +impl GeneratorOutput { + pub fn is_none(&self) -> bool { + matches!(self, Self::None) + } + + pub fn expect_none(&self) { + assert!(self.is_none()); + } + + pub fn to_info(&self) -> &[u8] { + if let Self::Info(it) = self { + it + } else { + panic!(); + } + } + + pub fn to_data(&self) -> &GeneratedDataStream { + if let Self::Data(it) = self { + it + } else { + panic!(); + } + } + + pub fn to_stream(&self) -> &GeneratedTokenStream { + if let Self::Stream(it) = self { + it + } else { + panic!(); + } + } + + pub fn into_info(self) -> Vec { + if let Self::Info(it) = self { + it + } else { + panic!(); + } + } + + pub fn into_data(self) -> GeneratedDataStream { + if let Self::Data(it) = self { + it + } else { + panic!(); + } + } + + pub fn into_stream(self) -> GeneratedTokenStream { + if let Self::Stream(it) = self { + it + } else { + panic!(); + } + } +} + +macro_rules! define_generator { + ($vis:vis struct $ident:ident $($lifetime:lifetime)? $($rest:tt)*) => { + $vis struct $ident $($lifetime)? $($rest)* + impl $($lifetime)? $crate::codegen::Runner for $ident $($lifetime)? { + type Context = $crate::codegen::LateCtx; + type Output = $crate::GeneratorOutput; + + fn name(&self) -> &'static str { + stringify!($ident) + } + + fn run(&mut self, ctx: &$crate::codegen::LateCtx) -> $crate::Result { + Ok(self.generate(ctx)) + } + } + }; +} +pub(crate) use define_generator; + /// Similar to how `insert` macro works in the context of `quote` macro family, But this one can be /// used outside and accepts expressions. /// Wraps the result of the given expression in `insert!({value here});` and outputs it as `TokenStream`. @@ -47,27 +147,5 @@ macro_rules! generated_header { } }}; } -pub(crate) use generated_header; - -pub trait Generator { - fn generate(&mut self, ctx: &LateCtx) -> GeneratorOutput; -} - -macro_rules! define_generator { - ($vis:vis struct $ident:ident $($lifetime:lifetime)? $($rest:tt)*) => { - $vis struct $ident $($lifetime)? $($rest)* - impl $($lifetime)? $crate::Runner for $ident $($lifetime)? { - type Context = $crate::LateCtx; - type Output = $crate::GeneratorOutput; - - fn name(&self) -> &'static str { - stringify!($ident) - } - fn run(&mut self, ctx: &$crate::LateCtx) -> $crate::Result { - Ok(self.generate(ctx)) - } - } - }; -} -pub(crate) use define_generator; +pub(crate) use generated_header; diff --git a/tasks/ast_codegen/src/generators/visit.rs b/tasks/ast_codegen/src/generators/visit.rs index d6bc5e2298ce8c..8ba8e4ecd7d326 100644 --- a/tasks/ast_codegen/src/generators/visit.rs +++ b/tasks/ast_codegen/src/generators/visit.rs @@ -7,12 +7,13 @@ use quote::{format_ident, quote, ToTokens}; use syn::{parse_quote, Ident}; use crate::{ + codegen::LateCtx, generators::{ast_kind::BLACK_LIST as KIND_BLACK_LIST, insert}, markers::{ScopeMarkers, VisitArg, VisitMarkers}, output, schema::{EnumDef, GetIdent, StructDef, ToType, TypeDef}, util::{StrExt, ToIdent, TokenStreamExt, TypeWrapper}, - Generator, GeneratorOutput, LateCtx, + Generator, GeneratorOutput, }; use super::{define_generator, generated_header}; @@ -156,9 +157,8 @@ impl<'a> VisitBuilder<'a> { fn build(mut self) -> (/* visits */ Vec, /* walks */ Vec) { let program = self .ctx - .schema - .definitions - .iter() + .schema() + .into_iter() .filter(|it| it.visitable()) .find(|it| it.name() == "Program") .expect("Couldn't find the `Program` type!"); diff --git a/tasks/ast_codegen/src/main.rs b/tasks/ast_codegen/src/main.rs index bbf25b9cdcf48c..67d46761106226 100644 --- a/tasks/ast_codegen/src/main.rs +++ b/tasks/ast_codegen/src/main.rs @@ -1,10 +1,11 @@ -use std::{cell::RefCell, collections::HashMap, io::Read, path::PathBuf, rc::Rc}; +use std::{cell::RefCell, io::Read, path::PathBuf, rc::Rc}; use bpaf::{Bpaf, Parser}; +use codegen::{AstCodegen, AstCodegenResult}; use itertools::Itertools; -use proc_macro2::TokenStream; use syn::parse_file; +mod codegen; mod fmt; mod generators; mod layout; @@ -17,11 +18,10 @@ mod util; use fmt::{cargo_fmt, pprint}; use generators::{ AssertLayouts, AstBuilderGenerator, AstKindGenerator, DeriveCloneIn, DeriveGetSpan, - DeriveGetSpanMut, Generator, VisitGenerator, VisitMutGenerator, + DeriveGetSpanMut, GeneratedDataStream, GeneratedTokenStream, Generator, GeneratorOutput, + VisitGenerator, VisitMutGenerator, }; -use passes::{CalcLayout, Linker, Pass}; -use rust_ast::AstRef; -use schema::{lower_ast_types, Schema, TypeDef}; +use passes::{CalcLayout, Linker}; use util::{write_all_to, NormalizeError}; static SOURCE_PATHS: &[&str] = &[ @@ -36,14 +36,9 @@ static SOURCE_PATHS: &[&str] = &[ ]; const AST_CRATE: &str = "crates/oxc_ast"; -#[allow(dead_code)] -const AST_MACROS_CRATE: &str = "crates/oxc_ast_macros"; type Result = std::result::Result; type TypeId = usize; -type TypeTable = Vec; -type DefTable = Vec; -type IdentTable = HashMap; #[derive(Debug, Bpaf)] pub struct CliOptions { @@ -57,217 +52,10 @@ pub struct CliOptions { schema: Option, } -#[derive(Default)] -struct AstCodegen { - files: Vec, - passes: Vec>>, - builders: Vec>>, -} - -type GeneratedStream = (/* output path */ PathBuf, TokenStream); -type DataStream = (/* output path */ PathBuf, Vec); - -// TODO: remove me -#[allow(dead_code)] -#[derive(Debug, Clone)] -enum GeneratorOutput { - None, - Info(Vec), - Data(DataStream), - Stream(GeneratedStream), -} - -// TODO: remove me -#[allow(dead_code)] -impl GeneratorOutput { - pub fn is_none(&self) -> bool { - matches!(self, Self::None) - } - - pub fn expect_none(&self) { - assert!(self.is_none()); - } - - pub fn to_info(&self) -> &[u8] { - if let Self::Info(it) = self { - it - } else { - panic!(); - } - } - - pub fn to_data(&self) -> &DataStream { - if let Self::Data(it) = self { - it - } else { - panic!(); - } - } - - pub fn to_stream(&self) -> &GeneratedStream { - if let Self::Stream(it) = self { - it - } else { - panic!(); - } - } - - pub fn into_info(self) -> Vec { - if let Self::Info(it) = self { - it - } else { - panic!(); - } - } - - pub fn into_data(self) -> DataStream { - if let Self::Data(it) = self { - it - } else { - panic!(); - } - } - - pub fn into_stream(self) -> GeneratedStream { - if let Self::Stream(it) = self { - it - } else { - panic!(); - } - } -} - -struct EarlyCtx { - ty_table: TypeTable, - ident_table: IdentTable, - mods: RefCell>, -} - -impl EarlyCtx { - fn new(mods: Vec) -> Self { - // worst case len - let len = mods.iter().fold(0, |acc, it| acc + it.items.len()); - let adts = mods.iter().flat_map(|it| it.items.iter()); - - let mut ty_table = TypeTable::with_capacity(len); - let mut ident_table = IdentTable::with_capacity(len); - for adt in adts { - if let Some(ident) = adt.borrow().ident() { - let ident = ident.to_string(); - let type_id = ty_table.len(); - ty_table.push(AstRef::clone(adt)); - ident_table.insert(ident, type_id); - } - } - - Self { ty_table, ident_table, mods: RefCell::new(mods) } - } - - fn into_late_ctx(self) -> LateCtx { - let schema = lower_ast_types(&self); - - LateCtx { schema } - } - - fn find(&self, key: &String) -> Option { - self.type_id(key).map(|id| AstRef::clone(&self.ty_table[id])) - } - - fn type_id(&self, key: &String) -> Option { - self.ident_table.get(key).copied() - } - - fn ast_ref(&self, id: TypeId) -> AstRef { - AstRef::clone(&self.ty_table[id]) - } -} - -struct LateCtx { - schema: Schema, -} - -struct CodegenResult { - schema: Schema, - outputs: Vec<(/* generator name */ &'static str, /* output */ GeneratorOutput)>, -} - -impl LateCtx { - fn type_def(&self, id: TypeId) -> Option<&TypeDef> { - self.schema.definitions.get(id) - } -} - -trait Runner { - type Context; - type Output; - fn name(&self) -> &'static str; - fn run(&mut self, ctx: &Self::Context) -> Result; -} - -impl AstCodegen { - #[must_use] - fn add_file

(mut self, path: P) -> Self - where - P: AsRef, - { - self.files.push(path.as_ref().into()); - self - } - - #[must_use] - fn pass

(mut self, pass: P) -> Self - where - P: Pass + Runner + 'static, - { - self.passes.push(Box::new(pass)); - self - } - - #[must_use] - fn gen(mut self, generator: G) -> Self - where - G: Generator + Runner + 'static, - { - self.builders.push(Box::new(generator)); - self - } - - fn generate(self) -> Result { - let modules = self - .files - .into_iter() - .map(rust_ast::Module::from) - .map(rust_ast::Module::load) - .map_ok(rust_ast::Module::expand) - .map_ok(|it| it.map(rust_ast::Module::analyze)) - .collect::>>>>()???; - - // early passes - let ctx = { - let ctx = EarlyCtx::new(modules); - _ = self - .passes - .into_iter() - .map(|mut runner| runner.run(&ctx).map(|res| (runner.name(), res))) - .collect::>>()?; - ctx.into_late_ctx() - }; - - let outputs = self - .builders - .into_iter() - .map(|mut runner| runner.run(&ctx).map(|res| (runner.name(), res))) - .collect::>>()?; - - Ok(CodegenResult { outputs, schema: ctx.schema }) - } -} - -#[allow(clippy::print_stdout)] fn main() -> std::result::Result<(), Box> { let cli_options = cli_options().run(); - let CodegenResult { outputs, schema } = SOURCE_PATHS + let AstCodegenResult { outputs, schema } = SOURCE_PATHS .iter() .fold(AstCodegen::default(), AstCodegen::add_file) .pass(Linker) @@ -316,7 +104,7 @@ fn output(krate: &str, path: &str) -> PathBuf { /// Writes all streams and returns a vector pointing to side-effects written on the disk fn write_generated_streams( - streams: impl IntoIterator, + streams: impl IntoIterator, ) -> std::io::Result> { streams .into_iter() @@ -332,7 +120,7 @@ fn write_generated_streams( /// Writes all streams and returns a vector pointing to side-effects written on the disk fn write_data_streams( - streams: impl IntoIterator, + streams: impl IntoIterator, ) -> std::io::Result> { streams .into_iter() diff --git a/tasks/ast_codegen/src/passes/calc_layout.rs b/tasks/ast_codegen/src/passes/calc_layout.rs index 678dbf6710aad9..3e82dfe94e2954 100644 --- a/tasks/ast_codegen/src/passes/calc_layout.rs +++ b/tasks/ast_codegen/src/passes/calc_layout.rs @@ -6,10 +6,11 @@ use quote::ToTokens; use syn::Type; use crate::{ + codegen::EarlyCtx, layout::{KnownLayout, Layout}, rust_ast::{AstRef, AstType, Enum, Struct}, util::{NormalizeError, TypeAnalysis, TypeExt, TypeWrapper}, - EarlyCtx, Result, + Result, }; use super::{define_pass, Pass}; diff --git a/tasks/ast_codegen/src/passes/linker.rs b/tasks/ast_codegen/src/passes/linker.rs index 23a360184b9761..d26bbbc40e82ea 100644 --- a/tasks/ast_codegen/src/passes/linker.rs +++ b/tasks/ast_codegen/src/passes/linker.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use syn::parse_quote; -use crate::{rust_ast::Inherit, util::NormalizeError, EarlyCtx}; +use crate::{codegen::EarlyCtx, rust_ast::Inherit, util::NormalizeError}; use super::{define_pass, AstType, Pass, Result}; diff --git a/tasks/ast_codegen/src/passes/mod.rs b/tasks/ast_codegen/src/passes/mod.rs index e98696fa23f467..4328e41893590a 100644 --- a/tasks/ast_codegen/src/passes/mod.rs +++ b/tasks/ast_codegen/src/passes/mod.rs @@ -1,8 +1,6 @@ use std::collections::VecDeque; -use itertools::Itertools; - -use crate::{rust_ast::AstType, EarlyCtx, Result}; +use crate::{codegen::EarlyCtx, rust_ast::AstType, Result}; mod calc_layout; mod linker; @@ -28,13 +26,13 @@ pub trait Pass { // call each // we sort by `TypeId` so we always have the same ordering as how it is written in the rust. - let mut unresolved = - ctx.ident_table.iter().sorted_by_key(|it| it.1).map(|it| it.0).collect::>(); + let mut unresolved = ctx.chronological_idents().collect::>(); while let Some(next) = unresolved.pop_back() { let next_id = ctx.type_id(next).unwrap(); - let val = &mut ctx.ty_table[next_id].borrow_mut(); + let ast_ref = ctx.ast_ref(next_id); + let val = &mut ast_ref.borrow_mut(); if !self.each(val, ctx)? { unresolved.push_front(next); @@ -47,8 +45,8 @@ pub trait Pass { macro_rules! define_pass { ($vis:vis struct $ident:ident $($lifetime:lifetime)? $($rest:tt)*) => { $vis struct $ident $($lifetime)? $($rest)* - impl $($lifetime)? $crate::Runner for $ident $($lifetime)? { - type Context = $crate::EarlyCtx; + impl $($lifetime)? $crate::codegen::Runner for $ident $($lifetime)? { + type Context = $crate::codegen::EarlyCtx; type Output = (); fn name(&self) -> &'static str { stringify!($ident) diff --git a/tasks/ast_codegen/src/schema/mod.rs b/tasks/ast_codegen/src/schema/mod.rs index d588e9a8fb62e7..e0828f80eaeac3 100644 --- a/tasks/ast_codegen/src/schema/mod.rs +++ b/tasks/ast_codegen/src/schema/mod.rs @@ -2,11 +2,12 @@ use quote::ToTokens; use serde::Serialize; use crate::{ + codegen, layout::KnownLayout, markers::{get_scope_attr, get_scope_markers, get_visit_markers}, rust_ast as rust, util::{unexpanded_macro_err, TypeExt}, - DefTable, Result, + Result, TypeId, }; mod defs; @@ -83,7 +84,22 @@ impl<'a> From> for TypeName { #[derive(Debug, Default, serde::Serialize)] pub struct Schema { - pub definitions: DefTable, + defs: Vec, +} + +impl Schema { + pub fn get(&self, id: TypeId) -> Option<&TypeDef> { + self.defs.get(id) + } +} + +impl<'a> IntoIterator for &'a Schema { + type Item = &'a TypeDef; + type IntoIter = std::slice::Iter<'a, TypeDef>; + + fn into_iter(self) -> Self::IntoIter { + self.defs.iter() + } } fn parse_outer_markers(attrs: &Vec) -> Result { @@ -99,18 +115,18 @@ fn parse_inner_markers(attrs: &Vec) -> Result { } // lower `AstType` to `TypeDef`. -pub fn lower_ast_types(ctx: &crate::EarlyCtx) -> Schema { - let definitions = ctx - .mods +pub fn lower_ast_types(ctx: &codegen::EarlyCtx) -> Schema { + let defs = ctx + .mods() .borrow() .iter() .flat_map(|it| &it.items) .map(|it| lower_ast_type(&it.borrow(), ctx)) .collect(); - Schema { definitions } + Schema { defs } } -fn lower_ast_type(ty: &rust::AstType, ctx: &crate::EarlyCtx) -> TypeDef { +fn lower_ast_type(ty: &rust::AstType, ctx: &codegen::EarlyCtx) -> TypeDef { match ty { rust::AstType::Enum(it) => TypeDef::Enum(lower_ast_enum(it, ctx)), rust::AstType::Struct(it) => TypeDef::Struct(lower_ast_struct(it, ctx)), @@ -118,7 +134,7 @@ fn lower_ast_type(ty: &rust::AstType, ctx: &crate::EarlyCtx) -> TypeDef { } } -fn lower_ast_enum(it @ rust::Enum { item, meta }: &rust::Enum, ctx: &crate::EarlyCtx) -> EnumDef { +fn lower_ast_enum(it @ rust::Enum { item, meta }: &rust::Enum, ctx: &codegen::EarlyCtx) -> EnumDef { let (size_64, align_64, offsets_64) = meta .layout_64 .clone() @@ -155,7 +171,7 @@ fn lower_ast_enum(it @ rust::Enum { item, meta }: &rust::Enum, ctx: &crate::Earl fn lower_ast_struct( it @ rust::Struct { item, meta }: &rust::Struct, - ctx: &crate::EarlyCtx, + ctx: &codegen::EarlyCtx, ) -> StructDef { let (size_64, align_64, offsets_64) = meta .layout_64 @@ -185,7 +201,7 @@ fn lower_ast_struct( } } -fn lower_variant(variant: &syn::Variant, enum_dbg_name: F, ctx: &crate::EarlyCtx) -> VariantDef +fn lower_variant(variant: &syn::Variant, enum_dbg_name: F, ctx: &codegen::EarlyCtx) -> VariantDef where F: Fn() -> String, { @@ -205,7 +221,7 @@ where } } -fn lower_inherit(inherit: &rust::Inherit, ctx: &crate::EarlyCtx) -> InheritDef { +fn lower_inherit(inherit: &rust::Inherit, ctx: &codegen::EarlyCtx) -> InheritDef { match inherit { rust::Inherit::Linked { super_, variants } => InheritDef { super_: create_type_ref(super_, ctx), @@ -220,7 +236,7 @@ fn lower_inherit(inherit: &rust::Inherit, ctx: &crate::EarlyCtx) -> InheritDef { } } -fn lower_field(field: &syn::Field, ctx: &crate::EarlyCtx) -> FieldDef { +fn lower_field(field: &syn::Field, ctx: &codegen::EarlyCtx) -> FieldDef { FieldDef { name: field.ident.as_ref().map(ToString::to_string), vis: Visibility::from(&field.vis), @@ -230,7 +246,7 @@ fn lower_field(field: &syn::Field, ctx: &crate::EarlyCtx) -> FieldDef { } } -fn create_type_ref(ty: &syn::Type, ctx: &crate::EarlyCtx) -> TypeRef { +fn create_type_ref(ty: &syn::Type, ctx: &codegen::EarlyCtx) -> TypeRef { let ident = ty.get_ident(); let id = ident.as_ident().and_then(|id| ctx.type_id(&id.to_string())); let transparent_id = ctx.type_id(&ident.inner_ident().to_string()); diff --git a/tasks/ast_codegen/src/util.rs b/tasks/ast_codegen/src/util.rs index 8ebbde3efc2294..0610ea72e02c80 100644 --- a/tasks/ast_codegen/src/util.rs +++ b/tasks/ast_codegen/src/util.rs @@ -4,7 +4,7 @@ use quote::{format_ident, ToTokens}; use serde::Serialize; use syn::{spanned::Spanned, GenericArgument, Ident, ItemMacro, PathArguments, Type, TypePath}; -use crate::{EarlyCtx, TypeId}; +use crate::{codegen::EarlyCtx, TypeId}; pub trait NormalizeError { fn normalize(self) -> crate::Result;