1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use crate::build_config::BuildConfig;
use crate::error::*;
use crate::span;
use crate::Ident;
use crate::Rule;
use pest::iterators::Pair;
#[derive(Debug, Clone)]
pub enum ImportType<'sc> {
Star,
Item(Ident<'sc>),
}
#[derive(Debug, Clone)]
pub struct UseStatement<'sc> {
pub(crate) call_path: Vec<Ident<'sc>>,
pub(crate) import_type: ImportType<'sc>,
pub(crate) is_absolute: bool,
pub(crate) alias: Option<Ident<'sc>>,
}
impl<'sc> UseStatement<'sc> {
pub(crate) fn parse_from_pair(
pair: Pair<'sc, Rule>,
config: Option<&BuildConfig>,
) -> CompileResult<'sc, Self> {
let mut errors = vec![];
let mut warnings = vec![];
let stmt = pair.into_inner().next().unwrap();
let is_absolute = stmt.as_rule() == Rule::absolute_use_statement;
let mut stmt = stmt.into_inner();
let _use_keyword = stmt.next();
let import_path = if is_absolute {
stmt.clone().nth(1).expect("Guaranteed by grammar")
} else {
stmt.clone().next().expect("Guaranteed by grammar")
};
let mut import_path_buf = vec![];
let mut import_path_vec = import_path.into_inner().collect::<Vec<_>>();
let last_item = import_path_vec.pop().unwrap();
let import_type = match last_item.as_rule() {
Rule::star => ImportType::Star,
Rule::ident => ImportType::Item(check!(
Ident::parse_from_pair(last_item, config),
return err(warnings, errors),
warnings,
errors
)),
_ => unreachable!(),
};
for item in import_path_vec.into_iter() {
if item.as_rule() == Rule::star {
errors.push(CompileError::NonFinalAsteriskInPath {
span: span::Span {
span: item.as_span(),
path: config.map(|c| c.path()),
},
});
continue;
} else if item.as_rule() == Rule::ident {
import_path_buf.push(check!(
Ident::parse_from_pair(item, config),
return err(warnings, errors),
warnings,
errors
));
}
}
let mut alias = None;
for item in stmt {
if item.as_rule() == Rule::alias {
let item = item.into_inner().nth(1).unwrap();
let alias_parsed = check!(
Ident::parse_from_pair(item, config),
continue,
warnings,
errors
);
alias = Some(alias_parsed);
}
}
ok(
UseStatement {
call_path: import_path_buf,
import_type,
is_absolute,
alias,
},
Vec::new(),
Vec::new(),
)
}
}