use sipha::types::FromSyntaxKind;
use sipha::SyntaxKinds;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, SyntaxKinds)]
#[repr(u16)]
pub enum Kind {
TriviaWs,
TriviaLineComment,
TriviaBlockComment,
TokNumber,
TokString,
TokIdent,
KwAbstract,
KwAnd,
KwAs,
KwBreak,
KwClass,
KwConst,
KwContinue,
KwDo,
KwElse,
KwFalse,
KwFor,
KwFunction,
KwGlobal,
KwIf,
KwIn,
KwInclude,
KwLet,
KwNew,
KwNot,
KwNull,
KwOr,
KwReturn,
KwTrue,
KwVar,
KwWhile,
KwXor,
KwFinal,
KwConstructor,
KwExtends,
KwStatic,
KwPublic,
KwPrivate,
KwProtected,
KwThis,
KwSuper,
KwInstanceof,
KwTry,
KwCatch,
KwSwitch,
KwCase,
KwDefault,
KwThrow,
KwReserved,
TokOp,
TokArrow,
TokDotDot,
TokDot,
TokColon,
TokComma,
TokSemi,
TokParenL,
TokParenR,
TokBracketL,
TokBracketR,
TokBraceL,
TokBraceR,
TokLemnisate,
TokPi,
TokEof,
NodeRoot,
NodeTokenStream,
NodeExpr,
NodePrimaryExpr,
NodeBinaryExpr,
NodeBinaryLevel, NodeUnaryExpr,
NodeCallExpr,
NodeMemberExpr,
NodeIndexExpr,
NodeArray,
NodeMap,
NodeMapPair,
NodeObject,
NodeObjectPair,
NodeSet,
NodeStmt,
NodeBlock,
NodeVarDecl,
NodeIfStmt,
NodeWhileStmt,
NodeForStmt,
NodeForInStmt,
NodeDoWhileStmt,
NodeReturnStmt,
NodeBreakStmt,
NodeContinueStmt,
NodeExprStmt,
NodeFunctionDecl,
NodeClassDecl,
NodeInclude,
NodeConstructorDecl,
NodeInterval,
NodeClassField,
NodeAsCast,
NodeAnonFn,
NodeTypeAnnot,
NodeParam,
NodeTypeExpr,
NodeTypeParams,
NodeSigFile,
NodeSigFunction,
NodeSigClass,
NodeSigMethod,
NodeSigConstructor,
NodeSigField,
NodeSigGlobal,
NodeSigParam,
NodeSigDocBlock,
TokSigDocLine,
TokSigDocBlock,
}
pub const SYNTHETIC_ROOT: sipha::types::SyntaxKind = u16::MAX;
pub const KEYWORDS: &[&str] = &[
"abstract",
"and",
"as",
"break",
"case",
"catch",
"class",
"const",
"constructor",
"continue",
"default",
"do",
"else",
"extends",
"false",
"final",
"for",
"function",
"global",
"if",
"in",
"include",
"instanceof",
"let",
"new",
"not",
"null",
"or",
"private",
"protected",
"public",
"reserved",
"return",
"static",
"super",
"switch",
"this",
"throw",
"true",
"try",
"var",
"while",
"xor",
];
#[must_use]
pub fn is_valid_identifier(name: &str) -> bool {
let mut chars = name.chars();
match chars.next() {
Some(c) if c.is_ascii_alphabetic() || c == '_' => {}
_ => return false,
}
chars.all(|c| c.is_ascii_alphanumeric() || c == '_')
}
#[cfg(test)]
mod tests {
use super::is_valid_identifier;
#[test]
fn valid_identifiers() {
assert!(is_valid_identifier("x"));
assert!(is_valid_identifier("_private"));
assert!(is_valid_identifier("foo_bar"));
assert!(is_valid_identifier("Cell"));
}
#[test]
fn invalid_identifiers() {
assert!(!is_valid_identifier(""));
assert!(!is_valid_identifier("123"));
assert!(!is_valid_identifier("bad name"));
assert!(!is_valid_identifier("x-y"));
}
}
pub const FIELD_RHS: sipha::types::FieldId = 0;
pub fn kind_name(kind: sipha::types::SyntaxKind) -> &'static str {
if kind == SYNTHETIC_ROOT {
return "ROOT";
}
Kind::from_syntax_kind(kind).map_or("?", kind_name_enum)
}
fn kind_name_enum(k: Kind) -> &'static str {
match k {
Kind::TokNumber => "NUMBER",
Kind::TokString => "STRING",
Kind::TokIdent => "IDENT",
Kind::TokOp => "OP",
Kind::TokParenL => "(",
Kind::TokParenR => ")",
Kind::TokDotDot => "..",
Kind::NodeTokenStream => "TOKEN_STREAM",
Kind::NodeRoot => "ROOT",
Kind::NodeExpr => "EXPR",
Kind::NodeExprStmt => "EXPR_STMT",
Kind::NodeVarDecl => "VAR_DECL",
Kind::NodeIfStmt => "IF_STMT",
Kind::NodeWhileStmt => "WHILE_STMT",
Kind::NodeBlock => "BLOCK",
Kind::NodeReturnStmt => "RETURN_STMT",
Kind::NodeForStmt => "FOR_STMT",
Kind::NodeForInStmt => "FOR_IN_STMT",
Kind::NodeDoWhileStmt => "DO_WHILE_STMT",
Kind::NodeFunctionDecl => "FUNCTION_DECL",
Kind::NodeClassDecl => "CLASS_DECL",
Kind::NodeConstructorDecl => "CONSTRUCTOR_DECL",
Kind::NodeClassField => "CLASS_FIELD",
Kind::NodeInterval => "INTERVAL",
Kind::NodeInclude => "INCLUDE",
Kind::NodeArray => "ARRAY",
Kind::NodeMap => "MAP",
Kind::NodeMapPair => "MAP_PAIR",
Kind::NodeObject => "OBJECT",
Kind::NodeObjectPair => "OBJECT_PAIR",
Kind::NodeSet => "SET",
Kind::NodeTypeExpr => "TYPE_EXPR",
Kind::NodeTypeParams => "TYPE_PARAMS",
Kind::NodeAsCast => "AS_CAST",
Kind::NodeSigFile => "SIG_FILE",
Kind::NodeSigFunction => "SIG_FUNCTION",
Kind::NodeSigClass => "SIG_CLASS",
Kind::NodeSigMethod => "SIG_METHOD",
Kind::NodeSigConstructor => "SIG_CONSTRUCTOR",
Kind::NodeSigField => "SIG_FIELD",
Kind::NodeSigGlobal => "SIG_GLOBAL",
Kind::NodeSigParam => "SIG_PARAM",
Kind::NodeSigDocBlock => "SIG_DOC_BLOCK",
Kind::TokSigDocLine => "SIG_DOC_LINE",
Kind::TokSigDocBlock => "SIG_DOC_BLOCK_TOKEN",
_ => "?",
}
}