From a99b62155a75360e168702d01f3ccc0627d0b8ce Mon Sep 17 00:00:00 2001 From: Ryan Chandler Date: Mon, 28 Nov 2022 13:09:45 +0000 Subject: [PATCH] parser: support group use statements --- src/ast.rs | 5 +++ src/parser/mod.rs | 82 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 67 insertions(+), 20 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 0344a2a..208e4a2 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -304,6 +304,11 @@ pub enum Statement { uses: Vec, kind: UseKind, }, + GroupUse { + prefix: Identifier, + kind: UseKind, + uses: Vec, + }, Comment { comment: ByteString, }, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index e6665e8..79bbec3 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -224,31 +224,62 @@ impl Parser { _ => UseKind::Normal, }; - let mut uses = Vec::new(); - while !self.is_eof() { - let name = self.full_name()?; - let mut alias = None; + if self.peek.kind == TokenKind::LeftBrace { + let prefix = self.full_name()?; + self.next(); - if self.current.kind == TokenKind::As { - self.next(); - alias = Some(self.ident()?.into()); - } - - uses.push(Use { - name: name.into(), - alias, - }); - - if self.current.kind == TokenKind::Comma { - self.next(); - continue; + let mut uses = Vec::new(); + while self.current.kind != TokenKind::RightBrace { + let name = self.full_name()?; + let mut alias = None; + + if self.current.kind == TokenKind::As { + self.next(); + alias = Some(self.ident()?.into()); + } + + uses.push(Use { + name: name.into(), + alias, + }); + + if self.current.kind == TokenKind::Comma { + self.next(); + continue; + } } + self.rbrace()?; self.semi()?; - break; - } - Statement::Use { uses, kind } + Statement::GroupUse { prefix: prefix.into(), kind, uses } + } else { + let mut uses = Vec::new(); + while !self.is_eof() { + let name = self.full_name()?; + let mut alias = None; + + if self.current.kind == TokenKind::As { + self.next(); + alias = Some(self.ident()?.into()); + } + + uses.push(Use { + name: name.into(), + alias, + }); + + if self.current.kind == TokenKind::Comma { + self.next(); + continue; + } + + self.semi()?; + break; + } + + Statement::Use { uses, kind } + } } TokenKind::Const => { self.next(); @@ -5299,6 +5330,17 @@ mod tests { ]); } + #[test] + fn simple_group_use() { + assert_ast("