1use crate::{Parse, ParseResult, ParseToEnd, Parser, ParserConsumed};
2
3use sway_ast::{attribute::Annotated, Module, ModuleKind};
4use sway_error::parser_error::ParseErrorKind;
5
6impl Parse for ModuleKind {
7 fn parse(parser: &mut Parser) -> ParseResult<Self> {
8 if let Some(script_token) = parser.take() {
9 Ok(Self::Script { script_token })
10 } else if let Some(contract_token) = parser.take() {
11 Ok(Self::Contract { contract_token })
12 } else if let Some(predicate_token) = parser.take() {
13 Ok(Self::Predicate { predicate_token })
14 } else if let Some(library_token) = parser.take() {
15 Ok(Self::Library { library_token })
16 } else {
17 Err(parser.emit_error(ParseErrorKind::ExpectedModuleKind))
18 }
19 }
20}
21
22impl ParseToEnd for Annotated<Module> {
23 fn parse_to_end<'a, 'e>(mut parser: Parser<'a, '_>) -> ParseResult<(Self, ParserConsumed<'a>)> {
24 let attributes = parser.parse()?;
25 let (kind, semicolon_token) = parser.parse()?;
26 let (items, consumed) = parser.parse_to_end()?;
27 let module = Annotated {
28 attributes,
29 value: Module {
30 kind,
31 semicolon_token,
32 items,
33 },
34 };
35 Ok((module, consumed))
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42 use crate::test_utils::parse_to_end;
43 use insta::*;
44
45 #[test]
46 fn parse_noop_script_module() {
47 assert_ron_snapshot!(parse_to_end::<Annotated<Module>>(r#"
48 script;
49
50 fn main() {
51 ()
52 }
53 "#,), @r#"
54 Annotated(
55 attributes: [],
56 value: Module(
57 kind: Script(
58 script_token: ScriptToken(
59 span: Span(
60 src: "\n script;\n \n fn main() {\n ()\n }\n ",
61 start: 13,
62 end: 19,
63 source_id: None,
64 ),
65 ),
66 ),
67 semicolon_token: SemicolonToken(
68 span: Span(
69 src: "\n script;\n \n fn main() {\n ()\n }\n ",
70 start: 19,
71 end: 20,
72 source_id: None,
73 ),
74 ),
75 items: [
76 Annotated(
77 attributes: [],
78 value: Fn(ItemFn(
79 fn_signature: FnSignature(
80 visibility: None,
81 fn_token: FnToken(
82 span: Span(
83 src: "\n script;\n \n fn main() {\n ()\n }\n ",
84 start: 42,
85 end: 44,
86 source_id: None,
87 ),
88 ),
89 name: BaseIdent(
90 name_override_opt: None,
91 span: Span(
92 src: "\n script;\n \n fn main() {\n ()\n }\n ",
93 start: 45,
94 end: 49,
95 source_id: None,
96 ),
97 is_raw_ident: false,
98 ),
99 generics: None,
100 arguments: Parens(
101 inner: Static(Punctuated(
102 value_separator_pairs: [],
103 final_value_opt: None,
104 )),
105 span: Span(
106 src: "\n script;\n \n fn main() {\n ()\n }\n ",
107 start: 49,
108 end: 51,
109 source_id: None,
110 ),
111 ),
112 return_type_opt: None,
113 where_clause_opt: None,
114 ),
115 body: Braces(
116 inner: CodeBlockContents(
117 statements: [],
118 final_expr_opt: Some(Tuple(Parens(
119 inner: Nil,
120 span: Span(
121 src: "\n script;\n \n fn main() {\n ()\n }\n ",
122 start: 70,
123 end: 72,
124 source_id: None,
125 ),
126 ))),
127 span: Span(
128 src: "\n script;\n \n fn main() {\n ()\n }\n ",
129 start: 53,
130 end: 85,
131 source_id: None,
132 ),
133 ),
134 span: Span(
135 src: "\n script;\n \n fn main() {\n ()\n }\n ",
136 start: 52,
137 end: 86,
138 source_id: None,
139 ),
140 ),
141 )),
142 ),
143 ],
144 ),
145 )
146 "#);
147 }
148}