From 52143f389fa49e1601fbc2c6cb526e4e9d1f113e Mon Sep 17 00:00:00 2001 From: Dawer <7803845+iDawer@users.noreply.github.com> Date: Thu, 6 May 2021 10:04:39 +0500 Subject: [PATCH 1/6] Update to rowan 0.13.0-pre.5 --- Cargo.lock | 4 ++-- crates/syntax/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c411ce8e62f..c378014f008 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1319,9 +1319,9 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "rowan" -version = "0.13.0-pre.3" +version = "0.13.0-pre.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77d315d6f2e33f294412faa47f41b56bdb3fce72c999d384b5e78c8d21551b13" +checksum = "32a5fc82ed0b7e7fba157331f0d8f64abd73bced6e7ac2a4dfa0c4cf0ab584e8" dependencies = [ "countme", "hashbrown", diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml index 556f808825a..c0bc5991887 100644 --- a/crates/syntax/Cargo.toml +++ b/crates/syntax/Cargo.toml @@ -13,7 +13,7 @@ doctest = false [dependencies] cov-mark = { version = "1.1", features = ["thread-local"] } itertools = "0.10.0" -rowan = "=0.13.0-pre.3" +rowan = "=0.13.0-pre.5" rustc_lexer = { version = "716.0.0", package = "rustc-ap-rustc_lexer" } rustc-hash = "1.1.0" arrayvec = "0.7" From dc4fa504ea2723bd5083284cabf81b4c5806ed4b Mon Sep 17 00:00:00 2001 From: Dawer <7803845+iDawer@users.noreply.github.com> Date: Thu, 6 May 2021 10:06:52 +0500 Subject: [PATCH 2/6] Adapt to a new rowan borrowing node API. --- crates/syntax/src/algo.rs | 2 +- crates/syntax/src/ast/make.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index c9229c4e07d..ba263be0dbd 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs @@ -555,7 +555,7 @@ impl SyntaxRewriter<'_> { fn element_to_green(element: SyntaxElement) -> NodeOrToken { match element { - NodeOrToken::Node(it) => NodeOrToken::Node(it.green()), + NodeOrToken::Node(it) => NodeOrToken::Node(it.green().into_owned()), NodeOrToken::Token(it) => NodeOrToken::Token(it.green().to_owned()), } } diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 42da0960615..4bcea28cca8 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs @@ -572,7 +572,7 @@ fn ast_from_text(text: &str) -> N { } fn unroot(n: SyntaxNode) -> SyntaxNode { - SyntaxNode::new_root(n.green()) + SyntaxNode::new_root(n.green().into()) } pub mod tokens { From d7e169fe55a15dd684e7a93dd111c66ed49ed949 Mon Sep 17 00:00:00 2001 From: Dawer <7803845+iDawer@users.noreply.github.com> Date: Thu, 6 May 2021 10:07:06 +0500 Subject: [PATCH 3/6] Borrow text from nodes of immutable syntax trees --- crates/syntax/src/ast/node_ext.rs | 36 +++++++++++++++++++++-------- crates/syntax/src/token_text.rs | 38 ++++++++++++++++++------------- 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 492fbc4a0fb..8e6d7b092f1 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -1,10 +1,11 @@ //! Various extension methods to ast Nodes, which are hard to code-generate. //! Extensions for various expressions live in a sibling `expr_extensions` module. -use std::{fmt, iter::successors}; +use std::{borrow::Cow, fmt, iter::successors}; use itertools::Itertools; use parser::SyntaxKind; +use rowan::{GreenNodeData, GreenTokenData, NodeOrToken}; use crate::{ ast::{self, support, AstNode, AstToken, AttrsOwner, NameOwner, SyntaxNode}, @@ -12,19 +13,19 @@ use crate::{ }; impl ast::Lifetime { - pub fn text(&self) -> TokenText { + pub fn text(&self) -> TokenText<'_> { text_of_first_token(self.syntax()) } } impl ast::Name { - pub fn text(&self) -> TokenText { + pub fn text(&self) -> TokenText<'_> { text_of_first_token(self.syntax()) } } impl ast::NameRef { - pub fn text(&self) -> TokenText { + pub fn text(&self) -> TokenText<'_> { text_of_first_token(self.syntax()) } @@ -33,11 +34,28 @@ impl ast::NameRef { } } -fn text_of_first_token(node: &SyntaxNode) -> TokenText { - let first_token = - node.green().children().next().and_then(|it| it.into_token()).unwrap().to_owned(); +fn _text_of_first_token(node: &SyntaxNode) -> Cow<'_, str> { + fn cow_map &str>(green: Cow, f: F) -> Cow { + match green { + Cow::Borrowed(green_ref) => Cow::Borrowed(f(green_ref)), + Cow::Owned(green) => Cow::Owned(f(&green).to_owned()), + } + } - TokenText(first_token) + cow_map(node.green(), |green_ref| { + green_ref.children().next().and_then(NodeOrToken::into_token).unwrap().text() + }) +} + +fn text_of_first_token(node: &SyntaxNode) -> TokenText<'_> { + fn first_token(green_ref: &GreenNodeData) -> &GreenTokenData { + green_ref.children().next().and_then(NodeOrToken::into_token).unwrap() + } + + match node.green() { + Cow::Borrowed(green_ref) => TokenText::Borrowed(first_token(green_ref).text()), + Cow::Owned(green) => TokenText::Owned(first_token(&green).to_owned()), + } } #[derive(Debug, PartialEq, Eq, Clone)] @@ -412,7 +430,7 @@ impl fmt::Display for NameOrNameRef { } impl NameOrNameRef { - pub fn text(&self) -> TokenText { + pub fn text(&self) -> TokenText<'_> { match self { NameOrNameRef::Name(name) => name.text(), NameOrNameRef::NameRef(name_ref) => name_ref.text(), diff --git a/crates/syntax/src/token_text.rs b/crates/syntax/src/token_text.rs index d2ed0a12a46..e29f4eea402 100644 --- a/crates/syntax/src/token_text.rs +++ b/crates/syntax/src/token_text.rs @@ -2,75 +2,81 @@ use std::{cmp::Ordering, fmt, ops}; -pub struct TokenText(pub(crate) rowan::GreenToken); +pub enum TokenText<'a> { + Borrowed(&'a str), + Owned(rowan::GreenToken), +} -impl TokenText { +impl TokenText<'_> { pub fn as_str(&self) -> &str { - self.0.text() + match self { + TokenText::Borrowed(it) => *it, + TokenText::Owned(green) => green.text(), + } } } -impl ops::Deref for TokenText { +impl ops::Deref for TokenText<'_> { type Target = str; fn deref(&self) -> &str { self.as_str() } } -impl AsRef for TokenText { +impl AsRef for TokenText<'_> { fn as_ref(&self) -> &str { self.as_str() } } -impl From for String { +impl From> for String { fn from(token_text: TokenText) -> Self { token_text.as_str().into() } } -impl PartialEq<&'_ str> for TokenText { +impl PartialEq<&'_ str> for TokenText<'_> { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } -impl PartialEq for &'_ str { +impl PartialEq> for &'_ str { fn eq(&self, other: &TokenText) -> bool { other == self } } -impl PartialEq for TokenText { +impl PartialEq for TokenText<'_> { fn eq(&self, other: &String) -> bool { self.as_str() == other.as_str() } } -impl PartialEq for String { +impl PartialEq> for String { fn eq(&self, other: &TokenText) -> bool { other == self } } -impl PartialEq for TokenText { +impl PartialEq for TokenText<'_> { fn eq(&self, other: &TokenText) -> bool { self.as_str() == other.as_str() } } -impl Eq for TokenText {} -impl Ord for TokenText { +impl Eq for TokenText<'_> {} +impl Ord for TokenText<'_> { fn cmp(&self, other: &Self) -> Ordering { self.as_str().cmp(other.as_str()) } } -impl PartialOrd for TokenText { +impl PartialOrd for TokenText<'_> { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl fmt::Display for TokenText { +impl fmt::Display for TokenText<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(self.as_str(), f) } } -impl fmt::Debug for TokenText { +impl fmt::Debug for TokenText<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(self.as_str(), f) } From d9b4ac81285985f384d1a9f0708ba54434b7f231 Mon Sep 17 00:00:00 2001 From: Dawer <7803845+iDawer@users.noreply.github.com> Date: Thu, 6 May 2021 10:07:06 +0500 Subject: [PATCH 4/6] Clean up --- crates/syntax/src/ast/node_ext.rs | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 8e6d7b092f1..88f9a0e978f 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -5,11 +5,11 @@ use std::{borrow::Cow, fmt, iter::successors}; use itertools::Itertools; use parser::SyntaxKind; -use rowan::{GreenNodeData, GreenTokenData, NodeOrToken}; +use rowan::{GreenNodeData, GreenTokenData}; use crate::{ ast::{self, support, AstNode, AstToken, AttrsOwner, NameOwner, SyntaxNode}, - SmolStr, SyntaxElement, SyntaxToken, TokenText, T, + NodeOrToken, SmolStr, SyntaxElement, SyntaxToken, TokenText, T, }; impl ast::Lifetime { @@ -34,19 +34,6 @@ impl ast::NameRef { } } -fn _text_of_first_token(node: &SyntaxNode) -> Cow<'_, str> { - fn cow_map &str>(green: Cow, f: F) -> Cow { - match green { - Cow::Borrowed(green_ref) => Cow::Borrowed(f(green_ref)), - Cow::Owned(green) => Cow::Owned(f(&green).to_owned()), - } - } - - cow_map(node.green(), |green_ref| { - green_ref.children().next().and_then(NodeOrToken::into_token).unwrap().text() - }) -} - fn text_of_first_token(node: &SyntaxNode) -> TokenText<'_> { fn first_token(green_ref: &GreenNodeData) -> &GreenTokenData { green_ref.children().next().and_then(NodeOrToken::into_token).unwrap() From 0a156c80af8df24543323bdf47d75c5a339cfe48 Mon Sep 17 00:00:00 2001 From: Dawer <7803845+iDawer@users.noreply.github.com> Date: Thu, 6 May 2021 10:07:06 +0500 Subject: [PATCH 5/6] Hide implementation details of TokenText --- crates/syntax/src/ast/node_ext.rs | 4 ++-- crates/syntax/src/token_text.rs | 24 ++++++++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 88f9a0e978f..bef49238f57 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -40,8 +40,8 @@ fn text_of_first_token(node: &SyntaxNode) -> TokenText<'_> { } match node.green() { - Cow::Borrowed(green_ref) => TokenText::Borrowed(first_token(green_ref).text()), - Cow::Owned(green) => TokenText::Owned(first_token(&green).to_owned()), + Cow::Borrowed(green_ref) => TokenText::borrowed(first_token(green_ref).text()), + Cow::Owned(green) => TokenText::owned(first_token(&green).to_owned()), } } diff --git a/crates/syntax/src/token_text.rs b/crates/syntax/src/token_text.rs index e29f4eea402..f3e8b321a7e 100644 --- a/crates/syntax/src/token_text.rs +++ b/crates/syntax/src/token_text.rs @@ -2,16 +2,28 @@ use std::{cmp::Ordering, fmt, ops}; -pub enum TokenText<'a> { +use rowan::GreenToken; + +pub struct TokenText<'a>(pub(crate) Repr<'a>); + +pub(crate) enum Repr<'a> { Borrowed(&'a str), - Owned(rowan::GreenToken), + Owned(GreenToken), } -impl TokenText<'_> { +impl<'a> TokenText<'a> { + pub(crate) fn borrowed(text: &'a str) -> Self { + TokenText(Repr::Borrowed(text)) + } + + pub(crate) fn owned(green: GreenToken) -> Self { + TokenText(Repr::Owned(green)) + } + pub fn as_str(&self) -> &str { - match self { - TokenText::Borrowed(it) => *it, - TokenText::Owned(green) => green.text(), + match self.0 { + Repr::Borrowed(it) => it, + Repr::Owned(ref green) => green.text(), } } } From 90a5dca0a2dbb858ee34eb7de06de8a1cad9e488 Mon Sep 17 00:00:00 2001 From: Dawer <7803845+iDawer@users.noreply.github.com> Date: Thu, 6 May 2021 10:22:51 +0500 Subject: [PATCH 6/6] Fix build --- crates/hir_expand/src/db.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index 3e9abd8a195..d61f4b31a49 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs @@ -283,7 +283,7 @@ fn macro_arg_text(db: &dyn AstDatabase, id: MacroCallId) -> Option { }; let loc = db.lookup_intern_macro(id); let arg = loc.kind.arg(db)?; - Some(arg.green()) + Some(arg.green().into()) } fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option> {