summaryrefslogtreecommitdiff
path: root/src/parse
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/mod.rs48
-rw-r--r--src/parse/parser.rs10
-rw-r--r--src/parse/tokens.rs2
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,
})
}