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