Skip to content

Commit 01422cc

Browse files
bors[bot]matklad
andauthored
Merge #2856
2856: More orthogonal path editing r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 2f1df3c + ef1326e commit 01422cc

File tree

3 files changed

+54
-19
lines changed

3 files changed

+54
-19
lines changed

crates/ra_assists/src/ast_transform.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use rustc_hash::FxHashMap;
33

44
use hir::{db::HirDatabase, InFile, PathResolution};
5-
use ra_syntax::ast::{self, make, AstNode};
5+
use ra_syntax::ast::{self, AstNode};
66

77
pub trait AstTransform<'a> {
88
fn get_substitution(
@@ -134,11 +134,18 @@ impl<'a, DB: HirDatabase> QualifyPaths<'a, DB> {
134134
match resolution {
135135
PathResolution::Def(def) => {
136136
let found_path = from.find_use_path(self.db, def)?;
137-
let args = p
137+
let mut path = path_to_ast(found_path);
138+
139+
let type_args = p
138140
.segment()
139141
.and_then(|s| s.type_arg_list())
140142
.map(|arg_list| apply(self, node.with_value(arg_list)));
141-
Some(make::path_with_type_arg_list(path_to_ast(found_path), args).syntax().clone())
143+
if let Some(type_args) = type_args {
144+
let last_segment = path.segment().unwrap();
145+
path = path.with_segment(last_segment.with_type_args(type_args))
146+
}
147+
148+
Some(path.syntax().clone())
142149
}
143150
PathResolution::Local(_)
144151
| PathResolution::TypeParam(_)

crates/ra_syntax/src/ast/edit.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,48 @@ impl ast::TypeParam {
207207
}
208208
}
209209

210+
impl ast::Path {
211+
#[must_use]
212+
pub fn with_segment(&self, segment: ast::PathSegment) -> ast::Path {
213+
if let Some(old) = self.segment() {
214+
return replace_children(
215+
self,
216+
single_node(old.syntax().clone()),
217+
iter::once(segment.syntax().clone().into()),
218+
);
219+
}
220+
self.clone()
221+
}
222+
}
223+
224+
impl ast::PathSegment {
225+
#[must_use]
226+
pub fn with_type_args(&self, type_args: ast::TypeArgList) -> ast::PathSegment {
227+
self._with_type_args(type_args, false)
228+
}
229+
230+
#[must_use]
231+
pub fn with_turbo_fish(&self, type_args: ast::TypeArgList) -> ast::PathSegment {
232+
self._with_type_args(type_args, true)
233+
}
234+
235+
fn _with_type_args(&self, type_args: ast::TypeArgList, turbo: bool) -> ast::PathSegment {
236+
if let Some(old) = self.type_arg_list() {
237+
return replace_children(
238+
self,
239+
single_node(old.syntax().clone()),
240+
iter::once(type_args.syntax().clone().into()),
241+
);
242+
}
243+
let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new();
244+
if turbo {
245+
to_insert.push(make::token(T![::]).into());
246+
}
247+
to_insert.push(type_args.syntax().clone().into());
248+
insert_children(self, InsertPosition::Last, to_insert)
249+
}
250+
}
251+
210252
#[must_use]
211253
pub fn strip_attrs_and_docs<N: ast::AttrsOwner>(node: &N) -> N {
212254
N::cast(strip_attrs_and_docs_inner(node.syntax().clone())).unwrap()

crates/ra_syntax/src/ast/make.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! of smaller pieces.
33
use itertools::Itertools;
44

5-
use crate::{algo, ast, AstNode, SourceFile, SyntaxKind, SyntaxToken};
5+
use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxToken};
66

77
pub fn name(text: &str) -> ast::Name {
88
ast_from_text(&format!("mod {};", text))
@@ -21,20 +21,6 @@ pub fn path_qualified(qual: ast::Path, name_ref: ast::NameRef) -> ast::Path {
2121
fn path_from_text(text: &str) -> ast::Path {
2222
ast_from_text(text)
2323
}
24-
pub fn path_with_type_arg_list(path: ast::Path, args: Option<ast::TypeArgList>) -> ast::Path {
25-
if let Some(args) = args {
26-
let syntax = path.syntax();
27-
// FIXME: remove existing type args
28-
let new_syntax = algo::insert_children(
29-
syntax,
30-
crate::algo::InsertPosition::Last,
31-
&mut Some(args).into_iter().map(|n| n.syntax().clone().into()),
32-
);
33-
ast::Path::cast(new_syntax).unwrap()
34-
} else {
35-
path
36-
}
37-
}
3824

3925
pub fn record_field(name: ast::NameRef, expr: Option<ast::Expr>) -> ast::RecordField {
4026
return match expr {
@@ -201,7 +187,7 @@ pub mod tokens {
201187
use once_cell::sync::Lazy;
202188

203189
pub(super) static SOURCE_FILE: Lazy<Parse<SourceFile>> =
204-
Lazy::new(|| SourceFile::parse("const C: () = (1 != 1, 2 == 2)\n;"));
190+
Lazy::new(|| SourceFile::parse("const C: <()>::Item = (1 != 1, 2 == 2)\n;"));
205191

206192
pub fn comma() -> SyntaxToken {
207193
SOURCE_FILE

0 commit comments

Comments
 (0)