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     ///         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 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 {
parse(input: ParseStream) -> Result<Self>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 {
to_tokens(&self, tokens: &mut TokenStream)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