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
use crate::priv_prelude::{Peek, Peeker};
use crate::{Parse, ParseBracket, ParseErrorKind, ParseResult, ParseToEnd, Parser, ParserConsumed};
use sway_ast::attribute::{Annotated, Attribute, AttributeDecl};
use sway_ast::brackets::{Parens, SquareBrackets};
use sway_ast::keywords::{HashToken, StorageToken, Token};
use sway_ast::punctuated::Punctuated;
use sway_ast::token::{DocComment, DocStyle};
use sway_types::Ident;
impl Peek for DocComment {
fn peek(peeker: Peeker<'_>) -> Option<DocComment> {
peeker.peek_doc_comment().ok().map(Clone::clone)
}
}
impl Parse for DocComment {
fn parse(parser: &mut Parser) -> ParseResult<DocComment> {
match parser.take::<DocComment>() {
Some(doc_comment) => Ok(doc_comment),
None => Err(parser.emit_error(ParseErrorKind::ExpectedDocComment)),
}
}
}
impl<T: Parse> Parse for Annotated<T> {
fn parse(parser: &mut Parser) -> ParseResult<Self> {
let mut attribute_list = Vec::new();
while let Some(DocComment {
doc_style: DocStyle::Outer,
..
}) = parser.peek()
{
let doc_comment = parser.parse::<DocComment>()?;
let value = Ident::new_no_trim(doc_comment.content_span.clone());
attribute_list.push(AttributeDecl {
hash_token: HashToken::new(doc_comment.span.clone()),
attribute: SquareBrackets::new(
Attribute {
name: Ident::new_with_override("doc", doc_comment.span.clone()),
args: Some(Parens::new(
Punctuated::single(value),
doc_comment.content_span,
)),
},
doc_comment.span,
),
});
}
while let Some(attr) = parser.guarded_parse::<HashToken, _>()? {
attribute_list.push(attr);
}
let value = parser.parse()?;
Ok(Annotated {
attribute_list,
value,
})
}
}
impl Parse for AttributeDecl {
fn parse(parser: &mut Parser) -> ParseResult<Self> {
Ok(AttributeDecl {
hash_token: parser.parse()?,
attribute: parser.parse()?,
})
}
}
impl Parse for Attribute {
fn parse(parser: &mut Parser) -> ParseResult<Self> {
let name = if let Some(storage) = parser.take::<StorageToken>() {
Ident::from(storage)
} else {
parser.parse()?
};
let args = Parens::try_parse(parser)?;
Ok(Attribute { name, args })
}
}
impl ParseToEnd for Attribute {
fn parse_to_end<'a, 'e>(mut parser: Parser<'a, 'e>) -> ParseResult<(Self, ParserConsumed<'a>)> {
let attrib = parser.parse()?;
match parser.check_empty() {
Some(consumed) => Ok((attrib, consumed)),
None => Err(parser.emit_error(ParseErrorKind::UnexpectedTokenAfterAttribute)),
}
}
}