internal: make sure macro test expand to valid syntax

This commit is contained in:
Aleksey Kladov 2021-10-09 18:06:24 +03:00
parent c41b7bbe69
commit c2e425dd00
5 changed files with 31 additions and 27 deletions

View file

@ -65,6 +65,11 @@ fn check(ra_fixture: &str, mut expect: Expect) {
format_to!(expn_text, "/* error: {} */", err); format_to!(expn_text, "/* error: {} */", err);
} }
if let Some((parse, _token_map)) = exp.value { if let Some((parse, _token_map)) = exp.value {
assert!(
parse.errors().is_empty(),
"parse errors in expansion: \n{:#?}",
parse.errors()
);
let pp = pretty_print_macro_expansion(parse.syntax_node()); let pp = pretty_print_macro_expansion(parse.syntax_node());
let indent = IndentLevel::from_node(call.syntax()); let indent = IndentLevel::from_node(call.syntax());
let pp = reindent(indent, pp); let pp = reindent(indent, pp);

View file

@ -165,17 +165,17 @@ fn test_match_group_pattern_with_multiple_defs() {
check( check(
r#" r#"
macro_rules! m { macro_rules! m {
($($i:ident),*) => ( impl Bar { $(fn $i {})* } ); ($($i:ident),*) => ( impl Bar { $(fn $i() {})* } );
} }
m! { foo, bar } m! { foo, bar }
"#, "#,
expect![[r#" expect![[r#"
macro_rules! m { macro_rules! m {
($($i:ident),*) => ( impl Bar { $(fn $i {})* } ); ($($i:ident),*) => ( impl Bar { $(fn $i() {})* } );
} }
impl Bar { impl Bar {
fn foo {} fn foo() {}
fn bar {} fn bar() {}
} }
"#]], "#]],
); );
@ -186,15 +186,15 @@ fn test_match_group_pattern_with_multiple_statement() {
check( check(
r#" r#"
macro_rules! m { macro_rules! m {
($($i:ident),*) => ( fn baz { $($i ();)* } ); ($($i:ident),*) => ( fn baz() { $($i ();)* } );
} }
m! { foo, bar } m! { foo, bar }
"#, "#,
expect![[r#" expect![[r#"
macro_rules! m { macro_rules! m {
($($i:ident),*) => ( fn baz { $($i ();)* } ); ($($i:ident),*) => ( fn baz() { $($i ();)* } );
} }
fn baz { fn baz() {
foo(); foo();
bar(); bar();
} }
@ -207,15 +207,15 @@ fn test_match_group_pattern_with_multiple_statement_without_semi() {
check( check(
r#" r#"
macro_rules! m { macro_rules! m {
($($i:ident),*) => ( fn baz { $($i() );* } ); ($($i:ident),*) => ( fn baz() { $($i() );* } );
} }
m! { foo, bar } m! { foo, bar }
"#, "#,
expect![[r#" expect![[r#"
macro_rules! m { macro_rules! m {
($($i:ident),*) => ( fn baz { $($i() );* } ); ($($i:ident),*) => ( fn baz() { $($i() );* } );
} }
fn baz { fn baz() {
foo(); foo();
bar() bar()
} }
@ -228,15 +228,15 @@ fn test_match_group_empty_fixed_token() {
check( check(
r#" r#"
macro_rules! m { macro_rules! m {
($($i:ident)* #abc) => ( fn baz { $($i ();)* } ); ($($i:ident)* #abc) => ( fn baz() { $($i ();)* } );
} }
m!{#abc} m!{#abc}
"#, "#,
expect![[r##" expect![[r##"
macro_rules! m { macro_rules! m {
($($i:ident)* #abc) => ( fn baz { $($i ();)* } ); ($($i:ident)* #abc) => ( fn baz() { $($i ();)* } );
} }
fn baz {} fn baz() {}
"##]], "##]],
) )
} }
@ -248,7 +248,7 @@ fn test_match_group_in_subtree() {
macro_rules! m { macro_rules! m {
(fn $name:ident { $($i:ident)* } ) => ( fn $name() { $($i ();)* } ); (fn $name:ident { $($i:ident)* } ) => ( fn $name() { $($i ();)* } );
} }
m! {fn baz { a b } } m! { fn baz { a b } }
"#, "#,
expect![[r#" expect![[r#"
macro_rules! m { macro_rules! m {

View file

@ -8,18 +8,18 @@ use crate::macro_expansion_tests::check;
fn unary_minus_is_a_literal() { fn unary_minus_is_a_literal() {
check( check(
r#" r#"
macro_rules! m { ($x:literal) => (literal!()); ($x:tt) => (not_a_literal!()); } macro_rules! m { ($x:literal) => (literal!();); ($x:tt) => (not_a_literal!();); }
m!(92); m!(92);
m!(-92); m!(-92);
m!(-9.2); m!(-9.2);
m!(--92); m!(--92);
"#, "#,
expect![[r#" expect![[r#"
macro_rules! m { ($x:literal) => (literal!()); ($x:tt) => (not_a_literal!()); } macro_rules! m { ($x:literal) => (literal!();); ($x:tt) => (not_a_literal!();); }
literal!() literal!();
literal!() literal!();
literal!() literal!();
/* error: leftover tokens */not_a_literal!() /* error: leftover tokens */not_a_literal!();
"#]], "#]],
) )
} }

View file

@ -16,7 +16,7 @@ macro_rules! m {
($($i:ident)*) => ($_); ($($i:ident)*) => ($_);
($($true:ident)*) => ($true); ($($true:ident)*) => ($true);
($($false:ident)*) => ($false); ($($false:ident)*) => ($false);
($) => ($); ($) => (m!($););
} }
m!($); m!($);
"#, "#,
@ -29,9 +29,9 @@ macro_rules! m {
($($i:ident)*) => ($_); ($($i:ident)*) => ($_);
($($true:ident)*) => ($true); ($($true:ident)*) => ($true);
($($false:ident)*) => ($false); ($($false:ident)*) => ($false);
($) => ($); ($) => (m!($););
} }
$ m!($);
"#]], "#]],
) )
} }

View file

@ -89,6 +89,9 @@ impl<T> Parse<T> {
pub fn syntax_node(&self) -> SyntaxNode { pub fn syntax_node(&self) -> SyntaxNode {
SyntaxNode::new_root(self.green.clone()) SyntaxNode::new_root(self.green.clone())
} }
pub fn errors(&self) -> &[SyntaxError] {
&*self.errors
}
} }
impl<T: AstNode> Parse<T> { impl<T: AstNode> Parse<T> {
@ -100,10 +103,6 @@ impl<T: AstNode> Parse<T> {
T::cast(self.syntax_node()).unwrap() T::cast(self.syntax_node()).unwrap()
} }
pub fn errors(&self) -> &[SyntaxError] {
&*self.errors
}
pub fn ok(self) -> Result<T, Arc<Vec<SyntaxError>>> { pub fn ok(self) -> Result<T, Arc<Vec<SyntaxError>>> {
if self.errors.is_empty() { if self.errors.is_empty() {
Ok(self.tree()) Ok(self.tree())