1use crate::{Parse, ParseResult, Parser};
2
3use sway_ast::keywords::{DoubleColonToken, OpenAngleBracketToken, SelfToken, StorageToken};
4use sway_ast::{
5 AngleBrackets, PathExpr, PathExprSegment, PathType, PathTypeSegment, QualifiedPathRoot,
6};
7use sway_types::{Ident, Spanned};
8
9impl Parse for PathExpr {
10 fn parse(parser: &mut Parser) -> ParseResult<PathExpr> {
11 let root_opt = match parser.take() {
12 Some(open_angle_bracket_token) => {
13 let qualified_path_root = parser.parse()?;
14 let close_angle_bracket_token = parser.parse()?;
15 let angle_brackets = AngleBrackets {
16 open_angle_bracket_token,
17 inner: qualified_path_root,
18 close_angle_bracket_token,
19 };
20 let double_colon_token = parser.parse()?;
21 Some((Some(angle_brackets), double_colon_token))
22 }
23 None => parser
24 .take()
25 .map(|double_colon_token| (None, double_colon_token)),
26 };
27 let prefix = parser.parse()?;
28 let mut suffix: Vec<(DoubleColonToken, PathExprSegment)> = Vec::new();
29 let mut incomplete_suffix = false;
30 while let Some(double_colon_token) = parser.take() {
31 if let Ok(segment) = parser.parse() {
32 suffix.push((double_colon_token, segment));
33 } else {
34 incomplete_suffix = true;
35 let dummy_path_expr_segment = PathExprSegment {
37 name: Ident::new(double_colon_token.span()),
38 generics_opt: None,
39 };
40 suffix.push((double_colon_token, dummy_path_expr_segment));
41 break;
42 }
43 }
44 Ok(PathExpr {
45 root_opt,
46 prefix,
47 suffix,
48 incomplete_suffix,
49 })
50 }
51}
52
53fn parse_ident(parser: &mut Parser) -> ParseResult<Ident> {
54 if let Some(token) = parser.take::<StorageToken>() {
55 Ok(Ident::from(token))
56 } else if let Some(token) = parser.take::<SelfToken>() {
57 Ok(Ident::from(token))
58 } else {
59 parser.parse::<Ident>()
60 }
61}
62
63impl Parse for PathExprSegment {
64 fn parse(parser: &mut Parser) -> ParseResult<PathExprSegment> {
65 Ok(PathExprSegment {
66 name: parse_ident(parser)?,
67 generics_opt: parser.guarded_parse::<(DoubleColonToken, OpenAngleBracketToken), _>()?,
68 })
69 }
70}
71
72impl Parse for PathType {
73 fn parse(parser: &mut Parser) -> ParseResult<PathType> {
74 let root_opt = match parser.take() {
75 Some(open_angle_bracket_token) => {
76 let qualified_path_root = parser.parse()?;
77 let close_angle_bracket_token = parser.parse()?;
78 let angle_brackets = AngleBrackets {
79 open_angle_bracket_token,
80 inner: qualified_path_root,
81 close_angle_bracket_token,
82 };
83 let double_colon_token = parser.parse()?;
84 Some((Some(angle_brackets), double_colon_token))
85 }
86 None => parser
87 .take()
88 .map(|double_colon_token| (None, double_colon_token)),
89 };
90 let prefix = parser.parse()?;
91 let mut suffix = Vec::new();
92 while let Some(double_colon_token) = parser.take() {
93 let segment = parser.parse()?;
94 suffix.push((double_colon_token, segment));
95 }
96 Ok(PathType {
97 root_opt,
98 prefix,
99 suffix,
100 })
101 }
102}
103
104impl Parse for PathTypeSegment {
105 fn parse(parser: &mut Parser) -> ParseResult<PathTypeSegment> {
106 let name = parse_ident(parser)?;
107 let generics_opt =
108 if let Some(generics) = parser.guarded_parse::<OpenAngleBracketToken, _>()? {
109 Some((None, generics))
110 } else if let Some((double_colon_token, generics)) =
111 parser.guarded_parse::<(DoubleColonToken, OpenAngleBracketToken), _>()?
112 {
113 Some((Some(double_colon_token), generics))
114 } else {
115 None
116 };
117 Ok(PathTypeSegment { name, generics_opt })
118 }
119}
120
121impl Parse for QualifiedPathRoot {
122 fn parse(parser: &mut Parser) -> ParseResult<QualifiedPathRoot> {
123 let ty = parser.parse()?;
124 let as_trait = (parser.parse()?, parser.parse()?);
125 Ok(QualifiedPathRoot { ty, as_trait })
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132 use crate::test_utils::parse;
133 use insta::*;
134
135 #[test]
136 fn parse_nested_path() {
137 assert_ron_snapshot!(parse::<PathExpr>(r#"
138 std::vec::Vec
139 "#,), @r#"
140 PathExpr(
141 root_opt: None,
142 prefix: PathExprSegment(
143 name: BaseIdent(
144 name_override_opt: None,
145 span: Span(
146 src: "\n std::vec::Vec\n ",
147 start: 13,
148 end: 16,
149 source_id: None,
150 ),
151 is_raw_ident: false,
152 ),
153 generics_opt: None,
154 ),
155 suffix: [
156 (DoubleColonToken(
157 span: Span(
158 src: "\n std::vec::Vec\n ",
159 start: 16,
160 end: 18,
161 source_id: None,
162 ),
163 ), PathExprSegment(
164 name: BaseIdent(
165 name_override_opt: None,
166 span: Span(
167 src: "\n std::vec::Vec\n ",
168 start: 18,
169 end: 21,
170 source_id: None,
171 ),
172 is_raw_ident: false,
173 ),
174 generics_opt: None,
175 )),
176 (DoubleColonToken(
177 span: Span(
178 src: "\n std::vec::Vec\n ",
179 start: 21,
180 end: 23,
181 source_id: None,
182 ),
183 ), PathExprSegment(
184 name: BaseIdent(
185 name_override_opt: None,
186 span: Span(
187 src: "\n std::vec::Vec\n ",
188 start: 23,
189 end: 26,
190 source_id: None,
191 ),
192 is_raw_ident: false,
193 ),
194 generics_opt: None,
195 )),
196 ],
197 )
198 "#);
199 }
200}