More orthogonal path editing
This commit is contained in:
parent
7d2d3ac3db
commit
ef1326ee19
@ -2,7 +2,7 @@
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use hir::{db::HirDatabase, InFile, PathResolution};
|
||||
use ra_syntax::ast::{self, make, AstNode};
|
||||
use ra_syntax::ast::{self, AstNode};
|
||||
|
||||
pub trait AstTransform<'a> {
|
||||
fn get_substitution(
|
||||
@ -134,11 +134,18 @@ fn get_substitution_inner(
|
||||
match resolution {
|
||||
PathResolution::Def(def) => {
|
||||
let found_path = from.find_use_path(self.db, def)?;
|
||||
let args = p
|
||||
let mut path = path_to_ast(found_path);
|
||||
|
||||
let type_args = p
|
||||
.segment()
|
||||
.and_then(|s| s.type_arg_list())
|
||||
.map(|arg_list| apply(self, node.with_value(arg_list)));
|
||||
Some(make::path_with_type_arg_list(path_to_ast(found_path), args).syntax().clone())
|
||||
if let Some(type_args) = type_args {
|
||||
let last_segment = path.segment().unwrap();
|
||||
path = path.with_segment(last_segment.with_type_args(type_args))
|
||||
}
|
||||
|
||||
Some(path.syntax().clone())
|
||||
}
|
||||
PathResolution::Local(_)
|
||||
| PathResolution::TypeParam(_)
|
||||
|
@ -207,6 +207,48 @@ pub fn remove_bounds(&self) -> ast::TypeParam {
|
||||
}
|
||||
}
|
||||
|
||||
impl ast::Path {
|
||||
#[must_use]
|
||||
pub fn with_segment(&self, segment: ast::PathSegment) -> ast::Path {
|
||||
if let Some(old) = self.segment() {
|
||||
return replace_children(
|
||||
self,
|
||||
single_node(old.syntax().clone()),
|
||||
iter::once(segment.syntax().clone().into()),
|
||||
);
|
||||
}
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl ast::PathSegment {
|
||||
#[must_use]
|
||||
pub fn with_type_args(&self, type_args: ast::TypeArgList) -> ast::PathSegment {
|
||||
self._with_type_args(type_args, false)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_turbo_fish(&self, type_args: ast::TypeArgList) -> ast::PathSegment {
|
||||
self._with_type_args(type_args, true)
|
||||
}
|
||||
|
||||
fn _with_type_args(&self, type_args: ast::TypeArgList, turbo: bool) -> ast::PathSegment {
|
||||
if let Some(old) = self.type_arg_list() {
|
||||
return replace_children(
|
||||
self,
|
||||
single_node(old.syntax().clone()),
|
||||
iter::once(type_args.syntax().clone().into()),
|
||||
);
|
||||
}
|
||||
let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new();
|
||||
if turbo {
|
||||
to_insert.push(make::token(T![::]).into());
|
||||
}
|
||||
to_insert.push(type_args.syntax().clone().into());
|
||||
insert_children(self, InsertPosition::Last, to_insert)
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn strip_attrs_and_docs<N: ast::AttrsOwner>(node: &N) -> N {
|
||||
N::cast(strip_attrs_and_docs_inner(node.syntax().clone())).unwrap()
|
||||
|
@ -2,7 +2,7 @@
|
||||
//! of smaller pieces.
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::{algo, ast, AstNode, SourceFile, SyntaxKind, SyntaxToken};
|
||||
use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxToken};
|
||||
|
||||
pub fn name(text: &str) -> ast::Name {
|
||||
ast_from_text(&format!("mod {};", text))
|
||||
@ -21,20 +21,6 @@ pub fn path_qualified(qual: ast::Path, name_ref: ast::NameRef) -> ast::Path {
|
||||
fn path_from_text(text: &str) -> ast::Path {
|
||||
ast_from_text(text)
|
||||
}
|
||||
pub fn path_with_type_arg_list(path: ast::Path, args: Option<ast::TypeArgList>) -> ast::Path {
|
||||
if let Some(args) = args {
|
||||
let syntax = path.syntax();
|
||||
// FIXME: remove existing type args
|
||||
let new_syntax = algo::insert_children(
|
||||
syntax,
|
||||
crate::algo::InsertPosition::Last,
|
||||
&mut Some(args).into_iter().map(|n| n.syntax().clone().into()),
|
||||
);
|
||||
ast::Path::cast(new_syntax).unwrap()
|
||||
} else {
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
pub fn record_field(name: ast::NameRef, expr: Option<ast::Expr>) -> ast::RecordField {
|
||||
return match expr {
|
||||
@ -201,7 +187,7 @@ pub mod tokens {
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub(super) static SOURCE_FILE: Lazy<Parse<SourceFile>> =
|
||||
Lazy::new(|| SourceFile::parse("const C: () = (1 != 1, 2 == 2)\n;"));
|
||||
Lazy::new(|| SourceFile::parse("const C: <()>::Item = (1 != 1, 2 == 2)\n;"));
|
||||
|
||||
pub fn comma() -> SyntaxToken {
|
||||
SOURCE_FILE
|
||||
|
Loading…
Reference in New Issue
Block a user