aboutsummaryrefslogtreecommitdiff
path: root/crates/assists/src/ast_transform.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/assists/src/ast_transform.rs')
-rw-r--r--crates/assists/src/ast_transform.rs30
1 files changed, 29 insertions, 1 deletions
diff --git a/crates/assists/src/ast_transform.rs b/crates/assists/src/ast_transform.rs
index 5216862ba..835da3bb2 100644
--- a/crates/assists/src/ast_transform.rs
+++ b/crates/assists/src/ast_transform.rs
@@ -18,6 +18,34 @@ pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: N) -> N {
18 .rewrite_ast(&node) 18 .rewrite_ast(&node)
19} 19}
20 20
21/// `AstTransform` helps with applying bulk transformations to syntax nodes.
22///
23/// This is mostly useful for IDE code generation. If you paste some existing
24/// code into a new context (for example, to add method overrides to an `impl`
25/// block), you generally want to appropriately qualify the names, and sometimes
26/// you might want to substitute generic parameters as well:
27///
28/// ```
29/// mod x {
30/// pub struct A;
31/// pub trait T<U> { fn foo(&self, _: U) -> A; }
32/// }
33///
34/// mod y {
35/// use x::T;
36///
37/// impl T<()> for () {
38/// // If we invoke **Add Missing Members** here, we want to copy-paste `foo`.
39/// // But we want a slightly-modified version of it:
40/// fn foo(&self, _: ()) -> x::A {}
41/// }
42/// }
43/// ```
44///
45/// So, a single `AstTransform` describes such function from `SyntaxNode` to
46/// `SyntaxNode`. Note that the API here is a bit too high-order and high-brow.
47/// We'd want to somehow express this concept simpler, but so far nobody got to
48/// simplifying this!
21pub trait AstTransform<'a> { 49pub trait AstTransform<'a> {
22 fn get_substitution(&self, node: &syntax::SyntaxNode) -> Option<syntax::SyntaxNode>; 50 fn get_substitution(&self, node: &syntax::SyntaxNode) -> Option<syntax::SyntaxNode>;
23 51
@@ -166,7 +194,7 @@ impl<'a> QualifyPaths<'a> {
166 .map(|arg_list| apply(self, arg_list)); 194 .map(|arg_list| apply(self, arg_list));
167 if let Some(type_args) = type_args { 195 if let Some(type_args) = type_args {
168 let last_segment = path.segment().unwrap(); 196 let last_segment = path.segment().unwrap();
169 path = path.with_segment(last_segment.with_type_args(type_args)) 197 path = path.with_segment(last_segment.with_generic_args(type_args))
170 } 198 }
171 199
172 Some(path.syntax().clone()) 200 Some(path.syntax().clone())