1 use super::*;
2 
3 ast_struct! {
4     /// A complete file of Rust source code.
5     ///
6     /// *This type is available only if Syn is built with the `"full"` feature.*
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     ///     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     ///         ExternCrate(
53     ///             ItemExternCrate {
54     ///                 attrs: [],
55     ///                 vis: Inherited,
56     ///                 extern_token: Extern,
57     ///                 crate_token: Crate,
58     ///                 ident: Ident {
59     ///                     term: Term(
60     ///                         "syn"
61     ///                     ),
62     ///                     span: Span
63     ///                 },
64     ///                 rename: None,
65     ///                 semi_token: Semi
66     ///             }
67     ///         ),
68     /// ...
69     /// ```
70     pub struct File {
71         pub shebang: Option<String>,
72         pub attrs: Vec<Attribute>,
73         pub items: Vec<Item>,
74     }
75 }
76 
77 #[cfg(feature = "parsing")]
78 pub mod parsing {
79     use super::*;
80 
81     use crate::parse::{Parse, ParseStream, Result};
82 
83     impl Parse for File {
parse(input: ParseStream) -> Result<Self>84         fn parse(input: ParseStream) -> Result<Self> {
85             Ok(File {
86                 shebang: None,
87                 attrs: input.call(Attribute::parse_inner)?,
88                 items: {
89                     let mut items = Vec::new();
90                     while !input.is_empty() {
91                         items.push(input.parse()?);
92                     }
93                     items
94                 },
95             })
96         }
97     }
98 }
99 
100 #[cfg(feature = "printing")]
101 mod printing {
102     use super::*;
103     use crate::attr::FilterAttrs;
104     use proc_macro2::TokenStream;
105     use quote::{ToTokens, TokenStreamExt};
106 
107     impl ToTokens for File {
to_tokens(&self, tokens: &mut TokenStream)108         fn to_tokens(&self, tokens: &mut TokenStream) {
109             tokens.append_all(self.attrs.inner());
110             tokens.append_all(&self.items);
111         }
112     }
113 }
114