blob: dfce4c96ac5a98444e265a99e5752372dedd0c39 [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 -07009extern crate proc_macro2;
Michael Layzell53fc31a2017-06-07 09:21:53 -040010extern crate syn;
David Tolnaycfa5cc02017-11-13 01:05:11 -080011extern crate syntax;
David Tolnaye9594252017-12-17 21:53:42 -080012extern crate syntax_pos;
Michael Layzell53fc31a2017-06-07 09:21:53 -040013
David Tolnaycfa5cc02017-11-13 01:05:11 -080014use self::syntax::ast;
15use self::syntax::ptr::P;
16use self::syntax::parse::{self, ParseSess};
17use self::syntax::codemap::FilePathMapping;
David Tolnaye9594252017-12-17 21:53:42 -080018use self::syntax_pos::FileName;
Michael Layzell53fc31a2017-06-07 09:21:53 -040019
20use std::panic;
21
David Tolnayc5ab8c62017-12-26 16:43:39 -050022use self::syn::synom::{Synom, SynomBuffer};
David Tolnayc7a5d3d2017-06-04 12:11:05 -070023
David Tolnaycfa5cc02017-11-13 01:05:11 -080024pub fn libsyntax_expr(input: &str) -> Option<P<ast::Expr>> {
Michael Layzell53fc31a2017-06-07 09:21:53 -040025 match panic::catch_unwind(|| {
26 let sess = ParseSess::new(FilePathMapping::empty());
27 sess.span_diagnostic.set_continue_after_error(false);
28 let e = parse::parse_expr_from_source_str(
David Tolnaye9594252017-12-17 21:53:42 -080029 FileName::Custom("test_precedence".to_string()),
Michael Layzell53fc31a2017-06-07 09:21:53 -040030 input.to_string(),
31 &sess,
32 );
33 Some(match e {
34 Ok(expr) => expr,
35 Err(mut diagnostic) => {
36 diagnostic.emit();;
David Tolnay51382052017-12-27 13:46:21 -050037 return None;
Michael Layzell53fc31a2017-06-07 09:21:53 -040038 }
39 })
40 }) {
41 Ok(Some(e)) => Some(e),
David Tolnay51382052017-12-27 13:46:21 -050042 Ok(None) => None,
Michael Layzell53fc31a2017-06-07 09:21:53 -040043 Err(_) => {
David Tolnayee97dbf2017-11-19 14:24:38 -080044 errorf!("libsyntax panicked\n");
Michael Layzell53fc31a2017-06-07 09:21:53 -040045 None
46 }
47 }
48}
49
50pub fn syn_expr(input: &str) -> Option<syn::Expr> {
David Tolnayc7a5d3d2017-06-04 12:11:05 -070051 match syn::parse_str(input) {
Michael Layzell53fc31a2017-06-07 09:21:53 -040052 Ok(e) => Some(e),
53 Err(msg) => {
54 errorf!("syn failed to parse\n{:?}\n", msg);
55 None
56 }
57 }
58}
David Tolnayc7a5d3d2017-06-04 12:11:05 -070059
60pub fn syn<T: Synom>(tokens: proc_macro2::TokenStream) -> T {
61 let buf = SynomBuffer::new(tokens);
62 let result = T::parse(buf.begin());
63 match result {
David Tolnayf4aa6b42017-12-31 16:40:33 -050064 Ok((t, rest)) => {
David Tolnayc7a5d3d2017-06-04 12:11:05 -070065 if rest.eof() {
66 t
67 } else if rest == buf.begin() {
68 panic!("failed to parse anything")
69 } else {
70 panic!("failed to parse all tokens")
71 }
72 }
73 Err(err) => panic!("failed to parse: {}", err),
74 }
75}