syn/file.rs
1use crate::attr::Attribute;
2use crate::item::Item;
3
4ast_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")]
87pub(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 {
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")]
112mod 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 {
120 fn to_tokens(&self, tokens: &mut TokenStream) {
121 tokens.append_all(self.attrs.inner());
122 tokens.append_all(&self.items);
123 }
124 }
125}