--- a/crates/jrsonnet-rowan-parser/jsonnet.ungram +++ b/crates/jrsonnet-rowan-parser/jsonnet.ungram @@ -136,6 +136,7 @@ | '<<' | '>>' | '+' | '-' | '*' | '/' | '%' +| 'META_OBJECT_APPLY!' | 'ERROR_NO_OPERATOR!' UnaryOperator = --- a/crates/jrsonnet-rowan-parser/src/binary.rs +++ /dev/null @@ -1,48 +0,0 @@ -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum BinaryOperator { - Mul, - Div, - Mod, - Plus, - Minus, - ShiftLeft, - ShiftRight, - LessThan, - GreaterThan, - LessThanOrEqual, - GreaterThanOrEqual, - Equal, - NotEqual, - BitAnd, - BitXor, - BitOr, - And, - Or, - In, - ObjectApply, - #[allow(dead_code)] - Invalid, -} - -impl BinaryOperator { - pub fn binding_power(&self) -> (u8, u8) { - match self { - Self::ObjectApply => (22, 23), - Self::Mul | Self::Div | Self::Mod => (20, 21), - Self::Plus | Self::Minus => (18, 19), - Self::ShiftLeft | Self::ShiftRight => (16, 17), - Self::LessThan - | Self::GreaterThan - | Self::LessThanOrEqual - | Self::GreaterThanOrEqual - | Self::In => (14, 15), - Self::Equal | Self::NotEqual => (12, 13), - Self::BitAnd => (10, 11), - Self::BitXor => (8, 9), - Self::BitOr => (6, 7), - Self::And => (4, 5), - Self::Or => (2, 3), - Self::Invalid => (0, 1), - } - } -} --- a/crates/jrsonnet-rowan-parser/src/generated/nodes.rs +++ b/crates/jrsonnet-rowan-parser/src/generated/nodes.rs @@ -1005,6 +1005,7 @@ Mul, Div, Modulo, + MetaObjectApply, ErrorNoOperator, } @@ -2508,101 +2509,51 @@ } impl AstToken for BinaryOperator { fn can_cast(kind: SyntaxKind) -> bool { + BinaryOperatorKind::can_cast(kind) + } + fn cast(syntax: SyntaxToken) -> Option { + let kind = BinaryOperatorKind::cast(syntax.kind())?; + Some(BinaryOperator { syntax, kind }) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl BinaryOperatorKind { + fn can_cast(kind: SyntaxKind) -> bool { match kind { OR | AND | BIT_OR | BIT_XOR | BIT_AND | EQ | NE | LT | GT | LE | GE | IN_KW | LHS - | RHS | PLUS | MINUS | MUL | DIV | MODULO | ERROR_NO_OPERATOR => true, + | RHS | PLUS | MINUS | MUL | DIV | MODULO | META_OBJECT_APPLY | ERROR_NO_OPERATOR => true, _ => false, } } - fn cast(syntax: SyntaxToken) -> Option { - let res = match syntax.kind() { - OR => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Or, - }, - AND => BinaryOperator { - syntax, - kind: BinaryOperatorKind::And, - }, - BIT_OR => BinaryOperator { - syntax, - kind: BinaryOperatorKind::BitOr, - }, - BIT_XOR => BinaryOperator { - syntax, - kind: BinaryOperatorKind::BitXor, - }, - BIT_AND => BinaryOperator { - syntax, - kind: BinaryOperatorKind::BitAnd, - }, - EQ => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Eq, - }, - NE => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Ne, - }, - LT => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Lt, - }, - GT => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Gt, - }, - LE => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Le, - }, - GE => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Ge, - }, - IN_KW => BinaryOperator { - syntax, - kind: BinaryOperatorKind::InKw, - }, - LHS => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Lhs, - }, - RHS => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Rhs, - }, - PLUS => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Plus, - }, - MINUS => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Minus, - }, - MUL => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Mul, - }, - DIV => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Div, - }, - MODULO => BinaryOperator { - syntax, - kind: BinaryOperatorKind::Modulo, - }, - ERROR_NO_OPERATOR => BinaryOperator { - syntax, - kind: BinaryOperatorKind::ErrorNoOperator, - }, + pub fn cast(kind: SyntaxKind) -> Option { + let res = match kind { + OR => Self::Or, + AND => Self::And, + BIT_OR => Self::BitOr, + BIT_XOR => Self::BitXor, + BIT_AND => Self::BitAnd, + EQ => Self::Eq, + NE => Self::Ne, + LT => Self::Lt, + GT => Self::Gt, + LE => Self::Le, + GE => Self::Ge, + IN_KW => Self::InKw, + LHS => Self::Lhs, + RHS => Self::Rhs, + PLUS => Self::Plus, + MINUS => Self::Minus, + MUL => Self::Mul, + DIV => Self::Div, + MODULO => Self::Modulo, + META_OBJECT_APPLY => Self::MetaObjectApply, + ERROR_NO_OPERATOR => Self::ErrorNoOperator, _ => return None, }; Some(res) } - fn syntax(&self) -> &SyntaxToken { - &self.syntax - } } impl BinaryOperator { pub fn kind(&self) -> BinaryOperatorKind { @@ -2616,31 +2567,31 @@ } impl AstToken for UnaryOperator { fn can_cast(kind: SyntaxKind) -> bool { + UnaryOperatorKind::can_cast(kind) + } + fn cast(syntax: SyntaxToken) -> Option { + let kind = UnaryOperatorKind::cast(syntax.kind())?; + Some(UnaryOperator { syntax, kind }) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl UnaryOperatorKind { + fn can_cast(kind: SyntaxKind) -> bool { match kind { MINUS | NOT | BIT_NOT => true, _ => false, } } - fn cast(syntax: SyntaxToken) -> Option { - let res = match syntax.kind() { - MINUS => UnaryOperator { - syntax, - kind: UnaryOperatorKind::Minus, - }, - NOT => UnaryOperator { - syntax, - kind: UnaryOperatorKind::Not, - }, - BIT_NOT => UnaryOperator { - syntax, - kind: UnaryOperatorKind::BitNot, - }, + pub fn cast(kind: SyntaxKind) -> Option { + let res = match kind { + MINUS => Self::Minus, + NOT => Self::Not, + BIT_NOT => Self::BitNot, _ => return None, }; Some(res) - } - fn syntax(&self) -> &SyntaxToken { - &self.syntax } } impl UnaryOperator { @@ -2655,44 +2606,35 @@ } impl AstToken for Literal { fn can_cast(kind: SyntaxKind) -> bool { + LiteralKind::can_cast(kind) + } + fn cast(syntax: SyntaxToken) -> Option { + let kind = LiteralKind::cast(syntax.kind())?; + Some(Literal { syntax, kind }) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl LiteralKind { + fn can_cast(kind: SyntaxKind) -> bool { match kind { NULL_KW | TRUE_KW | FALSE_KW | SELF_KW | DOLLAR | SUPER_KW => true, _ => false, } } - fn cast(syntax: SyntaxToken) -> Option { - let res = match syntax.kind() { - NULL_KW => Literal { - syntax, - kind: LiteralKind::NullKw, - }, - TRUE_KW => Literal { - syntax, - kind: LiteralKind::TrueKw, - }, - FALSE_KW => Literal { - syntax, - kind: LiteralKind::FalseKw, - }, - SELF_KW => Literal { - syntax, - kind: LiteralKind::SelfKw, - }, - DOLLAR => Literal { - syntax, - kind: LiteralKind::Dollar, - }, - SUPER_KW => Literal { - syntax, - kind: LiteralKind::SuperKw, - }, + pub fn cast(kind: SyntaxKind) -> Option { + let res = match kind { + NULL_KW => Self::NullKw, + TRUE_KW => Self::TrueKw, + FALSE_KW => Self::FalseKw, + SELF_KW => Self::SelfKw, + DOLLAR => Self::Dollar, + SUPER_KW => Self::SuperKw, _ => return None, }; Some(res) } - fn syntax(&self) -> &SyntaxToken { - &self.syntax - } } impl Literal { pub fn kind(&self) -> LiteralKind { @@ -2706,6 +2648,18 @@ } impl AstToken for Text { fn can_cast(kind: SyntaxKind) -> bool { + TextKind::can_cast(kind) + } + fn cast(syntax: SyntaxToken) -> Option { + let kind = TextKind::cast(syntax.kind())?; + Some(Text { syntax, kind }) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl TextKind { + fn can_cast(kind: SyntaxKind) -> bool { match kind { STRING_DOUBLE | ERROR_STRING_DOUBLE_UNTERMINATED @@ -2724,71 +2678,30 @@ _ => false, } } - fn cast(syntax: SyntaxToken) -> Option { - let res = match syntax.kind() { - STRING_DOUBLE => Text { - syntax, - kind: TextKind::StringDouble, - }, - ERROR_STRING_DOUBLE_UNTERMINATED => Text { - syntax, - kind: TextKind::ErrorStringDoubleUnterminated, - }, - STRING_SINGLE => Text { - syntax, - kind: TextKind::StringSingle, - }, - ERROR_STRING_SINGLE_UNTERMINATED => Text { - syntax, - kind: TextKind::ErrorStringSingleUnterminated, - }, - STRING_DOUBLE_VERBATIM => Text { - syntax, - kind: TextKind::StringDoubleVerbatim, - }, - ERROR_STRING_DOUBLE_VERBATIM_UNTERMINATED => Text { - syntax, - kind: TextKind::ErrorStringDoubleVerbatimUnterminated, - }, - STRING_SINGLE_VERBATIM => Text { - syntax, - kind: TextKind::StringSingleVerbatim, - }, - ERROR_STRING_SINGLE_VERBATIM_UNTERMINATED => Text { - syntax, - kind: TextKind::ErrorStringSingleVerbatimUnterminated, - }, - ERROR_STRING_VERBATIM_MISSING_QUOTES => Text { - syntax, - kind: TextKind::ErrorStringVerbatimMissingQuotes, - }, - STRING_BLOCK => Text { - syntax, - kind: TextKind::StringBlock, - }, - ERROR_STRING_BLOCK_UNEXPECTED_END => Text { - syntax, - kind: TextKind::ErrorStringBlockUnexpectedEnd, - }, - ERROR_STRING_BLOCK_MISSING_NEW_LINE => Text { - syntax, - kind: TextKind::ErrorStringBlockMissingNewLine, - }, - ERROR_STRING_BLOCK_MISSING_TERMINATION => Text { - syntax, - kind: TextKind::ErrorStringBlockMissingTermination, - }, - ERROR_STRING_BLOCK_MISSING_INDENT => Text { - syntax, - kind: TextKind::ErrorStringBlockMissingIndent, - }, + pub fn cast(kind: SyntaxKind) -> Option { + let res = match kind { + STRING_DOUBLE => Self::StringDouble, + ERROR_STRING_DOUBLE_UNTERMINATED => Self::ErrorStringDoubleUnterminated, + STRING_SINGLE => Self::StringSingle, + ERROR_STRING_SINGLE_UNTERMINATED => Self::ErrorStringSingleUnterminated, + STRING_DOUBLE_VERBATIM => Self::StringDoubleVerbatim, + ERROR_STRING_DOUBLE_VERBATIM_UNTERMINATED => { + Self::ErrorStringDoubleVerbatimUnterminated + } + STRING_SINGLE_VERBATIM => Self::StringSingleVerbatim, + ERROR_STRING_SINGLE_VERBATIM_UNTERMINATED => { + Self::ErrorStringSingleVerbatimUnterminated + } + ERROR_STRING_VERBATIM_MISSING_QUOTES => Self::ErrorStringVerbatimMissingQuotes, + STRING_BLOCK => Self::StringBlock, + ERROR_STRING_BLOCK_UNEXPECTED_END => Self::ErrorStringBlockUnexpectedEnd, + ERROR_STRING_BLOCK_MISSING_NEW_LINE => Self::ErrorStringBlockMissingNewLine, + ERROR_STRING_BLOCK_MISSING_TERMINATION => Self::ErrorStringBlockMissingTermination, + ERROR_STRING_BLOCK_MISSING_INDENT => Self::ErrorStringBlockMissingIndent, _ => return None, }; Some(res) } - fn syntax(&self) -> &SyntaxToken { - &self.syntax - } } impl Text { pub fn kind(&self) -> TextKind { @@ -2802,6 +2715,18 @@ } impl AstToken for Number { fn can_cast(kind: SyntaxKind) -> bool { + NumberKind::can_cast(kind) + } + fn cast(syntax: SyntaxToken) -> Option { + let kind = NumberKind::cast(syntax.kind())?; + Some(Number { syntax, kind }) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl NumberKind { + fn can_cast(kind: SyntaxKind) -> bool { match kind { FLOAT | ERROR_FLOAT_JUNK_AFTER_POINT @@ -2810,31 +2735,16 @@ _ => false, } } - fn cast(syntax: SyntaxToken) -> Option { - let res = match syntax.kind() { - FLOAT => Number { - syntax, - kind: NumberKind::Float, - }, - ERROR_FLOAT_JUNK_AFTER_POINT => Number { - syntax, - kind: NumberKind::ErrorFloatJunkAfterPoint, - }, - ERROR_FLOAT_JUNK_AFTER_EXPONENT => Number { - syntax, - kind: NumberKind::ErrorFloatJunkAfterExponent, - }, - ERROR_FLOAT_JUNK_AFTER_EXPONENT_SIGN => Number { - syntax, - kind: NumberKind::ErrorFloatJunkAfterExponentSign, - }, + pub fn cast(kind: SyntaxKind) -> Option { + let res = match kind { + FLOAT => Self::Float, + ERROR_FLOAT_JUNK_AFTER_POINT => Self::ErrorFloatJunkAfterPoint, + ERROR_FLOAT_JUNK_AFTER_EXPONENT => Self::ErrorFloatJunkAfterExponent, + ERROR_FLOAT_JUNK_AFTER_EXPONENT_SIGN => Self::ErrorFloatJunkAfterExponentSign, _ => return None, }; Some(res) } - fn syntax(&self) -> &SyntaxToken { - &self.syntax - } } impl Number { pub fn kind(&self) -> NumberKind { @@ -2848,32 +2758,32 @@ } impl AstToken for ImportKind { fn can_cast(kind: SyntaxKind) -> bool { + ImportKindKind::can_cast(kind) + } + fn cast(syntax: SyntaxToken) -> Option { + let kind = ImportKindKind::cast(syntax.kind())?; + Some(ImportKind { syntax, kind }) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl ImportKindKind { + fn can_cast(kind: SyntaxKind) -> bool { match kind { IMPORTSTR_KW | IMPORTBIN_KW | IMPORT_KW => true, _ => false, } } - fn cast(syntax: SyntaxToken) -> Option { - let res = match syntax.kind() { - IMPORTSTR_KW => ImportKind { - syntax, - kind: ImportKindKind::ImportstrKw, - }, - IMPORTBIN_KW => ImportKind { - syntax, - kind: ImportKindKind::ImportbinKw, - }, - IMPORT_KW => ImportKind { - syntax, - kind: ImportKindKind::ImportKw, - }, + pub fn cast(kind: SyntaxKind) -> Option { + let res = match kind { + IMPORTSTR_KW => Self::ImportstrKw, + IMPORTBIN_KW => Self::ImportbinKw, + IMPORT_KW => Self::ImportKw, _ => return None, }; Some(res) } - fn syntax(&self) -> &SyntaxToken { - &self.syntax - } } impl ImportKind { pub fn kind(&self) -> ImportKindKind { @@ -2887,31 +2797,31 @@ } impl AstToken for Visibility { fn can_cast(kind: SyntaxKind) -> bool { + VisibilityKind::can_cast(kind) + } + fn cast(syntax: SyntaxToken) -> Option { + let kind = VisibilityKind::cast(syntax.kind())?; + Some(Visibility { syntax, kind }) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl VisibilityKind { + fn can_cast(kind: SyntaxKind) -> bool { match kind { COLONCOLONCOLON | COLONCOLON | COLON => true, _ => false, } } - fn cast(syntax: SyntaxToken) -> Option { - let res = match syntax.kind() { - COLONCOLONCOLON => Visibility { - syntax, - kind: VisibilityKind::Coloncoloncolon, - }, - COLONCOLON => Visibility { - syntax, - kind: VisibilityKind::Coloncolon, - }, - COLON => Visibility { - syntax, - kind: VisibilityKind::Colon, - }, + pub fn cast(kind: SyntaxKind) -> Option { + let res = match kind { + COLONCOLONCOLON => Self::Coloncoloncolon, + COLONCOLON => Self::Coloncolon, + COLON => Self::Colon, _ => return None, }; Some(res) - } - fn syntax(&self) -> &SyntaxToken { - &self.syntax } } impl Visibility { @@ -2926,6 +2836,18 @@ } impl AstToken for Trivia { fn can_cast(kind: SyntaxKind) -> bool { + TriviaKind::can_cast(kind) + } + fn cast(syntax: SyntaxToken) -> Option { + let kind = TriviaKind::cast(syntax.kind())?; + Some(Trivia { syntax, kind }) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl TriviaKind { + fn can_cast(kind: SyntaxKind) -> bool { match kind { WHITESPACE | MULTI_LINE_COMMENT @@ -2936,38 +2858,17 @@ _ => false, } } - fn cast(syntax: SyntaxToken) -> Option { - let res = match syntax.kind() { - WHITESPACE => Trivia { - syntax, - kind: TriviaKind::Whitespace, - }, - MULTI_LINE_COMMENT => Trivia { - syntax, - kind: TriviaKind::MultiLineComment, - }, - ERROR_COMMENT_TOO_SHORT => Trivia { - syntax, - kind: TriviaKind::ErrorCommentTooShort, - }, - ERROR_COMMENT_UNTERMINATED => Trivia { - syntax, - kind: TriviaKind::ErrorCommentUnterminated, - }, - SINGLE_LINE_HASH_COMMENT => Trivia { - syntax, - kind: TriviaKind::SingleLineHashComment, - }, - SINGLE_LINE_SLASH_COMMENT => Trivia { - syntax, - kind: TriviaKind::SingleLineSlashComment, - }, + pub fn cast(kind: SyntaxKind) -> Option { + let res = match kind { + WHITESPACE => Self::Whitespace, + MULTI_LINE_COMMENT => Self::MultiLineComment, + ERROR_COMMENT_TOO_SHORT => Self::ErrorCommentTooShort, + ERROR_COMMENT_UNTERMINATED => Self::ErrorCommentUnterminated, + SINGLE_LINE_HASH_COMMENT => Self::SingleLineHashComment, + SINGLE_LINE_SLASH_COMMENT => Self::SingleLineSlashComment, _ => return None, }; Some(res) - } - fn syntax(&self) -> &SyntaxToken { - &self.syntax } } impl Trivia { --- a/crates/jrsonnet-rowan-parser/src/generated/syntax_kinds.rs +++ b/crates/jrsonnet-rowan-parser/src/generated/syntax_kinds.rs @@ -163,6 +163,7 @@ ERROR_KW, #[token("in")] IN_KW, + META_OBJECT_APPLY, ERROR_NO_OPERATOR, #[token("null")] NULL_KW, --- a/crates/jrsonnet-rowan-parser/src/lib.rs +++ b/crates/jrsonnet-rowan-parser/src/lib.rs @@ -1,17 +1,16 @@ #![deny(unused_must_use)] mod ast; -mod binary; mod event; mod generated; mod language; mod lex; mod marker; mod parser; +mod precedence; mod string_block; mod tests; mod token_set; -mod unary; pub use ast::{AstChildren, AstNode, AstToken}; use event::Sink; --- a/crates/jrsonnet-rowan-parser/src/parser.rs +++ b/crates/jrsonnet-rowan-parser/src/parser.rs @@ -4,13 +4,11 @@ use rowan::{GreenNode, TextRange, TextSize}; use crate::{ - binary::BinaryOperator, event::Event, lex::Lexeme, marker::{AsRange, CompletedMarker, Marker, Ranger}, - nodes::{Literal, Number, Text, Trivia}, + nodes::{BinaryOperatorKind, Literal, Number, Text, Trivia, UnaryOperatorKind}, token_set::SyntaxKindSet, - unary::UnaryOperator, AstToken, SyntaxKind, SyntaxKind::*, SyntaxNode, T, TS, @@ -397,18 +395,6 @@ enum ExpectedSyntaxTrackingState { Named, Unnamed, -} -macro_rules! at_match { - ($p:ident { - $($r:expr => $e:expr,)* - _ => $else:expr $(,)? - }) => {{ - $( - if $p.at($r) {$e} else - )* { - $else - } - }} } fn expr(p: &mut Parser) -> Option { @@ -417,37 +403,16 @@ fn expr_binding_power(p: &mut Parser, minimum_binding_power: u8) -> Option { let mut lhs = lhs(p)?; - loop { - let op = at_match!(p { - T![*] => BinaryOperator::Mul, - T![/] => BinaryOperator::Div, - T![%] => BinaryOperator::Mod, - T![+] => BinaryOperator::Plus, - T![-] => BinaryOperator::Minus, - T![<<] => BinaryOperator::ShiftLeft, - T![>>] => BinaryOperator::ShiftRight, - T![<] => BinaryOperator::LessThan, - T![>] => BinaryOperator::GreaterThan, - T![<=] => BinaryOperator::LessThanOrEqual, - T![>=] => BinaryOperator::GreaterThanOrEqual, - T![==] => BinaryOperator::Equal, - T![!=] => BinaryOperator::NotEqual, - T![&] => BinaryOperator::BitAnd, - T![^] => BinaryOperator::BitXor, - T![|] => BinaryOperator::BitOr, - T![&&] => BinaryOperator::And, - T![||] => BinaryOperator::Or, - T![in] => BinaryOperator::In, - T!['{'] => BinaryOperator::ObjectApply, - _ => break, - }); + while let Some(op) = BinaryOperatorKind::cast(p.current()) + .or_else(|| p.at(T!['{']).then(|| BinaryOperatorKind::MetaObjectApply)) + { let (left_binding_power, right_binding_power) = op.binding_power(); if left_binding_power < minimum_binding_power { break; } // Object apply is not a real operator, we dont have something to bump - if op != BinaryOperator::ObjectApply { + if op != BinaryOperatorKind::MetaObjectApply { p.bump(); } @@ -455,7 +420,7 @@ let parsed_rhs = expr_binding_power(p, right_binding_power).is_some(); lhs = m.complete( p, - if op == BinaryOperator::ObjectApply { + if op == BinaryOperatorKind::MetaObjectApply { EXPR_OBJ_EXTEND } else { EXPR_BINARY @@ -998,13 +963,7 @@ p.bump(); text(p); m.complete(p, EXPR_IMPORT) - } else if p.at(T![-]) || p.at(T![!]) || p.at(T![~]) { - let op = match p.current() { - T![-] => UnaryOperator::Minus, - T![!] => UnaryOperator::Not, - T![~] => UnaryOperator::BitNegate, - _ => unreachable!(), - }; + } else if let Some(op) = UnaryOperatorKind::cast(p.current()) { let ((), right_binding_power) = op.binding_power(); let m = p.start(); --- /dev/null +++ b/crates/jrsonnet-rowan-parser/src/precedence.rs @@ -0,0 +1,30 @@ +use crate::nodes::{BinaryOperatorKind, UnaryOperatorKind}; + +impl BinaryOperatorKind { + pub fn binding_power(&self) -> (u8, u8) { + match self { + Self::MetaObjectApply => (22, 23), + Self::Mul | Self::Div | Self::Modulo => (20, 21), + Self::Plus | Self::Minus => (18, 19), + Self::Lhs | Self::Rhs => (16, 17), + Self::Lt | Self::Gt | Self::Le | Self::Ge | Self::InKw => (14, 15), + Self::Eq | Self::Ne => (12, 13), + Self::BitAnd => (10, 11), + Self::BitXor => (8, 9), + Self::BitOr => (6, 7), + Self::And => (4, 5), + Self::Or => (2, 3), + Self::ErrorNoOperator => (0, 1), + } + } +} + +impl UnaryOperatorKind { + pub fn binding_power(&self) -> ((), u8) { + match self { + Self::Minus => ((), 20), + Self::Not => ((), 20), + Self::BitNot => ((), 20), + } + } +} --- a/crates/jrsonnet-rowan-parser/src/unary.rs +++ /dev/null @@ -1,15 +0,0 @@ -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum UnaryOperator { - Minus, - Not, - BitNegate, -} -impl UnaryOperator { - pub fn binding_power(&self) -> ((), u8) { - match self { - UnaryOperator::Minus => ((), 20), - UnaryOperator::Not => ((), 20), - UnaryOperator::BitNegate => ((), 20), - } - } -} --- a/xtask/src/sourcegen/mod.rs +++ b/xtask/src/sourcegen/mod.rs @@ -353,22 +353,30 @@ let ast_node = quote! { impl AstToken for #name { fn can_cast(kind: SyntaxKind) -> bool { + #kind_name::can_cast(kind) + } + fn cast(syntax: SyntaxToken) -> Option { + let kind = #kind_name::cast(syntax.kind())?; + Some(#name { syntax, kind }) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } + } + + impl #kind_name { + fn can_cast(kind: SyntaxKind) -> bool { match kind { #(#kinds)|* => true, _ => false, } } - fn cast(syntax: SyntaxToken) -> Option { - let res = match syntax.kind() { - #( - #kinds => #name { syntax, kind: #kind_name::#variants }, - )* + pub fn cast(kind: SyntaxKind) -> Option { + let res = match kind { + #(#kinds => Self::#variants,)* _ => return None, }; Some(res) - } - fn syntax(&self) -> &SyntaxToken { - &self.syntax } } };