• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vcfxb / wright-lang / 16336579506

17 Jul 2025 04:57AM UTC coverage: 75.6% (+0.2%) from 75.352%
16336579506

push

github

vcfxb
chore: clippy

0 of 1 new or added line in 1 file covered. (0.0%)

32 existing lines in 5 files now uncovered.

976 of 1291 relevant lines covered (75.6%)

35.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.39
/wright/src/parser/decl/import.rs
1
//! Parser implementation for `use path::to::thing;` declaration.
2

3
use 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

13
impl ImportDecl {
14
    /// Parse an import declaration.
15
    ///
16
    /// This will advance the parser if `use` is seen -- if a valid formed import does not follow,
17
    /// the parser may be left in the middle of a malformed declaration.
18
    pub fn parse(parser: &mut Parser) -> Result<Self, ParserError> {
5✔
19
        let use_kw: Token = parser.next_if_is(TokenTy::KwUse).ok_or(
5✔
20
            ParserErrorKind::ExpectedImportDeclaration.at(parser.peek_fragment_or_rest_cloned()),
5✔
UNCOV
21
        )?;
×
22

23
        // Require a whitespace after the keyword.
24
        parser.consume_at_least_one_whitespace()?;
5✔
25
        // Parse the path.
26
        let path: Path = Path::parse(parser)?;
5✔
27

28
        // Whitespace and then "as ...;" or optional whitespace and semi ";".
29

30
        // The "as ...;" requires a whitespace.
31
        let imported_as = match parser.next_if_is(TokenTy::Whitespace) {
5✔
32
            // If there's no whitespace after the path, we expect it to be followed by a semicolon (no renaming).
33
            None => None,
1✔
34

35
            // If there is a whitespace, then it could be followed by `as ...;` or just `;`.
36
            Some(_) => {
37
                // Either way, consume any additional whitespace/comments.
38
                parser.consume_optional_whitespace();
4✔
39

40
                // Check if we have an `as` and if so read the renaming clause.
41
                // Otherwise pass on to reading the semicolon.
42
                match parser.next_if_is(TokenTy::KwAs) {
4✔
43
                    // No `as` -- do nothing (return no renaming clause).
44
                    None => None,
1✔
45

46
                    // `as ...;` -- consume the ` ...` part.
47
                    Some(_) => {
48
                        parser.consume_at_least_one_whitespace().map_err(|e| {
3✔
UNCOV
49
                            e.with_help("whitespace needed between \"as\" and binding.")
×
50
                        })?;
×
51

52
                        let imported_as = Identifier::parse(parser).map_err(|e| {
3✔
UNCOV
53
                            e.with_help("expected binding in \"use ... as\" declaration.")
×
54
                        })?;
×
55

56
                        Some(imported_as)
3✔
57
                    }
58
                }
59
            }
60
        };
61

62
        parser.consume_optional_whitespace();
5✔
63

64
        if let Some(semi) = parser.next_if_is(TokenTy::Semi) {
5✔
65
            Ok(ImportDecl {
5✔
66
                matching_source: Fragment::cover(&use_kw.fragment, &semi.fragment),
5✔
67
                imported_item: path,
5✔
68
                imported_as,
5✔
69
            })
5✔
70
        } else {
UNCOV
71
            Err(ParserErrorKind::ImportMustEndWithSemicolon
×
72
                .at(parser.peek_fragment_or_rest_cloned()))
×
73
        }
74
    }
5✔
75
}
76

77
#[cfg(test)]
78
mod tests {
79
    use crate::{ast::decl::import::ImportDecl, lexer::Lexer, parser::Parser};
80

81
    #[test]
82
    fn test_import() {
1✔
83
        let mut parser = Parser::new(Lexer::new_test("use wright::util;"));
1✔
84
        let import_decl = ImportDecl::parse(&mut parser).unwrap();
1✔
85
        assert!(parser.lexer.remaining.is_empty());
1✔
86
        assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
1✔
87
        assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
1✔
88
    }
1✔
89

90
    #[test]
91
    fn test_import_with_whitespace() {
1✔
92
        let mut parser = Parser::new(Lexer::new_test("use wright :: util ;"));
1✔
93
        let import_decl = ImportDecl::parse(&mut parser).unwrap();
1✔
94
        assert!(parser.lexer.remaining.is_empty());
1✔
95
        assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
1✔
96
        assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
1✔
97
    }
1✔
98

99
    #[test]
100
    fn test_import_as() {
1✔
101
        let mut parser = Parser::new(Lexer::new_test("use wright::util as u;"));
1✔
102
        let import_decl = ImportDecl::parse(&mut parser).unwrap();
1✔
103
        assert!(parser.lexer.remaining.is_empty());
1✔
104
        assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
1✔
105
        assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
1✔
106
        assert_eq!(import_decl.imported_as.unwrap().fragment.as_str(), "u");
1✔
107
    }
1✔
108

109
    #[test]
110
    fn test_import_as_with_comment() {
1✔
111
        let mut parser = Parser::new(Lexer::new_test("use wright::util as /* old_name */ u;"));
1✔
112
        let import_decl = ImportDecl::parse(&mut parser).unwrap();
1✔
113
        assert!(parser.lexer.remaining.is_empty());
1✔
114
        assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
1✔
115
        assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
1✔
116
        assert_eq!(import_decl.imported_as.unwrap().fragment.as_str(), "u");
1✔
117
    }
1✔
118

119
    #[test]
120
    fn test_import_as_with_preceding_comment() {
1✔
121
        let mut parser = Parser::new(Lexer::new_test("use wright::util /* as old_name */ as u;"));
1✔
122
        let import_decl = ImportDecl::parse(&mut parser).unwrap();
1✔
123
        assert!(parser.lexer.remaining.is_empty());
1✔
124
        assert_eq!(import_decl.imported_item.head.fragment.as_str(), "wright");
1✔
125
        assert_eq!(import_decl.imported_item.tail[0].fragment.as_str(), "util");
1✔
126
        assert_eq!(import_decl.imported_as.unwrap().fragment.as_str(), "u");
1✔
127
    }
1✔
128
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc