blob: 7cb9f95de104b1d022ab99781747a803bef447bf [file] [log] [blame]
David Tolnay55535012018-01-05 16:39:23 -08001// 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 Tolnayc7a5d3d2017-06-04 12:11:05 -07009use super::*;
10
11ast_struct! {
David Tolnay48445662018-01-07 01:06:48 -080012 /// A complete file of Rust source code.
David Tolnay461d98e2018-01-07 11:07:19 -080013 ///
14 /// *This type is available if Syn is built with the `"full"` feature.*
David Tolnaya7786b42018-01-07 11:37:51 -080015 ///
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 Tolnayc7a5d3d2017-06-04 12:11:05 -070080 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")]
88pub mod parsing {
89 use super::*;
90
David Tolnay631e44d2018-08-26 18:56:37 -040091 use parse::{Parse, ParseStream, Result};
David Tolnayc7a5d3d2017-06-04 12:11:05 -070092
David Tolnay631e44d2018-08-26 18:56:37 -040093 impl Parse for File {
94 fn parse(input: ParseStream) -> Result<Self> {
95 Ok(File {
David Tolnayc7a5d3d2017-06-04 12:11:05 -070096 shebang: None,
David Tolnay631e44d2018-08-26 18:56:37 -040097 attrs: input.call(Attribute::parse_inner)?,
98 items: {
99 let mut items = Vec::new();
100 while !input.is_empty() {
David Tolnay6a170ce2018-08-26 22:29:24 -0700101 items.push(input.parse()?);
David Tolnay631e44d2018-08-26 18:56:37 -0400102 }
103 items
104 },
David Tolnayc7a5d3d2017-06-04 12:11:05 -0700105 })
David Tolnayc7a5d3d2017-06-04 12:11:05 -0700106 }
107 }
108}
109
110#[cfg(feature = "printing")]
111mod printing {
112 use super::*;
113 use attr::FilterAttrs;
Alex Crichtona74a1c82018-05-16 10:20:44 -0700114 use proc_macro2::TokenStream;
David Tolnay65fb5662018-05-20 20:02:28 -0700115 use quote::{ToTokens, TokenStreamExt};
David Tolnayc7a5d3d2017-06-04 12:11:05 -0700116
117 impl ToTokens for File {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700118 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnayc7a5d3d2017-06-04 12:11:05 -0700119 tokens.append_all(self.attrs.inner());
120 tokens.append_all(&self.items);
121 }
122 }
123}