diff options
Diffstat (limited to 'src/parse')
| -rw-r--r-- | src/parse/mod.rs | 48 | ||||
| -rw-r--r-- | src/parse/parser.rs | 10 | ||||
| -rw-r--r-- | src/parse/tokens.rs | 2 |
3 files changed, 32 insertions, 28 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 1d893ad9..c3d532a7 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -728,33 +728,29 @@ fn import_expr(p: &mut Parser) -> Option<Expr> { let start = p.next_start(); p.assert(Token::Import); - let mut import_expr = None; - if let Some(path) = expr(p) { - let imports = if p.expect(Token::Using) { - if p.eat_if(Token::Star) { - // This is the wildcard scenario. - Imports::Wildcard - } else { - // This is the list of identifier scenario. - p.start_group(Group::Expr, TokenMode::Code); - let items = collection(p).0; - if items.is_empty() { - p.expected_at("import items", p.prev_end()); - } - - let idents = idents(p, items); - p.end_group(); - Imports::Idents(idents) - } - } else { - Imports::Idents(vec![]) - }; + let imports = if p.eat_if(Token::Star) { + // This is the wildcard scenario. + Imports::Wildcard + } else { + // This is the list of identifiers scenario. + p.start_group(Group::Imports, TokenMode::Code); + let items = collection(p).0; + if items.is_empty() { + p.expected_at("import items", p.prev_end()); + } + p.end_group(); + Imports::Idents(idents(p, items)) + }; - import_expr = Some(Expr::Import(ImportExpr { - span: p.span(start), - imports, - path: Box::new(path), - })); + let mut import_expr = None; + if p.expect(Token::From) { + if let Some(path) = expr(p) { + import_expr = Some(Expr::Import(ImportExpr { + span: p.span(start), + imports, + path: Box::new(path), + })); + } } import_expr diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 8ea80d68..1e0f2f5d 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -51,6 +51,8 @@ pub enum Group { Stmt, /// A group for a single expression, ended by a line break. Expr, + /// A group for import items, ended by a semicolon, line break or `from`. + Imports, } impl<'s> Parser<'s> { @@ -128,6 +130,7 @@ impl<'s> Parser<'s> { Group::Brace => self.assert(Token::LeftBrace), Group::Stmt => {} Group::Expr => {} + Group::Imports => {} } } @@ -149,6 +152,7 @@ impl<'s> Parser<'s> { Group::Brace => Some((Token::RightBrace, true)), Group::Stmt => Some((Token::Semicolon, false)), Group::Expr => None, + Group::Imports => None, } { if self.next == Some(end) { // Bump the delimeter and return. No need to rescan in this case. @@ -361,6 +365,7 @@ impl<'s> Parser<'s> { Token::RightBracket => self.inside(Group::Bracket), Token::RightBrace => self.inside(Group::Brace), Token::Semicolon => self.inside(Group::Stmt), + Token::From => self.inside(Group::Imports), Token::Space(n) => n >= 1 && self.stop_at_newline(), _ => false, } { @@ -371,7 +376,10 @@ impl<'s> Parser<'s> { /// Whether the active group ends at a newline. fn stop_at_newline(&self) -> bool { let active = self.groups.last().map(|group| group.kind); - matches!(active, Some(Group::Stmt) | Some(Group::Expr)) + matches!( + active, + Some(Group::Stmt) | Some(Group::Expr) | Some(Group::Imports) + ) } /// Whether we are inside the given group. diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs index aebe7b70..d979d005 100644 --- a/src/parse/tokens.rs +++ b/src/parse/tokens.rs @@ -496,7 +496,7 @@ fn keyword(id: &str) -> Option<Token<'static>> { "return" => Token::Return, "import" => Token::Import, "include" => Token::Include, - "using" => Token::Using, + "from" => Token::From, _ => return None, }) } |
