David Tolnay | 5553501 | 2018-01-05 16:39:23 -0800 | [diff] [blame] | 1 | // Copyright 2018 Syn Developers |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
| 4 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
| 5 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
| 6 | // option. This file may not be copied, modified, or distributed |
| 7 | // except according to those terms. |
| 8 | |
David Tolnay | c7a5d3d | 2017-06-04 12:11:05 -0700 | [diff] [blame] | 9 | use super::*; |
| 10 | |
| 11 | ast_struct! { |
David Tolnay | 4844566 | 2018-01-07 01:06:48 -0800 | [diff] [blame] | 12 | /// A complete file of Rust source code. |
David Tolnay | 461d98e | 2018-01-07 11:07:19 -0800 | [diff] [blame] | 13 | /// |
| 14 | /// *This type is available if Syn is built with the `"full"` feature.* |
David Tolnay | a7786b4 | 2018-01-07 11:37:51 -0800 | [diff] [blame] | 15 | /// |
| 16 | /// # Example |
| 17 | /// |
| 18 | /// Parse a Rust source file into a `syn::File` and print out a debug |
| 19 | /// representation of the syntax tree. |
| 20 | /// |
| 21 | /// ``` |
| 22 | /// extern crate syn; |
| 23 | /// |
| 24 | /// use std::env; |
| 25 | /// use std::fs::File; |
| 26 | /// use std::io::Read; |
| 27 | /// use std::process; |
| 28 | /// |
| 29 | /// fn main() { |
| 30 | /// # } |
| 31 | /// # |
| 32 | /// # fn fake_main() { |
| 33 | /// let mut args = env::args(); |
| 34 | /// let _ = args.next(); // executable name |
| 35 | /// |
| 36 | /// let filename = match (args.next(), args.next()) { |
| 37 | /// (Some(filename), None) => filename, |
| 38 | /// _ => { |
| 39 | /// eprintln!("Usage: dump-syntax path/to/filename.rs"); |
| 40 | /// process::exit(1); |
| 41 | /// } |
| 42 | /// }; |
| 43 | /// |
| 44 | /// let mut file = File::open(&filename).expect("Unable to open file"); |
| 45 | /// |
| 46 | /// let mut src = String::new(); |
| 47 | /// file.read_to_string(&mut src).expect("Unable to read file"); |
| 48 | /// |
| 49 | /// let syntax = syn::parse_file(&src).expect("Unable to parse file"); |
| 50 | /// println!("{:#?}", syntax); |
| 51 | /// } |
| 52 | /// ``` |
| 53 | /// |
| 54 | /// Running with its own source code as input, this program prints output |
| 55 | /// that begins with: |
| 56 | /// |
| 57 | /// ```text |
| 58 | /// File { |
| 59 | /// shebang: None, |
| 60 | /// attrs: [], |
| 61 | /// items: [ |
| 62 | /// ExternCrate( |
| 63 | /// ItemExternCrate { |
| 64 | /// attrs: [], |
| 65 | /// vis: Inherited, |
| 66 | /// extern_token: Extern, |
| 67 | /// crate_token: Crate, |
| 68 | /// ident: Ident { |
| 69 | /// term: Term( |
| 70 | /// "syn" |
| 71 | /// ), |
| 72 | /// span: Span |
| 73 | /// }, |
| 74 | /// rename: None, |
| 75 | /// semi_token: Semi |
| 76 | /// } |
| 77 | /// ), |
| 78 | /// ... |
| 79 | /// ``` |
David Tolnay | c7a5d3d | 2017-06-04 12:11:05 -0700 | [diff] [blame] | 80 | pub struct File { |
| 81 | pub shebang: Option<String>, |
| 82 | pub attrs: Vec<Attribute>, |
| 83 | pub items: Vec<Item>, |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | #[cfg(feature = "parsing")] |
| 88 | pub mod parsing { |
| 89 | use super::*; |
| 90 | |
David Tolnay | 631e44d | 2018-08-26 18:56:37 -0400 | [diff] [blame] | 91 | use parse::{Parse, ParseStream, Result}; |
David Tolnay | c7a5d3d | 2017-06-04 12:11:05 -0700 | [diff] [blame] | 92 | |
David Tolnay | 631e44d | 2018-08-26 18:56:37 -0400 | [diff] [blame] | 93 | impl Parse for File { |
| 94 | fn parse(input: ParseStream) -> Result<Self> { |
| 95 | Ok(File { |
David Tolnay | c7a5d3d | 2017-06-04 12:11:05 -0700 | [diff] [blame] | 96 | shebang: None, |
David Tolnay | 631e44d | 2018-08-26 18:56:37 -0400 | [diff] [blame] | 97 | attrs: input.call(Attribute::parse_inner)?, |
| 98 | items: { |
| 99 | let mut items = Vec::new(); |
| 100 | while !input.is_empty() { |
David Tolnay | 6a170ce | 2018-08-26 22:29:24 -0700 | [diff] [blame] | 101 | items.push(input.parse()?); |
David Tolnay | 631e44d | 2018-08-26 18:56:37 -0400 | [diff] [blame] | 102 | } |
| 103 | items |
| 104 | }, |
David Tolnay | c7a5d3d | 2017-06-04 12:11:05 -0700 | [diff] [blame] | 105 | }) |
David Tolnay | c7a5d3d | 2017-06-04 12:11:05 -0700 | [diff] [blame] | 106 | } |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | #[cfg(feature = "printing")] |
| 111 | mod printing { |
| 112 | use super::*; |
| 113 | use attr::FilterAttrs; |
Alex Crichton | a74a1c8 | 2018-05-16 10:20:44 -0700 | [diff] [blame] | 114 | use proc_macro2::TokenStream; |
David Tolnay | 65fb566 | 2018-05-20 20:02:28 -0700 | [diff] [blame] | 115 | use quote::{ToTokens, TokenStreamExt}; |
David Tolnay | c7a5d3d | 2017-06-04 12:11:05 -0700 | [diff] [blame] | 116 | |
| 117 | impl ToTokens for File { |
Alex Crichton | a74a1c8 | 2018-05-16 10:20:44 -0700 | [diff] [blame] | 118 | fn to_tokens(&self, tokens: &mut TokenStream) { |
David Tolnay | c7a5d3d | 2017-06-04 12:11:05 -0700 | [diff] [blame] | 119 | tokens.append_all(self.attrs.inner()); |
| 120 | tokens.append_all(&self.items); |
| 121 | } |
| 122 | } |
| 123 | } |