1 | use crate::attr::Attribute; |
2 | use crate::item::Item; |
3 | |
4 | ast_struct! { |
5 | /// A complete file of Rust source code. |
6 | /// |
7 | /// Typically `File` objects are created with [`parse_file`]. |
8 | /// |
9 | /// [`parse_file`]: crate::parse_file |
10 | /// |
11 | /// # Example |
12 | /// |
13 | /// Parse a Rust source file into a `syn::File` and print out a debug |
14 | /// representation of the syntax tree. |
15 | /// |
16 | /// ``` |
17 | /// use std::env; |
18 | /// use std::fs; |
19 | /// use std::process; |
20 | /// |
21 | /// fn main() { |
22 | /// # } |
23 | /// # |
24 | /// # fn fake_main() { |
25 | /// let mut args = env::args(); |
26 | /// let _ = args.next(); // executable name |
27 | /// |
28 | /// let filename = match (args.next(), args.next()) { |
29 | /// (Some(filename), None) => filename, |
30 | /// _ => { |
31 | /// eprintln!("Usage: dump-syntax path/to/filename.rs"); |
32 | /// process::exit(1); |
33 | /// } |
34 | /// }; |
35 | /// |
36 | /// let src = fs::read_to_string(&filename).expect("unable to read file"); |
37 | /// let syntax = syn::parse_file(&src).expect("unable to parse file"); |
38 | /// |
39 | /// // Debug impl is available if Syn is built with "extra-traits" feature. |
40 | /// println!("{:#?}", syntax); |
41 | /// } |
42 | /// ``` |
43 | /// |
44 | /// Running with its own source code as input, this program prints output |
45 | /// that begins with: |
46 | /// |
47 | /// ```text |
48 | /// File { |
49 | /// shebang: None, |
50 | /// attrs: [], |
51 | /// items: [ |
52 | /// Use( |
53 | /// ItemUse { |
54 | /// attrs: [], |
55 | /// vis: Inherited, |
56 | /// use_token: Use, |
57 | /// leading_colon: None, |
58 | /// tree: Path( |
59 | /// UsePath { |
60 | /// ident: Ident( |
61 | /// std, |
62 | /// ), |
63 | /// colon2_token: Colon2, |
64 | /// tree: Name( |
65 | /// UseName { |
66 | /// ident: Ident( |
67 | /// env, |
68 | /// ), |
69 | /// }, |
70 | /// ), |
71 | /// }, |
72 | /// ), |
73 | /// semi_token: Semi, |
74 | /// }, |
75 | /// ), |
76 | /// ... |
77 | /// ``` |
78 | #[cfg_attr (docsrs, doc(cfg(feature = "full" )))] |
79 | pub struct File { |
80 | pub shebang: Option<String>, |
81 | pub attrs: Vec<Attribute>, |
82 | pub items: Vec<Item>, |
83 | } |
84 | } |
85 | |
86 | #[cfg (feature = "parsing" )] |
87 | pub(crate) mod parsing { |
88 | use crate::attr::Attribute; |
89 | use crate::error::Result; |
90 | use crate::file::File; |
91 | use crate::parse::{Parse, ParseStream}; |
92 | |
93 | #[cfg_attr (docsrs, doc(cfg(feature = "parsing" )))] |
94 | impl Parse for File { |
95 | fn parse(input: ParseStream) -> Result<Self> { |
96 | Ok(File { |
97 | shebang: None, |
98 | attrs: input.call(function:Attribute::parse_inner)?, |
99 | items: { |
100 | let mut items: Vec = Vec::new(); |
101 | while !input.is_empty() { |
102 | items.push(input.parse()?); |
103 | } |
104 | items |
105 | }, |
106 | }) |
107 | } |
108 | } |
109 | } |
110 | |
111 | #[cfg (feature = "printing" )] |
112 | mod printing { |
113 | use crate::attr::FilterAttrs; |
114 | use crate::file::File; |
115 | use proc_macro2::TokenStream; |
116 | use quote::{ToTokens, TokenStreamExt}; |
117 | |
118 | #[cfg_attr (docsrs, doc(cfg(feature = "printing" )))] |
119 | impl ToTokens for File { |
120 | fn to_tokens(&self, tokens: &mut TokenStream) { |
121 | tokens.append_all(self.attrs.inner()); |
122 | tokens.append_all(&self.items); |
123 | } |
124 | } |
125 | } |
126 | |