diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-12-16 16:52:46 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-12-16 16:52:46 +0000 |
commit | 63bbdb31e5148c804bbf940963c9c8f3481ad258 (patch) | |
tree | 2732cd2c3878257d9b55447830bc824447332c98 /crates/syntax | |
parent | 423f3872246f1a67b49e248f3437cb46fdfc8138 (diff) | |
parent | d34611633b3b2404188b9e12b08c5def589808c2 (diff) |
Merge #6897
6897: Basic support for macros 2.0 r=jonas-schievink a=jonas-schievink
This adds support for (built-in-only) macros 2.0, and removes some hacks used for builtin derives, which are declared via macros 2.0 in libcore.
First steps for https://github.com/rust-analyzer/rust-analyzer/issues/2248.
Blocked on https://github.com/rust-analyzer/ungrammar/pull/16.
Co-authored-by: Jonas Schievink <[email protected]>
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/syntax')
-rw-r--r-- | crates/syntax/src/ast.rs | 4 | ||||
-rw-r--r-- | crates/syntax/src/ast/generated/nodes.rs | 36 | ||||
-rw-r--r-- | crates/syntax/src/ast/node_ext.rs | 54 | ||||
-rw-r--r-- | crates/syntax/src/display.rs | 18 |
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)] |
289 | pub struct MacroDef { | ||
290 | pub(crate) syntax: SyntaxNode, | ||
291 | } | ||
292 | impl ast::AttrsOwner for MacroDef {} | ||
293 | impl ast::NameOwner for MacroDef {} | ||
294 | impl ast::VisibilityOwner for MacroDef {} | ||
295 | impl 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)] | ||
289 | pub struct Module { | 301 | pub 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 | } |
1705 | impl 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 | } | ||
1692 | impl AstNode for Module { | 1716 | impl 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 { | |||
3086 | impl From<MacroRules> for Item { | 3110 | impl From<MacroRules> for Item { |
3087 | fn from(node: MacroRules) -> Item { Item::MacroRules(node) } | 3111 | fn from(node: MacroRules) -> Item { Item::MacroRules(node) } |
3088 | } | 3112 | } |
3113 | impl From<MacroDef> for Item { | ||
3114 | fn from(node: MacroDef) -> Item { Item::MacroDef(node) } | ||
3115 | } | ||
3089 | impl From<Module> for Item { | 3116 | impl 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 | } |
3647 | impl 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 | } | ||
3618 | impl std::fmt::Display for Module { | 3652 | impl 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 | ||
4 | use std::fmt; | 4 | use std::fmt; |
5 | 5 | ||
6 | use ast::AttrsOwner; | ||
6 | use itertools::Itertools; | 7 | use itertools::Itertools; |
7 | use parser::SyntaxKind; | 8 | use 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 | ||
35 | pub enum Macro { | ||
36 | MacroRules(ast::MacroRules), | ||
37 | MacroDef(ast::MacroDef), | ||
38 | } | ||
39 | |||
40 | impl From<ast::MacroRules> for Macro { | ||
41 | fn from(it: ast::MacroRules) -> Self { | ||
42 | Macro::MacroRules(it) | ||
43 | } | ||
44 | } | ||
45 | |||
46 | impl From<ast::MacroDef> for Macro { | ||
47 | fn from(it: ast::MacroDef) -> Self { | ||
48 | Macro::MacroDef(it) | ||
49 | } | ||
50 | } | ||
51 | |||
52 | impl 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 | |||
75 | impl 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 | |||
84 | impl AttrsOwner for Macro {} | ||
85 | |||
34 | #[derive(Debug, Clone, PartialEq, Eq)] | 86 | #[derive(Debug, Clone, PartialEq, Eq)] |
35 | pub enum AttrKind { | 87 | pub enum AttrKind { |
36 | Inner, | 88 | Inner, |
@@ -462,4 +514,6 @@ impl ast::DocCommentsOwner for ast::Const {} | |||
462 | impl ast::DocCommentsOwner for ast::TypeAlias {} | 514 | impl ast::DocCommentsOwner for ast::TypeAlias {} |
463 | impl ast::DocCommentsOwner for ast::Impl {} | 515 | impl ast::DocCommentsOwner for ast::Impl {} |
464 | impl ast::DocCommentsOwner for ast::MacroRules {} | 516 | impl ast::DocCommentsOwner for ast::MacroRules {} |
517 | impl ast::DocCommentsOwner for ast::MacroDef {} | ||
518 | impl ast::DocCommentsOwner for ast::Macro {} | ||
465 | impl ast::DocCommentsOwner for ast::Use {} | 519 | impl 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 | ||
79 | pub fn macro_label(node: &ast::MacroRules) -> String { | 79 | pub 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 | } |