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 /// Use( 55 /// ItemUse { 56 /// attrs: [], 57 /// vis: Inherited, 58 /// use_token: Use, 59 /// leading_colon: None, 60 /// tree: Path( 61 /// UsePath { 62 /// ident: Ident( 63 /// std, 64 /// ), 65 /// colon2_token: Colon2, 66 /// tree: Name( 67 /// UseName { 68 /// ident: Ident( 69 /// env, 70 /// ), 71 /// }, 72 /// ), 73 /// }, 74 /// ), 75 /// semi_token: Semi, 76 /// }, 77 /// ), 78 /// ... 79 /// ``` 80 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] 81 pub struct File { 82 pub shebang: Option<String>, 83 pub attrs: Vec<Attribute>, 84 pub items: Vec<Item>, 85 } 86 } 87 88 #[cfg(feature = "parsing")] 89 pub mod parsing { 90 use super::*; 91 use crate::parse::{Parse, ParseStream, Result}; 92 93 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 94 impl Parse for File { parse(input: ParseStream) -> Result<Self>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")] 112 mod printing { 113 use super::*; 114 use crate::attr::FilterAttrs; 115 use proc_macro2::TokenStream; 116 use quote::{ToTokens, TokenStreamExt}; 117 118 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 119 impl ToTokens for File { to_tokens(&self, tokens: &mut TokenStream)120 fn to_tokens(&self, tokens: &mut TokenStream) { 121 tokens.append_all(self.attrs.inner()); 122 tokens.append_all(&self.items); 123 } 124 } 125 } 126