blob: 31c27595fe03c6da43f31bd45056d7c4e3bc40e0 [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;
David Tolnaycfa5cc02017-11-13 01:05:11 -080015use self::syntax::codemap::FilePathMapping;
David Tolnayeb7d79b2018-03-31 22:52:17 +020016use self::syntax::parse::{self, ParseSess};
17use self::syntax::ptr::P;
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 Tolnaydfc886b2018-01-06 08:03:09 -080022use self::syn::buffer::TokenBuffer;
23use self::syn::synom::Synom;
David Tolnayc7a5d3d2017-06-04 12:11:05 -070024
David Tolnaycfa5cc02017-11-13 01:05:11 -080025pub fn libsyntax_expr(input: &str) -> Option<P<ast::Expr>> {
Michael Layzell53fc31a2017-06-07 09:21:53 -040026 match panic::catch_unwind(|| {
27 let sess = ParseSess::new(FilePathMapping::empty());
28 sess.span_diagnostic.set_continue_after_error(false);
29 let e = parse::parse_expr_from_source_str(
David Tolnaye9594252017-12-17 21:53:42 -080030 FileName::Custom("test_precedence".to_string()),
Michael Layzell53fc31a2017-06-07 09:21:53 -040031 input.to_string(),
32 &sess,
33 );
34 Some(match e {
35 Ok(expr) => expr,
36 Err(mut diagnostic) => {
37 diagnostic.emit();;
David Tolnay51382052017-12-27 13:46:21 -050038 return None;
Michael Layzell53fc31a2017-06-07 09:21:53 -040039 }
40 })
41 }) {
42 Ok(Some(e)) => Some(e),
David Tolnay51382052017-12-27 13:46:21 -050043 Ok(None) => None,
Michael Layzell53fc31a2017-06-07 09:21:53 -040044 Err(_) => {
David Tolnayee97dbf2017-11-19 14:24:38 -080045 errorf!("libsyntax panicked\n");
Michael Layzell53fc31a2017-06-07 09:21:53 -040046 None
47 }
48 }
49}
50
51pub fn syn_expr(input: &str) -> Option<syn::Expr> {
David Tolnayc7a5d3d2017-06-04 12:11:05 -070052 match syn::parse_str(input) {
Michael Layzell53fc31a2017-06-07 09:21:53 -040053 Ok(e) => Some(e),
54 Err(msg) => {
55 errorf!("syn failed to parse\n{:?}\n", msg);
56 None
57 }
58 }
59}
David Tolnayc7a5d3d2017-06-04 12:11:05 -070060
61pub fn syn<T: Synom>(tokens: proc_macro2::TokenStream) -> T {
David Tolnayd5ddbb42018-01-06 18:55:45 -080062 let buf = TokenBuffer::new2(tokens);
David Tolnayc7a5d3d2017-06-04 12:11:05 -070063 let result = T::parse(buf.begin());
64 match result {
David Tolnayf4aa6b42017-12-31 16:40:33 -050065 Ok((t, rest)) => {
David Tolnayc7a5d3d2017-06-04 12:11:05 -070066 if rest.eof() {
67 t
68 } else if rest == buf.begin() {
69 panic!("failed to parse anything")
70 } else {
71 panic!("failed to parse all tokens")
72 }
73 }
74 Err(err) => panic!("failed to parse: {}", err),
75 }
76}