working for path segments
This commit is contained in:
parent
c4cff80269
commit
b9ee4a5167
@ -24,12 +24,23 @@ pub(crate) fn complete_type_path(
|
|||||||
// no values in type places
|
// no values in type places
|
||||||
ScopeDef::ModuleDef(Function(_) | Variant(_) | Static(_)) | ScopeDef::Local(_) => false,
|
ScopeDef::ModuleDef(Function(_) | Variant(_) | Static(_)) | ScopeDef::Local(_) => false,
|
||||||
// unless its a constant in a generic arg list position
|
// unless its a constant in a generic arg list position
|
||||||
ScopeDef::ModuleDef(Const(_)) | ScopeDef::GenericParam(ConstParam(_)) => {
|
ScopeDef::ModuleDef(Const(_)) | ScopeDef::GenericParam(ConstParam(_)) => match location
|
||||||
matches!(location, TypeLocation::GenericArgList(_))
|
{
|
||||||
|
TypeLocation::GenericArgList(location) => match location {
|
||||||
|
Some((_, Some(generic_param))) => {
|
||||||
|
matches!(generic_param, ast::GenericParam::ConstParam(_))
|
||||||
}
|
}
|
||||||
ScopeDef::ImplSelfType(_) => {
|
_ => true,
|
||||||
!matches!(location, TypeLocation::ImplTarget | TypeLocation::ImplTrait)
|
},
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
ScopeDef::ImplSelfType(_) => match location {
|
||||||
|
TypeLocation::ImplTarget | TypeLocation::ImplTrait => false,
|
||||||
|
TypeLocation::GenericArgList(Some((_, Some(generic_param)))) => {
|
||||||
|
matches!(generic_param, ast::GenericParam::TypeParam(_))
|
||||||
}
|
}
|
||||||
|
_ => true,
|
||||||
|
},
|
||||||
// Don't suggest attribute macros and derives.
|
// Don't suggest attribute macros and derives.
|
||||||
ScopeDef::ModuleDef(Macro(mac)) => mac.is_fn_like(ctx.db),
|
ScopeDef::ModuleDef(Macro(mac)) => mac.is_fn_like(ctx.db),
|
||||||
// Type things are fine
|
// Type things are fine
|
||||||
@ -38,7 +49,12 @@ pub(crate) fn complete_type_path(
|
|||||||
)
|
)
|
||||||
| ScopeDef::AdtSelfType(_)
|
| ScopeDef::AdtSelfType(_)
|
||||||
| ScopeDef::Unknown
|
| ScopeDef::Unknown
|
||||||
| ScopeDef::GenericParam(TypeParam(_)) => true,
|
| ScopeDef::GenericParam(TypeParam(_)) => match location {
|
||||||
|
TypeLocation::GenericArgList(Some((_, Some(generic_param)))) => {
|
||||||
|
matches!(generic_param, ast::GenericParam::TypeParam(_))
|
||||||
|
}
|
||||||
|
_ => true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -157,7 +173,7 @@ pub(crate) fn complete_type_path(
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TypeLocation::GenericArgList(Some(arg_list)) => {
|
TypeLocation::GenericArgList(Some((arg_list, generic_param))) => {
|
||||||
let in_assoc_type_arg = ctx
|
let in_assoc_type_arg = ctx
|
||||||
.original_token
|
.original_token
|
||||||
.parent_ancestors()
|
.parent_ancestors()
|
||||||
|
@ -155,7 +155,7 @@ pub(crate) struct ExprCtx {
|
|||||||
pub(crate) enum TypeLocation {
|
pub(crate) enum TypeLocation {
|
||||||
TupleField,
|
TupleField,
|
||||||
TypeAscription(TypeAscriptionTarget),
|
TypeAscription(TypeAscriptionTarget),
|
||||||
GenericArgList(Option<ast::GenericArgList>),
|
GenericArgList(Option<(ast::GenericArgList, Option<ast::GenericParam>)>),
|
||||||
TypeBound,
|
TypeBound,
|
||||||
ImplTarget,
|
ImplTarget,
|
||||||
ImplTrait,
|
ImplTrait,
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
//! Module responsible for analyzing the code surrounding the cursor for completion.
|
//! Module responsible for analyzing the code surrounding the cursor for completion.
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use hir::{Semantics, Type, TypeInfo, Variant};
|
use hir::{HasSource, Semantics, Type, TypeInfo, Variant};
|
||||||
use ide_db::{active_parameter::ActiveParameter, RootDatabase};
|
use ide_db::{active_parameter::ActiveParameter, RootDatabase};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
algo::{find_node_at_offset, non_trivia_sibling},
|
algo::{find_node_at_offset, non_trivia_sibling},
|
||||||
ast::{self, AttrKind, HasArgList, HasLoopBody, HasName, NameOrNameRef},
|
ast::{self, AttrKind, HasArgList, HasGenericParams, HasLoopBody, HasName, NameOrNameRef},
|
||||||
match_ast, AstNode, AstToken, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode,
|
match_ast, AstNode, AstToken, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode,
|
||||||
SyntaxToken, TextRange, TextSize, T,
|
SyntaxToken, TextRange, TextSize, T,
|
||||||
};
|
};
|
||||||
@ -774,9 +774,40 @@ fn classify_name_ref(
|
|||||||
ast::TypeBound(_) => TypeLocation::TypeBound,
|
ast::TypeBound(_) => TypeLocation::TypeBound,
|
||||||
// is this case needed?
|
// is this case needed?
|
||||||
ast::TypeBoundList(_) => TypeLocation::TypeBound,
|
ast::TypeBoundList(_) => TypeLocation::TypeBound,
|
||||||
ast::GenericArg(it) => TypeLocation::GenericArgList(find_opt_node_in_file_compensated(sema, original_file, it.syntax().parent().and_then(ast::GenericArgList::cast))),
|
ast::GenericArg(it) => {
|
||||||
|
let location = find_opt_node_in_file_compensated(sema, original_file, it.syntax().parent().and_then(ast::GenericArgList::cast))
|
||||||
|
.map(|args| {
|
||||||
|
// Determine the index of the parameter in the `GenericArgList`
|
||||||
|
// (subtract 1 because `siblings` includes the node itself)
|
||||||
|
let param_idx = it.syntax().siblings(Direction::Prev).count() - 1;
|
||||||
|
let param = args
|
||||||
|
.syntax()
|
||||||
|
.parent()
|
||||||
|
.and_then(|p| ast::PathSegment::cast(p))
|
||||||
|
.and_then(|segment| sema.resolve_path(&segment.parent_path().top_path()))
|
||||||
|
.and_then(|resolved| {
|
||||||
|
match resolved {
|
||||||
|
hir::PathResolution::Def(def) => match def {
|
||||||
|
hir::ModuleDef::Function(func) => {
|
||||||
|
let src = func.source(sema.db)?;
|
||||||
|
let params = src.value.generic_param_list()?;
|
||||||
|
params.generic_params().nth(param_idx)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
(args, param)
|
||||||
|
});
|
||||||
|
TypeLocation::GenericArgList(location)
|
||||||
|
},
|
||||||
// is this case needed?
|
// is this case needed?
|
||||||
ast::GenericArgList(it) => TypeLocation::GenericArgList(find_opt_node_in_file_compensated(sema, original_file, Some(it))),
|
ast::GenericArgList(it) => {
|
||||||
|
let location = find_opt_node_in_file_compensated(sema, original_file, Some(it))
|
||||||
|
.map(|node| (node, None));
|
||||||
|
TypeLocation::GenericArgList(location)
|
||||||
|
},
|
||||||
ast::TupleField(_) => TypeLocation::TupleField,
|
ast::TupleField(_) => TypeLocation::TupleField,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
}
|
}
|
||||||
@ -883,25 +914,8 @@ fn classify_name_ref(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let make_path_kind_type = |ty: ast::Type| {
|
let make_path_kind_type = |ty: ast::Type| {
|
||||||
let location = type_location(ty.syntax()).unwrap_or(TypeLocation::Other);
|
let location = type_location(ty.syntax());
|
||||||
match &location {
|
PathKind::Type { location: location.unwrap_or(TypeLocation::Other) }
|
||||||
TypeLocation::TupleField => (),
|
|
||||||
TypeLocation::TypeAscription(_) => (),
|
|
||||||
TypeLocation::GenericArgList(args) => {
|
|
||||||
dbg!(&args);
|
|
||||||
if let Some(segment) =
|
|
||||||
args.as_ref().and_then(|args| ast::PathSegment::cast(args.syntax().parent()?))
|
|
||||||
{
|
|
||||||
let path = dbg!(segment.parent_path().top_path());
|
|
||||||
dbg!(sema.resolve_path(&path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TypeLocation::TypeBound => (),
|
|
||||||
TypeLocation::ImplTarget => (),
|
|
||||||
TypeLocation::ImplTrait => (),
|
|
||||||
TypeLocation::Other => (),
|
|
||||||
}
|
|
||||||
PathKind::Type { location }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut kind_macro_call = |it: ast::MacroCall| {
|
let mut kind_macro_call = |it: ast::MacroCall| {
|
||||||
|
@ -726,15 +726,21 @@ fn completes_const_and_type_generics_separately() {
|
|||||||
r#"
|
r#"
|
||||||
struct Foo;
|
struct Foo;
|
||||||
const X: usize = 0;
|
const X: usize = 0;
|
||||||
mod foo {
|
fn foo<T, const N: usize>() {}
|
||||||
fn foo<T>() {}
|
|
||||||
}
|
|
||||||
fn main() {
|
fn main() {
|
||||||
self::foo::foo::<F$0>();
|
foo::<F$0, _>();
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
|
en Enum
|
||||||
|
ma makro!(…) macro_rules! makro
|
||||||
|
md module
|
||||||
st Foo
|
st Foo
|
||||||
|
st Record
|
||||||
|
st Tuple
|
||||||
|
st Unit
|
||||||
|
tt Trait
|
||||||
|
un Union
|
||||||
bt u32
|
bt u32
|
||||||
kw crate::
|
kw crate::
|
||||||
kw self::
|
kw self::
|
||||||
@ -744,13 +750,15 @@ fn main() {
|
|||||||
r#"
|
r#"
|
||||||
struct Foo;
|
struct Foo;
|
||||||
const X: usize = 0;
|
const X: usize = 0;
|
||||||
fn foo<const X: usize>() {}
|
fn foo<T, const N: usize>() {}
|
||||||
fn main() {
|
fn main() {
|
||||||
foo::<F$0>();
|
foo::<_, $0>();
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
|
ct CONST
|
||||||
ct X
|
ct X
|
||||||
|
ma makro!(…) macro_rules! makro
|
||||||
kw crate::
|
kw crate::
|
||||||
kw self::
|
kw self::
|
||||||
"#]],
|
"#]],
|
||||||
|
Loading…
Reference in New Issue
Block a user