blob: 419ac1f53ea944c8f436f197ce2f577a5953231c [file] [log] [blame]
David Tolnayc7a5d3d2017-06-04 12:11:05 -07001extern crate proc_macro2;
Michael Layzell53fc31a2017-06-07 09:21:53 -04002extern crate syn;
David Tolnaycfa5cc02017-11-13 01:05:11 -08003extern crate syntax;
David Tolnaye9594252017-12-17 21:53:42 -08004extern crate syntax_pos;
Michael Layzell53fc31a2017-06-07 09:21:53 -04005
David Tolnaycfa5cc02017-11-13 01:05:11 -08006use self::syntax::ast;
7use self::syntax::ptr::P;
8use self::syntax::parse::{self, ParseSess};
9use self::syntax::codemap::FilePathMapping;
David Tolnaye9594252017-12-17 21:53:42 -080010use self::syntax_pos::FileName;
Michael Layzell53fc31a2017-06-07 09:21:53 -040011
12use std::panic;
13
David Tolnayc5ab8c62017-12-26 16:43:39 -050014use self::syn::synom::{Synom, SynomBuffer};
David Tolnayc7a5d3d2017-06-04 12:11:05 -070015
David Tolnaycfa5cc02017-11-13 01:05:11 -080016pub fn libsyntax_expr(input: &str) -> Option<P<ast::Expr>> {
Michael Layzell53fc31a2017-06-07 09:21:53 -040017 match panic::catch_unwind(|| {
18 let sess = ParseSess::new(FilePathMapping::empty());
19 sess.span_diagnostic.set_continue_after_error(false);
20 let e = parse::parse_expr_from_source_str(
David Tolnaye9594252017-12-17 21:53:42 -080021 FileName::Custom("test_precedence".to_string()),
Michael Layzell53fc31a2017-06-07 09:21:53 -040022 input.to_string(),
23 &sess,
24 );
25 Some(match e {
26 Ok(expr) => expr,
27 Err(mut diagnostic) => {
28 diagnostic.emit();;
David Tolnay51382052017-12-27 13:46:21 -050029 return None;
Michael Layzell53fc31a2017-06-07 09:21:53 -040030 }
31 })
32 }) {
33 Ok(Some(e)) => Some(e),
David Tolnay51382052017-12-27 13:46:21 -050034 Ok(None) => None,
Michael Layzell53fc31a2017-06-07 09:21:53 -040035 Err(_) => {
David Tolnayee97dbf2017-11-19 14:24:38 -080036 errorf!("libsyntax panicked\n");
Michael Layzell53fc31a2017-06-07 09:21:53 -040037 None
38 }
39 }
40}
41
42pub fn syn_expr(input: &str) -> Option<syn::Expr> {
David Tolnayc7a5d3d2017-06-04 12:11:05 -070043 match syn::parse_str(input) {
Michael Layzell53fc31a2017-06-07 09:21:53 -040044 Ok(e) => Some(e),
45 Err(msg) => {
46 errorf!("syn failed to parse\n{:?}\n", msg);
47 None
48 }
49 }
50}
David Tolnayc7a5d3d2017-06-04 12:11:05 -070051
52pub fn syn<T: Synom>(tokens: proc_macro2::TokenStream) -> T {
53 let buf = SynomBuffer::new(tokens);
54 let result = T::parse(buf.begin());
55 match result {
David Tolnayf4aa6b42017-12-31 16:40:33 -050056 Ok((t, rest)) => {
David Tolnayc7a5d3d2017-06-04 12:11:05 -070057 if rest.eof() {
58 t
59 } else if rest == buf.begin() {
60 panic!("failed to parse anything")
61 } else {
62 panic!("failed to parse all tokens")
63 }
64 }
65 Err(err) => panic!("failed to parse: {}", err),
66 }
67}