mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-06 13:44:13 +00:00
Merge #6150
6150: Move ModPath->ast::Path function to IDE layer r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
81d6816f17
@ -1,13 +1,14 @@
|
||||
//! `AstTransformer`s are functions that replace nodes in an AST and can be easily combined.
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use hir::{HirDisplay, PathResolution, SemanticsScope};
|
||||
use rustc_hash::FxHashMap;
|
||||
use syntax::{
|
||||
algo::SyntaxRewriter,
|
||||
ast::{self, AstNode},
|
||||
SyntaxNode,
|
||||
};
|
||||
|
||||
use crate::utils::mod_path_to_ast;
|
||||
|
||||
pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: N) -> N {
|
||||
SyntaxRewriter::from_fn(|element| match element {
|
||||
syntax::SyntaxElement::Node(n) => {
|
||||
@ -189,7 +190,7 @@ impl<'a> AstTransform<'a> for QualifyPaths<'a> {
|
||||
match resolution {
|
||||
PathResolution::Def(def) => {
|
||||
let found_path = from.find_use_path(self.source_scope.db.upcast(), def)?;
|
||||
let mut path = path_to_ast(found_path);
|
||||
let mut path = mod_path_to_ast(&found_path);
|
||||
|
||||
let type_args = p
|
||||
.segment()
|
||||
@ -210,13 +211,3 @@ impl<'a> AstTransform<'a> for QualifyPaths<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn path_to_ast(path: hir::ModPath) -> ast::Path {
|
||||
let parse = ast::SourceFile::parse(&path.to_string());
|
||||
parse
|
||||
.tree()
|
||||
.syntax()
|
||||
.descendants()
|
||||
.find_map(ast::Path::cast)
|
||||
.unwrap_or_else(|| panic!("failed to parse path {:?}, `{}`", path, path))
|
||||
}
|
||||
|
@ -820,4 +820,29 @@ impl Tr for () {
|
||||
}"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn weird_path() {
|
||||
check_assist(
|
||||
add_missing_impl_members,
|
||||
r#"
|
||||
trait Test {
|
||||
fn foo(&self, x: crate)
|
||||
}
|
||||
impl Test for () {
|
||||
<|>
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
trait Test {
|
||||
fn foo(&self, x: crate)
|
||||
}
|
||||
impl Test for () {
|
||||
fn foo(&self, x: crate) {
|
||||
${0:todo!()}
|
||||
}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,10 @@ use syntax::{
|
||||
SyntaxNode,
|
||||
};
|
||||
|
||||
use crate::{utils::insert_use, AssistContext, AssistId, AssistKind, Assists, GroupLabel};
|
||||
use crate::{
|
||||
utils::insert_use, utils::mod_path_to_ast, AssistContext, AssistId, AssistKind, Assists,
|
||||
GroupLabel,
|
||||
};
|
||||
|
||||
// Assist: auto_import
|
||||
//
|
||||
@ -54,7 +57,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
|
||||
range,
|
||||
|builder| {
|
||||
let new_syntax =
|
||||
insert_use(&scope, import.to_ast_path(), ctx.config.insert_use.merge);
|
||||
insert_use(&scope, mod_path_to_ast(&import), ctx.config.insert_use.merge);
|
||||
builder.replace(syntax.text_range(), new_syntax.to_string())
|
||||
},
|
||||
);
|
||||
|
@ -10,9 +10,10 @@ use syntax::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
assist_context::AssistBuilder, utils::insert_use, AssistContext, AssistId, AssistKind, Assists,
|
||||
assist_context::AssistBuilder,
|
||||
utils::{insert_use, mod_path_to_ast, ImportScope},
|
||||
AssistContext, AssistId, AssistKind, Assists,
|
||||
};
|
||||
use insert_use::ImportScope;
|
||||
|
||||
// Assist: extract_struct_from_enum_variant
|
||||
//
|
||||
@ -111,7 +112,8 @@ fn insert_import(
|
||||
let scope = ImportScope::find_insert_use_container(path.syntax(), ctx)?;
|
||||
let syntax = scope.as_syntax_node();
|
||||
|
||||
let new_syntax = insert_use(&scope, mod_path.to_ast_path(), ctx.config.insert_use.merge);
|
||||
let new_syntax =
|
||||
insert_use(&scope, mod_path_to_ast(&mod_path), ctx.config.insert_use.merge);
|
||||
// FIXME: this will currently panic as multiple imports will have overlapping text ranges
|
||||
builder.replace(syntax.text_range(), new_syntax.to_string())
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat};
|
||||
use test_utils::mark;
|
||||
|
||||
use crate::{
|
||||
utils::{render_snippet, Cursor, FamousDefs},
|
||||
utils::{mod_path_to_ast, render_snippet, Cursor, FamousDefs},
|
||||
AssistContext, AssistId, AssistKind, Assists,
|
||||
};
|
||||
|
||||
@ -192,7 +192,7 @@ fn resolve_tuple_of_enum_def(
|
||||
}
|
||||
|
||||
fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> Option<ast::Pat> {
|
||||
let path = crate::ast_transform::path_to_ast(module.find_use_path(db, ModuleDef::from(var))?);
|
||||
let path = mod_path_to_ast(&module.find_use_path(db, ModuleDef::from(var))?);
|
||||
|
||||
// FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though
|
||||
let pat: ast::Pat = match var.source(db).value.kind() {
|
||||
|
@ -19,6 +19,27 @@ use crate::assist_config::SnippetCap;
|
||||
pub use insert_use::MergeBehaviour;
|
||||
pub(crate) use insert_use::{insert_use, ImportScope};
|
||||
|
||||
pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path {
|
||||
let mut segments = Vec::new();
|
||||
let mut is_abs = false;
|
||||
match path.kind {
|
||||
hir::PathKind::Plain => {}
|
||||
hir::PathKind::Super(0) => segments.push(make::path_segment_self()),
|
||||
hir::PathKind::Super(n) => segments.extend((0..n).map(|_| make::path_segment_super())),
|
||||
hir::PathKind::DollarCrate(_) | hir::PathKind::Crate => {
|
||||
segments.push(make::path_segment_crate())
|
||||
}
|
||||
hir::PathKind::Abs => is_abs = true,
|
||||
}
|
||||
|
||||
segments.extend(
|
||||
path.segments
|
||||
.iter()
|
||||
.map(|segment| make::path_segment(make::name_ref(&segment.to_string()))),
|
||||
);
|
||||
make::path_from_segments(segments, is_abs)
|
||||
}
|
||||
|
||||
pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr {
|
||||
extract_trivial_expression(&block)
|
||||
.filter(|expr| !expr.syntax().text().contains_char('\n'))
|
||||
|
@ -51,7 +51,7 @@ pub use hir_def::{
|
||||
find_path::PrefixKind,
|
||||
item_scope::ItemInNs,
|
||||
nameres::ModuleSource,
|
||||
path::ModPath,
|
||||
path::{ModPath, PathKind},
|
||||
type_ref::{Mutability, TypeRef},
|
||||
};
|
||||
pub use hir_expand::{
|
||||
@ -63,7 +63,4 @@ pub use hir_ty::display::HirDisplay;
|
||||
// These are negative re-exports: pub using these names is forbidden, they
|
||||
// should remain private to hir internals.
|
||||
#[allow(unused)]
|
||||
use {
|
||||
hir_def::path::{Path, PathKind},
|
||||
hir_expand::hygiene::Hygiene,
|
||||
};
|
||||
use {hir_def::path::Path, hir_expand::hygiene::Hygiene};
|
||||
|
@ -13,7 +13,7 @@ use hir_expand::{
|
||||
hygiene::Hygiene,
|
||||
name::{AsName, Name},
|
||||
};
|
||||
use syntax::ast::{self, make};
|
||||
use syntax::ast::{self};
|
||||
|
||||
use crate::{
|
||||
type_ref::{TypeBound, TypeRef},
|
||||
@ -100,26 +100,6 @@ impl ModPath {
|
||||
}
|
||||
self.segments.first()
|
||||
}
|
||||
|
||||
pub fn to_ast_path(&self) -> ast::Path {
|
||||
let mut segments = Vec::new();
|
||||
let mut is_abs = false;
|
||||
match self.kind {
|
||||
PathKind::Plain => {}
|
||||
PathKind::Super(0) => segments.push(make::path_segment_self()),
|
||||
PathKind::Super(n) => segments.extend((0..n).map(|_| make::path_segment_super())),
|
||||
PathKind::Crate => segments.push(make::path_segment_crate()),
|
||||
PathKind::Abs => is_abs = true,
|
||||
PathKind::DollarCrate(_) => (),
|
||||
}
|
||||
|
||||
segments.extend(
|
||||
self.segments
|
||||
.iter()
|
||||
.map(|segment| make::path_segment(make::name_ref(&segment.to_string()))),
|
||||
);
|
||||
make::path_from_segments(segments, is_abs)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
Loading…
Reference in New Issue
Block a user