use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(u16)]
#[allow(non_camel_case_types)]
pub enum SyntaxKind {
WHITESPACE,
LINE_COMMENT,
BLOCK_COMMENT,
IDENT,
NUMBER,
STRING,
L_BRACE,
R_BRACE,
L_BRACK,
R_BRACK,
L_PAREN,
R_PAREN,
COMMA,
COLON,
DOT,
AT,
HASH,
AMP,
QUESTION,
EQ,
ELLIPSIS,
EQ_EQ,
BANG_EQ,
LT_EQ,
GT_EQ,
AMP_AMP,
PIPE_PIPE,
PLUS_PLUS,
FAT_ARROW,
THIN_ARROW,
LT,
GT,
PLUS,
MINUS,
STAR,
SLASH,
PERCENT,
BANG,
PIPE,
UNDERSCORE,
UNKNOWN,
F_STRING_OPEN,
F_STRING_CLOSE,
F_STRING_LITERAL,
F_STRING_INTERP_START,
F_STRING_INTERP_END,
DOCUMENT,
DIRECTIVE,
DECORATOR,
DICT,
DICT_FIELD,
LIST,
COMPREHENSION,
CLOSURE,
CLOSURE_PARAM,
CALL_EXPR,
CALL_ARG,
BINARY_EXPR,
UNARY_EXPR,
TERNARY_EXPR,
REFERENCE_EXPR,
VARIABLE_EXPR,
WHERE_EXPR,
MATCH_EXPR,
MATCH_ARM,
MATCH_PATTERN,
VARIANT_CTOR,
F_STRING,
F_STRING_INTERPOLATION,
SPREAD_EXPR,
TYPE_NODE,
WILDCARD,
LITERAL,
ERROR,
TUPLE_TYPE,
SCHEMA_WITH,
SCHEMA_METHOD,
ENUM_VARIANT,
ENUM_VARIANT_FIELD,
TUPLE,
__LAST,
}
impl SyntaxKind {
pub fn is_trivia(self) -> bool {
matches!(
self,
SyntaxKind::WHITESPACE | SyntaxKind::LINE_COMMENT | SyntaxKind::BLOCK_COMMENT
)
}
pub fn is_token(self) -> bool {
(self as u16) < (SyntaxKind::DOCUMENT as u16)
}
pub fn is_node(self) -> bool {
!self.is_token()
}
}
impl fmt::Display for SyntaxKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl From<SyntaxKind> for rowan::SyntaxKind {
fn from(kind: SyntaxKind) -> Self {
rowan::SyntaxKind(kind as u16)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum RelonLanguage {}
impl rowan::Language for RelonLanguage {
type Kind = SyntaxKind;
fn kind_from_raw(raw: rowan::SyntaxKind) -> Self::Kind {
SyntaxKind::from_raw(raw.0).unwrap_or_else(|| panic!("raw kind out of range: {raw:?}"))
}
fn kind_to_raw(kind: Self::Kind) -> rowan::SyntaxKind {
kind.into()
}
}
impl SyntaxKind {
pub fn from_raw(raw: u16) -> Option<Self> {
let kind = match raw {
x if x == Self::WHITESPACE as u16 => Self::WHITESPACE,
x if x == Self::LINE_COMMENT as u16 => Self::LINE_COMMENT,
x if x == Self::BLOCK_COMMENT as u16 => Self::BLOCK_COMMENT,
x if x == Self::IDENT as u16 => Self::IDENT,
x if x == Self::NUMBER as u16 => Self::NUMBER,
x if x == Self::STRING as u16 => Self::STRING,
x if x == Self::L_BRACE as u16 => Self::L_BRACE,
x if x == Self::R_BRACE as u16 => Self::R_BRACE,
x if x == Self::L_BRACK as u16 => Self::L_BRACK,
x if x == Self::R_BRACK as u16 => Self::R_BRACK,
x if x == Self::L_PAREN as u16 => Self::L_PAREN,
x if x == Self::R_PAREN as u16 => Self::R_PAREN,
x if x == Self::COMMA as u16 => Self::COMMA,
x if x == Self::COLON as u16 => Self::COLON,
x if x == Self::DOT as u16 => Self::DOT,
x if x == Self::AT as u16 => Self::AT,
x if x == Self::HASH as u16 => Self::HASH,
x if x == Self::AMP as u16 => Self::AMP,
x if x == Self::QUESTION as u16 => Self::QUESTION,
x if x == Self::EQ as u16 => Self::EQ,
x if x == Self::ELLIPSIS as u16 => Self::ELLIPSIS,
x if x == Self::EQ_EQ as u16 => Self::EQ_EQ,
x if x == Self::BANG_EQ as u16 => Self::BANG_EQ,
x if x == Self::LT_EQ as u16 => Self::LT_EQ,
x if x == Self::GT_EQ as u16 => Self::GT_EQ,
x if x == Self::AMP_AMP as u16 => Self::AMP_AMP,
x if x == Self::PIPE_PIPE as u16 => Self::PIPE_PIPE,
x if x == Self::PLUS_PLUS as u16 => Self::PLUS_PLUS,
x if x == Self::FAT_ARROW as u16 => Self::FAT_ARROW,
x if x == Self::THIN_ARROW as u16 => Self::THIN_ARROW,
x if x == Self::LT as u16 => Self::LT,
x if x == Self::GT as u16 => Self::GT,
x if x == Self::PLUS as u16 => Self::PLUS,
x if x == Self::MINUS as u16 => Self::MINUS,
x if x == Self::STAR as u16 => Self::STAR,
x if x == Self::SLASH as u16 => Self::SLASH,
x if x == Self::PERCENT as u16 => Self::PERCENT,
x if x == Self::BANG as u16 => Self::BANG,
x if x == Self::PIPE as u16 => Self::PIPE,
x if x == Self::UNDERSCORE as u16 => Self::UNDERSCORE,
x if x == Self::UNKNOWN as u16 => Self::UNKNOWN,
x if x == Self::F_STRING_OPEN as u16 => Self::F_STRING_OPEN,
x if x == Self::F_STRING_CLOSE as u16 => Self::F_STRING_CLOSE,
x if x == Self::F_STRING_LITERAL as u16 => Self::F_STRING_LITERAL,
x if x == Self::F_STRING_INTERP_START as u16 => Self::F_STRING_INTERP_START,
x if x == Self::F_STRING_INTERP_END as u16 => Self::F_STRING_INTERP_END,
x if x == Self::DOCUMENT as u16 => Self::DOCUMENT,
x if x == Self::DIRECTIVE as u16 => Self::DIRECTIVE,
x if x == Self::DECORATOR as u16 => Self::DECORATOR,
x if x == Self::DICT as u16 => Self::DICT,
x if x == Self::DICT_FIELD as u16 => Self::DICT_FIELD,
x if x == Self::LIST as u16 => Self::LIST,
x if x == Self::COMPREHENSION as u16 => Self::COMPREHENSION,
x if x == Self::CLOSURE as u16 => Self::CLOSURE,
x if x == Self::CLOSURE_PARAM as u16 => Self::CLOSURE_PARAM,
x if x == Self::CALL_EXPR as u16 => Self::CALL_EXPR,
x if x == Self::CALL_ARG as u16 => Self::CALL_ARG,
x if x == Self::BINARY_EXPR as u16 => Self::BINARY_EXPR,
x if x == Self::UNARY_EXPR as u16 => Self::UNARY_EXPR,
x if x == Self::TERNARY_EXPR as u16 => Self::TERNARY_EXPR,
x if x == Self::REFERENCE_EXPR as u16 => Self::REFERENCE_EXPR,
x if x == Self::VARIABLE_EXPR as u16 => Self::VARIABLE_EXPR,
x if x == Self::WHERE_EXPR as u16 => Self::WHERE_EXPR,
x if x == Self::MATCH_EXPR as u16 => Self::MATCH_EXPR,
x if x == Self::MATCH_ARM as u16 => Self::MATCH_ARM,
x if x == Self::MATCH_PATTERN as u16 => Self::MATCH_PATTERN,
x if x == Self::VARIANT_CTOR as u16 => Self::VARIANT_CTOR,
x if x == Self::F_STRING as u16 => Self::F_STRING,
x if x == Self::F_STRING_INTERPOLATION as u16 => Self::F_STRING_INTERPOLATION,
x if x == Self::SPREAD_EXPR as u16 => Self::SPREAD_EXPR,
x if x == Self::TYPE_NODE as u16 => Self::TYPE_NODE,
x if x == Self::WILDCARD as u16 => Self::WILDCARD,
x if x == Self::LITERAL as u16 => Self::LITERAL,
x if x == Self::ERROR as u16 => Self::ERROR,
x if x == Self::TUPLE_TYPE as u16 => Self::TUPLE_TYPE,
x if x == Self::SCHEMA_WITH as u16 => Self::SCHEMA_WITH,
x if x == Self::SCHEMA_METHOD as u16 => Self::SCHEMA_METHOD,
x if x == Self::ENUM_VARIANT as u16 => Self::ENUM_VARIANT,
x if x == Self::ENUM_VARIANT_FIELD as u16 => Self::ENUM_VARIANT_FIELD,
x if x == Self::TUPLE as u16 => Self::TUPLE,
_ => return None,
};
Some(kind)
}
}
pub type SyntaxNode = rowan::SyntaxNode<RelonLanguage>;
pub type SyntaxToken = rowan::SyntaxToken<RelonLanguage>;
pub type SyntaxElement = rowan::SyntaxElement<RelonLanguage>;
#[cfg(test)]
mod tests {
use super::*;
use rowan::Language;
#[test]
fn trivia_classification() {
assert!(SyntaxKind::WHITESPACE.is_trivia());
assert!(SyntaxKind::LINE_COMMENT.is_trivia());
assert!(SyntaxKind::BLOCK_COMMENT.is_trivia());
assert!(!SyntaxKind::IDENT.is_trivia());
assert!(!SyntaxKind::DOCUMENT.is_trivia());
}
#[test]
fn token_vs_node_split() {
assert!(SyntaxKind::WHITESPACE.is_token());
assert!(SyntaxKind::IDENT.is_token());
assert!(SyntaxKind::EQ.is_token());
assert!(SyntaxKind::PIPE.is_token());
assert!(SyntaxKind::DOCUMENT.is_node());
assert!(SyntaxKind::DICT.is_node());
assert!(SyntaxKind::ERROR.is_node());
}
#[test]
fn round_trip_through_rowan_language() {
for kind in [
SyntaxKind::WHITESPACE,
SyntaxKind::IDENT,
SyntaxKind::NUMBER,
SyntaxKind::STRING,
SyntaxKind::HASH,
SyntaxKind::DOCUMENT,
SyntaxKind::DICT,
SyntaxKind::CLOSURE,
SyntaxKind::ERROR,
] {
let raw = RelonLanguage::kind_to_raw(kind);
assert_eq!(RelonLanguage::kind_from_raw(raw), kind);
}
}
}