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 },
10 source_tracking::fragment::Fragment,
11};
12
13impl ImportDecl {
14 pub fn parse(parser: &mut Parser) -> Result<Self, ParserError> {
19 let use_kw: Token = parser.next_if_is(TokenTy::KwUse).ok_or(
20 ParserErrorKind::ExpectedImportDeclaration.at(parser.peek_fragment_or_rest_cloned()),
21 )?;
22
23 parser.consume_at_least_one_whitespace()?;
25 let path: Path = Path::parse(parser)?;
27
28 let imported_as = match parser.next_if_is(TokenTy::Whitespace) {
32 None => None,
34
35 Some(_) => {
37 parser.consume_optional_whitespace();
39
40 match parser.next_if_is(TokenTy::KwAs) {
43 None => None,
45
46 Some(_) => {
48 parser.consume_at_least_one_whitespace().map_err(|e| {
49 e.with_help("whitespace needed between \"as\" and binding.")
50 })?;
51
52 let imported_as = Identifier::parse(parser).map_err(|e| {
53 e.with_help("expected binding in \"use ... as\" declaration.")
54 })?;
55
56 Some(imported_as)
57 }
58 }
59 }
60 };
61
62 parser.consume_optional_whitespace();
63
64 if let Some(semi) = parser.next_if_is(TokenTy::Semi) {
65 Ok(ImportDecl {
66 matching_source: Fragment::cover(&use_kw.fragment, &semi.fragment),
67 imported_item: path,
68 imported_as,
69 })
70 } else {
71 Err(ParserErrorKind::ImportMustEndWithSemicolon
72 .at(parser.peek_fragment_or_rest_cloned()))
73 }
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use crate::{ast::decl::import::ImportDecl, lexer::Lexer, parser::Parser};
80
81 #[test]
82 fn test_import() {
83 let mut parser = Parser::new(Lexer::new_test("use wright::util;"));
84 let import_decl = ImportDecl::parse(&mut parser).unwrap();
85 assert!(parser.lexer.remaining.is_empty());
86 assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
87 assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
88 }
89
90 #[test]
91 fn test_import_with_whitespace() {
92 let mut parser = Parser::new(Lexer::new_test("use wright :: util ;"));
93 let import_decl = ImportDecl::parse(&mut parser).unwrap();
94 assert!(parser.lexer.remaining.is_empty());
95 assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
96 assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
97 }
98
99 #[test]
100 fn test_import_as() {
101 let mut parser = Parser::new(Lexer::new_test("use wright::util as u;"));
102 let import_decl = ImportDecl::parse(&mut parser).unwrap();
103 assert!(parser.lexer.remaining.is_empty());
104 assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
105 assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
106 assert_eq!(import_decl.imported_as.unwrap().fragment.as_str(), "u");
107 }
108
109 #[test]
110 fn test_import_as_with_comment() {
111 let mut parser = Parser::new(Lexer::new_test("use wright::util as /* old_name */ u;"));
112 let import_decl = ImportDecl::parse(&mut parser).unwrap();
113 assert!(parser.lexer.remaining.is_empty());
114 assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
115 assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
116 assert_eq!(import_decl.imported_as.unwrap().fragment.as_str(), "u");
117 }
118
119 #[test]
120 fn test_import_as_with_preceding_comment() {
121 let mut parser = Parser::new(Lexer::new_test("use wright::util /* as old_name */ as u;"));
122 let import_decl = ImportDecl::parse(&mut parser).unwrap();
123 assert!(parser.lexer.remaining.is_empty());
124 assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
125 assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
126 assert_eq!(import_decl.imported_as.unwrap().fragment.as_str(), "u");
127 }
128}