// SPDX-License-Identifier: Apache-2.0 OR MIT12use crate::attr::Attribute;3use crate::item::Item;45ast_struct! {6/// A complete file of Rust source code.7///8/// Typically `File` objects are created with [`parse_file`].9///10/// [`parse_file`]: crate::parse_file11///12/// # Example13///14/// Parse a Rust source file into a `syn::File` and print out a debug15/// representation of the syntax tree.16///17/// ```18/// use std::env;19/// use std::fs;20/// use std::process;21///22/// fn main() {23/// # }24/// #25/// # fn fake_main() {26/// let mut args = env::args();27/// let _ = args.next(); // executable name28///29/// let filename = match (args.next(), args.next()) {30/// (Some(filename), None) => filename,31/// _ => {32/// eprintln!("Usage: dump-syntax path/to/filename.rs");33/// process::exit(1);34/// }35/// };36///37/// let src = fs::read_to_string(&filename).expect("unable to read file");38/// let syntax = syn::parse_file(&src).expect("unable to parse file");39///40/// // Debug impl is available if Syn is built with "extra-traits" feature.41/// println!("{:#?}", syntax);42/// }43/// ```44///45/// Running with its own source code as input, this program prints output46/// that begins with:47///48/// ```text49/// File {50/// shebang: None,51/// attrs: [],52/// items: [53/// Use(54/// ItemUse {55/// attrs: [],56/// vis: Inherited,57/// use_token: Use,58/// leading_colon: None,59/// tree: Path(60/// UsePath {61/// ident: Ident(62/// std,63/// ),64/// colon2_token: Colon2,65/// tree: Name(66/// UseName {67/// ident: Ident(68/// env,69/// ),70/// },71/// ),72/// },73/// ),74/// semi_token: Semi,75/// },76/// ),77/// ...78/// ```79#[cfg_attr(docsrs, doc(cfg(feature = "full")))]80pub struct File {81pub shebang: Option<String>,82pub attrs: Vec<Attribute>,83pub items: Vec<Item>,84}85}8687#[cfg(feature = "parsing")]88pub(crate) mod parsing {89use crate::attr::Attribute;90use crate::error::Result;91use crate::file::File;92use crate::parse::{Parse, ParseStream};9394#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]95impl Parse for File {96fn parse(input: ParseStream) -> Result<Self> {97Ok(File {98shebang: None,99attrs: input.call(Attribute::parse_inner)?,100items: {101let mut items = Vec::new();102while !input.is_empty() {103items.push(input.parse()?);104}105items106},107})108}109}110}111112#[cfg(feature = "printing")]113mod printing {114use crate::attr::FilterAttrs;115use crate::file::File;116use proc_macro2::TokenStream;117use quote::{ToTokens, TokenStreamExt};118119#[cfg_attr(docsrs, doc(cfg(feature = "printing")))]120impl ToTokens for File {121fn to_tokens(&self, tokens: &mut TokenStream) {122tokens.append_all(self.attrs.inner());123tokens.append_all(&self.items);124}125}126}127128129