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 /// 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 /// ``` 72 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")] 80 pub mod parsing { 81 use super::*; 82 use crate::parse::{Parse, ParseStream, Result}; 83 84 impl Parse for File { parse(input: ParseStream) -> Result<Self>85 fn parse(input: ParseStream) -> Result<Self> { 86 Ok(File { 87 shebang: None, 88 attrs: input.call(Attribute::parse_inner)?, 89 items: { 90 let mut items = Vec::new(); 91 while !input.is_empty() { 92 items.push(input.parse()?); 93 } 94 items 95 }, 96 }) 97 } 98 } 99 } 100 101 #[cfg(feature = "printing")] 102 mod printing { 103 use super::*; 104 use crate::attr::FilterAttrs; 105 use proc_macro2::TokenStream; 106 use quote::{ToTokens, TokenStreamExt}; 107 108 impl ToTokens for File { to_tokens(&self, tokens: &mut TokenStream)109 fn to_tokens(&self, tokens: &mut TokenStream) { 110 tokens.append_all(self.attrs.inner()); 111 tokens.append_all(&self.items); 112 } 113 } 114 } 115