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