diff --git a/trunk_lexer/src/lexer.rs b/trunk_lexer/src/lexer.rs index d0377b0..a816f53 100644 --- a/trunk_lexer/src/lexer.rs +++ b/trunk_lexer/src/lexer.rs @@ -836,6 +836,7 @@ impl Lexer { #[allow(dead_code)] fn identifier_to_keyword(ident: &[u8]) -> Option { Some(match ident { + b"readonly" => TokenKind::Readonly, b"global" => TokenKind::Global, b"match" => TokenKind::Match, b"abstract" => TokenKind::Abstract, @@ -949,7 +950,7 @@ mod tests { #[test] fn keywords() { - assert_tokens(") -> std::fmt::Result { let s = match self { + Self::Readonly => "readonly", Self::AsteriskEqual => "*=", Self::ObjectCast => "(object)", Self::Abstract => "abstract", diff --git a/trunk_parser/src/ast.rs b/trunk_parser/src/ast.rs index e6cd1cd..8862704 100644 --- a/trunk_parser/src/ast.rs +++ b/trunk_parser/src/ast.rs @@ -118,6 +118,7 @@ impl From for MethodFlag { pub enum ClassFlag { Final, Abstract, + Readonly, } impl From for ClassFlag { @@ -125,6 +126,7 @@ impl From for ClassFlag { match k { TokenKind::Final => Self::Final, TokenKind::Abstract => Self::Abstract, + TokenKind::Readonly => Self::Readonly, _ => unreachable!("token {:?} can't be converted into class flag.", k), } } diff --git a/trunk_parser/src/parser/mod.rs b/trunk_parser/src/parser/mod.rs index e6b4547..c835051 100644 --- a/trunk_parser/src/parser/mod.rs +++ b/trunk_parser/src/parser/mod.rs @@ -416,6 +416,26 @@ impl Parser { _ => unreachable!(), } } + TokenKind::Readonly if self.peek.kind == TokenKind::Class => { + self.next(); + + match self.class()? { + Statement::Class { + name, + extends, + implements, + body, + .. + } => Statement::Class { + name, + extends, + implements, + body, + flag: Some(ClassFlag::Readonly), + }, + _ => unreachable!(), + } + } TokenKind::Trait => { self.next(); @@ -2193,8 +2213,8 @@ mod tests { use super::Parser; use crate::{ ast::{ - Arg, ArrayItem, Case, Constant, DeclareItem, ElseIf, IncludeKind, InfixOp, MethodFlag, - PropertyFlag, + Arg, ArrayItem, Case, ClassFlag, Constant, DeclareItem, ElseIf, IncludeKind, InfixOp, + MethodFlag, PropertyFlag, }, Catch, Expression, Identifier, Param, Statement, Type, }; @@ -3515,6 +3535,20 @@ mod tests { ) } + #[test] + fn readonly_classes() { + assert_ast( + "