blob: f1f703433a93451367ab6ff4fa0806c4adea1bae [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 ///
13 /// ```
David Tolnay9b00f652018-09-01 10:31:02 -070014 /// # extern crate syn;
15 /// #
David Tolnaya7786b42018-01-07 11:37:51 -080016 /// use std::env;
17 /// use std::fs::File;
18 /// use std::io::Read;
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 mut file = File::open(&filename).expect("Unable to open file");
37 ///
38 /// let mut src = String::new();
39 /// file.read_to_string(&mut src).expect("Unable to read file");
40 ///
41 /// let syntax = syn::parse_file(&src).expect("Unable to parse file");
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 /// ```
David Tolnayc7a5d3d2017-06-04 12:11:05 -070072 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")]
80pub mod parsing {
81 use super::*;
82
David Tolnay631e44d2018-08-26 18:56:37 -040083 use parse::{Parse, ParseStream, Result};
David Tolnayc7a5d3d2017-06-04 12:11:05 -070084
David Tolnay631e44d2018-08-26 18:56:37 -040085 impl Parse for File {
86 fn parse(input: ParseStream) -> Result<Self> {
87 Ok(File {
David Tolnayc7a5d3d2017-06-04 12:11:05 -070088 shebang: None,
David Tolnay631e44d2018-08-26 18:56:37 -040089 attrs: input.call(Attribute::parse_inner)?,
90 items: {
91 let mut items = Vec::new();
92 while !input.is_empty() {
David Tolnay6a170ce2018-08-26 22:29:24 -070093 items.push(input.parse()?);
David Tolnay631e44d2018-08-26 18:56:37 -040094 }
95 items
96 },
David Tolnayc7a5d3d2017-06-04 12:11:05 -070097 })
David Tolnayc7a5d3d2017-06-04 12:11:05 -070098 }
99 }
100}
101
102#[cfg(feature = "printing")]
103mod printing {
104 use super::*;
105 use attr::FilterAttrs;
Alex Crichtona74a1c82018-05-16 10:20:44 -0700106 use proc_macro2::TokenStream;
David Tolnay65fb5662018-05-20 20:02:28 -0700107 use quote::{ToTokens, TokenStreamExt};
David Tolnayc7a5d3d2017-06-04 12:11:05 -0700108
109 impl ToTokens for File {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700110 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnayc7a5d3d2017-06-04 12:11:05 -0700111 tokens.append_all(self.attrs.inner());
112 tokens.append_all(&self.items);
113 }
114 }
115}