• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
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 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 {
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