aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r--crates/ra_syntax/Cargo.toml1
-rw-r--r--crates/ra_syntax/src/algo.rs32
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs9
3 files changed, 42 insertions, 0 deletions
diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml
index d3a8b516a..724c38e17 100644
--- a/crates/ra_syntax/Cargo.toml
+++ b/crates/ra_syntax/Cargo.toml
@@ -11,6 +11,7 @@ repository = "https://github.com/rust-analyzer/rust-analyzer"
11itertools = "0.8.0" 11itertools = "0.8.0"
12rowan = "0.6.1" 12rowan = "0.6.1"
13rustc_lexer = "0.1.0" 13rustc_lexer = "0.1.0"
14rustc-hash = "1.0.1"
14 15
15# ideally, `serde` should be enabled by `ra_lsp_server`, but we enable it here 16# ideally, `serde` should be enabled by `ra_lsp_server`, but we enable it here
16# to reduce number of compilations 17# to reduce number of compilations
diff --git a/crates/ra_syntax/src/algo.rs b/crates/ra_syntax/src/algo.rs
index 7ee5aa85b..f0ed96a17 100644
--- a/crates/ra_syntax/src/algo.rs
+++ b/crates/ra_syntax/src/algo.rs
@@ -3,6 +3,7 @@ pub mod visit;
3use std::ops::RangeInclusive; 3use std::ops::RangeInclusive;
4 4
5use itertools::Itertools; 5use itertools::Itertools;
6use rustc_hash::FxHashMap;
6 7
7use crate::{ 8use crate::{
8 AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxNodePtr, TextRange, TextUnit, 9 AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxNodePtr, TextRange, TextUnit,
@@ -123,6 +124,37 @@ pub fn replace_children(
123 with_children(parent, new_children) 124 with_children(parent, new_children)
124} 125}
125 126
127/// Replaces descendants in the node, according to the mapping.
128///
129/// This is a type-unsafe low-level editing API, if you need to use it, prefer
130/// to create a type-safe abstraction on top of it instead.
131pub fn replace_descendants(
132 parent: &SyntaxNode,
133 map: &FxHashMap<SyntaxElement, SyntaxElement>,
134) -> SyntaxNode {
135 // FIXME: this could be made much faster.
136 let new_children = parent.children_with_tokens().map(|it| go(map, it)).collect::<Box<[_]>>();
137 return with_children(parent, new_children);
138
139 fn go(
140 map: &FxHashMap<SyntaxElement, SyntaxElement>,
141 element: SyntaxElement,
142 ) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> {
143 if let Some(replacement) = map.get(&element) {
144 return match replacement {
145 NodeOrToken::Node(it) => NodeOrToken::Node(it.green().clone()),
146 NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()),
147 };
148 }
149 match element {
150 NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()),
151 NodeOrToken::Node(it) => {
152 NodeOrToken::Node(replace_descendants(&it, map).green().clone())
153 }
154 }
155 }
156}
157
126fn with_children( 158fn with_children(
127 parent: &SyntaxNode, 159 parent: &SyntaxNode,
128 new_children: Box<[NodeOrToken<rowan::GreenNode, rowan::GreenToken>]>, 160 new_children: Box<[NodeOrToken<rowan::GreenNode, rowan::GreenToken>]>,
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index d3a375f87..5f7e9f5b1 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -373,6 +373,15 @@ impl ast::LifetimeParam {
373 } 373 }
374} 374}
375 375
376impl ast::TypeParam {
377 pub fn colon_token(&self) -> Option<SyntaxToken> {
378 self.syntax()
379 .children_with_tokens()
380 .filter_map(|it| it.into_token())
381 .find(|it| it.kind() == T![:])
382 }
383}
384
376impl ast::WherePred { 385impl ast::WherePred {
377 pub fn lifetime_token(&self) -> Option<SyntaxToken> { 386 pub fn lifetime_token(&self) -> Option<SyntaxToken> {
378 self.syntax() 387 self.syntax()