wright/parser/decl/
import.rs1use crate::{
4 ast::{decl::import::ImportDecl, identifier::Identifier, path::Path},
5 lexer::token::{Token, TokenTy},
6 parser::{
7 Parser,
8 error::{ParserError, ParserErrorKind},
9 whitespace,
10 },
11 source_tracking::fragment::Fragment,
12};
13
14impl ImportDecl {
15 pub fn parse(parser: &mut Parser) -> Result<Self, ParserError> {
20 let use_kw: Token = parser.next_if_is(TokenTy::KwUse).ok_or(
21 ParserErrorKind::ExpectedImportDeclaration.at(parser.peek_fragment_or_rest_cloned()),
22 )?;
23
24 whitespace::require_whitespace(parser)?;
26 let path: Path = Path::parse(parser)?;
28
29 let imported_as = if parser.matches(&[TokenTy::Whitespace, TokenTy::KwAs]) {
33 parser.advance(2);
34
35 whitespace::require_whitespace(parser)
36 .map_err(|e| e.with_help("whitespace needed between \"as\" and binding."))?;
37
38 let imported_as = Identifier::parse(parser)
39 .map_err(|e| e.with_help("expected binding in \"use ... as\" declaration."))?;
40
41 Some(imported_as)
42 } else {
43 None
44 };
45
46 whitespace::optional_whitespace(parser);
47
48 if let Some(semi) = parser.next_if_is(TokenTy::Semi) {
49 Ok(ImportDecl {
50 matching_source: Fragment::cover(use_kw.fragment, semi.fragment),
51 imported_item: path,
52 imported_as,
53 })
54 } else {
55 Err(ParserErrorKind::ImportMustEndWithSemicolon
56 .at(parser.peek_fragment_or_rest_cloned()))
57 }
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use crate::{ast::decl::import::ImportDecl, lexer::Lexer, parser::Parser};
64
65 #[test]
66 fn test_import() {
67 let mut parser = Parser::new(Lexer::new_test("use wright::util;"));
68 let import_decl = ImportDecl::parse(&mut parser).unwrap();
69 assert!(parser.lexer.remaining.is_empty());
70 assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
71 assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
72 }
73
74 #[test]
75 fn test_import_with_whitespace() {
76 let mut parser = Parser::new(Lexer::new_test("use wright :: util ;"));
77 let import_decl = ImportDecl::parse(&mut parser).unwrap();
78 assert!(parser.lexer.remaining.is_empty());
79 assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
80 assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
81 }
82
83 #[test]
84 fn test_import_as() {
85 let mut parser = Parser::new(Lexer::new_test("use wright::util as u;"));
86 let import_decl = ImportDecl::parse(&mut parser).unwrap();
87 assert!(parser.lexer.remaining.is_empty());
88 assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
89 assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
90 assert_eq!(import_decl.imported_as.unwrap().fragment.as_str(), "u");
91 }
92
93 #[test]
94 fn test_import_as_with_comment() {
95 let mut parser = Parser::new(Lexer::new_test("use wright::util as /* old_name */ u;"));
96 let import_decl = ImportDecl::parse(&mut parser).unwrap();
97 assert!(parser.lexer.remaining.is_empty());
98 assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
99 assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
100 assert_eq!(import_decl.imported_as.unwrap().fragment.as_str(), "u");
101 }
102}