diff --git a/Cargo.lock b/Cargo.lock index e933598fb92c..dabfe21e7f06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,11 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "ahash" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35b909d1c126f78ace756fc337133356c499eebeefcce930fa5fb018823f2b2d" + [[package]] name = "aho-corasick" version = "0.7.10" @@ -330,6 +336,16 @@ dependencies = [ "log", ] +[[package]] +name = "erasable" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c18404d99ecdee16598948437ef1a18b94c74f4d3a374cd41f642626c2c57cd8" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "filetime" version = "0.2.9" @@ -436,6 +452,16 @@ dependencies = [ "scroll", ] +[[package]] +name = "hashbrown" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96282e96bfcd3da0d3aa9938bedf1e50df3269b6db08b4876d2da0bb1a0841cf" +dependencies = [ + "ahash", + "autocfg", +] + [[package]] name = "heck" version = "0.3.1" @@ -883,6 +909,17 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "ptr-union" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72879a26de5e77411f27a863b96c364f67bb0c0593b8e8fe384c3336ab935c9f" +dependencies = [ + "autocfg", + "erasable", + "paste", +] + [[package]] name = "quote" version = "1.0.3" @@ -1282,6 +1319,16 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "rc-borrow" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7bdd8c212bc511390dda00c5efc91ea7f7dcbd17d6f321d48eb6b7c3566ccbc" +dependencies = [ + "autocfg", + "erasable", +] + [[package]] name = "redox_syscall" version = "0.1.56" @@ -1323,14 +1370,12 @@ dependencies = [ [[package]] name = "rowan" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e081ed6eacce09e243b619ab90f069c27b0cff8a6d0eb8ad2ec935b65853798" +version = "0.11.0" dependencies = [ - "rustc-hash", - "smol_str", + "erasable", + "rc-borrow", + "sorbus", "text-size", - "thin-dst", ] [[package]] @@ -1544,6 +1589,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +[[package]] +name = "slice-dst" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac98499b6248e831d6818a8963aa8885a5854ddeb89ee569518ff6f3bf959d9" +dependencies = [ + "autocfg", + "erasable", +] + [[package]] name = "smallvec" version = "1.4.0" @@ -1559,6 +1614,19 @@ dependencies = [ "serde", ] +[[package]] +name = "sorbus" +version = "0.1.0" +source = "git+https://github.com/CAD97/sorbus.git#470f6fd77006e40139303e8c8bc7646361b76a5b" +dependencies = [ + "erasable", + "hashbrown", + "ptr-union", + "rc-borrow", + "slice-dst", + "text-size", +] + [[package]] name = "stdx" version = "0.1.0" @@ -1630,12 +1698,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f03e7efdedc3bc78cb2337f1e2785c39e45f5ef762d9e4ebb137fff7380a6d8a" -[[package]] -name = "thin-dst" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c46be180f1af9673ebb27bc1235396f61ef6965b3fe0dbb2e624deb604f0e" - [[package]] name = "thread_local" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index c034e24244e0..c9077b6db013 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ opt-level = 0 opt-level = 0 [patch.'crates-io'] -# rowan = { path = "../rowan" } +rowan = { path = "../rowan" } [patch.'https://github.com/rust-lang/chalk.git'] # chalk-solve = { path = "../chalk/chalk-solve" } diff --git a/crates/ra_assists/src/handlers/add_custom_impl.rs b/crates/ra_assists/src/handlers/add_custom_impl.rs index 4ea26a55082c..e0b97e5aa717 100644 --- a/crates/ra_assists/src/handlers/add_custom_impl.rs +++ b/crates/ra_assists/src/handlers/add_custom_impl.rs @@ -29,24 +29,21 @@ pub(crate) fn add_custom_impl(ctx: AssistCtx) -> Option { let input = ctx.find_node_at_offset::()?; let attr = input.syntax().parent().and_then(ast::Attr::cast)?; - let attr_name = attr + let attr_node = attr .syntax() .descendants_with_tokens() .filter(|t| t.kind() == IDENT) .find_map(|i| i.into_token()) - .filter(|t| *t.text() == "derive")? - .text() - .clone(); + .filter(|t| t.text() == "derive")?; + let attr_name = attr_node.text(); - let trait_token = - ctx.token_at_offset().find(|t| t.kind() == IDENT && *t.text() != attr_name)?; + let trait_token = ctx.token_at_offset().find(|t| t.kind() == IDENT && t.text() != attr_name)?; let annotated = attr.syntax().siblings(Direction::Next).find_map(ast::Name::cast)?; let annotated_name = annotated.syntax().text().to_string(); let start_offset = annotated.syntax().parent()?.text_range().end(); - let label = - format!("Add custom impl '{}' for '{}'", trait_token.text().as_str(), annotated_name); + let label = format!("Add custom impl '{}' for '{}'", trait_token.text(), annotated_name); ctx.add_assist(AssistId("add_custom_impl"), label, |edit| { edit.target(attr.syntax().text_range()); @@ -55,7 +52,7 @@ pub(crate) fn add_custom_impl(ctx: AssistCtx) -> Option { .syntax() .descendants_with_tokens() .filter(|t| t.kind() == IDENT) - .filter_map(|t| t.into_token().map(|t| t.text().clone())) + .filter_map(|t| t.into_token().map(|t| SmolStr::from(t.text()))) .filter(|t| t != trait_token.text()) .collect::>(); let has_more_derives = !new_attr_input.is_empty(); @@ -63,7 +60,7 @@ pub(crate) fn add_custom_impl(ctx: AssistCtx) -> Option { let mut buf = String::new(); buf.push_str("\n\nimpl "); - buf.push_str(trait_token.text().as_str()); + buf.push_str(trait_token.text()); buf.push_str(" for "); buf.push_str(annotated_name.as_str()); buf.push_str(" {\n"); diff --git a/crates/ra_assists/src/handlers/add_impl.rs b/crates/ra_assists/src/handlers/add_impl.rs index d26f8b93da00..a8f2599fb7bd 100644 --- a/crates/ra_assists/src/handlers/add_impl.rs +++ b/crates/ra_assists/src/handlers/add_impl.rs @@ -1,6 +1,6 @@ use ra_syntax::{ ast::{self, AstNode, NameOwner, TypeParamsOwner}, - TextSize, + SmolStr, TextSize, }; use stdx::{format_to, SepBy}; @@ -28,7 +28,7 @@ use crate::{Assist, AssistCtx, AssistId}; pub(crate) fn add_impl(ctx: AssistCtx) -> Option { let nominal = ctx.find_node_at_offset::()?; let name = nominal.name()?; - ctx.add_assist(AssistId("add_impl"), format!("Implement {}", name.text().as_str()), |edit| { + ctx.add_assist(AssistId("add_impl"), format!("Implement {}", name.text()), |edit| { edit.target(nominal.syntax().text_range()); let type_params = nominal.type_param_list(); let start_offset = nominal.syntax().text_range().end(); @@ -38,14 +38,16 @@ pub(crate) fn add_impl(ctx: AssistCtx) -> Option { format_to!(buf, "{}", type_params.syntax()); } buf.push_str(" "); - buf.push_str(name.text().as_str()); + buf.push_str(name.text()); if let Some(type_params) = type_params { let lifetime_params = type_params .lifetime_params() .filter_map(|it| it.lifetime_token()) - .map(|it| it.text().clone()); - let type_params = - type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone()); + .map(|it| SmolStr::from(it.text())); + let type_params = type_params + .type_params() + .filter_map(|it| it.name()) + .map(|it| SmolStr::from(it.text())); let generic_params = lifetime_params.chain(type_params).sep_by(", "); format_to!(buf, "<{}>", generic_params) diff --git a/crates/ra_assists/src/handlers/add_missing_impl_members.rs b/crates/ra_assists/src/handlers/add_missing_impl_members.rs index 2d6d44980e18..cf0b7b0f440c 100644 --- a/crates/ra_assists/src/handlers/add_missing_impl_members.rs +++ b/crates/ra_assists/src/handlers/add_missing_impl_members.rs @@ -112,7 +112,7 @@ fn add_missing_impl_members_inner( ast::ImplItem::TypeAliasDef(def) => def.name(), ast::ImplItem::ConstDef(def) => def.name(), } - .map(|it| it.text().clone()) + .map(|it| it.text().into()) }; let missing_items = get_missing_impl_items(&ctx.sema, &impl_node) diff --git a/crates/ra_assists/src/handlers/add_new.rs b/crates/ra_assists/src/handlers/add_new.rs index 0f9174a29952..dd173ef05e7f 100644 --- a/crates/ra_assists/src/handlers/add_new.rs +++ b/crates/ra_assists/src/handlers/add_new.rs @@ -3,7 +3,7 @@ use ra_syntax::{ ast::{ self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner, }, - TextSize, T, + SmolStr, TextSize, T, }; use stdx::{format_to, SepBy}; @@ -101,14 +101,14 @@ fn generate_impl_text(strukt: &ast::StructDef, code: &str) -> String { format_to!(buf, "{}", type_params.syntax()); } buf.push_str(" "); - buf.push_str(strukt.name().unwrap().text().as_str()); + buf.push_str(strukt.name().unwrap().text()); if let Some(type_params) = type_params { let lifetime_params = type_params .lifetime_params() .filter_map(|it| it.lifetime_token()) - .map(|it| it.text().clone()); + .map(|it| SmolStr::from(it.text())); let type_params = - type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone()); + type_params.type_params().filter_map(|it| it.name()).map(|it| SmolStr::from(it.text())); format_to!(buf, "<{}>", lifetime_params.chain(type_params).sep_by(", ")) } diff --git a/crates/ra_assists/src/handlers/raw_string.rs b/crates/ra_assists/src/handlers/raw_string.rs index 567400b9c274..400f55f4cd99 100644 --- a/crates/ra_assists/src/handlers/raw_string.rs +++ b/crates/ra_assists/src/handlers/raw_string.rs @@ -103,7 +103,7 @@ pub(crate) fn add_hash(ctx: AssistCtx) -> Option { // ``` pub(crate) fn remove_hash(ctx: AssistCtx) -> Option { let token = ctx.find_token_at_offset(RAW_STRING)?; - let text = token.text().as_str(); + let text = token.text(); if text.starts_with("r\"") { // no hash to remove return None; diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs index e60f879a3935..57ae812b45f5 100644 --- a/crates/ra_hir_expand/src/builtin_derive.rs +++ b/crates/ra_hir_expand/src/builtin_derive.rs @@ -90,7 +90,7 @@ fn parse_adt(tt: &tt::Subtree) -> Result { debug!("name token not found"); mbe::ExpandError::ConversionError })?; - let name_token = tt::Ident { id: name_token_id, text: name.text().clone() }; + let name_token = tt::Ident { id: name_token_id, text: name.text().into() }; let type_params = params.map_or(0, |type_param_list| type_param_list.type_params().count()); Ok(BasicAdtInfo { name: name_token, type_params }) } diff --git a/crates/ra_hir_expand/src/name.rs b/crates/ra_hir_expand/src/name.rs index fecce224ee60..e4119530bbdc 100644 --- a/crates/ra_hir_expand/src/name.rs +++ b/crates/ra_hir_expand/src/name.rs @@ -43,12 +43,12 @@ impl Name { } /// Resolve a name from the text of token. - fn resolve(raw_text: &SmolStr) -> Name { + fn resolve(raw_text: &str) -> Name { let raw_start = "r#"; - if raw_text.as_str().starts_with(raw_start) { + if raw_text.starts_with(raw_start) { Name::new_text(SmolStr::new(&raw_text[raw_start.len()..])) } else { - Name::new_text(raw_text.clone()) + Name::new_text(raw_text.into()) } } diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs index 914a8b471e3f..c4c9a99be8b7 100644 --- a/crates/ra_ide/src/display/navigation_target.rs +++ b/crates/ra_ide/src/display/navigation_target.rs @@ -132,7 +132,7 @@ impl NavigationTarget { description: Option, ) -> NavigationTarget { //FIXME: use `_` instead of empty string - let name = node.value.name().map(|it| it.text().clone()).unwrap_or_default(); + let name = node.value.name().map(|it| SmolStr::from(it.text())).unwrap_or_default(); let focus_range = node.value.name().map(|it| original_range(db, node.with_value(it.syntax())).range); let frange = original_range(db, node.map(|it| it.syntax())); diff --git a/crates/ra_ide/src/display/short_label.rs b/crates/ra_ide/src/display/short_label.rs index 4b081bf6c606..591b61b9a9b7 100644 --- a/crates/ra_ide/src/display/short_label.rs +++ b/crates/ra_ide/src/display/short_label.rs @@ -92,6 +92,6 @@ where { let mut buf = node.visibility().map(|v| format!("{} ", v.syntax())).unwrap_or_default(); buf.push_str(label); - buf.push_str(node.name()?.text().as_str()); + buf.push_str(node.name()?.text()); Some(buf) } diff --git a/crates/ra_ide/src/extend_selection.rs b/crates/ra_ide/src/extend_selection.rs index 554594a436ce..04da3a520005 100644 --- a/crates/ra_ide/src/extend_selection.rs +++ b/crates/ra_ide/src/extend_selection.rs @@ -205,8 +205,8 @@ fn extend_ws(root: &SyntaxNode, ws: SyntaxToken, offset: TextSize) -> TextRange let ws_text = ws.text(); let suffix = TextRange::new(offset, ws.text_range().end()) - ws.text_range().start(); let prefix = TextRange::new(ws.text_range().start(), offset) - ws.text_range().start(); - let ws_suffix = &ws_text.as_str()[suffix]; - let ws_prefix = &ws_text.as_str()[prefix]; + let ws_suffix = &ws_text[suffix]; + let ws_prefix = &ws_text[prefix]; if ws_text.contains('\n') && !ws_suffix.contains('\n') { if let Some(node) = ws.next_sibling_or_token() { let start = match ws_prefix.rfind('\n') { diff --git a/crates/ra_ide/src/join_lines.rs b/crates/ra_ide/src/join_lines.rs index fde0bfa98b34..59ee07ef7ee3 100644 --- a/crates/ra_ide/src/join_lines.rs +++ b/crates/ra_ide/src/join_lines.rs @@ -52,7 +52,7 @@ fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextS // The node is either the first or the last in the file let suff = &token.text()[TextRange::new( offset - token.text_range().start() + TextSize::of('\n'), - TextSize::of(token.text().as_str()), + TextSize::of(token.text()), )]; let spaces = suff.bytes().take_while(|&b| b == b' ').count(); diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 6658c7bb270e..5bb3d2d30c54 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs @@ -201,7 +201,7 @@ pub(crate) fn highlight( if let Some(name) = fmt_macro_call.path().and_then(|p| p.segment()).and_then(|s| s.name_ref()) { - match name.text().as_str() { + match name.text() { "format_args" | "format_args_nl" => { format_string = parent .children_with_tokens() diff --git a/crates/ra_ide_db/src/symbol_index.rs b/crates/ra_ide_db/src/symbol_index.rs index 95be11134554..d2b9e49e8941 100644 --- a/crates/ra_ide_db/src/symbol_index.rs +++ b/crates/ra_ide_db/src/symbol_index.rs @@ -349,7 +349,7 @@ fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> { fn decl(node: N) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> { let name = node.name()?; let name_range = name.syntax().text_range(); - let name = name.text().clone(); + let name = name.text().into(); let ptr = SyntaxNodePtr::new(node.syntax()); Some((name, ptr, name_range)) diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index bb28acfd95d8..47f2f110a9cf 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs @@ -503,7 +503,7 @@ impl SrcToken for SynToken { } } fn to_text(&self) -> SmolStr { - self.token().text().clone() + self.token().text().into() } } @@ -672,9 +672,9 @@ impl<'a> TreeSink for TtTreeSink<'a> { self.text_pos += TextSize::of(text.as_str()); } - let text = SmolStr::new(self.buf.as_str()); - self.buf.clear(); + let text = self.buf.as_str(); self.inner.token(kind, text); + self.buf.clear(); // Add whitespace between adjoint puncts let next = last.bump(); diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml index 7ffe46c6994f..d5536b4abb87 100644 --- a/crates/ra_syntax/Cargo.toml +++ b/crates/ra_syntax/Cargo.toml @@ -12,7 +12,7 @@ doctest = false [dependencies] itertools = "0.9.0" -rowan = "0.10.0" +rowan = "0.11.0" rustc_lexer = { version = "652.0.0", package = "rustc-ap-rustc_lexer" } rustc-hash = "1.1.0" arrayvec = "0.5.1" diff --git a/crates/ra_syntax/src/algo.rs b/crates/ra_syntax/src/algo.rs index 2a8dac757b61..3f13baae5f7b 100644 --- a/crates/ra_syntax/src/algo.rs +++ b/crates/ra_syntax/src/algo.rs @@ -3,6 +3,7 @@ use std::{ fmt, ops::{self, RangeInclusive}, + sync::Arc, }; use itertools::Itertools; @@ -10,8 +11,8 @@ use ra_text_edit::TextEditBuilder; use rustc_hash::FxHashMap; use crate::{ - AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxNodePtr, - SyntaxToken, TextRange, TextSize, + ArcBorrow, AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, + SyntaxNodePtr, SyntaxToken, TextRange, TextSize, }; /// Returns ancestors of the node at the offset, sorted by length. This should @@ -186,9 +187,10 @@ fn _insert_children( to_green_element(element) }); - let mut old_children = parent.green().children().map(|it| match it { - NodeOrToken::Token(it) => NodeOrToken::Token(it.clone()), - NodeOrToken::Node(it) => NodeOrToken::Node(it.clone()), + let green = parent.green(); + let mut old_children = green.children().map(|it| match it { + NodeOrToken::Token(it) => NodeOrToken::Token(ArcBorrow::upgrade(it)), + NodeOrToken::Node(it) => NodeOrToken::Node(ArcBorrow::upgrade(it)), }); let new_children = match &position { @@ -225,9 +227,10 @@ fn _replace_children( ) -> SyntaxNode { let start = position_of_child(parent, to_delete.start().clone()); let end = position_of_child(parent, to_delete.end().clone()); - let mut old_children = parent.green().children().map(|it| match it { - NodeOrToken::Token(it) => NodeOrToken::Token(it.clone()), - NodeOrToken::Node(it) => NodeOrToken::Node(it.clone()), + let green = parent.green(); + let mut old_children = green.children().map(|it| match it { + NodeOrToken::Token(it) => NodeOrToken::Token(ArcBorrow::upgrade(it)), + NodeOrToken::Node(it) => NodeOrToken::Node(ArcBorrow::upgrade(it)), }); let before = old_children.by_ref().take(start).collect::>(); @@ -310,21 +313,23 @@ impl<'a> SyntaxRewriter<'a> { fn rewrite_self( &self, element: &SyntaxElement, - ) -> Option> { + ) -> Option, Arc>> { if let Some(replacement) = self.replacement(&element) { return match replacement { Replacement::Single(NodeOrToken::Node(it)) => { - Some(NodeOrToken::Node(it.green().clone())) + Some(NodeOrToken::Node(ArcBorrow::upgrade(it.green()))) } Replacement::Single(NodeOrToken::Token(it)) => { - Some(NodeOrToken::Token(it.green().clone())) + Some(NodeOrToken::Token(ArcBorrow::upgrade(it.green()))) } Replacement::Delete => None, }; } let res = match element { - NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()), - NodeOrToken::Node(it) => NodeOrToken::Node(self.rewrite_children(it).green().clone()), + NodeOrToken::Token(it) => NodeOrToken::Token(ArcBorrow::upgrade(it.green())), + NodeOrToken::Node(it) => { + NodeOrToken::Node(ArcBorrow::upgrade(self.rewrite_children(it).green())) + } }; Some(res) } @@ -345,7 +350,7 @@ enum Replacement { fn with_children( parent: &SyntaxNode, - new_children: Vec>, + new_children: Vec, Arc>>, ) -> SyntaxNode { let len = new_children.iter().map(|it| it.text_len()).sum::(); let new_node = rowan::GreenNode::new(rowan::SyntaxKind(parent.kind() as u16), new_children); @@ -366,9 +371,11 @@ fn position_of_child(parent: &SyntaxNode, child: SyntaxElement) -> usize { .expect("element is not a child of current element") } -fn to_green_element(element: SyntaxElement) -> NodeOrToken { +fn to_green_element( + element: SyntaxElement, +) -> NodeOrToken, Arc> { match element { - NodeOrToken::Node(it) => it.green().clone().into(), - NodeOrToken::Token(it) => it.green().clone().into(), + NodeOrToken::Node(it) => ArcBorrow::upgrade(it.green()).into(), + NodeOrToken::Token(it) => ArcBorrow::upgrade(it.green()).into(), } } diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index a716e525b952..210b7fb9ae93 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -12,7 +12,7 @@ use std::marker::PhantomData; use crate::{ syntax_node::{SyntaxNode, SyntaxNodeChildren, SyntaxToken}, - SmolStr, SyntaxKind, + SyntaxKind, }; pub use self::{ @@ -54,7 +54,7 @@ pub trait AstToken { fn syntax(&self) -> &SyntaxToken; - fn text(&self) -> &SmolStr { + fn text(&self) -> &str { self.syntax().text() } } diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs index f2ea5088e7ab..9bbf49d53b56 100644 --- a/crates/ra_syntax/src/ast/extensions.rs +++ b/crates/ra_syntax/src/ast/extensions.rs @@ -8,17 +8,17 @@ use ra_parser::SyntaxKind; use crate::{ ast::{self, support, AstNode, AttrInput, NameOwner, SyntaxNode}, - SmolStr, SyntaxElement, SyntaxToken, T, + ArcBorrow, SmolStr, SyntaxElement, SyntaxToken, T, }; impl ast::Name { - pub fn text(&self) -> &SmolStr { + pub fn text(&self) -> &str { text_of_first_token(self.syntax()) } } impl ast::NameRef { - pub fn text(&self) -> &SmolStr { + pub fn text(&self) -> &str { text_of_first_token(self.syntax()) } @@ -27,8 +27,10 @@ impl ast::NameRef { } } -fn text_of_first_token(node: &SyntaxNode) -> &SmolStr { - node.green().children().next().and_then(|it| it.into_token()).unwrap().text() +fn text_of_first_token(node: &SyntaxNode) -> &str { + let green = ArcBorrow::downgrade(node.green()); + let token = ArcBorrow::downgrade(green.children().next().unwrap().into_token().unwrap()); + token.text() } #[derive(Debug, Clone, PartialEq, Eq)] @@ -67,7 +69,7 @@ impl ast::Attr { pub fn simple_name(&self) -> Option { let path = self.path()?; match (path.segment(), path.qualifier()) { - (Some(segment), None) => Some(segment.syntax().first_token()?.text().clone()), + (Some(segment), None) => Some(segment.syntax().first_token()?.text().into()), _ => None, } } diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs index ee0f5cc406a4..3a0acb6e983b 100644 --- a/crates/ra_syntax/src/ast/make.rs +++ b/crates/ra_syntax/src/ast/make.rs @@ -3,7 +3,7 @@ use itertools::Itertools; use stdx::format_to; -use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken}; +use crate::{ast, ArcBorrow, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken}; pub fn name(text: &str) -> ast::Name { ast_from_text(&format!("mod {};", text)) @@ -328,7 +328,7 @@ fn try_ast_from_text(text: &str) -> Option { } fn unroot(n: SyntaxNode) -> SyntaxNode { - SyntaxNode::new_root(n.green().clone()) + SyntaxNode::new_root(ArcBorrow::upgrade(n.green())) } pub mod tokens { @@ -345,7 +345,7 @@ pub mod tokens { .syntax() .descendants_with_tokens() .filter_map(|it| it.into_token()) - .find(|it| it.kind() == WHITESPACE && it.text().as_str() == " ") + .find(|it| it.kind() == WHITESPACE && it.text() == " ") .unwrap() } @@ -373,7 +373,7 @@ pub mod tokens { .syntax() .descendants_with_tokens() .filter_map(|it| it.into_token()) - .find(|it| it.kind() == WHITESPACE && it.text().as_str() == "\n") + .find(|it| it.kind() == WHITESPACE && it.text() == "\n") .unwrap() } diff --git a/crates/ra_syntax/src/ast/tokens.rs b/crates/ra_syntax/src/ast/tokens.rs index 74906d8a62ef..16f6e3668894 100644 --- a/crates/ra_syntax/src/ast/tokens.rs +++ b/crates/ra_syntax/src/ast/tokens.rs @@ -111,7 +111,7 @@ impl QuoteOffsets { pub trait HasQuotes: AstToken { fn quote_offsets(&self) -> Option { - let text = self.text().as_str(); + let text = self.text(); let offsets = QuoteOffsets::new(text)?; let o = self.syntax().text_range().start(); let offsets = QuoteOffsets { @@ -142,7 +142,7 @@ pub trait HasStringValue: HasQuotes { impl HasStringValue for String { fn value(&self) -> Option { - let text = self.text().as_str(); + let text = self.text(); let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()]; let mut buf = std::string::String::with_capacity(text.len()); @@ -161,7 +161,7 @@ impl HasStringValue for String { impl HasStringValue for RawString { fn value(&self) -> Option { - let text = self.text().as_str(); + let text = self.text(); let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()]; Some(text.to_string()) } @@ -493,7 +493,7 @@ impl HasFormatSpecifier for String { fn char_ranges( &self, ) -> Option)>> { - let text = self.text().as_str(); + let text = self.text(); let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()]; let offset = self.text_range_between_quotes()?.start() - self.syntax().text_range().start(); @@ -514,7 +514,7 @@ impl HasFormatSpecifier for RawString { fn char_ranges( &self, ) -> Option)>> { - let text = self.text().as_str(); + let text = self.text(); let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()]; let offset = self.text_range_between_quotes()?.start() - self.syntax().text_range().start(); diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs index bfc05e08bf24..ecc80f1a3a4e 100644 --- a/crates/ra_syntax/src/ast/traits.rs +++ b/crates/ra_syntax/src/ast/traits.rs @@ -95,7 +95,7 @@ pub trait DocCommentsOwner: AstNode { has_comments = true; let prefix_len = comment.prefix().len(); - let line: &str = comment.text().as_str(); + let line: &str = comment.text(); // Determine if the prefix or prefix + 1 char is stripped let pos = diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index ceeb2bde9f30..870cf7269be7 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs @@ -55,7 +55,8 @@ pub use crate::{ }, }; pub use ra_parser::{SyntaxKind, T}; -pub use rowan::{SmolStr, SyntaxText, TextRange, TextSize, TokenAtOffset, WalkEvent}; +pub use rowan::{ArcBorrow, SyntaxText, TextRange, TextSize, TokenAtOffset, WalkEvent}; +pub use smol_str::SmolStr; /// `Parse` is the result of the parsing: a syntax tree and a collection of /// errors. @@ -64,7 +65,7 @@ pub use rowan::{SmolStr, SyntaxText, TextRange, TextSize, TokenAtOffset, WalkEve /// files. #[derive(Debug, PartialEq, Eq)] pub struct Parse { - green: GreenNode, + green: Arc, errors: Arc>, _ty: PhantomData T>, } @@ -76,7 +77,7 @@ impl Clone for Parse { } impl Parse { - fn new(green: GreenNode, errors: Vec) -> Parse { + fn new(green: Arc, errors: Vec) -> Parse { Parse { green, errors: Arc::new(errors), _ty: PhantomData } } diff --git a/crates/ra_syntax/src/parsing.rs b/crates/ra_syntax/src/parsing.rs index e5eb808500de..3441569bf04a 100644 --- a/crates/ra_syntax/src/parsing.rs +++ b/crates/ra_syntax/src/parsing.rs @@ -6,6 +6,8 @@ mod text_token_source; mod text_tree_sink; mod reparsing; +use std::sync::Arc; + use crate::{syntax_node::GreenNode, SyntaxError}; use text_token_source::TextTokenSource; use text_tree_sink::TextTreeSink; @@ -14,7 +16,7 @@ pub use lexer::*; pub(crate) use self::reparsing::incremental_reparse; -pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec) { +pub(crate) fn parse_text(text: &str) -> (Arc, Vec) { let (tokens, lexer_errors) = tokenize(&text); let mut token_source = TextTokenSource::new(text, &tokens); diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs index ffff0a7b2026..664eabebf523 100644 --- a/crates/ra_syntax/src/parsing/reparsing.rs +++ b/crates/ra_syntax/src/parsing/reparsing.rs @@ -6,6 +6,8 @@ //! - otherwise, we search for the nearest `{}` block which contains the edit //! and try to parse only this block. +use std::sync::Arc; + use ra_parser::Reparser; use ra_text_edit::AtomTextEdit; @@ -26,7 +28,7 @@ pub(crate) fn incremental_reparse( node: &SyntaxNode, edit: &AtomTextEdit, errors: Vec, -) -> Option<(GreenNode, Vec, TextRange)> { +) -> Option<(Arc, Vec, TextRange)> { if let Some((green, new_errors, old_range)) = reparse_token(node, &edit) { return Some((green, merge_errors(errors, new_errors, old_range, edit), old_range)); } @@ -40,7 +42,7 @@ pub(crate) fn incremental_reparse( fn reparse_token<'node>( root: &'node SyntaxNode, edit: &AtomTextEdit, -) -> Option<(GreenNode, Vec, TextRange)> { +) -> Option<(Arc, Vec, TextRange)> { let prev_token = algo::find_covering_element(root, edit.delete).as_token()?.clone(); let prev_token_kind = prev_token.kind(); match prev_token_kind { @@ -74,8 +76,7 @@ fn reparse_token<'node>( new_text.pop(); } - let new_token = - GreenToken::new(rowan::SyntaxKind(prev_token_kind.into()), new_text.into()); + let new_token = GreenToken::new(rowan::SyntaxKind(prev_token_kind.into()), &new_text); Some(( prev_token.replace_with(new_token), new_err.into_iter().collect(), @@ -89,7 +90,7 @@ fn reparse_token<'node>( fn reparse_block<'node>( root: &'node SyntaxNode, edit: &AtomTextEdit, -) -> Option<(GreenNode, Vec, TextRange)> { +) -> Option<(Arc, Vec, TextRange)> { let (node, reparser) = find_reparsable_node(root, edit.delete)?; let text = get_text_after_edit(node.clone().into(), edit); diff --git a/crates/ra_syntax/src/parsing/text_tree_sink.rs b/crates/ra_syntax/src/parsing/text_tree_sink.rs index 22aed1db16d6..3ac6defbb5d9 100644 --- a/crates/ra_syntax/src/parsing/text_tree_sink.rs +++ b/crates/ra_syntax/src/parsing/text_tree_sink.rs @@ -1,13 +1,13 @@ //! FIXME: write short doc here -use std::mem; +use std::{mem, sync::Arc}; use ra_parser::{ParseError, TreeSink}; use crate::{ parsing::Token, syntax_node::GreenNode, - SmolStr, SyntaxError, + SyntaxError, SyntaxKind::{self, *}, SyntaxTreeBuilder, TextRange, TextSize, }; @@ -103,7 +103,7 @@ impl<'a> TextTreeSink<'a> { } } - pub(super) fn finish(mut self) -> (GreenNode, Vec) { + pub(super) fn finish(mut self) -> (Arc, Vec) { match mem::replace(&mut self.state, State::Normal) { State::PendingFinish => { self.eat_trivias(); @@ -134,7 +134,7 @@ impl<'a> TextTreeSink<'a> { fn do_token(&mut self, kind: SyntaxKind, len: TextSize, n_tokens: usize) { let range = TextRange::at(self.text_pos, len); - let text: SmolStr = self.text[range].into(); + let text = &self.text[range]; self.text_pos += len; self.token_pos += n_tokens; self.inner.token(kind, text); diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs index f9d379abf3c1..aa51b0e7e9a8 100644 --- a/crates/ra_syntax/src/syntax_node.rs +++ b/crates/ra_syntax/src/syntax_node.rs @@ -6,11 +6,13 @@ //! The *real* implementation is in the (language-agnostic) `rowan` crate, this //! module just wraps its API. +use std::sync::Arc; + use rowan::{GreenNodeBuilder, Language}; -use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextSize}; +use crate::{Parse, SyntaxError, SyntaxKind, TextSize}; -pub(crate) use rowan::{GreenNode, GreenToken}; +pub(crate) use rowan::{ArcBorrow, GreenNode, GreenToken}; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum RustLanguage {} @@ -41,7 +43,7 @@ pub struct SyntaxTreeBuilder { } impl SyntaxTreeBuilder { - pub(crate) fn finish_raw(self) -> (GreenNode, Vec) { + pub(crate) fn finish_raw(self) -> (Arc, Vec) { let green = self.inner.finish(); (green, self.errors) } @@ -52,10 +54,10 @@ impl SyntaxTreeBuilder { if cfg!(debug_assertions) { crate::validation::validate_block_structure(&node); } - Parse::new(node.green().clone(), errors) + Parse::new(ArcBorrow::upgrade(node.green()), errors) } - pub fn token(&mut self, kind: SyntaxKind, text: SmolStr) { + pub fn token(&mut self, kind: SyntaxKind, text: &str) { let kind = RustLanguage::kind_to_raw(kind); self.inner.token(kind, text) } diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index 5e93895ec5de..c4afb95c64ce 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs @@ -110,7 +110,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec) { } let token = literal.token(); - let text = token.text().as_str(); + let text = token.text(); // FIXME: lift this lambda refactor to `fn` (https://github.com/rust-analyzer/rust-analyzer/pull/2834#discussion_r366199205) let mut push_err = |prefix_len, (off, err): (usize, unescape::EscapeError)| {