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