diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs index 75ae198..a678124 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -26,10 +26,15 @@ pub trait GetRust { } } +pub enum Include { + Glob(Path), + Use(Visibility, Path), +} + pub struct RustCodegen { output: String, indent: usize, - pub crates: HashMap>, + pub crates: HashMap>, pub mapping: Mapping, position: RustMap, } @@ -101,8 +106,17 @@ impl RustCodegen { for item in items { self.add_indented("pub use "); - item.gen_rust(&mut ctx, self); - self.addln("::*;"); + match item { + Include::Glob(item) => { + item.gen_rust(&mut ctx, self); + self.add("::*"); + } + Include::Use(vis, item) => { + vis.gen_rust(&mut ctx, self); + item.gen_rust(&mut ctx, self); + } + } + self.addln(";"); } self.indent -= 1; diff --git a/crates/codegen/src/top_level.rs b/crates/codegen/src/top_level.rs index b65190c..9927a11 100644 --- a/crates/codegen/src/top_level.rs +++ b/crates/codegen/src/top_level.rs @@ -330,7 +330,13 @@ impl GenRust for TopLevelKind { cg.crates .entry(incl.0[0].clone()) .or_insert(Vec::new()) - .push(incl.clone()); + .push(crate::Include::Glob(incl.clone())); + } + Self::IncludeUse(vis, incl) => { + cg.crates + .entry(incl.0[0].clone()) + .or_insert(Vec::new()) + .push(crate::Include::Use(vis.clone(), incl.clone())); } } } diff --git a/crates/parser/src/ast/top_level.rs b/crates/parser/src/ast/top_level.rs index a759d33..707e8c9 100644 --- a/crates/parser/src/ast/top_level.rs +++ b/crates/parser/src/ast/top_level.rs @@ -29,6 +29,7 @@ pub enum TopLevelKind { ModAttribute, Import(Visibility, Path), IncludeGlobal(Path), + IncludeUse(Visibility, Path), DeclareModule(Visibility, Identifier), ImplDecl(ImplDecl), StaticDecl(VarDeclStmt), diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 6eb3973..8e7eeaf 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -262,6 +262,10 @@ include_global = { "#" ~ "include" ~ "<" ~ identifier ~ ("/" ~ identifier)* ~ ">" } +include_use_global = { + visibility? ~ "#" ~ "use" ~ static_path ~ semicolon +} + import = { visibility? ~ "use" ~ static_path ~ semicolon } @@ -388,7 +392,7 @@ type_alias = { "type" ~ identifier ~ generics_decl? ~ "=" ~ type_expr ~ ";" } top_level = { mod_attribute - | (attributes ~ (include_global | import | impl_for_decl | impl_decl | trait_decl | struct_decl | enum_decl | class_decl | declare_module | function_decl | const_decl | static_decl | type_alias)) + | (attributes ~ (include_global | include_use_global | import | impl_for_decl | impl_decl | trait_decl | struct_decl | enum_decl | class_decl | declare_module | function_decl | const_decl | static_decl | type_alias)) } // ====================================================== diff --git a/crates/parser/src/parser/items/mod.rs b/crates/parser/src/parser/items/mod.rs index 2b27e99..b0c1b38 100644 --- a/crates/parser/src/parser/items/mod.rs +++ b/crates/parser/src/parser/items/mod.rs @@ -129,7 +129,14 @@ impl<'a> TryFrom> for TopLevelKind { ty: inner.next().unwrap().try_into()?, }), - Rule::include_global => Ok(TopLevelKind::IncludeGlobal(Path(collect_recovered(&mut inner)?))), + Rule::include_global => Ok(TopLevelKind::IncludeGlobal(Path(collect_recovered( + &mut inner, + )?))), + + Rule::include_use_global => Ok(TopLevelKind::IncludeUse( + Visibility::try_from(&mut inner)?, + Path::try_from(inner.next().unwrap())?, + )), _ => AstError::bug_unimplemented(pair), }