aboutsummaryrefslogtreecommitdiff
path: root/crates/mbe/src/tests.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mbe/src/tests.rs')
-rw-r--r--crates/mbe/src/tests.rs233
1 files changed, 156 insertions, 77 deletions
diff --git a/crates/mbe/src/tests.rs b/crates/mbe/src/tests.rs
index bd2977ebd..8d978163d 100644
--- a/crates/mbe/src/tests.rs
+++ b/crates/mbe/src/tests.rs
@@ -6,7 +6,7 @@ use syntax::{
6 SyntaxKind::{ERROR, IDENT}, 6 SyntaxKind::{ERROR, IDENT},
7 SyntaxNode, WalkEvent, T, 7 SyntaxNode, WalkEvent, T,
8}; 8};
9use test_utils::assert_eq_text; 9use test_utils::{assert_eq_text, mark};
10 10
11use super::*; 11use super::*;
12 12
@@ -675,6 +675,36 @@ fn test_match_literal() {
675 .assert_expand_items("foo! ['('];", "fn foo () {}"); 675 .assert_expand_items("foo! ['('];", "fn foo () {}");
676} 676}
677 677
678#[test]
679fn test_parse_macro_def_simple() {
680 mark::check!(parse_macro_def_simple);
681
682 parse_macro2(
683 r#"
684macro foo($id:ident) {
685 fn $id() {}
686}
687"#,
688 )
689 .assert_expand_items("foo!(bar);", "fn bar () {}");
690}
691
692#[test]
693fn test_parse_macro_def_rules() {
694 mark::check!(parse_macro_def_rules);
695
696 parse_macro2(
697 r#"
698macro foo {
699 ($id:ident) => {
700 fn $id() {}
701 }
702}
703"#,
704 )
705 .assert_expand_items("foo!(bar);", "fn bar () {}");
706}
707
678// The following tests are port from intellij-rust directly 708// The following tests are port from intellij-rust directly
679// https://github.com/intellij-rust/intellij-rust/blob/c4e9feee4ad46e7953b1948c112533360b6087bb/src/test/kotlin/org/rust/lang/core/macros/RsMacroExpansionTest.kt 709// https://github.com/intellij-rust/intellij-rust/blob/c4e9feee4ad46e7953b1948c112533360b6087bb/src/test/kotlin/org/rust/lang/core/macros/RsMacroExpansionTest.kt
680 710
@@ -1699,95 +1729,122 @@ pub(crate) struct MacroFixture {
1699 rules: MacroRules, 1729 rules: MacroRules,
1700} 1730}
1701 1731
1702impl MacroFixture { 1732pub(crate) struct MacroFixture2 {
1703 pub(crate) fn expand_tt(&self, invocation: &str) -> tt::Subtree { 1733 rules: MacroDef,
1704 self.try_expand_tt(invocation).unwrap() 1734}
1705 }
1706
1707 fn try_expand_tt(&self, invocation: &str) -> Result<tt::Subtree, ExpandError> {
1708 let source_file = ast::SourceFile::parse(invocation).tree();
1709 let macro_invocation =
1710 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
1711
1712 let (invocation_tt, _) = ast_to_token_tree(&macro_invocation.token_tree().unwrap())
1713 .ok_or_else(|| ExpandError::ConversionError)?;
1714 1735
1715 self.rules.expand(&invocation_tt).result() 1736macro_rules! impl_fixture {
1716 } 1737 ($name:ident) => {
1738 impl $name {
1739 pub(crate) fn expand_tt(&self, invocation: &str) -> tt::Subtree {
1740 self.try_expand_tt(invocation).unwrap()
1741 }
1717 1742
1718 fn assert_expand_err(&self, invocation: &str, err: &ExpandError) { 1743 fn try_expand_tt(&self, invocation: &str) -> Result<tt::Subtree, ExpandError> {
1719 assert_eq!(self.try_expand_tt(invocation).as_ref(), Err(err)); 1744 let source_file = ast::SourceFile::parse(invocation).tree();
1720 } 1745 let macro_invocation =
1746 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
1721 1747
1722 fn expand_items(&self, invocation: &str) -> SyntaxNode { 1748 let (invocation_tt, _) = ast_to_token_tree(&macro_invocation.token_tree().unwrap())
1723 let expanded = self.expand_tt(invocation); 1749 .ok_or_else(|| ExpandError::ConversionError)?;
1724 token_tree_to_syntax_node(&expanded, FragmentKind::Items).unwrap().0.syntax_node()
1725 }
1726 1750
1727 fn expand_statements(&self, invocation: &str) -> SyntaxNode { 1751 self.rules.expand(&invocation_tt).result()
1728 let expanded = self.expand_tt(invocation); 1752 }
1729 token_tree_to_syntax_node(&expanded, FragmentKind::Statements).unwrap().0.syntax_node()
1730 }
1731 1753
1732 fn expand_expr(&self, invocation: &str) -> SyntaxNode { 1754 #[allow(unused)]
1733 let expanded = self.expand_tt(invocation); 1755 fn assert_expand_err(&self, invocation: &str, err: &ExpandError) {
1734 token_tree_to_syntax_node(&expanded, FragmentKind::Expr).unwrap().0.syntax_node() 1756 assert_eq!(self.try_expand_tt(invocation).as_ref(), Err(err));
1735 } 1757 }
1736 1758
1737 fn assert_expand_tt(&self, invocation: &str, expected: &str) { 1759 #[allow(unused)]
1738 let expansion = self.expand_tt(invocation); 1760 fn expand_items(&self, invocation: &str) -> SyntaxNode {
1739 assert_eq!(expansion.to_string(), expected); 1761 let expanded = self.expand_tt(invocation);
1740 } 1762 token_tree_to_syntax_node(&expanded, FragmentKind::Items).unwrap().0.syntax_node()
1763 }
1741 1764
1742 fn assert_expand(&self, invocation: &str, expected: &str) { 1765 #[allow(unused)]
1743 let expansion = self.expand_tt(invocation); 1766 fn expand_statements(&self, invocation: &str) -> SyntaxNode {
1744 let actual = format!("{:?}", expansion); 1767 let expanded = self.expand_tt(invocation);
1745 test_utils::assert_eq_text!(&expected.trim(), &actual.trim()); 1768 token_tree_to_syntax_node(&expanded, FragmentKind::Statements)
1746 } 1769 .unwrap()
1770 .0
1771 .syntax_node()
1772 }
1747 1773
1748 fn assert_expand_items(&self, invocation: &str, expected: &str) -> &MacroFixture { 1774 #[allow(unused)]
1749 self.assert_expansion(FragmentKind::Items, invocation, expected); 1775 fn expand_expr(&self, invocation: &str) -> SyntaxNode {
1750 self 1776 let expanded = self.expand_tt(invocation);
1751 } 1777 token_tree_to_syntax_node(&expanded, FragmentKind::Expr).unwrap().0.syntax_node()
1778 }
1752 1779
1753 fn assert_expand_statements(&self, invocation: &str, expected: &str) -> &MacroFixture { 1780 #[allow(unused)]
1754 self.assert_expansion(FragmentKind::Statements, invocation, expected); 1781 fn assert_expand_tt(&self, invocation: &str, expected: &str) {
1755 self 1782 let expansion = self.expand_tt(invocation);
1756 } 1783 assert_eq!(expansion.to_string(), expected);
1784 }
1757 1785
1758 fn assert_expansion(&self, kind: FragmentKind, invocation: &str, expected: &str) { 1786 #[allow(unused)]
1759 let expanded = self.expand_tt(invocation); 1787 fn assert_expand(&self, invocation: &str, expected: &str) {
1760 assert_eq!(expanded.to_string(), expected); 1788 let expansion = self.expand_tt(invocation);
1761 1789 let actual = format!("{:?}", expansion);
1762 let expected = expected.replace("$crate", "C_C__C"); 1790 test_utils::assert_eq_text!(&expected.trim(), &actual.trim());
1763 1791 }
1764 // wrap the given text to a macro call
1765 let expected = {
1766 let wrapped = format!("wrap_macro!( {} )", expected);
1767 let wrapped = ast::SourceFile::parse(&wrapped);
1768 let wrapped =
1769 wrapped.tree().syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
1770 let mut wrapped = ast_to_token_tree(&wrapped).unwrap().0;
1771 wrapped.delimiter = None;
1772 wrapped
1773 };
1774 1792
1775 let expanded_tree = token_tree_to_syntax_node(&expanded, kind).unwrap().0.syntax_node(); 1793 fn assert_expand_items(&self, invocation: &str, expected: &str) -> &$name {
1776 let expanded_tree = debug_dump_ignore_spaces(&expanded_tree).trim().to_string(); 1794 self.assert_expansion(FragmentKind::Items, invocation, expected);
1795 self
1796 }
1777 1797
1778 let expected_tree = token_tree_to_syntax_node(&expected, kind).unwrap().0.syntax_node(); 1798 #[allow(unused)]
1779 let expected_tree = debug_dump_ignore_spaces(&expected_tree).trim().to_string(); 1799 fn assert_expand_statements(&self, invocation: &str, expected: &str) -> &$name {
1800 self.assert_expansion(FragmentKind::Statements, invocation, expected);
1801 self
1802 }
1780 1803
1781 let expected_tree = expected_tree.replace("C_C__C", "$crate"); 1804 fn assert_expansion(&self, kind: FragmentKind, invocation: &str, expected: &str) {
1782 assert_eq!( 1805 let expanded = self.expand_tt(invocation);
1783 expanded_tree, expected_tree, 1806 assert_eq!(expanded.to_string(), expected);
1784 "\nleft:\n{}\nright:\n{}", 1807
1785 expanded_tree, expected_tree, 1808 let expected = expected.replace("$crate", "C_C__C");
1786 ); 1809
1787 } 1810 // wrap the given text to a macro call
1811 let expected = {
1812 let wrapped = format!("wrap_macro!( {} )", expected);
1813 let wrapped = ast::SourceFile::parse(&wrapped);
1814 let wrapped = wrapped
1815 .tree()
1816 .syntax()
1817 .descendants()
1818 .find_map(ast::TokenTree::cast)
1819 .unwrap();
1820 let mut wrapped = ast_to_token_tree(&wrapped).unwrap().0;
1821 wrapped.delimiter = None;
1822 wrapped
1823 };
1824
1825 let expanded_tree =
1826 token_tree_to_syntax_node(&expanded, kind).unwrap().0.syntax_node();
1827 let expanded_tree = debug_dump_ignore_spaces(&expanded_tree).trim().to_string();
1828
1829 let expected_tree =
1830 token_tree_to_syntax_node(&expected, kind).unwrap().0.syntax_node();
1831 let expected_tree = debug_dump_ignore_spaces(&expected_tree).trim().to_string();
1832
1833 let expected_tree = expected_tree.replace("C_C__C", "$crate");
1834 assert_eq!(
1835 expanded_tree, expected_tree,
1836 "\nleft:\n{}\nright:\n{}",
1837 expanded_tree, expected_tree,
1838 );
1839 }
1840 }
1841 };
1788} 1842}
1789 1843
1790fn parse_macro_to_tt(ra_fixture: &str) -> tt::Subtree { 1844impl_fixture!(MacroFixture);
1845impl_fixture!(MacroFixture2);
1846
1847fn parse_macro_rules_to_tt(ra_fixture: &str) -> tt::Subtree {
1791 let source_file = ast::SourceFile::parse(ra_fixture).ok().unwrap(); 1848 let source_file = ast::SourceFile::parse(ra_fixture).ok().unwrap();
1792 let macro_definition = 1849 let macro_definition =
1793 source_file.syntax().descendants().find_map(ast::MacroRules::cast).unwrap(); 1850 source_file.syntax().descendants().find_map(ast::MacroRules::cast).unwrap();
@@ -1804,14 +1861,36 @@ fn parse_macro_to_tt(ra_fixture: &str) -> tt::Subtree {
1804 definition_tt 1861 definition_tt
1805} 1862}
1806 1863
1864fn parse_macro_def_to_tt(ra_fixture: &str) -> tt::Subtree {
1865 let source_file = ast::SourceFile::parse(ra_fixture).ok().unwrap();
1866 let macro_definition =
1867 source_file.syntax().descendants().find_map(ast::MacroDef::cast).unwrap();
1868
1869 let (definition_tt, _) = ast_to_token_tree(&macro_definition.body().unwrap()).unwrap();
1870
1871 let parsed =
1872 parse_to_token_tree(&ra_fixture[macro_definition.body().unwrap().syntax().text_range()])
1873 .unwrap()
1874 .0;
1875 assert_eq!(definition_tt, parsed);
1876
1877 definition_tt
1878}
1879
1807pub(crate) fn parse_macro(ra_fixture: &str) -> MacroFixture { 1880pub(crate) fn parse_macro(ra_fixture: &str) -> MacroFixture {
1808 let definition_tt = parse_macro_to_tt(ra_fixture); 1881 let definition_tt = parse_macro_rules_to_tt(ra_fixture);
1809 let rules = MacroRules::parse(&definition_tt).unwrap(); 1882 let rules = MacroRules::parse(&definition_tt).unwrap();
1810 MacroFixture { rules } 1883 MacroFixture { rules }
1811} 1884}
1812 1885
1886pub(crate) fn parse_macro2(ra_fixture: &str) -> MacroFixture2 {
1887 let definition_tt = parse_macro_def_to_tt(ra_fixture);
1888 let rules = MacroDef::parse(&definition_tt).unwrap();
1889 MacroFixture2 { rules }
1890}
1891
1813pub(crate) fn parse_macro_error(ra_fixture: &str) -> ParseError { 1892pub(crate) fn parse_macro_error(ra_fixture: &str) -> ParseError {
1814 let definition_tt = parse_macro_to_tt(ra_fixture); 1893 let definition_tt = parse_macro_rules_to_tt(ra_fixture);
1815 1894
1816 match MacroRules::parse(&definition_tt) { 1895 match MacroRules::parse(&definition_tt) {
1817 Ok(_) => panic!("Expect error"), 1896 Ok(_) => panic!("Expect error"),