aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax/src
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-12-15 17:43:19 +0000
committerJonas Schievink <[email protected]>2020-12-15 17:43:34 +0000
commitc31c3246a8c87a3639623c30b692a57e728bb046 (patch)
treee66cdc459e249767c69c1b29b13e85fe30bdc935 /crates/syntax/src
parentbd4c352831662762ee7a66da77ec9adf623b0a0a (diff)
Basic support for decl macros 2.0
Diffstat (limited to 'crates/syntax/src')
-rw-r--r--crates/syntax/src/ast.rs4
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs36
-rw-r--r--crates/syntax/src/ast/node_ext.rs54
-rw-r--r--crates/syntax/src/display.rs18
4 files changed, 106 insertions, 6 deletions
diff --git a/crates/syntax/src/ast.rs b/crates/syntax/src/ast.rs
index 7844f9ed6..70c568ea1 100644
--- a/crates/syntax/src/ast.rs
+++ b/crates/syntax/src/ast.rs
@@ -19,8 +19,8 @@ pub use self::{
19 expr_ext::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp}, 19 expr_ext::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp},
20 generated::{nodes::*, tokens::*}, 20 generated::{nodes::*, tokens::*},
21 node_ext::{ 21 node_ext::{
22 AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents, 22 AttrKind, FieldKind, Macro, NameOrNameRef, PathSegmentKind, SelfParamKind,
23 StructKind, TypeBoundKind, VisibilityKind, 23 SlicePatComponents, StructKind, TypeBoundKind, VisibilityKind,
24 }, 24 },
25 token_ext::*, 25 token_ext::*,
26 traits::*, 26 traits::*,
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index 0ad75214f..6eae323f4 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -286,6 +286,18 @@ impl MacroRules {
286 pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) } 286 pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
287} 287}
288#[derive(Debug, Clone, PartialEq, Eq, Hash)] 288#[derive(Debug, Clone, PartialEq, Eq, Hash)]
289pub struct MacroDef {
290 pub(crate) syntax: SyntaxNode,
291}
292impl ast::AttrsOwner for MacroDef {}
293impl ast::NameOwner for MacroDef {}
294impl ast::VisibilityOwner for MacroDef {}
295impl MacroDef {
296 pub fn macro_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![macro]) }
297 pub fn args(&self) -> Option<TokenTree> { support::child(&self.syntax) }
298 pub fn body(&self) -> Option<TokenTree> { support::child(&self.syntax) }
299}
300#[derive(Debug, Clone, PartialEq, Eq, Hash)]
289pub struct Module { 301pub struct Module {
290 pub(crate) syntax: SyntaxNode, 302 pub(crate) syntax: SyntaxNode,
291} 303}
@@ -1332,6 +1344,7 @@ pub enum Item {
1332 Impl(Impl), 1344 Impl(Impl),
1333 MacroCall(MacroCall), 1345 MacroCall(MacroCall),
1334 MacroRules(MacroRules), 1346 MacroRules(MacroRules),
1347 MacroDef(MacroDef),
1335 Module(Module), 1348 Module(Module),
1336 Static(Static), 1349 Static(Static),
1337 Struct(Struct), 1350 Struct(Struct),
@@ -1689,6 +1702,17 @@ impl AstNode for MacroRules {
1689 } 1702 }
1690 fn syntax(&self) -> &SyntaxNode { &self.syntax } 1703 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1691} 1704}
1705impl AstNode for MacroDef {
1706 fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_DEF }
1707 fn cast(syntax: SyntaxNode) -> Option<Self> {
1708 if Self::can_cast(syntax.kind()) {
1709 Some(Self { syntax })
1710 } else {
1711 None
1712 }
1713 }
1714 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1715}
1692impl AstNode for Module { 1716impl AstNode for Module {
1693 fn can_cast(kind: SyntaxKind) -> bool { kind == MODULE } 1717 fn can_cast(kind: SyntaxKind) -> bool { kind == MODULE }
1694 fn cast(syntax: SyntaxNode) -> Option<Self> { 1718 fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3086,6 +3110,9 @@ impl From<MacroCall> for Item {
3086impl From<MacroRules> for Item { 3110impl From<MacroRules> for Item {
3087 fn from(node: MacroRules) -> Item { Item::MacroRules(node) } 3111 fn from(node: MacroRules) -> Item { Item::MacroRules(node) }
3088} 3112}
3113impl From<MacroDef> for Item {
3114 fn from(node: MacroDef) -> Item { Item::MacroDef(node) }
3115}
3089impl From<Module> for Item { 3116impl From<Module> for Item {
3090 fn from(node: Module) -> Item { Item::Module(node) } 3117 fn from(node: Module) -> Item { Item::Module(node) }
3091} 3118}
@@ -3111,7 +3138,7 @@ impl AstNode for Item {
3111 fn can_cast(kind: SyntaxKind) -> bool { 3138 fn can_cast(kind: SyntaxKind) -> bool {
3112 match kind { 3139 match kind {
3113 CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL | MACRO_CALL | MACRO_RULES 3140 CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL | MACRO_CALL | MACRO_RULES
3114 | MODULE | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE => true, 3141 | MACRO_DEF | MODULE | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE => true,
3115 _ => false, 3142 _ => false,
3116 } 3143 }
3117 } 3144 }
@@ -3125,6 +3152,7 @@ impl AstNode for Item {
3125 IMPL => Item::Impl(Impl { syntax }), 3152 IMPL => Item::Impl(Impl { syntax }),
3126 MACRO_CALL => Item::MacroCall(MacroCall { syntax }), 3153 MACRO_CALL => Item::MacroCall(MacroCall { syntax }),
3127 MACRO_RULES => Item::MacroRules(MacroRules { syntax }), 3154 MACRO_RULES => Item::MacroRules(MacroRules { syntax }),
3155 MACRO_DEF => Item::MacroDef(MacroDef { syntax }),
3128 MODULE => Item::Module(Module { syntax }), 3156 MODULE => Item::Module(Module { syntax }),
3129 STATIC => Item::Static(Static { syntax }), 3157 STATIC => Item::Static(Static { syntax }),
3130 STRUCT => Item::Struct(Struct { syntax }), 3158 STRUCT => Item::Struct(Struct { syntax }),
@@ -3146,6 +3174,7 @@ impl AstNode for Item {
3146 Item::Impl(it) => &it.syntax, 3174 Item::Impl(it) => &it.syntax,
3147 Item::MacroCall(it) => &it.syntax, 3175 Item::MacroCall(it) => &it.syntax,
3148 Item::MacroRules(it) => &it.syntax, 3176 Item::MacroRules(it) => &it.syntax,
3177 Item::MacroDef(it) => &it.syntax,
3149 Item::Module(it) => &it.syntax, 3178 Item::Module(it) => &it.syntax,
3150 Item::Static(it) => &it.syntax, 3179 Item::Static(it) => &it.syntax,
3151 Item::Struct(it) => &it.syntax, 3180 Item::Struct(it) => &it.syntax,
@@ -3615,6 +3644,11 @@ impl std::fmt::Display for MacroRules {
3615 std::fmt::Display::fmt(self.syntax(), f) 3644 std::fmt::Display::fmt(self.syntax(), f)
3616 } 3645 }
3617} 3646}
3647impl std::fmt::Display for MacroDef {
3648 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3649 std::fmt::Display::fmt(self.syntax(), f)
3650 }
3651}
3618impl std::fmt::Display for Module { 3652impl std::fmt::Display for Module {
3619 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3653 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3620 std::fmt::Display::fmt(self.syntax(), f) 3654 std::fmt::Display::fmt(self.syntax(), f)
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index c59a29eab..40dec3c7f 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -3,6 +3,7 @@
3 3
4use std::fmt; 4use std::fmt;
5 5
6use ast::AttrsOwner;
6use itertools::Itertools; 7use itertools::Itertools;
7use parser::SyntaxKind; 8use parser::SyntaxKind;
8 9
@@ -31,6 +32,57 @@ fn text_of_first_token(node: &SyntaxNode) -> &SmolStr {
31 node.green().children().next().and_then(|it| it.into_token()).unwrap().text() 32 node.green().children().next().and_then(|it| it.into_token()).unwrap().text()
32} 33}
33 34
35pub enum Macro {
36 MacroRules(ast::MacroRules),
37 MacroDef(ast::MacroDef),
38}
39
40impl From<ast::MacroRules> for Macro {
41 fn from(it: ast::MacroRules) -> Self {
42 Macro::MacroRules(it)
43 }
44}
45
46impl From<ast::MacroDef> for Macro {
47 fn from(it: ast::MacroDef) -> Self {
48 Macro::MacroDef(it)
49 }
50}
51
52impl AstNode for Macro {
53 fn can_cast(kind: SyntaxKind) -> bool {
54 match kind {
55 SyntaxKind::MACRO_RULES | SyntaxKind::MACRO_DEF => true,
56 _ => false,
57 }
58 }
59 fn cast(syntax: SyntaxNode) -> Option<Self> {
60 let res = match syntax.kind() {
61 SyntaxKind::MACRO_RULES => Macro::MacroRules(ast::MacroRules { syntax }),
62 SyntaxKind::MACRO_DEF => Macro::MacroDef(ast::MacroDef { syntax }),
63 _ => return None,
64 };
65 Some(res)
66 }
67 fn syntax(&self) -> &SyntaxNode {
68 match self {
69 Macro::MacroRules(it) => it.syntax(),
70 Macro::MacroDef(it) => it.syntax(),
71 }
72 }
73}
74
75impl NameOwner for Macro {
76 fn name(&self) -> Option<ast::Name> {
77 match self {
78 Macro::MacroRules(mac) => mac.name(),
79 Macro::MacroDef(mac) => mac.name(),
80 }
81 }
82}
83
84impl AttrsOwner for Macro {}
85
34#[derive(Debug, Clone, PartialEq, Eq)] 86#[derive(Debug, Clone, PartialEq, Eq)]
35pub enum AttrKind { 87pub enum AttrKind {
36 Inner, 88 Inner,
@@ -462,4 +514,6 @@ impl ast::DocCommentsOwner for ast::Const {}
462impl ast::DocCommentsOwner for ast::TypeAlias {} 514impl ast::DocCommentsOwner for ast::TypeAlias {}
463impl ast::DocCommentsOwner for ast::Impl {} 515impl ast::DocCommentsOwner for ast::Impl {}
464impl ast::DocCommentsOwner for ast::MacroRules {} 516impl ast::DocCommentsOwner for ast::MacroRules {}
517impl ast::DocCommentsOwner for ast::MacroDef {}
518impl ast::DocCommentsOwner for ast::Macro {}
465impl ast::DocCommentsOwner for ast::Use {} 519impl ast::DocCommentsOwner for ast::Use {}
diff --git a/crates/syntax/src/display.rs b/crates/syntax/src/display.rs
index d33bde30c..391647fc6 100644
--- a/crates/syntax/src/display.rs
+++ b/crates/syntax/src/display.rs
@@ -76,8 +76,20 @@ pub fn type_label(node: &ast::TypeAlias) -> String {
76 label.trim().to_owned() 76 label.trim().to_owned()
77} 77}
78 78
79pub fn macro_label(node: &ast::MacroRules) -> String { 79pub fn macro_label(node: &ast::Macro) -> String {
80 let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default(); 80 let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default();
81 let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" }; 81 match node {
82 format!("{}macro_rules! {}", vis, name) 82 ast::Macro::MacroRules(node) => {
83 let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" };
84 format!("{}macro_rules! {}", vis, name)
85 }
86 ast::Macro::MacroDef(node) => {
87 let mut s = String::new();
88 if let Some(vis) = node.visibility() {
89 format_to!(s, "{} ", vis);
90 }
91 format_to!(s, "macro {}", name);
92 s
93 }
94 }
83} 95}