blob: 868cc21c6547dfe0e1a10804f15734b99fef6184 [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 Tolnayc7a5d3d2017-06-04 12:11:05 -07003extern crate synom;
David Tolnaycfa5cc02017-11-13 01:05:11 -08004extern crate syntax;
David Tolnaye9594252017-12-17 21:53:42 -08005extern crate syntax_pos;
Michael Layzell53fc31a2017-06-07 09:21:53 -04006
David Tolnaycfa5cc02017-11-13 01:05:11 -08007use self::syntax::ast;
8use self::syntax::ptr::P;
9use self::syntax::parse::{self, ParseSess};
10use self::syntax::codemap::FilePathMapping;
David Tolnaye9594252017-12-17 21:53:42 -080011use self::syntax_pos::FileName;
Michael Layzell53fc31a2017-06-07 09:21:53 -040012
13use std::panic;
14
David Tolnayc7a5d3d2017-06-04 12:11:05 -070015use self::synom::{Synom, SynomBuffer};
16
David Tolnaycfa5cc02017-11-13 01:05:11 -080017pub fn libsyntax_expr(input: &str) -> Option<P<ast::Expr>> {
Michael Layzell53fc31a2017-06-07 09:21:53 -040018 match panic::catch_unwind(|| {
19 let sess = ParseSess::new(FilePathMapping::empty());
20 sess.span_diagnostic.set_continue_after_error(false);
21 let e = parse::parse_expr_from_source_str(
David Tolnaye9594252017-12-17 21:53:42 -080022 FileName::Custom("test_precedence".to_string()),
Michael Layzell53fc31a2017-06-07 09:21:53 -040023 input.to_string(),
24 &sess,
25 );
26 Some(match e {
27 Ok(expr) => expr,
28 Err(mut diagnostic) => {
29 diagnostic.emit();;
30 return None
31 }
32 })
33 }) {
34 Ok(Some(e)) => Some(e),
35 Ok(None) => {
36 None
37 }
38 Err(_) => {
David Tolnayee97dbf2017-11-19 14:24:38 -080039 errorf!("libsyntax panicked\n");
Michael Layzell53fc31a2017-06-07 09:21:53 -040040 None
41 }
42 }
43}
44
45pub fn syn_expr(input: &str) -> Option<syn::Expr> {
David Tolnayc7a5d3d2017-06-04 12:11:05 -070046 match syn::parse_str(input) {
Michael Layzell53fc31a2017-06-07 09:21:53 -040047 Ok(e) => Some(e),
48 Err(msg) => {
49 errorf!("syn failed to parse\n{:?}\n", msg);
50 None
51 }
52 }
53}
David Tolnayc7a5d3d2017-06-04 12:11:05 -070054
55pub fn syn<T: Synom>(tokens: proc_macro2::TokenStream) -> T {
56 let buf = SynomBuffer::new(tokens);
57 let result = T::parse(buf.begin());
58 match result {
59 Ok((rest, t)) => {
60 if rest.eof() {
61 t
62 } else if rest == buf.begin() {
63 panic!("failed to parse anything")
64 } else {
65 panic!("failed to parse all tokens")
66 }
67 }
68 Err(err) => panic!("failed to parse: {}", err),
69 }
70}