blob: 30defe7df105155f4b49b997452f3f891ebd622c [file] [log] [blame]
David Tolnayc7a5d3d2017-06-04 12:11:05 -07001use super::*;
2
3ast_struct! {
David Tolnay48445662018-01-07 01:06:48 -08004 /// A complete file of Rust source code.
David Tolnay461d98e2018-01-07 11:07:19 -08005 ///
6 /// *This type is available if Syn is built with the `"full"` feature.*
David Tolnaya7786b42018-01-07 11:37:51 -08007 ///
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 ///
David Tolnay95989db2019-01-01 15:05:57 -050013 /// ```edition2018
David Tolnaya7786b42018-01-07 11:37:51 -080014 /// 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 /// ```
David Tolnayc7a5d3d2017-06-04 12:11:05 -070070 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")]
78pub mod parsing {
79 use super::*;
80
David Tolnay631e44d2018-08-26 18:56:37 -040081 use parse::{Parse, ParseStream, Result};
David Tolnayc7a5d3d2017-06-04 12:11:05 -070082
David Tolnay631e44d2018-08-26 18:56:37 -040083 impl Parse for File {
84 fn parse(input: ParseStream) -> Result<Self> {
85 Ok(File {
David Tolnayc7a5d3d2017-06-04 12:11:05 -070086 shebang: None,
David Tolnay631e44d2018-08-26 18:56:37 -040087 attrs: input.call(Attribute::parse_inner)?,
88 items: {
89 let mut items = Vec::new();
90 while !input.is_empty() {
David Tolnay6a170ce2018-08-26 22:29:24 -070091 items.push(input.parse()?);
David Tolnay631e44d2018-08-26 18:56:37 -040092 }
93 items
94 },
David Tolnayc7a5d3d2017-06-04 12:11:05 -070095 })
David Tolnayc7a5d3d2017-06-04 12:11:05 -070096 }
97 }
98}
99
100#[cfg(feature = "printing")]
101mod printing {
102 use super::*;
103 use attr::FilterAttrs;
Alex Crichtona74a1c82018-05-16 10:20:44 -0700104 use proc_macro2::TokenStream;
David Tolnay65fb5662018-05-20 20:02:28 -0700105 use quote::{ToTokens, TokenStreamExt};
David Tolnayc7a5d3d2017-06-04 12:11:05 -0700106
107 impl ToTokens for File {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700108 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnayc7a5d3d2017-06-04 12:11:05 -0700109 tokens.append_all(self.attrs.inner());
110 tokens.append_all(&self.items);
111 }
112 }
113}