about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAleksey Kladov <aleksey.kladov@gmail.com>2020-07-30 20:16:04 +0200
committerAleksey Kladov <aleksey.kladov@gmail.com>2020-07-30 20:21:32 +0200
commitfcce07d2d1b07cf4578af65b00a243e743a67f05 (patch)
treea6a9437d26f62040d62921eca2f7aafb5d1233f3
parente28ea81b2b68a61b5c5eec3c815172b17256a25f (diff)
downloadrust-fcce07d2d1b07cf4578af65b00a243e743a67f05.tar.gz
rust-fcce07d2d1b07cf4578af65b00a243e743a67f05.zip
Finalize attribute grammar
-rw-r--r--crates/ra_assists/src/handlers/add_custom_impl.rs4
-rw-r--r--crates/ra_hir_def/src/attr.rs19
-rw-r--r--crates/ra_ide/src/completion/complete_attribute.rs10
-rw-r--r--crates/ra_syntax/src/ast/generated/nodes.rs41
-rw-r--r--crates/ra_syntax/src/ast/node_ext.rs28
-rw-r--r--xtask/src/codegen/rust.ungram5
6 files changed, 28 insertions, 79 deletions
diff --git a/crates/ra_assists/src/handlers/add_custom_impl.rs b/crates/ra_assists/src/handlers/add_custom_impl.rs
index acb07e36a25..b67438b6ba2 100644
--- a/crates/ra_assists/src/handlers/add_custom_impl.rs
+++ b/crates/ra_assists/src/handlers/add_custom_impl.rs
@@ -29,8 +29,8 @@ use crate::{
 // }
 // ```
 pub(crate) fn add_custom_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
-    let input = ctx.find_node_at_offset::<ast::AttrInput>()?;
-    let attr = input.syntax().parent().and_then(ast::Attr::cast)?;
+    let attr = ctx.find_node_at_offset::<ast::Attr>()?;
+    let input = attr.token_tree()?;
 
     let attr_name = attr
         .syntax()
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 70ccd430526..050832ce01b 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -151,18 +151,15 @@ pub enum AttrInput {
 impl Attr {
     fn from_src(ast: ast::Attr, hygiene: &Hygiene) -> Option<Attr> {
         let path = ModPath::from_src(ast.path()?, hygiene)?;
-        let input = match ast.input() {
-            None => None,
-            Some(ast::AttrInput::Literal(lit)) => {
-                // FIXME: escape? raw string?
-                let value = lit.syntax().first_token()?.text().trim_matches('"').into();
-                Some(AttrInput::Literal(value))
-            }
-            Some(ast::AttrInput::TokenTree(tt)) => {
-                Some(AttrInput::TokenTree(ast_to_token_tree(&tt)?.0))
-            }
+        let input = if let Some(lit) = ast.literal() {
+            // FIXME: escape? raw string?
+            let value = lit.syntax().first_token()?.text().trim_matches('"').into();
+            Some(AttrInput::Literal(value))
+        } else if let Some(tt) = ast.token_tree() {
+            Some(AttrInput::TokenTree(ast_to_token_tree(&tt)?.0))
+        } else {
+            None
         };
-
         Some(Attr { path, input })
     }
 }
diff --git a/crates/ra_ide/src/completion/complete_attribute.rs b/crates/ra_ide/src/completion/complete_attribute.rs
index 109c5e9a880..2faaae97460 100644
--- a/crates/ra_ide/src/completion/complete_attribute.rs
+++ b/crates/ra_ide/src/completion/complete_attribute.rs
@@ -13,20 +13,18 @@ use crate::completion::{
 
 pub(super) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
     let attribute = ctx.attribute_under_caret.as_ref()?;
-    match (attribute.path(), attribute.input()) {
-        (Some(path), Some(ast::AttrInput::TokenTree(token_tree)))
-            if path.to_string() == "derive" =>
-        {
+    match (attribute.path(), attribute.token_tree()) {
+        (Some(path), Some(token_tree)) if path.to_string() == "derive" => {
             complete_derive(acc, ctx, token_tree)
         }
-        (Some(path), Some(ast::AttrInput::TokenTree(token_tree)))
+        (Some(path), Some(token_tree))
             if ["allow", "warn", "deny", "forbid"]
                 .iter()
                 .any(|lint_level| lint_level == &path.to_string()) =>
         {
             complete_lint(acc, ctx, token_tree)
         }
-        (_, Some(ast::AttrInput::TokenTree(_token_tree))) => {}
+        (_, Some(_token_tree)) => {}
         _ => complete_attribute_start(acc, ctx, attribute),
     }
     Some(())
diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs
index e898c9181ef..05f75871d89 100644
--- a/crates/ra_syntax/src/ast/generated/nodes.rs
+++ b/crates/ra_syntax/src/ast/generated/nodes.rs
@@ -24,7 +24,8 @@ impl Attr {
     pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
     pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
     pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
-    pub fn input(&self) -> Option<AttrInput> { support::child(&self.syntax) }
+    pub fn literal(&self) -> Option<Literal> { support::child(&self.syntax) }
+    pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
     pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1378,11 +1379,6 @@ pub enum GenericParam {
 }
 impl ast::AttrsOwner for GenericParam {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum AttrInput {
-    Literal(Literal),
-    TokenTree(TokenTree),
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum Stmt {
     LetStmt(LetStmt),
     ExprStmt(ExprStmt),
@@ -3342,34 +3338,6 @@ impl AstNode for GenericParam {
         }
     }
 }
-impl From<Literal> for AttrInput {
-    fn from(node: Literal) -> AttrInput { AttrInput::Literal(node) }
-}
-impl From<TokenTree> for AttrInput {
-    fn from(node: TokenTree) -> AttrInput { AttrInput::TokenTree(node) }
-}
-impl AstNode for AttrInput {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            LITERAL | TOKEN_TREE => true,
-            _ => false,
-        }
-    }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        let res = match syntax.kind() {
-            LITERAL => AttrInput::Literal(Literal { syntax }),
-            TOKEN_TREE => AttrInput::TokenTree(TokenTree { syntax }),
-            _ => return None,
-        };
-        Some(res)
-    }
-    fn syntax(&self) -> &SyntaxNode {
-        match self {
-            AttrInput::Literal(it) => &it.syntax,
-            AttrInput::TokenTree(it) => &it.syntax,
-        }
-    }
-}
 impl From<LetStmt> for Stmt {
     fn from(node: LetStmt) -> Stmt { Stmt::LetStmt(node) }
 }
@@ -3471,11 +3439,6 @@ impl std::fmt::Display for GenericParam {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for AttrInput {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
 impl std::fmt::Display for Stmt {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
diff --git a/crates/ra_syntax/src/ast/node_ext.rs b/crates/ra_syntax/src/ast/node_ext.rs
index d2ee9586d2a..bba7310adee 100644
--- a/crates/ra_syntax/src/ast/node_ext.rs
+++ b/crates/ra_syntax/src/ast/node_ext.rs
@@ -7,7 +7,7 @@ use itertools::Itertools;
 use ra_parser::SyntaxKind;
 
 use crate::{
-    ast::{self, support, AstNode, AttrInput, NameOwner, SyntaxNode},
+    ast::{self, support, AstNode, NameOwner, SyntaxNode},
     SmolStr, SyntaxElement, SyntaxToken, T,
 };
 
@@ -39,29 +39,23 @@ pub enum AttrKind {
 
 impl ast::Attr {
     pub fn as_simple_atom(&self) -> Option<SmolStr> {
-        match self.input() {
-            None => self.simple_name(),
-            Some(_) => None,
+        if self.eq_token().is_some() || self.token_tree().is_some() {
+            return None;
         }
+        self.simple_name()
     }
 
     pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
-        match self.input() {
-            Some(AttrInput::TokenTree(tt)) => Some((self.simple_name()?, tt)),
-            _ => None,
-        }
+        let tt = self.token_tree()?;
+        Some((self.simple_name()?, tt))
     }
 
     pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> {
-        match self.input() {
-            Some(AttrInput::Literal(lit)) => {
-                let key = self.simple_name()?;
-                // FIXME: escape? raw string?
-                let value = lit.syntax().first_token()?.text().trim_matches('"').into();
-                Some((key, value))
-            }
-            _ => None,
-        }
+        let lit = self.literal()?;
+        let key = self.simple_name()?;
+        // FIXME: escape? raw string?
+        let value = lit.syntax().first_token()?.text().trim_matches('"').into();
+        Some((key, value))
     }
 
     pub fn simple_name(&self) -> Option<SmolStr> {
diff --git a/xtask/src/codegen/rust.ungram b/xtask/src/codegen/rust.ungram
index a97cc80e992..42ef2fb8284 100644
--- a/xtask/src/codegen/rust.ungram
+++ b/xtask/src/codegen/rust.ungram
@@ -182,10 +182,7 @@ Visibility =
   ')')?
 
 Attr =
-  '#' '!'? '[' Path ('=' input:AttrInput)? ']'
-
-AttrInput =
-  Literal | TokenTree
+  '#' '!'? '[' Path ('=' Literal | TokenTree)? ']'
 
 ParenType =
   '(' TypeRef ')'