From 2e814d245a30a543491d43af98513a03d2436844 Mon Sep 17 00:00:00 2001 From: azjezz Date: Wed, 30 Nov 2022 22:55:58 +0100 Subject: [PATCH] chore: don't use class member flags for interface member flags Signed-off-by: azjezz --- src/parser/classish_statement.rs | 17 ++++---- src/parser/flags.rs | 66 ++++++++++++++++++++------------ src/parser/macros.rs | 38 ++++++++++-------- 3 files changed, 71 insertions(+), 50 deletions(-) diff --git a/src/parser/classish_statement.rs b/src/parser/classish_statement.rs index b2234b01..ec003492 100644 --- a/src/parser/classish_statement.rs +++ b/src/parser/classish_statement.rs @@ -2,6 +2,7 @@ use super::ParseResult; use crate::expect_token; use crate::expected_token_err; use crate::parser::precedence::Precedence; +use crate::peek_token; use crate::ClassFlag; use crate::Identifier; use crate::MethodFlag; @@ -34,16 +35,15 @@ impl Parser { return self.method(ClassishDefinitionType::Interface, vec![]); } - let member_flags = self.class_members_flags()?; + let member_flags = self.interface_members_flags()?; - match &self.current.kind { + peek_token!([ TokenKind::Const => self.parse_classish_const(member_flags), TokenKind::Function => self.method( ClassishDefinitionType::Interface, member_flags.iter().map(|t| t.clone().into()).collect(), - ), - _ => expected_token_err!(["`const`", "`function`"], self), - } + ) + ], self, ["`const`", "`function`"]) } pub(crate) fn trait_statement(&mut self) -> ParseResult { @@ -87,14 +87,13 @@ impl Parser { let member_flags = self.enum_members_flags()?; - match &self.current.kind { + peek_token!([ TokenKind::Const => self.parse_classish_const(member_flags), TokenKind::Function => self.method( ClassishDefinitionType::Enum, member_flags.iter().map(|t| t.clone().into()).collect(), - ), - _ => expected_token_err!(["`const`", "`function`"], self), - } + ) + ], self, ["`const`", "`function`"]) } fn complete_class_statement( diff --git a/src/parser/flags.rs b/src/parser/flags.rs index 643f86c6..0a826e1c 100644 --- a/src/parser/flags.rs +++ b/src/parser/flags.rs @@ -3,10 +3,12 @@ use crate::ParseError; use crate::Parser; use crate::TokenKind; +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] enum FlagTarget { Class, EnumMember, ClassMember, + InterfaceMember, PromotedProperty, } @@ -18,6 +20,18 @@ impl Parser { ) } + pub(crate) fn interface_members_flags(&mut self) -> ParseResult> { + self.collect( + vec![ + TokenKind::Private, + TokenKind::Protected, + TokenKind::Public, + TokenKind::Static, + ], + FlagTarget::InterfaceMember, + ) + } + pub(crate) fn class_members_flags(&mut self) -> ParseResult> { self.collect( vec![ @@ -92,34 +106,36 @@ impl Parser { { return Err(ParseError::MultipleAccessModifiers(self.current.span)); } - TokenKind::Final if collected.contains(&TokenKind::Abstract) => match target { - FlagTarget::Class => { - return Err(ParseError::FinalModifierOnAbstractClass( - self.current.span, - )); - } - FlagTarget::ClassMember => { - return Err(ParseError::FinalModifierOnAbstractClassMember( - self.current.span, - )); - } - _ => {} - }, - TokenKind::Abstract if collected.contains(&TokenKind::Final) => match target { - FlagTarget::Class => { - return Err(ParseError::FinalModifierOnAbstractClass( - self.current.span, - )); + _ => {} + }; + + if matches!(target, FlagTarget::ClassMember | FlagTarget::Class) { + match self.current.kind { + TokenKind::Final if collected.contains(&TokenKind::Abstract) => { + if target == FlagTarget::Class { + return Err(ParseError::FinalModifierOnAbstractClass( + self.current.span, + )); + } else { + return Err(ParseError::FinalModifierOnAbstractClassMember( + self.current.span, + )); + } } - FlagTarget::ClassMember => { - return Err(ParseError::FinalModifierOnAbstractClassMember( - self.current.span, - )); + TokenKind::Abstract if collected.contains(&TokenKind::Final) => { + if target == FlagTarget::Class { + return Err(ParseError::FinalModifierOnAbstractClass( + self.current.span, + )); + } else { + return Err(ParseError::FinalModifierOnAbstractClassMember( + self.current.span, + )); + } } _ => {} - }, - _ => {} - }; + }; + } collected.push(self.current.kind.clone()); self.next(); diff --git a/src/parser/macros.rs b/src/parser/macros.rs index f869a91b..1bc4f279 100644 --- a/src/parser/macros.rs +++ b/src/parser/macros.rs @@ -1,13 +1,10 @@ #[macro_export] -macro_rules! expect_token { +macro_rules! peek_token { ([ $($expected:pat => $out:expr),+ $(,)? ], $parser:expr, [ $($message:literal),+ $(,)? ]) => {{ $parser.skip_comments(); match $parser.current.kind.clone() { $( - $expected => { - $parser.next(); - $out - } + $expected => $out, )+ _ => { return $crate::expected_token_err!([ $($message,)+ ], $parser); @@ -16,22 +13,31 @@ macro_rules! expect_token { }}; ([ $($expected:pat),+ $(,)? ], $parser:expr, [ $($message:literal),+ $(,)? ]) => {{ $parser.skip_comments(); - match $parser.current.kind.clone() { - $( - $expected => { - $parser.next(); - } - )+ - _ => { - return $crate::expected_token_err!([ $($message,)+ ], $parser); - } + if !matches!($parser.current.kind, $(| $expected )+) { + return $crate::expected_token_err!([ $($message,)+ ], $parser); } }}; ([ $($expected:pat => $out:expr),+ $(,)? ], $parser:expr, $message:literal) => { - $crate::expect_token!([ $($expected => $out,)+ ], $parser, [$message]) + $crate::peek_token!([ $($expected => $out,)+ ], $parser, [$message]) + }; + ([ $($expected:pat),+ $(,)? ], $parser:expr, $message:literal) => { + $crate::peek_token!([ $($expected,)+ ], $parser, [$message]) + }; +} + +#[macro_export] +macro_rules! expect_token { + ([ $($expected:pat => $out:expr),+ $(,)? ], $parser:expr, [ $($message:literal),+ $(,)? ]) => { + $crate::peek_token!([ $($expected => { $parser.next(); $out },)+ ], $parser, [$($message,)+]) + }; + ([ $($expected:pat),+ $(,)? ], $parser:expr, [ $($message:literal),+ $(,)? ]) => { + $crate::peek_token!([ $($expected => { $parser.next(); },)+ ], $parser, [$($message,)+]) + }; + ([ $($expected:pat => $out:expr),+ $(,)? ], $parser:expr, $message:literal) => { + $crate::peek_token!([ $($expected => { $parser.next(); $out },)+ ], $parser, [$message]) }; ([ $($expected:pat),+ $(,)? ], $parser:expr, $message:literal) => { - $crate::expect_token!([ $($expected,)+ ], $parser, [$message]) + $crate::peek_token!([ $($expected => { $parser.next(); },)+ ], $parser, [$message]) }; }