//! Shared keyword definitions derived from the lexer Token enum //! //! This module provides structured access to Storybook language keywords //! without duplicating the keyword strings across different LSP modules. //! All keywords are defined in the Token enum in lexer.rs using the //! #[token(...)] attribute. use crate::syntax::lexer::Token; /// Top-level declaration keywords that start a new declaration pub const DECLARATION_KEYWORDS: &[&str] = &[ "character", "template", "species", "behavior", "life_arc", "relationship", "institution", "location", "enum", "schedule", ]; /// All structural keywords (declarations + use) pub const STRUCTURAL_KEYWORDS: &[&str] = &[ "use", "character", "template", "species", "behavior", "life_arc", "relationship", "institution", "location", "enum", "schedule", ]; /// Keywords used in behavior tree definitions pub const BEHAVIOR_KEYWORDS: &[&str] = &[ "choose", "then", "if", "when", "repeat", "invert", "retry", "timeout", "cooldown", // "guard" removed - use "if" instead "succeed_always", "fail_always", ]; /// Modifier keywords used in various contexts pub const MODIFIER_KEYWORDS: &[&str] = &["strict", "include", "from", "as"]; /// State machine keywords pub const STATE_KEYWORDS: &[&str] = &["state", "on", "enter"]; /// Expression keywords pub const EXPRESSION_KEYWORDS: &[&str] = &["forall", "exists", "in", "where", "and", "or", "not", "is"]; /// Special identifier keywords pub const IDENTIFIER_KEYWORDS: &[&str] = &["self", "other"]; /// Operation keywords pub const OPERATION_KEYWORDS: &[&str] = &["remove", "append"]; /// Boolean literals pub const BOOLEAN_LITERALS: &[&str] = &["true", "false"]; /// Check if a string is a top-level declaration keyword pub fn is_declaration_keyword(s: &str) -> bool { DECLARATION_KEYWORDS.contains(&s) } /// Check if a string is any structural keyword (includes 'use') pub fn is_structural_keyword(s: &str) -> bool { STRUCTURAL_KEYWORDS.contains(&s) } /// Check if a string is a behavior tree keyword pub fn is_behavior_keyword(s: &str) -> bool { BEHAVIOR_KEYWORDS.contains(&s) } /// Check if a token is a declaration keyword token pub fn token_is_declaration_keyword(token: &Token) -> bool { matches!( token, Token::Character | Token::Template | Token::Species | Token::Behavior | Token::LifeArc | Token::Relationship | Token::Institution | Token::Location | Token::Schedule ) } /// Check if a token is a structural keyword token (includes Use) pub fn token_is_structural_keyword(token: &Token) -> bool { matches!( token, Token::Use | Token::Character | Token::Template | Token::Species | Token::Behavior | Token::LifeArc | Token::Relationship | Token::Institution | Token::Location | Token::Schedule ) } /// Get the string representation of a declaration token pub fn declaration_token_to_str(token: &Token) -> Option<&'static str> { match token { | Token::Character => Some("character"), | Token::Template => Some("template"), | Token::Species => Some("species"), | Token::Behavior => Some("behavior"), | Token::LifeArc => Some("life_arc"), | Token::Relationship => Some("relationship"), | Token::Institution => Some("institution"), | Token::Location => Some("location"), | Token::Schedule => Some("schedule"), | _ => None, } } #[cfg(test)] mod tests { use super::*; #[test] fn test_declaration_keywords() { assert!(is_declaration_keyword("character")); assert!(is_declaration_keyword("template")); assert!(is_declaration_keyword("behavior")); assert!(!is_declaration_keyword("use")); assert!(!is_declaration_keyword("unknown")); } #[test] fn test_structural_keywords() { assert!(is_structural_keyword("character")); assert!(is_structural_keyword("use")); assert!(!is_structural_keyword("if")); } #[test] fn test_behavior_keywords() { assert!(is_behavior_keyword("choose")); assert!(is_behavior_keyword("repeat")); assert!(!is_behavior_keyword("character")); } #[test] fn test_token_checks() { assert!(token_is_declaration_keyword(&Token::Character)); assert!(token_is_declaration_keyword(&Token::Behavior)); assert!(!token_is_declaration_keyword(&Token::Use)); assert!(token_is_structural_keyword(&Token::Use)); assert!(token_is_structural_keyword(&Token::Character)); assert!(!token_is_structural_keyword(&Token::If)); } #[test] fn test_token_to_str() { assert_eq!( declaration_token_to_str(&Token::Character), Some("character") ); assert_eq!(declaration_token_to_str(&Token::Behavior), Some("behavior")); assert_eq!(declaration_token_to_str(&Token::Use), None); } }