diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 73f7713..237c293 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -81,7 +81,7 @@ pub fn class_decl( let v_table = methods .iter() .filter_map(|method| match method.item.visibility { - Visibility::Public => Some((method.item.name.clone(), method.item.is_override)), + Visibility::Public => Some((method.item.name.clone(), method.item.is_override.clone())), _ => None, }) .collect::>(); @@ -126,7 +126,7 @@ pub fn class_decl( cg.addln("::__V_TABLE;"); for (name, is_override) in v_table { - if is_override { + if is_override.is_some() { cg.add_indentedln(&format!( "table[{}::__FN_{}] = Self::__m_{} as *const std::ffi::c_void;", inherits.get_rust(), @@ -145,7 +145,7 @@ pub fn class_decl( cg.indent += 1; for i in &methods { - if i.item.is_override { + if i.item.is_override.is_some() { let mut params = i .item .params @@ -200,7 +200,7 @@ pub fn class_decl( for mut method in methods { match method.item.visibility { Visibility::Public => { - if !method.item.is_override { + if method.item.is_override.is_none() { gen_method_point(&method.item, ctx, cg); } @@ -358,7 +358,7 @@ impl GenRust column: self.1.column, item: FunctionDecl { visibility: self.1.item.visibility.clone(), - is_override: false, + is_override: None, name: Identifier(String::from("constructor")), generics: self.1.item.generics.clone(), params: ParamList(constructor_params), diff --git a/crates/parser/src/ast/top_level.rs b/crates/parser/src/ast/top_level.rs index f6fe296..b1196b6 100644 --- a/crates/parser/src/ast/top_level.rs +++ b/crates/parser/src/ast/top_level.rs @@ -91,10 +91,13 @@ pub struct ClassConstructor { pub body: Block, } +#[derive(Debug, Clone, Serialize)] +pub struct Override(pub Option); + #[derive(Debug, Clone, Serialize)] pub struct FunctionDecl { pub visibility: Visibility, - pub is_override: bool, + pub is_override: Option, pub name: Identifier, pub generics: GenericsDecl, pub params: ParamList, diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 3c20825..3a0d648 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -325,7 +325,7 @@ trait_decl = { // FUNCTIONS // ====================================================== -override_kw = { "override" } +override_kw = { "override" ~ ("(" ~ expr_path ~ ")")? } function_decl = { visibility? ~ override_kw? ~ "fn" ~ identifier ~ generics_decl? ~ "(" ~ method_args ~ ")" ~ type_expr? ~ (block | semicolon) diff --git a/crates/parser/src/parser/items/function.rs b/crates/parser/src/parser/items/function.rs index 4e68469..18b720b 100644 --- a/crates/parser/src/parser/items/function.rs +++ b/crates/parser/src/parser/items/function.rs @@ -13,7 +13,7 @@ impl<'a> TryFrom> for FunctionDecl { ast_ensure!(pair, Rule::function_decl => { let mut inner = pair.into_inner(); let visibility = Visibility::try_from(&mut inner); - let is_override: AstResult = Ok(listen_rule(&mut inner, Rule::override_kw)); + let is_override = consume_rule(&mut inner, Rule::override_kw).map(Override::try_from).transpose(); let name = Identifier::try_from(inner.next().unwrap()); let generics = consume_rule(&mut inner, Rule::generics_decl) @@ -77,3 +77,13 @@ impl<'a> TryFrom> for FunctionDecl { }) } } + +impl<'a> TryFrom> for Override { + type Error = AstError<'a, Self>; + + fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result { + ast_ensure!(pair, Rule::override_kw => { + ast_expr!(Override(pair.into_inner().next().map(ExprPath::try_from).transpose())) + }) + } +}