aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-03-18 21:25:10 +0000
committerLukas Wirth <[email protected]>2021-03-19 01:13:46 +0000
commit4771a5679188177e653262e69ed7e33b4bf60c65 (patch)
tree9cd52bcda5a72f00b176681d13897b938297fb9a
parent816bc7389516dda1eb4821f2ac4d5993cd5611dd (diff)
Parse extended_key_value_attributes
-rw-r--r--Cargo.lock4
-rw-r--r--crates/hir_def/src/attr.rs2
-rw-r--r--crates/ide/src/syntax_highlighting/inject.rs5
-rw-r--r--crates/parser/src/grammar/attributes.rs4
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs46
-rw-r--r--crates/syntax/src/ast/node_ext.rs10
-rw-r--r--xtask/Cargo.toml2
7 files changed, 32 insertions, 41 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b99c243a4..9f013c275 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1809,9 +1809,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
1809 1809
1810[[package]] 1810[[package]]
1811name = "ungrammar" 1811name = "ungrammar"
1812version = "1.12.2" 1812version = "1.13.0"
1813source = "registry+https://github.com/rust-lang/crates.io-index" 1813source = "registry+https://github.com/rust-lang/crates.io-index"
1814checksum = "df6586a7c530704efe803d49a0b4132dcbdb4063163df39110548e6b5f2373ba" 1814checksum = "76760314176cc2b94047af2f921b92c39f11a34dc05c43a3c2b0fc91cb22959f"
1815 1815
1816[[package]] 1816[[package]]
1817name = "unicase" 1817name = "unicase"
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index e4c84afbf..85d01ac3e 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -414,7 +414,7 @@ pub enum AttrInput {
414impl Attr { 414impl Attr {
415 fn from_src(ast: ast::Attr, hygiene: &Hygiene, index: u32) -> Option<Attr> { 415 fn from_src(ast: ast::Attr, hygiene: &Hygiene, index: u32) -> Option<Attr> {
416 let path = ModPath::from_src(ast.path()?, hygiene)?; 416 let path = ModPath::from_src(ast.path()?, hygiene)?;
417 let input = if let Some(lit) = ast.literal() { 417 let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() {
418 let value = match lit.kind() { 418 let value = match lit.kind() {
419 ast::LiteralKind::String(string) => string.value()?.into(), 419 ast::LiteralKind::String(string) => string.value()?.into(),
420 _ => lit.syntax().first_token()?.text().trim_matches('"').into(), 420 _ => lit.syntax().first_token()?.text().trim_matches('"').into(),
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs
index 947cc974c..90feb6c18 100644
--- a/crates/ide/src/syntax_highlighting/inject.rs
+++ b/crates/ide/src/syntax_highlighting/inject.rs
@@ -277,9 +277,9 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n
277} 277}
278 278
279fn find_doc_string_in_attr(attr: &hir::Attr, it: &ast::Attr) -> Option<ast::String> { 279fn find_doc_string_in_attr(attr: &hir::Attr, it: &ast::Attr) -> Option<ast::String> {
280 match it.literal() { 280 match it.expr() {
281 // #[doc = lit] 281 // #[doc = lit]
282 Some(lit) => match lit.kind() { 282 Some(ast::Expr::Literal(lit)) => match lit.kind() {
283 ast::LiteralKind::String(it) => Some(it), 283 ast::LiteralKind::String(it) => Some(it),
284 _ => None, 284 _ => None,
285 }, 285 },
@@ -297,6 +297,7 @@ fn find_doc_string_in_attr(attr: &hir::Attr, it: &ast::Attr) -> Option<ast::Stri
297 string.text().get(1..string.text().len() - 1).map_or(false, |it| it == text) 297 string.text().get(1..string.text().len() - 1).map_or(false, |it| it == text)
298 }) 298 })
299 } 299 }
300 _ => return None,
300 } 301 }
301} 302}
302 303
diff --git a/crates/parser/src/grammar/attributes.rs b/crates/parser/src/grammar/attributes.rs
index dab0f62c3..96791ffc2 100644
--- a/crates/parser/src/grammar/attributes.rs
+++ b/crates/parser/src/grammar/attributes.rs
@@ -30,8 +30,8 @@ fn attr(p: &mut Parser, inner: bool) {
30 match p.current() { 30 match p.current() {
31 T![=] => { 31 T![=] => {
32 p.bump(T![=]); 32 p.bump(T![=]);
33 if expressions::literal(p).is_none() { 33 if expressions::expr(p).0.is_none() {
34 p.error("expected literal"); 34 p.error("expected expression");
35 } 35 }
36 } 36 }
37 T!['('] | T!['['] | T!['{'] => items::token_tree(p), 37 T!['('] | T!['['] | T!['{'] => items::token_tree(p),
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index 6097178b6..9a88fdb56 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -152,7 +152,7 @@ impl Attr {
152 pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) } 152 pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
153 pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } 153 pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
154 pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) } 154 pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
155 pub fn literal(&self) -> Option<Literal> { support::child(&self.syntax) } 155 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
156 pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) } 156 pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
157 pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) } 157 pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
158} 158}
@@ -632,12 +632,6 @@ impl WherePred {
632 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } 632 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
633} 633}
634#[derive(Debug, Clone, PartialEq, Eq, Hash)] 634#[derive(Debug, Clone, PartialEq, Eq, Hash)]
635pub struct Literal {
636 pub(crate) syntax: SyntaxNode,
637}
638impl ast::AttrsOwner for Literal {}
639impl Literal {}
640#[derive(Debug, Clone, PartialEq, Eq, Hash)]
641pub struct ExprStmt { 635pub struct ExprStmt {
642 pub(crate) syntax: SyntaxNode, 636 pub(crate) syntax: SyntaxNode,
643} 637}
@@ -805,6 +799,12 @@ impl IndexExpr {
805 pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) } 799 pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
806} 800}
807#[derive(Debug, Clone, PartialEq, Eq, Hash)] 801#[derive(Debug, Clone, PartialEq, Eq, Hash)]
802pub struct Literal {
803 pub(crate) syntax: SyntaxNode,
804}
805impl ast::AttrsOwner for Literal {}
806impl Literal {}
807#[derive(Debug, Clone, PartialEq, Eq, Hash)]
808pub struct LoopExpr { 808pub struct LoopExpr {
809 pub(crate) syntax: SyntaxNode, 809 pub(crate) syntax: SyntaxNode,
810} 810}
@@ -2072,17 +2072,6 @@ impl AstNode for WherePred {
2072 } 2072 }
2073 fn syntax(&self) -> &SyntaxNode { &self.syntax } 2073 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2074} 2074}
2075impl AstNode for Literal {
2076 fn can_cast(kind: SyntaxKind) -> bool { kind == LITERAL }
2077 fn cast(syntax: SyntaxNode) -> Option<Self> {
2078 if Self::can_cast(syntax.kind()) {
2079 Some(Self { syntax })
2080 } else {
2081 None
2082 }
2083 }
2084 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2085}
2086impl AstNode for ExprStmt { 2075impl AstNode for ExprStmt {
2087 fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_STMT } 2076 fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_STMT }
2088 fn cast(syntax: SyntaxNode) -> Option<Self> { 2077 fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -2259,6 +2248,17 @@ impl AstNode for IndexExpr {
2259 } 2248 }
2260 fn syntax(&self) -> &SyntaxNode { &self.syntax } 2249 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2261} 2250}
2251impl AstNode for Literal {
2252 fn can_cast(kind: SyntaxKind) -> bool { kind == LITERAL }
2253 fn cast(syntax: SyntaxNode) -> Option<Self> {
2254 if Self::can_cast(syntax.kind()) {
2255 Some(Self { syntax })
2256 } else {
2257 None
2258 }
2259 }
2260 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2261}
2262impl AstNode for LoopExpr { 2262impl AstNode for LoopExpr {
2263 fn can_cast(kind: SyntaxKind) -> bool { kind == LOOP_EXPR } 2263 fn can_cast(kind: SyntaxKind) -> bool { kind == LOOP_EXPR }
2264 fn cast(syntax: SyntaxNode) -> Option<Self> { 2264 fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3887,11 +3887,6 @@ impl std::fmt::Display for WherePred {
3887 std::fmt::Display::fmt(self.syntax(), f) 3887 std::fmt::Display::fmt(self.syntax(), f)
3888 } 3888 }
3889} 3889}
3890impl std::fmt::Display for Literal {
3891 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3892 std::fmt::Display::fmt(self.syntax(), f)
3893 }
3894}
3895impl std::fmt::Display for ExprStmt { 3890impl std::fmt::Display for ExprStmt {
3896 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3891 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3897 std::fmt::Display::fmt(self.syntax(), f) 3892 std::fmt::Display::fmt(self.syntax(), f)
@@ -3972,6 +3967,11 @@ impl std::fmt::Display for IndexExpr {
3972 std::fmt::Display::fmt(self.syntax(), f) 3967 std::fmt::Display::fmt(self.syntax(), f)
3973 } 3968 }
3974} 3969}
3970impl std::fmt::Display for Literal {
3971 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3972 std::fmt::Display::fmt(self.syntax(), f)
3973 }
3974}
3975impl std::fmt::Display for LoopExpr { 3975impl std::fmt::Display for LoopExpr {
3976 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3976 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3977 std::fmt::Display::fmt(self.syntax(), f) 3977 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 0b0d39a75..5a9834cbb 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -109,16 +109,6 @@ impl ast::Attr {
109 Some((self.simple_name()?, tt)) 109 Some((self.simple_name()?, tt))
110 } 110 }
111 111
112 pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> {
113 let lit = self.literal()?;
114 let key = self.simple_name()?;
115 let value_token = lit.syntax().first_token()?;
116
117 let value: SmolStr = ast::String::cast(value_token)?.value()?.into();
118
119 Some((key, value))
120 }
121
122 pub fn simple_name(&self) -> Option<SmolStr> { 112 pub fn simple_name(&self) -> Option<SmolStr> {
123 let path = self.path()?; 113 let path = self.path()?;
124 match (path.segment(), path.qualifier()) { 114 match (path.segment(), path.qualifier()) {
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index ad93fbe3b..997770958 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -11,7 +11,7 @@ anyhow = "1.0.26"
11flate2 = "1.0" 11flate2 = "1.0"
12proc-macro2 = "1.0.8" 12proc-macro2 = "1.0.8"
13quote = "1.0.2" 13quote = "1.0.2"
14ungrammar = "=1.12" 14ungrammar = "=1.13"
15walkdir = "2.3.1" 15walkdir = "2.3.1"
16write-json = "0.1.0" 16write-json = "0.1.0"
17xshell = "0.1" 17xshell = "0.1"