use super::*;
fn parse_literal<P: ExpressionParser>(p: &mut P) -> bool {
if p.at_any(&[
SyntaxKind::INTEGER,
SyntaxKind::DECIMAL,
SyntaxKind::STRING,
SyntaxKind::TRUE_KW,
SyntaxKind::FALSE_KW,
SyntaxKind::NULL_KW,
]) {
p.bump();
true
} else {
false
}
}
fn parse_instantiation<P: ExpressionParser>(p: &mut P) {
p.bump(); p.skip_trivia();
p.parse_qualified_name();
p.skip_trivia();
if p.at(SyntaxKind::L_PAREN) {
parse_argument_list(p);
}
}
fn parse_block_expression<P: ExpressionParser>(p: &mut P) {
p.bump(); p.skip_trivia();
if !p.at(SyntaxKind::R_BRACE) {
parse_expression(p);
}
p.skip_trivia();
p.expect(SyntaxKind::R_BRACE);
}
fn parse_parenthesized_expression<P: ExpressionParser>(p: &mut P) {
p.bump(); p.skip_trivia();
if !p.at(SyntaxKind::R_PAREN) {
parse_expression(p);
while p.at(SyntaxKind::COMMA) {
p.bump();
p.skip_trivia();
parse_expression(p);
p.skip_trivia();
}
}
p.skip_trivia();
p.expect(SyntaxKind::R_PAREN);
}
fn is_feature_reference_token(kind: SyntaxKind) -> bool {
!matches!(
kind,
SyntaxKind::ERROR
| SyntaxKind::WHITESPACE
| SyntaxKind::LINE_COMMENT
| SyntaxKind::BLOCK_COMMENT
| SyntaxKind::L_BRACE
| SyntaxKind::R_BRACE
| SyntaxKind::L_BRACKET
| SyntaxKind::R_BRACKET
| SyntaxKind::L_PAREN
| SyntaxKind::R_PAREN
| SyntaxKind::SEMICOLON
| SyntaxKind::COLON
| SyntaxKind::COLON_COLON
| SyntaxKind::COLON_GT
| SyntaxKind::COLON_GT_GT
| SyntaxKind::COLON_COLON_GT
| SyntaxKind::DOT
| SyntaxKind::DOT_DOT
| SyntaxKind::COMMA
| SyntaxKind::EQ
| SyntaxKind::EQ_EQ
| SyntaxKind::EQ_EQ_EQ
| SyntaxKind::BANG_EQ
| SyntaxKind::BANG_EQ_EQ
| SyntaxKind::LT
| SyntaxKind::GT
| SyntaxKind::LT_EQ
| SyntaxKind::GT_EQ
| SyntaxKind::AT
| SyntaxKind::AT_AT
| SyntaxKind::HASH
| SyntaxKind::STAR
| SyntaxKind::STAR_STAR
| SyntaxKind::PLUS
| SyntaxKind::MINUS
| SyntaxKind::SLASH
| SyntaxKind::PERCENT
| SyntaxKind::CARET
| SyntaxKind::AMP
| SyntaxKind::AMP_AMP
| SyntaxKind::PIPE
| SyntaxKind::PIPE_PIPE
| SyntaxKind::BANG
| SyntaxKind::TILDE
| SyntaxKind::QUESTION
| SyntaxKind::QUESTION_QUESTION
| SyntaxKind::ARROW
| SyntaxKind::FAT_ARROW
| SyntaxKind::INTEGER
| SyntaxKind::DECIMAL
| SyntaxKind::STRING
| SyntaxKind::TRUE_KW
| SyntaxKind::FALSE_KW
| SyntaxKind::NULL_KW
)
}
fn parse_feature_reference<P: ExpressionParser>(p: &mut P) {
p.parse_qualified_name();
p.skip_trivia();
if p.at(SyntaxKind::L_PAREN) {
parse_argument_list(p);
}
}
fn parse_metadata_access<P: ExpressionParser>(p: &mut P) {
p.bump(); p.skip_trivia();
p.parse_qualified_name();
}
pub fn parse_base_expression<P: ExpressionParser>(p: &mut P) {
p.skip_trivia();
match p.current_kind() {
kind if parse_literal(p) => {}
SyntaxKind::NEW_KW => parse_instantiation(p),
SyntaxKind::L_BRACE => parse_block_expression(p),
SyntaxKind::L_PAREN => parse_parenthesized_expression(p),
kind if is_feature_reference_token(kind) => parse_feature_reference(p),
SyntaxKind::AT => parse_metadata_access(p),
_ => {}
}
}
pub fn parse_argument_list<P: ExpressionParser>(p: &mut P) {
p.start_node(SyntaxKind::ARGUMENT_LIST);
p.expect(SyntaxKind::L_PAREN);
p.skip_trivia();
if !p.at(SyntaxKind::R_PAREN) {
parse_argument_via_trait(p);
p.skip_trivia();
while p.at(SyntaxKind::COMMA) {
p.bump();
p.skip_trivia();
parse_argument_via_trait(p);
p.skip_trivia();
}
}
p.expect(SyntaxKind::R_PAREN);
p.finish_node();
}
fn parse_argument_via_trait<P: ExpressionParser>(p: &mut P) {
p.parse_argument();
}
pub fn parse_argument<P: ExpressionParser>(p: &mut P) {
p.start_node(SyntaxKind::ARGUMENT_LIST);
if p.at(SyntaxKind::IDENT) {
let next = p.peek_kind(1);
if next == SyntaxKind::EQ {
p.bump(); p.skip_trivia();
p.bump(); p.skip_trivia();
}
}
parse_expression(p);
p.finish_node();
}