Compare commits
1 Commits
main
...
ag/fix-loc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc3000115b |
@@ -11,6 +11,7 @@ use ruff_python_ast::{self as ast, AnyNodeRef};
|
|||||||
use ruff_python_codegen::Stylist;
|
use ruff_python_codegen::Stylist;
|
||||||
use ruff_text_size::{Ranged, TextRange, TextSize};
|
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
|
use ty_python_semantic::semantic_index::definition::Definition;
|
||||||
use ty_python_semantic::types::UnionType;
|
use ty_python_semantic::types::UnionType;
|
||||||
use ty_python_semantic::{
|
use ty_python_semantic::{
|
||||||
Completion as SemanticCompletion, KnownModule, ModuleName, NameKind, SemanticModel,
|
Completion as SemanticCompletion, KnownModule, ModuleName, NameKind, SemanticModel,
|
||||||
@@ -250,6 +251,9 @@ pub struct Completion<'db> {
|
|||||||
/// an unimported symbol. In that case, computing the
|
/// an unimported symbol. In that case, computing the
|
||||||
/// type of all such symbols could be quite expensive.
|
/// type of all such symbols could be quite expensive.
|
||||||
pub ty: Option<Type<'db>>,
|
pub ty: Option<Type<'db>>,
|
||||||
|
/// The first reachable definition for this
|
||||||
|
/// completion, if available.
|
||||||
|
pub first_reachable_definition: Option<Definition<'db>>,
|
||||||
/// The "kind" of this completion.
|
/// The "kind" of this completion.
|
||||||
///
|
///
|
||||||
/// When this is set, it takes priority over any kind
|
/// When this is set, it takes priority over any kind
|
||||||
@@ -306,6 +310,7 @@ impl<'db> Completion<'db> {
|
|||||||
qualified: None,
|
qualified: None,
|
||||||
insert: None,
|
insert: None,
|
||||||
ty: semantic.ty,
|
ty: semantic.ty,
|
||||||
|
first_reachable_definition: semantic.first_reachable_definition,
|
||||||
kind: None,
|
kind: None,
|
||||||
module_name: None,
|
module_name: None,
|
||||||
import: None,
|
import: None,
|
||||||
@@ -326,7 +331,7 @@ impl<'db> Completion<'db> {
|
|||||||
type CompletionKindVisitor<'db> =
|
type CompletionKindVisitor<'db> =
|
||||||
CycleDetector<CompletionKind, Type<'db>, Option<CompletionKind>>;
|
CycleDetector<CompletionKind, Type<'db>, Option<CompletionKind>>;
|
||||||
|
|
||||||
fn imp<'db>(
|
fn by_type<'db>(
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
ty: Type<'db>,
|
ty: Type<'db>,
|
||||||
visitor: &CompletionKindVisitor<'db>,
|
visitor: &CompletionKindVisitor<'db>,
|
||||||
@@ -361,10 +366,10 @@ impl<'db> Completion<'db> {
|
|||||||
Type::Union(union) => union
|
Type::Union(union) => union
|
||||||
.elements(db)
|
.elements(db)
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|&ty| imp(db, ty, visitor))?,
|
.find_map(|&ty| by_type(db, ty, visitor))?,
|
||||||
Type::Intersection(intersection) => intersection
|
Type::Intersection(intersection) => intersection
|
||||||
.iter_positive(db)
|
.iter_positive(db)
|
||||||
.find_map(|ty| imp(db, ty, visitor))?,
|
.find_map(|ty| by_type(db, ty, visitor))?,
|
||||||
Type::Dynamic(_)
|
Type::Dynamic(_)
|
||||||
| Type::Never
|
| Type::Never
|
||||||
| Type::SpecialForm(_)
|
| Type::SpecialForm(_)
|
||||||
@@ -372,14 +377,45 @@ impl<'db> Completion<'db> {
|
|||||||
| Type::AlwaysTruthy
|
| Type::AlwaysTruthy
|
||||||
| Type::AlwaysFalsy => return None,
|
| Type::AlwaysFalsy => return None,
|
||||||
Type::TypeAlias(alias) => {
|
Type::TypeAlias(alias) => {
|
||||||
visitor.visit(ty, || imp(db, alias.value_type(db), visitor))?
|
visitor.visit(ty, || by_type(db, alias.value_type(db), visitor))?
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
self.kind.or_else(|| {
|
|
||||||
self.ty
|
fn by_definition<'db>(db: &'db dyn Db, def: Definition<'db>) -> Option<CompletionKind> {
|
||||||
.and_then(|ty| imp(db, ty, &CompletionKindVisitor::default()))
|
use ty_python_semantic::semantic_index::definition::DefinitionKind::*;
|
||||||
})
|
Some(match def.kind(db) {
|
||||||
|
Import(_) | ImportFrom(_) | ImportFromSubmodule(_) => CompletionKind::Module,
|
||||||
|
Function(_) => CompletionKind::Function,
|
||||||
|
Class(_) => CompletionKind::Class,
|
||||||
|
NamedExpression(_)
|
||||||
|
| Assignment(_)
|
||||||
|
| AnnotatedAssignment(_)
|
||||||
|
| AugmentedAssignment(_)
|
||||||
|
| For(_)
|
||||||
|
| Comprehension(_)
|
||||||
|
| VariadicPositionalParameter(_)
|
||||||
|
| VariadicKeywordParameter(_)
|
||||||
|
| Parameter(_)
|
||||||
|
| WithItem(_)
|
||||||
|
| MatchPattern(_)
|
||||||
|
| ExceptHandler(_)
|
||||||
|
| ParamSpec(_) => CompletionKind::Variable,
|
||||||
|
TypeVar(_) | TypeVarTuple(_) => CompletionKind::TypeParameter,
|
||||||
|
// Give up and defer to type.
|
||||||
|
StarImport(_) | TypeAlias(_) => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
self.kind
|
||||||
|
.or_else(|| {
|
||||||
|
self.first_reachable_definition
|
||||||
|
.and_then(|def| by_definition(db, def))
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
self.ty
|
||||||
|
.and_then(|ty| by_type(db, ty, &CompletionKindVisitor::default()))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn keyword(name: &str) -> Self {
|
fn keyword(name: &str) -> Self {
|
||||||
@@ -388,6 +424,7 @@ impl<'db> Completion<'db> {
|
|||||||
qualified: None,
|
qualified: None,
|
||||||
insert: None,
|
insert: None,
|
||||||
ty: None,
|
ty: None,
|
||||||
|
first_reachable_definition: None,
|
||||||
kind: Some(CompletionKind::Keyword),
|
kind: Some(CompletionKind::Keyword),
|
||||||
module_name: None,
|
module_name: None,
|
||||||
import: None,
|
import: None,
|
||||||
@@ -404,6 +441,7 @@ impl<'db> Completion<'db> {
|
|||||||
qualified: None,
|
qualified: None,
|
||||||
insert: None,
|
insert: None,
|
||||||
ty: Some(ty),
|
ty: Some(ty),
|
||||||
|
first_reachable_definition: None,
|
||||||
kind: Some(CompletionKind::Keyword),
|
kind: Some(CompletionKind::Keyword),
|
||||||
module_name: None,
|
module_name: None,
|
||||||
import: None,
|
import: None,
|
||||||
@@ -1137,6 +1175,7 @@ fn add_function_arg_completions<'db>(
|
|||||||
qualified: None,
|
qualified: None,
|
||||||
insert,
|
insert,
|
||||||
ty: p.ty,
|
ty: p.ty,
|
||||||
|
first_reachable_definition: None,
|
||||||
kind: Some(CompletionKind::Variable),
|
kind: Some(CompletionKind::Variable),
|
||||||
module_name: None,
|
module_name: None,
|
||||||
import: None,
|
import: None,
|
||||||
@@ -1324,6 +1363,7 @@ fn add_unimported_completions<'db>(
|
|||||||
qualified: Some(ast::name::Name::new(qualified)),
|
qualified: Some(ast::name::Name::new(qualified)),
|
||||||
insert: Some(import_action.symbol_text().into()),
|
insert: Some(import_action.symbol_text().into()),
|
||||||
ty: None,
|
ty: None,
|
||||||
|
first_reachable_definition: None,
|
||||||
kind: symbol.kind().to_completion_kind(),
|
kind: symbol.kind().to_completion_kind(),
|
||||||
module_name: Some(module_name),
|
module_name: Some(module_name),
|
||||||
import: import_action.import().cloned(),
|
import: import_action.import().cloned(),
|
||||||
@@ -7508,6 +7548,52 @@ TypedDi<CURSOR>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn local_variable_kind_string() {
|
||||||
|
let builder = completion_test_builder(
|
||||||
|
"\
|
||||||
|
zqzqzq = 'Hello ty'
|
||||||
|
zqzq<CURSOR>
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_snapshot!(
|
||||||
|
builder.kinds().skip_auto_import().build().snapshot(),
|
||||||
|
@"zqzqzq :: Variable",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn local_variable_kind_int() {
|
||||||
|
let builder = completion_test_builder(
|
||||||
|
"\
|
||||||
|
zqzqzq: int = 3
|
||||||
|
zqzq<CURSOR>
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_snapshot!(
|
||||||
|
builder.kinds().skip_auto_import().build().snapshot(),
|
||||||
|
@"zqzqzq :: Variable",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn local_variable_kind_class_and_rebind() {
|
||||||
|
let builder = completion_test_builder(
|
||||||
|
"\
|
||||||
|
class zqzqzq: pass
|
||||||
|
zqzqzq_var = zqzqzq
|
||||||
|
zqzq<CURSOR>
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_snapshot!(
|
||||||
|
builder.kinds().skip_auto_import().build().snapshot(),
|
||||||
|
@r"
|
||||||
|
zqzqzq :: Class
|
||||||
|
zqzqzq_var :: Variable
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// A way to create a simple single-file (named `main.py`) completion test
|
/// A way to create a simple single-file (named `main.py`) completion test
|
||||||
/// builder.
|
/// builder.
|
||||||
///
|
///
|
||||||
@@ -7535,6 +7621,7 @@ TypedDi<CURSOR>
|
|||||||
type_signatures: bool,
|
type_signatures: bool,
|
||||||
imports: bool,
|
imports: bool,
|
||||||
module_names: bool,
|
module_names: bool,
|
||||||
|
kinds: bool,
|
||||||
// This doesn't seem like a "very complex" type to me... ---AG
|
// This doesn't seem like a "very complex" type to me... ---AG
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
predicate: Option<Box<dyn Fn(&Completion) -> bool>>,
|
predicate: Option<Box<dyn Fn(&Completion) -> bool>>,
|
||||||
@@ -7568,6 +7655,7 @@ TypedDi<CURSOR>
|
|||||||
type_signatures: self.type_signatures,
|
type_signatures: self.type_signatures,
|
||||||
imports: self.imports,
|
imports: self.imports,
|
||||||
module_names: self.module_names,
|
module_names: self.module_names,
|
||||||
|
kinds: self.kinds,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7643,6 +7731,13 @@ TypedDi<CURSOR>
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// When set, the "completion kind" for each symbol is included
|
||||||
|
/// in the snapshot (if available).
|
||||||
|
fn kinds(mut self) -> CompletionTestBuilder {
|
||||||
|
self.kinds = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Apply arbitrary filtering to completions.
|
/// Apply arbitrary filtering to completions.
|
||||||
fn filter(
|
fn filter(
|
||||||
mut self,
|
mut self,
|
||||||
@@ -7674,6 +7769,9 @@ TypedDi<CURSOR>
|
|||||||
/// Whether module names should be included in the snapshot
|
/// Whether module names should be included in the snapshot
|
||||||
/// generated by `CompletionTest::snapshot`.
|
/// generated by `CompletionTest::snapshot`.
|
||||||
module_names: bool,
|
module_names: bool,
|
||||||
|
/// Whether "completion kinds" should be included in the snapshot
|
||||||
|
/// generated by `CompletionTest::snapshot`.
|
||||||
|
kinds: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'db> CompletionTest<'db> {
|
impl<'db> CompletionTest<'db> {
|
||||||
@@ -7717,6 +7815,13 @@ TypedDi<CURSOR>
|
|||||||
snapshot = format!("{snapshot} :: <no import edit>");
|
snapshot = format!("{snapshot} :: <no import edit>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if self.kinds {
|
||||||
|
if let Some(kind) = c.kind(self.db) {
|
||||||
|
snapshot = format!("{snapshot} :: {kind:?}");
|
||||||
|
} else {
|
||||||
|
snapshot = format!("{snapshot} :: <no completion kind>");
|
||||||
|
}
|
||||||
|
}
|
||||||
snapshot
|
snapshot
|
||||||
})
|
})
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
@@ -7767,6 +7872,7 @@ TypedDi<CURSOR>
|
|||||||
type_signatures: false,
|
type_signatures: false,
|
||||||
imports: false,
|
imports: false,
|
||||||
module_names: false,
|
module_names: false,
|
||||||
|
kinds: false,
|
||||||
predicate: None,
|
predicate: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ impl<'db> SemanticModel<'db> {
|
|||||||
let ty = Type::module_literal(self.db, self.file, module);
|
let ty = Type::module_literal(self.db, self.file, module);
|
||||||
Completion {
|
Completion {
|
||||||
name: Name::new(module.name(self.db).as_str()),
|
name: Name::new(module.name(self.db).as_str()),
|
||||||
|
first_reachable_definition: None,
|
||||||
ty: Some(ty),
|
ty: Some(ty),
|
||||||
builtin,
|
builtin,
|
||||||
}
|
}
|
||||||
@@ -164,9 +165,15 @@ impl<'db> SemanticModel<'db> {
|
|||||||
let builtin = module.is_known(self.db, KnownModule::Builtins);
|
let builtin = module.is_known(self.db, KnownModule::Builtins);
|
||||||
|
|
||||||
let mut completions = vec![];
|
let mut completions = vec![];
|
||||||
for Member { name, ty } in all_members(self.db, ty) {
|
for Member {
|
||||||
|
name,
|
||||||
|
first_reachable_definition,
|
||||||
|
ty,
|
||||||
|
} in all_members(self.db, ty)
|
||||||
|
{
|
||||||
completions.push(Completion {
|
completions.push(Completion {
|
||||||
name,
|
name,
|
||||||
|
first_reachable_definition,
|
||||||
ty: Some(ty),
|
ty: Some(ty),
|
||||||
builtin,
|
builtin,
|
||||||
});
|
});
|
||||||
@@ -187,6 +194,7 @@ impl<'db> SemanticModel<'db> {
|
|||||||
};
|
};
|
||||||
completions.push(Completion {
|
completions.push(Completion {
|
||||||
name: Name::new(base),
|
name: Name::new(base),
|
||||||
|
first_reachable_definition: None,
|
||||||
ty: Some(ty),
|
ty: Some(ty),
|
||||||
builtin,
|
builtin,
|
||||||
});
|
});
|
||||||
@@ -204,6 +212,7 @@ impl<'db> SemanticModel<'db> {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|member| Completion {
|
.map(|member| Completion {
|
||||||
name: member.name,
|
name: member.name,
|
||||||
|
first_reachable_definition: member.first_reachable_definition,
|
||||||
ty: Some(member.ty),
|
ty: Some(member.ty),
|
||||||
builtin: false,
|
builtin: false,
|
||||||
})
|
})
|
||||||
@@ -227,6 +236,7 @@ impl<'db> SemanticModel<'db> {
|
|||||||
all_reachable_members(self.db, file_scope.to_scope_id(self.db, self.file)).map(
|
all_reachable_members(self.db, file_scope.to_scope_id(self.db, self.file)).map(
|
||||||
|memberdef| Completion {
|
|memberdef| Completion {
|
||||||
name: memberdef.member.name,
|
name: memberdef.member.name,
|
||||||
|
first_reachable_definition: Some(memberdef.first_reachable_definition),
|
||||||
ty: Some(memberdef.member.ty),
|
ty: Some(memberdef.member.ty),
|
||||||
builtin: false,
|
builtin: false,
|
||||||
},
|
},
|
||||||
@@ -410,6 +420,8 @@ impl NameKind {
|
|||||||
pub struct Completion<'db> {
|
pub struct Completion<'db> {
|
||||||
/// The label shown to the user for this suggestion.
|
/// The label shown to the user for this suggestion.
|
||||||
pub name: Name,
|
pub name: Name,
|
||||||
|
/// The definition from which this symbol was extracted.
|
||||||
|
pub first_reachable_definition: Option<Definition<'db>>,
|
||||||
/// The type of this completion, if available.
|
/// The type of this completion, if available.
|
||||||
///
|
///
|
||||||
/// Generally speaking, this is always available
|
/// Generally speaking, this is always available
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ pub(crate) fn all_end_of_scope_members<'db>(
|
|||||||
let symbol = table.symbol(symbol_id);
|
let symbol = table.symbol(symbol_id);
|
||||||
let member = Member {
|
let member = Member {
|
||||||
name: symbol.name().clone(),
|
name: symbol.name().clone(),
|
||||||
|
first_reachable_definition: Some(first_reachable_definition),
|
||||||
ty,
|
ty,
|
||||||
};
|
};
|
||||||
Some(MemberWithDefinition {
|
Some(MemberWithDefinition {
|
||||||
@@ -66,6 +67,7 @@ pub(crate) fn all_end_of_scope_members<'db>(
|
|||||||
let symbol = table.symbol(symbol_id);
|
let symbol = table.symbol(symbol_id);
|
||||||
let member = Member {
|
let member = Member {
|
||||||
name: symbol.name().clone(),
|
name: symbol.name().clone(),
|
||||||
|
first_reachable_definition: Some(first_reachable_definition),
|
||||||
ty,
|
ty,
|
||||||
};
|
};
|
||||||
Some(MemberWithDefinition {
|
Some(MemberWithDefinition {
|
||||||
@@ -101,6 +103,7 @@ pub(crate) fn all_reachable_members<'db>(
|
|||||||
.ignore_possibly_undefined()?;
|
.ignore_possibly_undefined()?;
|
||||||
let member = Member {
|
let member = Member {
|
||||||
name: symbol.name().clone(),
|
name: symbol.name().clone(),
|
||||||
|
first_reachable_definition: Some(first_reachable_definition),
|
||||||
ty,
|
ty,
|
||||||
};
|
};
|
||||||
Some(MemberWithDefinition {
|
Some(MemberWithDefinition {
|
||||||
@@ -117,6 +120,7 @@ pub(crate) fn all_reachable_members<'db>(
|
|||||||
let ty = place_with_definition.place.ignore_possibly_undefined()?;
|
let ty = place_with_definition.place.ignore_possibly_undefined()?;
|
||||||
let member = Member {
|
let member = Member {
|
||||||
name: symbol.name().clone(),
|
name: symbol.name().clone(),
|
||||||
|
first_reachable_definition: Some(first_reachable_definition),
|
||||||
ty,
|
ty,
|
||||||
};
|
};
|
||||||
Some(MemberWithDefinition {
|
Some(MemberWithDefinition {
|
||||||
@@ -322,13 +326,19 @@ impl<'db> AllMembers<'db> {
|
|||||||
let use_def_map = use_def_map(db, module_scope);
|
let use_def_map = use_def_map(db, module_scope);
|
||||||
let place_table = place_table(db, module_scope);
|
let place_table = place_table(db, module_scope);
|
||||||
|
|
||||||
for (symbol_id, _) in use_def_map.all_end_of_scope_symbol_declarations() {
|
for (symbol_id, declarations) in use_def_map.all_end_of_scope_symbol_declarations()
|
||||||
|
{
|
||||||
let symbol_name = place_table.symbol(symbol_id).name();
|
let symbol_name = place_table.symbol(symbol_id).name();
|
||||||
let Place::Defined(ty, _, _) =
|
let Place::Defined(ty, _, _) =
|
||||||
imported_symbol(db, file, symbol_name, None).place
|
imported_symbol(db, file, symbol_name, None).place
|
||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
let Some(first_reachable_definition) =
|
||||||
|
place_from_declarations(db, declarations).first_declaration
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
// Filter private symbols from stubs if they appear to be internal types
|
// Filter private symbols from stubs if they appear to be internal types
|
||||||
let is_stub_file = file.path(db).extension() == Some("pyi");
|
let is_stub_file = file.path(db).extension() == Some("pyi");
|
||||||
@@ -365,6 +375,7 @@ impl<'db> AllMembers<'db> {
|
|||||||
|
|
||||||
self.members.insert(Member {
|
self.members.insert(Member {
|
||||||
name: symbol_name.clone(),
|
name: symbol_name.clone(),
|
||||||
|
first_reachable_definition: Some(first_reachable_definition),
|
||||||
ty,
|
ty,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -374,7 +385,11 @@ impl<'db> AllMembers<'db> {
|
|||||||
|submodule_name| {
|
|submodule_name| {
|
||||||
let ty = literal.resolve_submodule(db, &submodule_name)?;
|
let ty = literal.resolve_submodule(db, &submodule_name)?;
|
||||||
let name = submodule_name.clone();
|
let name = submodule_name.clone();
|
||||||
Some(Member { name, ty })
|
Some(Member {
|
||||||
|
name,
|
||||||
|
first_reachable_definition: None,
|
||||||
|
ty,
|
||||||
|
})
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -421,6 +436,7 @@ impl<'db> AllMembers<'db> {
|
|||||||
};
|
};
|
||||||
self.members.insert(Member {
|
self.members.insert(Member {
|
||||||
name: memberdef.member.name,
|
name: memberdef.member.name,
|
||||||
|
first_reachable_definition: Some(memberdef.first_reachable_definition),
|
||||||
ty,
|
ty,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -452,6 +468,7 @@ impl<'db> AllMembers<'db> {
|
|||||||
};
|
};
|
||||||
self.members.insert(Member {
|
self.members.insert(Member {
|
||||||
name: Name::new(name),
|
name: Name::new(name),
|
||||||
|
first_reachable_definition: None,
|
||||||
ty,
|
ty,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -469,6 +486,7 @@ impl<'db> AllMembers<'db> {
|
|||||||
};
|
};
|
||||||
self.members.insert(Member {
|
self.members.insert(Member {
|
||||||
name: memberdef.member.name,
|
name: memberdef.member.name,
|
||||||
|
first_reachable_definition: Some(memberdef.first_reachable_definition),
|
||||||
ty,
|
ty,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -496,6 +514,7 @@ impl<'db> AllMembers<'db> {
|
|||||||
if let Place::Defined(synthetic_member, _, _) = ty.member(db, attr).place {
|
if let Place::Defined(synthetic_member, _, _) = ty.member(db, attr).place {
|
||||||
self.members.insert(Member {
|
self.members.insert(Member {
|
||||||
name: Name::from(*attr),
|
name: Name::from(*attr),
|
||||||
|
first_reachable_definition: None,
|
||||||
ty: synthetic_member,
|
ty: synthetic_member,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -529,6 +548,7 @@ pub struct MemberWithDefinition<'db> {
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Member<'db> {
|
pub struct Member<'db> {
|
||||||
pub name: Name,
|
pub name: Name,
|
||||||
|
pub first_reachable_definition: Option<Definition<'db>>,
|
||||||
pub ty: Type<'db>,
|
pub ty: Type<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user