syn_solidity/item/
pragma.rs1use crate::{kw, utils::tts_until_semi, SolIdent, Spanned};
2use proc_macro2::{Span, TokenStream};
3use std::fmt;
4use syn::{
5 parse::{Parse, ParseStream},
6 Result, Token,
7};
8
9#[derive(Clone)]
11pub struct PragmaDirective {
12 pub pragma_token: kw::pragma,
13 pub tokens: PragmaTokens,
14 pub semi_token: Token![;],
15}
16
17impl fmt::Display for PragmaDirective {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 write!(f, "pragma {};", self.tokens)
20 }
21}
22
23impl fmt::Debug for PragmaDirective {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 f.debug_tuple("PragmaDirective").field(&self.tokens).finish()
26 }
27}
28
29impl Parse for PragmaDirective {
30 fn parse(input: ParseStream<'_>) -> Result<Self> {
31 Ok(Self {
32 pragma_token: input.parse()?,
33 tokens: input.parse()?,
34 semi_token: input.parse()?,
35 })
36 }
37}
38
39impl Spanned for PragmaDirective {
40 fn span(&self) -> Span {
41 let span = self.pragma_token.span;
42 span.join(self.semi_token.span).unwrap_or(span)
43 }
44
45 fn set_span(&mut self, span: Span) {
46 self.pragma_token.span = span;
47 self.tokens.set_span(span);
48 self.semi_token.span = span;
49 }
50}
51
52#[derive(Clone, Debug)]
53pub enum PragmaTokens {
54 Version(kw::solidity, TokenStream),
55 Abicoder(kw::abicoder, SolIdent),
56 Experimental(kw::experimental, SolIdent),
57 Verbatim(TokenStream),
58}
59
60impl fmt::Display for PragmaTokens {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 match self {
63 Self::Version(_, version) => write!(f, "solidity {version}"),
64 Self::Abicoder(_, ident) => write!(f, "abicoder {ident}"),
65 Self::Experimental(_, ident) => write!(f, "experimental {ident}"),
66 Self::Verbatim(tokens) => tokens.fmt(f),
67 }
68 }
69}
70
71impl Parse for PragmaTokens {
72 fn parse(input: ParseStream<'_>) -> Result<Self> {
73 if input.peek(kw::solidity) {
74 let solidity = input.parse()?;
75 let version = tts_until_semi(input);
76 Ok(Self::Version(solidity, version))
77 } else if input.peek(kw::abicoder) {
78 let abicoder = input.parse()?;
79 let ident = input.parse()?;
80 Ok(Self::Abicoder(abicoder, ident))
81 } else if input.peek(kw::experimental) {
82 let experimental = input.parse()?;
83 let ident = input.parse()?;
84 Ok(Self::Experimental(experimental, ident))
85 } else {
86 Ok(Self::Verbatim(tts_until_semi(input)))
87 }
88 }
89}
90
91impl Spanned for PragmaTokens {
92 fn span(&self) -> Span {
93 match self {
94 Self::Version(solidity, version) => {
95 let span = solidity.span;
96 span.join(version.span()).unwrap_or(span)
97 }
98 Self::Abicoder(abicoder, ident) => {
99 let span = abicoder.span;
100 span.join(ident.span()).unwrap_or(span)
101 }
102 Self::Experimental(experimental, ident) => {
103 let span = experimental.span;
104 span.join(ident.span()).unwrap_or(span)
105 }
106 Self::Verbatim(tokens) => tokens.span(),
107 }
108 }
109
110 fn set_span(&mut self, span: Span) {
111 match self {
112 Self::Version(solidity, _version) => {
113 solidity.span = span;
114 }
115 Self::Abicoder(abicoder, ident) => {
116 abicoder.span = span;
117 ident.set_span(span);
118 }
119 Self::Experimental(experimental, ident) => {
120 experimental.span = span;
121 ident.set_span(span);
122 }
123 Self::Verbatim(_tokens) => {}
124 }
125 }
126}