blob: 59dd3482ce4937af9383bf42d9e8cb455c17aa24 [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 Tolnay5d871d92018-07-31 21:43:00 -070018use self::syntax_pos::edition::Edition;
David Tolnaya25d1dc2018-07-31 21:46:19 -070019use self::syntax_pos::{hygiene, FileName};
Michael Layzell53fc31a2017-06-07 09:21:53 -040020
21use std::panic;
22
David Tolnaydfc886b2018-01-06 08:03:09 -080023use self::syn::buffer::TokenBuffer;
24use self::syn::synom::Synom;
David Tolnayc7a5d3d2017-06-04 12:11:05 -070025
David Tolnaycfa5cc02017-11-13 01:05:11 -080026pub fn libsyntax_expr(input: &str) -> Option<P<ast::Expr>> {
Michael Layzell53fc31a2017-06-07 09:21:53 -040027 match panic::catch_unwind(|| {
David Tolnay5d871d92018-07-31 21:43:00 -070028 hygiene::set_default_edition(Edition::Edition2018);
Michael Layzell53fc31a2017-06-07 09:21:53 -040029 let sess = ParseSess::new(FilePathMapping::empty());
30 sess.span_diagnostic.set_continue_after_error(false);
David Tolnay0bb614f2018-06-14 21:41:43 -070031 let e = parse::new_parser_from_source_str(
32 &sess,
David Tolnaye9594252017-12-17 21:53:42 -080033 FileName::Custom("test_precedence".to_string()),
Michael Layzell53fc31a2017-06-07 09:21:53 -040034 input.to_string(),
David Tolnay0bb614f2018-06-14 21:41:43 -070035 ).parse_expr();
Michael Layzell53fc31a2017-06-07 09:21:53 -040036 Some(match e {
37 Ok(expr) => expr,
38 Err(mut diagnostic) => {
39 diagnostic.emit();;
David Tolnay51382052017-12-27 13:46:21 -050040 return None;
Michael Layzell53fc31a2017-06-07 09:21:53 -040041 }
42 })
43 }) {
44 Ok(Some(e)) => Some(e),
David Tolnay51382052017-12-27 13:46:21 -050045 Ok(None) => None,
Michael Layzell53fc31a2017-06-07 09:21:53 -040046 Err(_) => {
David Tolnayee97dbf2017-11-19 14:24:38 -080047 errorf!("libsyntax panicked\n");
Michael Layzell53fc31a2017-06-07 09:21:53 -040048 None
49 }
50 }
51}
52
53pub fn syn_expr(input: &str) -> Option<syn::Expr> {
David Tolnayc7a5d3d2017-06-04 12:11:05 -070054 match syn::parse_str(input) {
Michael Layzell53fc31a2017-06-07 09:21:53 -040055 Ok(e) => Some(e),
56 Err(msg) => {
57 errorf!("syn failed to parse\n{:?}\n", msg);
58 None
59 }
60 }
61}
David Tolnayc7a5d3d2017-06-04 12:11:05 -070062
63pub fn syn<T: Synom>(tokens: proc_macro2::TokenStream) -> T {
David Tolnayd5ddbb42018-01-06 18:55:45 -080064 let buf = TokenBuffer::new2(tokens);
David Tolnayc7a5d3d2017-06-04 12:11:05 -070065 let result = T::parse(buf.begin());
66 match result {
David Tolnayf4aa6b42017-12-31 16:40:33 -050067 Ok((t, rest)) => {
David Tolnayc7a5d3d2017-06-04 12:11:05 -070068 if rest.eof() {
69 t
70 } else if rest == buf.begin() {
71 panic!("failed to parse anything")
72 } else {
73 panic!("failed to parse all tokens")
74 }
75 }
76 Err(err) => panic!("failed to parse: {}", err),
77 }
78}