syn_pub_items/
lib.rs

1//! Syn is a parsing library for parsing a stream of Rust tokens into a syntax
2//! tree of Rust source code.
3//!
4//! Currently this library is geared toward use in Rust procedural macros, but
5//! contains some APIs that may be useful more generally.
6//!
7//! - **Data structures** — Syn provides a complete syntax tree that can
8//!   represent any valid Rust source code. The syntax tree is rooted at
9//!   [`syn::File`] which represents a full source file, but there are other
10//!   entry points that may be useful to procedural macros including
11//!   [`syn::Item`], [`syn::Expr`] and [`syn::Type`].
12//!
13//! - **Custom derives** — Of particular interest to custom derives is
14//!   [`syn::DeriveInput`] which is any of the three legal input items to a
15//!   derive macro. An example below shows using this type in a library that can
16//!   derive implementations of a trait of your own.
17//!
18//! - **Parsing** — Parsing in Syn is built around [parser functions] with the
19//!   signature `fn(ParseStream) -> Result<T>`. Every syntax tree node defined
20//!   by Syn is individually parsable and may be used as a building block for
21//!   custom syntaxes, or you may dream up your own brand new syntax without
22//!   involving any of our syntax tree types.
23//!
24//! - **Location information** — Every token parsed by Syn is associated with a
25//!   `Span` that tracks line and column information back to the source of that
26//!   token. These spans allow a procedural macro to display detailed error
27//!   messages pointing to all the right places in the user's code. There is an
28//!   example of this below.
29//!
30//! - **Feature flags** — Functionality is aggressively feature gated so your
31//!   procedural macros enable only what they need, and do not pay in compile
32//!   time for all the rest.
33//!
34//! [`syn::File`]: struct.File.html
35//! [`syn::Item`]: enum.Item.html
36//! [`syn::Expr`]: enum.Expr.html
37//! [`syn::Type`]: enum.Type.html
38//! [`syn::DeriveInput`]: struct.DeriveInput.html
39//! [parser functions]: parse/index.html
40//!
41//! *Version requirement: Syn supports any compiler version back to Rust's very
42//! first support for procedural macros in Rust 1.15.0. Some features especially
43//! around error reporting are only available in newer compilers or on the
44//! nightly channel.*
45//!
46//! ## Example of a custom derive
47//!
48//! The canonical custom derive using Syn looks like this. We write an ordinary
49//! Rust function tagged with a `proc_macro_derive` attribute and the name of
50//! the trait we are deriving. Any time that derive appears in the user's code,
51//! the Rust compiler passes their data structure as tokens into our macro. We
52//! get to execute arbitrary Rust code to figure out what to do with those
53//! tokens, then hand some tokens back to the compiler to compile into the
54//! user's crate.
55//!
56//! [`TokenStream`]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html
57//!
58//! ```toml
59//! [dependencies]
60//! syn = "0.15"
61//! quote = "0.6"
62//!
63//! [lib]
64//! proc-macro = true
65//! ```
66//!
67//! ```edition2018
68//! extern crate proc_macro;
69//!
70//! use proc_macro::TokenStream;
71//! use quote::quote;
72//! use syn::{parse_macro_input, DeriveInput};
73//!
74//! # const IGNORE_TOKENS: &str = stringify! {
75//! #[proc_macro_derive(MyMacro)]
76//! # };
77//! pub fn my_macro(input: TokenStream) -> TokenStream {
78//!     // Parse the input tokens into a syntax tree
79//!     let input = parse_macro_input!(input as DeriveInput);
80//!
81//!     // Build the output, possibly using quasi-quotation
82//!     let expanded = quote! {
83//!         // ...
84//!     };
85//!
86//!     // Hand the output tokens back to the compiler
87//!     TokenStream::from(expanded)
88//! }
89//! ```
90//!
91//! The [`heapsize`] example directory shows a complete working Macros 1.1
92//! implementation of a custom derive. It works on any Rust compiler 1.15+.
93//! The example derives a `HeapSize` trait which computes an estimate of the
94//! amount of heap memory owned by a value.
95//!
96//! [`heapsize`]: https://github.com/dtolnay/syn/tree/master/examples/heapsize
97//!
98//! ```edition2018
99//! pub trait HeapSize {
100//!     /// Total number of bytes of heap memory owned by `self`.
101//!     fn heap_size_of_children(&self) -> usize;
102//! }
103//! ```
104//!
105//! The custom derive allows users to write `#[derive(HeapSize)]` on data
106//! structures in their program.
107//!
108//! ```edition2018
109//! # const IGNORE_TOKENS: &str = stringify! {
110//! #[derive(HeapSize)]
111//! # };
112//! struct Demo<'a, T: ?Sized> {
113//!     a: Box<T>,
114//!     b: u8,
115//!     c: &'a str,
116//!     d: String,
117//! }
118//! ```
119//!
120//! ## Spans and error reporting
121//!
122//! The token-based procedural macro API provides great control over where the
123//! compiler's error messages are displayed in user code. Consider the error the
124//! user sees if one of their field types does not implement `HeapSize`.
125//!
126//! ```edition2018
127//! # const IGNORE_TOKENS: &str = stringify! {
128//! #[derive(HeapSize)]
129//! # };
130//! struct Broken {
131//!     ok: String,
132//!     bad: std::thread::Thread,
133//! }
134//! ```
135//!
136//! By tracking span information all the way through the expansion of a
137//! procedural macro as shown in the `heapsize` example, token-based macros in
138//! Syn are able to trigger errors that directly pinpoint the source of the
139//! problem.
140//!
141//! ```text
142//! error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied
143//!  --> src/main.rs:7:5
144//!   |
145//! 7 |     bad: std::thread::Thread,
146//!   |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `Thread`
147//! ```
148//!
149//! ## Parsing a custom syntax
150//!
151//! The [`lazy-static`] example directory shows the implementation of a
152//! `functionlike!(...)` procedural macro in which the input tokens are parsed
153//! using Syn's parsing API.
154//!
155//! [`lazy-static`]: https://github.com/dtolnay/syn/tree/master/examples/lazy-static
156//!
157//! The example reimplements the popular `lazy_static` crate from crates.io as a
158//! procedural macro.
159//!
160//! ```edition2018
161//! # macro_rules! lazy_static {
162//! #     ($($tt:tt)*) => {}
163//! # }
164//! #
165//! lazy_static! {
166//!     static ref USERNAME: Regex = Regex::new("^[a-z0-9_-]{3,16}$").unwrap();
167//! }
168//! ```
169//!
170//! The implementation shows how to trigger custom warnings and error messages
171//! on the macro input.
172//!
173//! ```text
174//! warning: come on, pick a more creative name
175//!   --> src/main.rs:10:16
176//!    |
177//! 10 |     static ref FOO: String = "lazy_static".to_owned();
178//!    |                ^^^
179//! ```
180//!
181//! ## Debugging
182//!
183//! When developing a procedural macro it can be helpful to look at what the
184//! generated code looks like. Use `cargo rustc -- -Zunstable-options
185//! --pretty=expanded` or the [`cargo expand`] subcommand.
186//!
187//! [`cargo expand`]: https://github.com/dtolnay/cargo-expand
188//!
189//! To show the expanded code for some crate that uses your procedural macro,
190//! run `cargo expand` from that crate. To show the expanded code for one of
191//! your own test cases, run `cargo expand --test the_test_case` where the last
192//! argument is the name of the test file without the `.rs` extension.
193//!
194//! This write-up by Brandon W Maister discusses debugging in more detail:
195//! [Debugging Rust's new Custom Derive system][debugging].
196//!
197//! [debugging]: https://quodlibetor.github.io/posts/debugging-rusts-new-custom-derive-system/
198//!
199//! ## Optional features
200//!
201//! Syn puts a lot of functionality behind optional features in order to
202//! optimize compile time for the most common use cases. The following features
203//! are available.
204//!
205//! - **`derive`** *(enabled by default)* — Data structures for representing the
206//!   possible input to a custom derive, including structs and enums and types.
207//! - **`full`** — Data structures for representing the syntax tree of all valid
208//!   Rust source code, including items and expressions.
209//! - **`parsing`** *(enabled by default)* — Ability to parse input tokens into
210//!   a syntax tree node of a chosen type.
211//! - **`printing`** *(enabled by default)* — Ability to print a syntax tree
212//!   node as tokens of Rust source code.
213//! - **`visit`** — Trait for traversing a syntax tree.
214//! - **`visit-mut`** — Trait for traversing and mutating in place a syntax
215//!   tree.
216//! - **`fold`** — Trait for transforming an owned syntax tree.
217//! - **`clone-impls`** *(enabled by default)* — Clone impls for all syntax tree
218//!   types.
219//! - **`extra-traits`** — Debug, Eq, PartialEq, Hash impls for all syntax tree
220//!   types.
221//! - **`proc-macro`** *(enabled by default)* — Runtime dependency on the
222//!   dynamic library libproc_macro from rustc toolchain.
223
224// Syn types in rustdoc of other crates get linked to here.
225#![doc(html_root_url = "https://docs.rs/syn/0.15.30")]
226#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
227#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
228// Ignored clippy lints.
229#![cfg_attr(
230    feature = "cargo-clippy",
231    allow(
232        block_in_if_condition_stmt,
233        cognitive_complexity,
234        cyclomatic_complexity,
235        const_static_lifetime,
236        deprecated_cfg_attr,
237        doc_markdown,
238        eval_order_dependence,
239        large_enum_variant,
240        needless_pass_by_value,
241        never_loop,
242        redundant_field_names,
243        too_many_arguments,
244    )
245)]
246// Ignored clippy_pedantic lints.
247#![cfg_attr(
248    feature = "cargo-clippy",
249    allow(
250        cast_possible_truncation,
251        cast_possible_wrap,
252        empty_enum,
253        if_not_else,
254        items_after_statements,
255        module_name_repetitions,
256        shadow_unrelated,
257        similar_names,
258        single_match_else,
259        unseparated_literal_suffix,
260        use_self,
261        used_underscore_binding,
262    )
263)]
264
265#[cfg(all(
266    not(all(target_arch = "wasm32", target_os = "unknown")),
267    feature = "proc-macro"
268))]
269extern crate proc_macro;
270extern crate proc_macro2;
271extern crate unicode_xid;
272
273#[cfg(feature = "printing")]
274extern crate quote;
275
276#[macro_use]
277pub mod macros;
278pub use macros::*;
279
280// Not public API.
281#[cfg(feature = "parsing")]
282#[doc(hidden)]
283#[macro_use]
284pub mod group;
285
286#[macro_use]
287pub mod token;
288
289pub mod ident;
290pub use ident::Ident;
291
292#[cfg(any(feature = "full", feature = "derive"))]
293pub mod attr;
294#[cfg(any(feature = "full", feature = "derive"))]
295pub use attr::{AttrStyle, Attribute, AttributeArgs, Meta, MetaList, MetaNameValue, NestedMeta};
296
297#[cfg(any(feature = "full", feature = "derive"))]
298pub mod data;
299#[cfg(any(feature = "full", feature = "derive"))]
300pub use data::{
301    Field, Fields, FieldsNamed, FieldsUnnamed, Variant, VisCrate, VisPublic, VisRestricted,
302    Visibility,
303};
304
305#[cfg(any(feature = "full", feature = "derive"))]
306pub mod expr;
307#[cfg(any(feature = "full", feature = "derive"))]
308pub use expr::{
309    Expr, ExprArray, ExprAssign, ExprAssignOp, ExprAsync, ExprBinary, ExprBlock, ExprBox,
310    ExprBreak, ExprCall, ExprCast, ExprClosure, ExprContinue, ExprField, ExprForLoop, ExprGroup,
311    ExprIf, ExprInPlace, ExprIndex, ExprLet, ExprLit, ExprLoop, ExprMacro, ExprMatch,
312    ExprMethodCall, ExprParen, ExprPath, ExprRange, ExprReference, ExprRepeat, ExprReturn,
313    ExprStruct, ExprTry, ExprTryBlock, ExprTuple, ExprType, ExprUnary, ExprUnsafe, ExprVerbatim,
314    ExprWhile, ExprYield, Index, Member,
315};
316
317#[cfg(feature = "full")]
318pub use expr::{
319    Arm, Block, FieldPat, FieldValue, GenericMethodArgument, Label, Local, MethodTurbofish, Pat,
320    PatBox, PatIdent, PatLit, PatMacro, PatPath, PatRange, PatRef, PatSlice, PatStruct, PatTuple,
321    PatTupleStruct, PatVerbatim, PatWild, RangeLimits, Stmt,
322};
323
324#[cfg(any(feature = "full", feature = "derive"))]
325pub mod generics;
326#[cfg(any(feature = "full", feature = "derive"))]
327pub use generics::{
328    BoundLifetimes, ConstParam, GenericParam, Generics, LifetimeDef, PredicateEq,
329    PredicateLifetime, PredicateType, TraitBound, TraitBoundModifier, TypeParam, TypeParamBound,
330    WhereClause, WherePredicate,
331};
332#[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))]
333pub use generics::{ImplGenerics, Turbofish, TypeGenerics};
334
335#[cfg(feature = "full")]
336pub mod item;
337#[cfg(feature = "full")]
338pub use item::{
339    ArgCaptured, ArgSelf, ArgSelfRef, FnArg, FnDecl, ForeignItem, ForeignItemFn, ForeignItemMacro,
340    ForeignItemStatic, ForeignItemType, ForeignItemVerbatim, ImplItem, ImplItemConst,
341    ImplItemExistential, ImplItemMacro, ImplItemMethod, ImplItemType, ImplItemVerbatim, Item,
342    ItemConst, ItemEnum, ItemExistential, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl,
343    ItemMacro, ItemMacro2, ItemMod, ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType,
344    ItemUnion, ItemUse, ItemVerbatim, MethodSig, TraitItem, TraitItemConst, TraitItemMacro,
345    TraitItemMethod, TraitItemType, TraitItemVerbatim, UseGlob, UseGroup, UseName, UsePath,
346    UseRename, UseTree,
347};
348
349#[cfg(feature = "full")]
350pub mod file;
351#[cfg(feature = "full")]
352pub use file::File;
353
354pub mod lifetime;
355pub use lifetime::Lifetime;
356
357#[cfg(any(feature = "full", feature = "derive"))]
358pub mod lit;
359#[cfg(any(feature = "full", feature = "derive"))]
360pub use lit::{
361    FloatSuffix, IntSuffix, Lit, LitBool, LitByte, LitByteStr, LitChar, LitFloat, LitInt, LitStr,
362    LitVerbatim, StrStyle,
363};
364
365#[cfg(any(feature = "full", feature = "derive"))]
366pub mod mac;
367#[cfg(any(feature = "full", feature = "derive"))]
368pub use mac::{Macro, MacroDelimiter};
369
370#[cfg(any(feature = "full", feature = "derive"))]
371pub mod derive;
372#[cfg(feature = "derive")]
373pub use derive::{Data, DataEnum, DataStruct, DataUnion, DeriveInput};
374
375#[cfg(any(feature = "full", feature = "derive"))]
376pub mod op;
377#[cfg(any(feature = "full", feature = "derive"))]
378pub use op::{BinOp, UnOp};
379
380#[cfg(any(feature = "full", feature = "derive"))]
381pub mod ty;
382#[cfg(any(feature = "full", feature = "derive"))]
383pub use ty::{
384    Abi, BareFnArg, BareFnArgName, ReturnType, Type, TypeArray, TypeBareFn, TypeGroup,
385    TypeImplTrait, TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr, TypeReference,
386    TypeSlice, TypeTraitObject, TypeTuple, TypeVerbatim,
387};
388
389#[cfg(any(feature = "full", feature = "derive"))]
390pub mod path;
391#[cfg(any(feature = "full", feature = "derive"))]
392pub use path::{
393    AngleBracketedGenericArguments, Binding, Constraint, GenericArgument,
394    ParenthesizedGenericArguments, Path, PathArguments, PathSegment, QSelf,
395};
396
397#[cfg(feature = "parsing")]
398pub mod buffer;
399#[cfg(feature = "parsing")]
400pub mod ext;
401pub mod punctuated;
402#[cfg(all(any(feature = "full", feature = "derive"), feature = "extra-traits"))]
403pub mod tt;
404
405// Not public API except the `parse_quote!` macro.
406#[cfg(feature = "parsing")]
407#[doc(hidden)]
408pub mod parse_quote;
409
410// Not public API except the `parse_macro_input!` macro.
411#[cfg(all(
412    not(all(target_arch = "wasm32", target_os = "unknown")),
413    feature = "parsing",
414    feature = "proc-macro"
415))]
416#[doc(hidden)]
417pub mod parse_macro_input;
418
419#[cfg(all(feature = "parsing", feature = "printing"))]
420pub mod spanned;
421
422pub mod gen {
423    /// Syntax tree traversal to walk a shared borrow of a syntax tree.
424    ///
425    /// Each method of the [`Visit`] trait is a hook that can be overridden to
426    /// customize the behavior when visiting the corresponding type of node. By
427    /// default, every method recursively visits the substructure of the input
428    /// by invoking the right visitor method of each of its fields.
429    ///
430    /// [`Visit`]: trait.Visit.html
431    ///
432    /// ```edition2018
433    /// # use syn::{Attribute, BinOp, Expr, ExprBinary};
434    /// #
435    /// pub trait Visit<'ast> {
436    ///     /* ... */
437    ///
438    ///     fn visit_expr_binary(&mut self, node: &'ast ExprBinary) {
439    ///         for attr in &node.attrs {
440    ///             self.visit_attribute(attr);
441    ///         }
442    ///         self.visit_expr(&*node.left);
443    ///         self.visit_bin_op(&node.op);
444    ///         self.visit_expr(&*node.right);
445    ///     }
446    ///
447    ///     /* ... */
448    ///     # fn visit_attribute(&mut self, node: &'ast Attribute);
449    ///     # fn visit_expr(&mut self, node: &'ast Expr);
450    ///     # fn visit_bin_op(&mut self, node: &'ast BinOp);
451    /// }
452    /// ```
453    ///
454    /// *This module is available if Syn is built with the `"visit"` feature.*
455    #[cfg(feature = "visit")]
456    pub mod visit;
457
458    /// Syntax tree traversal to mutate an exclusive borrow of a syntax tree in
459    /// place.
460    ///
461    /// Each method of the [`VisitMut`] trait is a hook that can be overridden
462    /// to customize the behavior when mutating the corresponding type of node.
463    /// By default, every method recursively visits the substructure of the
464    /// input by invoking the right visitor method of each of its fields.
465    ///
466    /// [`VisitMut`]: trait.VisitMut.html
467    ///
468    /// ```edition2018
469    /// # use syn::{Attribute, BinOp, Expr, ExprBinary};
470    /// #
471    /// pub trait VisitMut {
472    ///     /* ... */
473    ///
474    ///     fn visit_expr_binary_mut(&mut self, node: &mut ExprBinary) {
475    ///         for attr in &mut node.attrs {
476    ///             self.visit_attribute_mut(attr);
477    ///         }
478    ///         self.visit_expr_mut(&mut *node.left);
479    ///         self.visit_bin_op_mut(&mut node.op);
480    ///         self.visit_expr_mut(&mut *node.right);
481    ///     }
482    ///
483    ///     /* ... */
484    ///     # fn visit_attribute_mut(&mut self, node: &mut Attribute);
485    ///     # fn visit_expr_mut(&mut self, node: &mut Expr);
486    ///     # fn visit_bin_op_mut(&mut self, node: &mut BinOp);
487    /// }
488    /// ```
489    ///
490    /// *This module is available if Syn is built with the `"visit-mut"`
491    /// feature.*
492    #[cfg(feature = "visit-mut")]
493    pub mod visit_mut;
494
495    /// Syntax tree traversal to transform the nodes of an owned syntax tree.
496    ///
497    /// Each method of the [`Fold`] trait is a hook that can be overridden to
498    /// customize the behavior when transforming the corresponding type of node.
499    /// By default, every method recursively visits the substructure of the
500    /// input by invoking the right visitor method of each of its fields.
501    ///
502    /// [`Fold`]: trait.Fold.html
503    ///
504    /// ```edition2018
505    /// # use syn::{Attribute, BinOp, Expr, ExprBinary};
506    /// #
507    /// pub trait Fold {
508    ///     /* ... */
509    ///
510    ///     fn fold_expr_binary(&mut self, node: ExprBinary) -> ExprBinary {
511    ///         ExprBinary {
512    ///             attrs: node.attrs
513    ///                        .into_iter()
514    ///                        .map(|attr| self.fold_attribute(attr))
515    ///                        .collect(),
516    ///             left: Box::new(self.fold_expr(*node.left)),
517    ///             op: self.fold_bin_op(node.op),
518    ///             right: Box::new(self.fold_expr(*node.right)),
519    ///         }
520    ///     }
521    ///
522    ///     /* ... */
523    ///     # fn fold_attribute(&mut self, node: Attribute) -> Attribute;
524    ///     # fn fold_expr(&mut self, node: Expr) -> Expr;
525    ///     # fn fold_bin_op(&mut self, node: BinOp) -> BinOp;
526    /// }
527    /// ```
528    ///
529    /// *This module is available if Syn is built with the `"fold"` feature.*
530    #[cfg(feature = "fold")]
531    pub mod fold;
532
533    #[cfg(any(feature = "full", feature = "derive"))]
534    #[path = "../gen_helper.rs"]
535    mod helper;
536}
537pub use gen::*;
538
539// Not public API.
540#[doc(hidden)]
541pub mod export;
542
543pub mod keyword;
544
545#[cfg(feature = "parsing")]
546pub mod lookahead;
547
548#[cfg(feature = "parsing")]
549pub mod parse;
550
551pub mod span;
552
553#[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))]
554pub mod print;
555
556pub mod thread;
557
558////////////////////////////////////////////////////////////////////////////////
559
560#[cfg(any(feature = "parsing", feature = "full", feature = "derive"))]
561#[allow(non_camel_case_types)]
562pub struct private;
563
564////////////////////////////////////////////////////////////////////////////////
565
566pub mod error;
567pub use error::{Error, Result};
568
569/// Parse tokens of source code into the chosen syntax tree node.
570///
571/// This is preferred over parsing a string because tokens are able to preserve
572/// information about where in the user's code they were originally written (the
573/// "span" of the token), possibly allowing the compiler to produce better error
574/// messages.
575///
576/// This function parses a `proc_macro::TokenStream` which is the type used for
577/// interop with the compiler in a procedural macro. To parse a
578/// `proc_macro2::TokenStream`, use [`syn::parse2`] instead.
579///
580/// [`syn::parse2`]: fn.parse2.html
581///
582/// *This function is available if Syn is built with both the `"parsing"` and
583/// `"proc-macro"` features.*
584///
585/// # Examples
586///
587/// ```edition2018
588/// extern crate proc_macro;
589///
590/// use proc_macro::TokenStream;
591/// use quote::quote;
592/// use syn::DeriveInput;
593///
594/// # const IGNORE_TOKENS: &str = stringify! {
595/// #[proc_macro_derive(MyMacro)]
596/// # };
597/// pub fn my_macro(input: TokenStream) -> TokenStream {
598///     // Parse the tokens into a syntax tree
599///     let ast: DeriveInput = syn::parse(input).unwrap();
600///
601///     // Build the output, possibly using quasi-quotation
602///     let expanded = quote! {
603///         /* ... */
604///     };
605///
606///     // Convert into a token stream and return it
607///     expanded.into()
608/// }
609/// ```
610#[cfg(all(
611    not(all(target_arch = "wasm32", target_os = "unknown")),
612    feature = "parsing",
613    feature = "proc-macro"
614))]
615pub fn parse<T: parse::Parse>(tokens: proc_macro::TokenStream) -> Result<T> {
616    parse::Parser::parse(T::parse, tokens)
617}
618
619/// Parse a proc-macro2 token stream into the chosen syntax tree node.
620///
621/// This function parses a `proc_macro2::TokenStream` which is commonly useful
622/// when the input comes from a node of the Syn syntax tree, for example the tts
623/// of a [`Macro`] node. When in a procedural macro parsing the
624/// `proc_macro::TokenStream` provided by the compiler, use [`syn::parse`]
625/// instead.
626///
627/// [`Macro`]: struct.Macro.html
628/// [`syn::parse`]: fn.parse.html
629///
630/// *This function is available if Syn is built with the `"parsing"` feature.*
631#[cfg(feature = "parsing")]
632pub fn parse2<T: parse::Parse>(tokens: proc_macro2::TokenStream) -> Result<T> {
633    parse::Parser::parse2(T::parse, tokens)
634}
635
636/// Parse a string of Rust code into the chosen syntax tree node.
637///
638/// *This function is available if Syn is built with the `"parsing"` feature.*
639///
640/// # Hygiene
641///
642/// Every span in the resulting syntax tree will be set to resolve at the macro
643/// call site.
644///
645/// # Examples
646///
647/// ```edition2018
648/// use syn::{Expr, Result};
649///
650/// fn run() -> Result<()> {
651///     let code = "assert_eq!(u8::max_value(), 255)";
652///     let expr = syn::parse_str::<Expr>(code)?;
653///     println!("{:#?}", expr);
654///     Ok(())
655/// }
656/// #
657/// # fn main() {
658/// #     run().unwrap();
659/// # }
660/// ```
661#[cfg(feature = "parsing")]
662pub fn parse_str<T: parse::Parse>(s: &str) -> Result<T> {
663    parse::Parser::parse_str(T::parse, s)
664}
665
666// FIXME the name parse_file makes it sound like you might pass in a path to a
667// file, rather than the content.
668/// Parse the content of a file of Rust code.
669///
670/// This is different from `syn::parse_str::<File>(content)` in two ways:
671///
672/// - It discards a leading byte order mark `\u{FEFF}` if the file has one.
673/// - It preserves the shebang line of the file, such as `#!/usr/bin/env rustx`.
674///
675/// If present, either of these would be an error using `from_str`.
676///
677/// *This function is available if Syn is built with the `"parsing"` and
678/// `"full"` features.*
679///
680/// # Examples
681///
682/// ```edition2018,no_run
683/// use std::error::Error;
684/// use std::fs::File;
685/// use std::io::Read;
686///
687/// fn run() -> Result<(), Box<Error>> {
688///     let mut file = File::open("path/to/code.rs")?;
689///     let mut content = String::new();
690///     file.read_to_string(&mut content)?;
691///
692///     let ast = syn::parse_file(&content)?;
693///     if let Some(shebang) = ast.shebang {
694///         println!("{}", shebang);
695///     }
696///     println!("{} items", ast.items.len());
697///
698///     Ok(())
699/// }
700/// #
701/// # fn main() {
702/// #     run().unwrap();
703/// # }
704/// ```
705#[cfg(all(feature = "parsing", feature = "full"))]
706pub fn parse_file(mut content: &str) -> Result<File> {
707    // Strip the BOM if it is present
708    const BOM: &'static str = "\u{feff}";
709    if content.starts_with(BOM) {
710        content = &content[BOM.len()..];
711    }
712
713    let mut shebang = None;
714    if content.starts_with("#!") && !content.starts_with("#![") {
715        if let Some(idx) = content.find('\n') {
716            shebang = Some(content[..idx].to_string());
717            content = &content[idx..];
718        } else {
719            shebang = Some(content.to_string());
720            content = "";
721        }
722    }
723
724    let mut file: File = parse_str(content)?;
725    file.shebang = shebang;
726    Ok(file)
727}