mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Merge #7115
7115: Migrate HasSource::source to return Option r=matklad a=nick96 I've made a start on fixing #6913 based on the provided work plan, migrating `HasSource::source` to return an `Option`. The simple cases are migrated but there are a few that I'm unsure exactly how they should be handled: - Logging the processing of functions in `AnalysisStatsCmd::run`: In verbose mode it includes the path to the module containing the function and the syntax range. I've handled this with an if-let but would it be better to blow up here with `expect`? I'm not 100% on the code paths but if we're processing a function definition then the source should exist. I've handled `source()` in all code paths as `None` being a valid return value but are there some cases where we should just blow up? Also, all I've done is bubble up the returned `None`s, there may be some places where we can recover and still provide something. Co-authored-by: Nick Spain <nicholas.spain@stileeducation.com> Co-authored-by: Nick Spain <nicholas.spain96@gmail.com>
This commit is contained in:
commit
520b8a5a4d
20 changed files with 237 additions and 223 deletions
|
@ -196,7 +196,7 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::Variant) -> Optio
|
|||
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() {
|
||||
let pat: ast::Pat = match var.source(db)?.value.kind() {
|
||||
ast::StructKind::Tuple(field_list) => {
|
||||
let pats = iter::repeat(make::wildcard_pat().into()).take(field_list.fields().count());
|
||||
make::tuple_struct_pat(path, pats).into()
|
||||
|
|
|
@ -97,7 +97,8 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) ->
|
|||
let parent_name = parent.name(ctx.db());
|
||||
let target_module = parent.module(ctx.db());
|
||||
|
||||
let in_file_source = record_field_def.source(ctx.db());
|
||||
#[allow(deprecated)]
|
||||
let in_file_source = record_field_def.source(ctx.db())?;
|
||||
let (offset, current_visibility, target) = match in_file_source.value {
|
||||
hir::FieldSource::Named(it) => {
|
||||
let s = it.syntax();
|
||||
|
@ -145,53 +146,53 @@ fn target_data_for_def(
|
|||
fn offset_target_and_file_id<S, Ast>(
|
||||
db: &dyn HirDatabase,
|
||||
x: S,
|
||||
) -> (TextSize, Option<ast::Visibility>, TextRange, FileId)
|
||||
) -> Option<(TextSize, Option<ast::Visibility>, TextRange, FileId)>
|
||||
where
|
||||
S: HasSource<Ast = Ast>,
|
||||
Ast: AstNode + ast::VisibilityOwner,
|
||||
{
|
||||
let source = x.source(db);
|
||||
let source = x.source(db)?;
|
||||
let in_file_syntax = source.syntax();
|
||||
let file_id = in_file_syntax.file_id;
|
||||
let syntax = in_file_syntax.value;
|
||||
let current_visibility = source.value.visibility();
|
||||
(
|
||||
Some((
|
||||
vis_offset(syntax),
|
||||
current_visibility,
|
||||
syntax.text_range(),
|
||||
file_id.original_file(db.upcast()),
|
||||
)
|
||||
))
|
||||
}
|
||||
|
||||
let target_name;
|
||||
let (offset, current_visibility, target, target_file) = match def {
|
||||
hir::ModuleDef::Function(f) => {
|
||||
target_name = Some(f.name(db));
|
||||
offset_target_and_file_id(db, f)
|
||||
offset_target_and_file_id(db, f)?
|
||||
}
|
||||
hir::ModuleDef::Adt(adt) => {
|
||||
target_name = Some(adt.name(db));
|
||||
match adt {
|
||||
hir::Adt::Struct(s) => offset_target_and_file_id(db, s),
|
||||
hir::Adt::Union(u) => offset_target_and_file_id(db, u),
|
||||
hir::Adt::Enum(e) => offset_target_and_file_id(db, e),
|
||||
hir::Adt::Struct(s) => offset_target_and_file_id(db, s)?,
|
||||
hir::Adt::Union(u) => offset_target_and_file_id(db, u)?,
|
||||
hir::Adt::Enum(e) => offset_target_and_file_id(db, e)?,
|
||||
}
|
||||
}
|
||||
hir::ModuleDef::Const(c) => {
|
||||
target_name = c.name(db);
|
||||
offset_target_and_file_id(db, c)
|
||||
offset_target_and_file_id(db, c)?
|
||||
}
|
||||
hir::ModuleDef::Static(s) => {
|
||||
target_name = s.name(db);
|
||||
offset_target_and_file_id(db, s)
|
||||
offset_target_and_file_id(db, s)?
|
||||
}
|
||||
hir::ModuleDef::Trait(t) => {
|
||||
target_name = Some(t.name(db));
|
||||
offset_target_and_file_id(db, t)
|
||||
offset_target_and_file_id(db, t)?
|
||||
}
|
||||
hir::ModuleDef::TypeAlias(t) => {
|
||||
target_name = Some(t.name(db));
|
||||
offset_target_and_file_id(db, t)
|
||||
offset_target_and_file_id(db, t)?
|
||||
}
|
||||
hir::ModuleDef::Module(m) => {
|
||||
target_name = m.name(db);
|
||||
|
|
|
@ -98,10 +98,14 @@ pub fn filter_assoc_items(
|
|||
|
||||
items
|
||||
.iter()
|
||||
.map(|i| match i {
|
||||
hir::AssocItem::Function(i) => ast::AssocItem::Fn(i.source(db).value),
|
||||
hir::AssocItem::TypeAlias(i) => ast::AssocItem::TypeAlias(i.source(db).value),
|
||||
hir::AssocItem::Const(i) => ast::AssocItem::Const(i.source(db).value),
|
||||
// Note: This throws away items with no source.
|
||||
.filter_map(|i| {
|
||||
let item = match i {
|
||||
hir::AssocItem::Function(i) => ast::AssocItem::Fn(i.source(db)?.value),
|
||||
hir::AssocItem::TypeAlias(i) => ast::AssocItem::TypeAlias(i.source(db)?.value),
|
||||
hir::AssocItem::Const(i) => ast::AssocItem::Const(i.source(db)?.value),
|
||||
};
|
||||
Some(item)
|
||||
})
|
||||
.filter(has_def_name)
|
||||
.filter(|it| match it {
|
||||
|
|
|
@ -106,8 +106,9 @@ impl Completions {
|
|||
func: hir::Function,
|
||||
local_name: Option<String>,
|
||||
) {
|
||||
let item = render_fn(RenderContext::new(ctx), None, local_name, func);
|
||||
self.add(item)
|
||||
if let Some(item) = render_fn(RenderContext::new(ctx), None, local_name, func) {
|
||||
self.add(item)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn add_variant_pat(
|
||||
|
|
|
@ -156,19 +156,21 @@ fn add_function_impl(
|
|||
};
|
||||
let range = TextRange::new(fn_def_node.text_range().start(), ctx.source_range().end());
|
||||
|
||||
let function_decl = function_declaration(&func.source(ctx.db).value);
|
||||
match ctx.config.snippet_cap {
|
||||
Some(cap) => {
|
||||
let snippet = format!("{} {{\n $0\n}}", function_decl);
|
||||
builder.snippet_edit(cap, TextEdit::replace(range, snippet))
|
||||
}
|
||||
None => {
|
||||
let header = format!("{} {{", function_decl);
|
||||
builder.text_edit(TextEdit::replace(range, header))
|
||||
if let Some(src) = func.source(ctx.db) {
|
||||
let function_decl = function_declaration(&src.value);
|
||||
match ctx.config.snippet_cap {
|
||||
Some(cap) => {
|
||||
let snippet = format!("{} {{\n $0\n}}", function_decl);
|
||||
builder.snippet_edit(cap, TextEdit::replace(range, snippet))
|
||||
}
|
||||
None => {
|
||||
let header = format!("{} {{", function_decl);
|
||||
builder.text_edit(TextEdit::replace(range, header))
|
||||
}
|
||||
}
|
||||
.kind(completion_kind)
|
||||
.add_to(acc);
|
||||
}
|
||||
.kind(completion_kind)
|
||||
.add_to(acc);
|
||||
}
|
||||
|
||||
fn add_type_alias_impl(
|
||||
|
@ -200,16 +202,19 @@ fn add_const_impl(
|
|||
let const_name = const_.name(ctx.db).map(|n| n.to_string());
|
||||
|
||||
if let Some(const_name) = const_name {
|
||||
let snippet = make_const_compl_syntax(&const_.source(ctx.db).value);
|
||||
if let Some(source) = const_.source(ctx.db) {
|
||||
let snippet = make_const_compl_syntax(&source.value);
|
||||
|
||||
let range = TextRange::new(const_def_node.text_range().start(), ctx.source_range().end());
|
||||
let range =
|
||||
TextRange::new(const_def_node.text_range().start(), ctx.source_range().end());
|
||||
|
||||
CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone())
|
||||
.text_edit(TextEdit::replace(range, snippet))
|
||||
.lookup_by(const_name)
|
||||
.kind(CompletionItemKind::Const)
|
||||
.set_documentation(const_.docs(ctx.db))
|
||||
.add_to(acc);
|
||||
CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone())
|
||||
.text_edit(TextEdit::replace(range, snippet))
|
||||
.lookup_by(const_name)
|
||||
.kind(CompletionItemKind::Const)
|
||||
.set_documentation(const_.docs(ctx.db))
|
||||
.add_to(acc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -157,8 +157,7 @@ impl<'a> Render<'a> {
|
|||
|
||||
let kind = match resolution {
|
||||
ScopeDef::ModuleDef(Function(func)) => {
|
||||
let item = render_fn(self.ctx, import_to_add, Some(local_name), *func);
|
||||
return Some(item);
|
||||
return render_fn(self.ctx, import_to_add, Some(local_name), *func);
|
||||
}
|
||||
ScopeDef::ModuleDef(Variant(_))
|
||||
if self.ctx.completion.is_pat_binding_or_const
|
||||
|
|
|
@ -15,7 +15,7 @@ pub(crate) fn render_const<'a>(
|
|||
ctx: RenderContext<'a>,
|
||||
const_: hir::Const,
|
||||
) -> Option<CompletionItem> {
|
||||
ConstRender::new(ctx, const_).render()
|
||||
ConstRender::new(ctx, const_)?.render()
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -26,9 +26,9 @@ struct ConstRender<'a> {
|
|||
}
|
||||
|
||||
impl<'a> ConstRender<'a> {
|
||||
fn new(ctx: RenderContext<'a>, const_: hir::Const) -> ConstRender<'a> {
|
||||
let ast_node = const_.source(ctx.db()).value;
|
||||
ConstRender { ctx, const_, ast_node }
|
||||
fn new(ctx: RenderContext<'a>, const_: hir::Const) -> Option<ConstRender<'a>> {
|
||||
let ast_node = const_.source(ctx.db())?.value;
|
||||
Some(ConstRender { ctx, const_, ast_node })
|
||||
}
|
||||
|
||||
fn render(self) -> Option<CompletionItem> {
|
||||
|
|
|
@ -14,9 +14,9 @@ pub(crate) fn render_fn<'a>(
|
|||
import_to_add: Option<ImportEdit>,
|
||||
local_name: Option<String>,
|
||||
fn_: hir::Function,
|
||||
) -> CompletionItem {
|
||||
) -> Option<CompletionItem> {
|
||||
let _p = profile::span("render_fn");
|
||||
FunctionRender::new(ctx, local_name, fn_).render(import_to_add)
|
||||
Some(FunctionRender::new(ctx, local_name, fn_)?.render(import_to_add))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -32,11 +32,11 @@ impl<'a> FunctionRender<'a> {
|
|||
ctx: RenderContext<'a>,
|
||||
local_name: Option<String>,
|
||||
fn_: hir::Function,
|
||||
) -> FunctionRender<'a> {
|
||||
) -> Option<FunctionRender<'a>> {
|
||||
let name = local_name.unwrap_or_else(|| fn_.name(ctx.db()).to_string());
|
||||
let ast_node = fn_.source(ctx.db()).value;
|
||||
let ast_node = fn_.source(ctx.db())?.value;
|
||||
|
||||
FunctionRender { ctx, name, func: fn_, ast_node }
|
||||
Some(FunctionRender { ctx, name, func: fn_, ast_node })
|
||||
}
|
||||
|
||||
fn render(self, import_to_add: Option<ImportEdit>) -> CompletionItem {
|
||||
|
|
|
@ -39,20 +39,13 @@ impl<'a> MacroRender<'a> {
|
|||
}
|
||||
|
||||
fn render(&self, import_to_add: Option<ImportEdit>) -> Option<CompletionItem> {
|
||||
// FIXME: Currently proc-macro do not have ast-node,
|
||||
// such that it does not have source
|
||||
// more discussion: https://github.com/rust-analyzer/rust-analyzer/issues/6913
|
||||
if self.macro_.is_proc_macro() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut builder =
|
||||
CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), &self.label())
|
||||
.kind(CompletionItemKind::Macro)
|
||||
.set_documentation(self.docs.clone())
|
||||
.set_deprecated(self.ctx.is_deprecated(self.macro_))
|
||||
.add_import(import_to_add)
|
||||
.detail(self.detail());
|
||||
.set_detail(self.detail());
|
||||
|
||||
let needs_bang = self.needs_bang();
|
||||
builder = match self.ctx.snippet_cap() {
|
||||
|
@ -95,9 +88,9 @@ impl<'a> MacroRender<'a> {
|
|||
format!("{}!", self.name)
|
||||
}
|
||||
|
||||
fn detail(&self) -> String {
|
||||
let ast_node = self.macro_.source(self.ctx.db()).value;
|
||||
macro_label(&ast_node)
|
||||
fn detail(&self) -> Option<String> {
|
||||
let ast_node = self.macro_.source(self.ctx.db())?.value;
|
||||
Some(macro_label(&ast_node))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ pub(crate) fn render_type_alias<'a>(
|
|||
ctx: RenderContext<'a>,
|
||||
type_alias: hir::TypeAlias,
|
||||
) -> Option<CompletionItem> {
|
||||
TypeAliasRender::new(ctx, type_alias).render()
|
||||
TypeAliasRender::new(ctx, type_alias)?.render()
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -26,9 +26,9 @@ struct TypeAliasRender<'a> {
|
|||
}
|
||||
|
||||
impl<'a> TypeAliasRender<'a> {
|
||||
fn new(ctx: RenderContext<'a>, type_alias: hir::TypeAlias) -> TypeAliasRender<'a> {
|
||||
let ast_node = type_alias.source(ctx.db()).value;
|
||||
TypeAliasRender { ctx, type_alias, ast_node }
|
||||
fn new(ctx: RenderContext<'a>, type_alias: hir::TypeAlias) -> Option<TypeAliasRender<'a>> {
|
||||
let ast_node = type_alias.source(ctx.db())?.value;
|
||||
Some(TypeAliasRender { ctx, type_alias, ast_node })
|
||||
}
|
||||
|
||||
fn render(self) -> Option<CompletionItem> {
|
||||
|
|
|
@ -983,13 +983,7 @@ impl MacroDef {
|
|||
|
||||
/// XXX: this parses the file
|
||||
pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
|
||||
// FIXME: Currently proc-macro do not have ast-node,
|
||||
// such that it does not have source
|
||||
// more discussion: https://github.com/rust-analyzer/rust-analyzer/issues/6913
|
||||
if self.is_proc_macro() {
|
||||
return None;
|
||||
}
|
||||
self.source(db).value.name().map(|it| it.as_name())
|
||||
self.source(db)?.value.name().map(|it| it.as_name())
|
||||
}
|
||||
|
||||
/// Indicate it is a proc-macro
|
||||
|
@ -1378,7 +1372,7 @@ impl Impl {
|
|||
}
|
||||
|
||||
pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> {
|
||||
let src = self.source(db);
|
||||
let src = self.source(db)?;
|
||||
let item = src.file_id.is_builtin_derive(db.upcast())?;
|
||||
let hygenic = hir_expand::hygiene::Hygiene::new(db.upcast(), item.file_id);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::{
|
|||
|
||||
pub trait HasSource {
|
||||
type Ast;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast>;
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>>;
|
||||
}
|
||||
|
||||
/// NB: Module is !HasSource, because it has two source nodes at the same time:
|
||||
|
@ -46,105 +46,104 @@ impl Module {
|
|||
|
||||
impl HasSource for Field {
|
||||
type Ast = FieldSource;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<FieldSource> {
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
let var = VariantId::from(self.parent);
|
||||
let src = var.child_source(db.upcast());
|
||||
src.map(|it| match it[self.id].clone() {
|
||||
let field_source = src.map(|it| match it[self.id].clone() {
|
||||
Either::Left(it) => FieldSource::Pos(it),
|
||||
Either::Right(it) => FieldSource::Named(it),
|
||||
})
|
||||
});
|
||||
Some(field_source)
|
||||
}
|
||||
}
|
||||
impl HasSource for Struct {
|
||||
type Ast = ast::Struct;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<ast::Struct> {
|
||||
self.id.lookup(db.upcast()).source(db.upcast())
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
Some(self.id.lookup(db.upcast()).source(db.upcast()))
|
||||
}
|
||||
}
|
||||
impl HasSource for Union {
|
||||
type Ast = ast::Union;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<ast::Union> {
|
||||
self.id.lookup(db.upcast()).source(db.upcast())
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
Some(self.id.lookup(db.upcast()).source(db.upcast()))
|
||||
}
|
||||
}
|
||||
impl HasSource for Enum {
|
||||
type Ast = ast::Enum;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<ast::Enum> {
|
||||
self.id.lookup(db.upcast()).source(db.upcast())
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
Some(self.id.lookup(db.upcast()).source(db.upcast()))
|
||||
}
|
||||
}
|
||||
impl HasSource for Variant {
|
||||
type Ast = ast::Variant;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<ast::Variant> {
|
||||
self.parent.id.child_source(db.upcast()).map(|map| map[self.id].clone())
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<ast::Variant>> {
|
||||
Some(self.parent.id.child_source(db.upcast()).map(|map| map[self.id].clone()))
|
||||
}
|
||||
}
|
||||
impl HasSource for Function {
|
||||
type Ast = ast::Fn;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<ast::Fn> {
|
||||
self.id.lookup(db.upcast()).source(db.upcast())
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
Some(self.id.lookup(db.upcast()).source(db.upcast()))
|
||||
}
|
||||
}
|
||||
impl HasSource for Const {
|
||||
type Ast = ast::Const;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<ast::Const> {
|
||||
self.id.lookup(db.upcast()).source(db.upcast())
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
Some(self.id.lookup(db.upcast()).source(db.upcast()))
|
||||
}
|
||||
}
|
||||
impl HasSource for Static {
|
||||
type Ast = ast::Static;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<ast::Static> {
|
||||
self.id.lookup(db.upcast()).source(db.upcast())
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
Some(self.id.lookup(db.upcast()).source(db.upcast()))
|
||||
}
|
||||
}
|
||||
impl HasSource for Trait {
|
||||
type Ast = ast::Trait;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<ast::Trait> {
|
||||
self.id.lookup(db.upcast()).source(db.upcast())
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
Some(self.id.lookup(db.upcast()).source(db.upcast()))
|
||||
}
|
||||
}
|
||||
impl HasSource for TypeAlias {
|
||||
type Ast = ast::TypeAlias;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<ast::TypeAlias> {
|
||||
self.id.lookup(db.upcast()).source(db.upcast())
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
Some(self.id.lookup(db.upcast()).source(db.upcast()))
|
||||
}
|
||||
}
|
||||
impl HasSource for MacroDef {
|
||||
type Ast = ast::Macro;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<ast::Macro> {
|
||||
InFile {
|
||||
file_id: self.id.ast_id.expect("MacroDef without ast_id").file_id,
|
||||
value: self.id.ast_id.expect("MacroDef without ast_id").to_node(db.upcast()),
|
||||
}
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
let ast_id = self.id.ast_id?;
|
||||
Some(InFile { file_id: ast_id.file_id, value: ast_id.to_node(db.upcast()) })
|
||||
}
|
||||
}
|
||||
impl HasSource for Impl {
|
||||
type Ast = ast::Impl;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<ast::Impl> {
|
||||
self.id.lookup(db.upcast()).source(db.upcast())
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
Some(self.id.lookup(db.upcast()).source(db.upcast()))
|
||||
}
|
||||
}
|
||||
|
||||
impl HasSource for TypeParam {
|
||||
type Ast = Either<ast::Trait, ast::TypeParam>;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> {
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
let child_source = self.id.parent.child_source(db.upcast());
|
||||
child_source.map(|it| it[self.id.local_id].clone())
|
||||
Some(child_source.map(|it| it[self.id.local_id].clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl HasSource for LifetimeParam {
|
||||
type Ast = ast::LifetimeParam;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> {
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
let child_source = self.id.parent.child_source(db.upcast());
|
||||
child_source.map(|it| it[self.id.local_id].clone())
|
||||
Some(child_source.map(|it| it[self.id.local_id].clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl HasSource for ConstParam {
|
||||
type Ast = ast::ConstParam;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> {
|
||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||
let child_source = self.id.parent.child_source(db.upcast());
|
||||
child_source.map(|it| it[self.id.local_id].clone())
|
||||
Some(child_source.map(|it| it[self.id.local_id].clone()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use ide_db::RootDatabase;
|
|||
use syntax::{ast, match_ast, AstNode, TextRange};
|
||||
|
||||
use crate::{
|
||||
display::ToNav, goto_definition, references, FilePosition, NavigationTarget, RangeInfo,
|
||||
display::TryToNav, goto_definition, references, FilePosition, NavigationTarget, RangeInfo,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -61,7 +61,7 @@ pub(crate) fn incoming_calls(db: &RootDatabase, position: FilePosition) -> Optio
|
|||
match node {
|
||||
ast::Fn(it) => {
|
||||
let def = sema.to_def(&it)?;
|
||||
Some(def.to_nav(sema.db))
|
||||
def.try_to_nav(sema.db)
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Optio
|
|||
match callable.kind() {
|
||||
hir::CallableKind::Function(it) => {
|
||||
let fn_def: hir::Function = it.into();
|
||||
let nav = fn_def.to_nav(db);
|
||||
let nav = fn_def.try_to_nav(db)?;
|
||||
Some(nav)
|
||||
}
|
||||
_ => None,
|
||||
|
@ -107,7 +107,7 @@ pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Optio
|
|||
}
|
||||
FnCallNode::MethodCallExpr(expr) => {
|
||||
let function = sema.resolve_method_call(&expr)?;
|
||||
Some(function.to_nav(db))
|
||||
function.try_to_nav(db)
|
||||
}
|
||||
} {
|
||||
Some((func_target, name_ref.syntax().text_range()))
|
||||
|
|
|
@ -156,20 +156,23 @@ fn missing_record_expr_field_fix(
|
|||
let record_fields = match VariantDef::from(def_id) {
|
||||
VariantDef::Struct(s) => {
|
||||
module = s.module(sema.db);
|
||||
let source = s.source(sema.db);
|
||||
#[allow(deprecated)]
|
||||
let source = s.source(sema.db)?;
|
||||
def_file_id = source.file_id;
|
||||
let fields = source.value.field_list()?;
|
||||
record_field_list(fields)?
|
||||
}
|
||||
VariantDef::Union(u) => {
|
||||
module = u.module(sema.db);
|
||||
let source = u.source(sema.db);
|
||||
#[allow(deprecated)]
|
||||
let source = u.source(sema.db)?;
|
||||
def_file_id = source.file_id;
|
||||
source.value.record_field_list()?
|
||||
}
|
||||
VariantDef::Variant(e) => {
|
||||
module = e.module(sema.db);
|
||||
let source = e.source(sema.db);
|
||||
#[allow(deprecated)]
|
||||
let source = e.source(sema.db)?;
|
||||
def_file_id = source.file_id;
|
||||
let fields = source.value.field_list()?;
|
||||
record_field_list(fields)?
|
||||
|
|
|
@ -210,41 +210,32 @@ impl ToNav for FileSymbol {
|
|||
impl TryToNav for Definition {
|
||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||
match self {
|
||||
Definition::Macro(it) => {
|
||||
// FIXME: Currently proc-macro do not have ast-node,
|
||||
// such that it does not have source
|
||||
// more discussion: https://github.com/rust-analyzer/rust-analyzer/issues/6913
|
||||
if it.is_proc_macro() {
|
||||
return None;
|
||||
}
|
||||
Some(it.to_nav(db))
|
||||
}
|
||||
Definition::Field(it) => Some(it.to_nav(db)),
|
||||
Definition::Macro(it) => it.try_to_nav(db),
|
||||
Definition::Field(it) => it.try_to_nav(db),
|
||||
Definition::ModuleDef(it) => it.try_to_nav(db),
|
||||
Definition::SelfType(it) => Some(it.to_nav(db)),
|
||||
Definition::SelfType(it) => it.try_to_nav(db),
|
||||
Definition::Local(it) => Some(it.to_nav(db)),
|
||||
Definition::TypeParam(it) => Some(it.to_nav(db)),
|
||||
Definition::LifetimeParam(it) => Some(it.to_nav(db)),
|
||||
Definition::TypeParam(it) => it.try_to_nav(db),
|
||||
Definition::LifetimeParam(it) => it.try_to_nav(db),
|
||||
Definition::Label(it) => Some(it.to_nav(db)),
|
||||
Definition::ConstParam(it) => Some(it.to_nav(db)),
|
||||
Definition::ConstParam(it) => it.try_to_nav(db),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryToNav for hir::ModuleDef {
|
||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||
let res = match self {
|
||||
hir::ModuleDef::Module(it) => it.to_nav(db),
|
||||
hir::ModuleDef::Function(it) => it.to_nav(db),
|
||||
hir::ModuleDef::Adt(it) => it.to_nav(db),
|
||||
hir::ModuleDef::Variant(it) => it.to_nav(db),
|
||||
hir::ModuleDef::Const(it) => it.to_nav(db),
|
||||
hir::ModuleDef::Static(it) => it.to_nav(db),
|
||||
hir::ModuleDef::Trait(it) => it.to_nav(db),
|
||||
hir::ModuleDef::TypeAlias(it) => it.to_nav(db),
|
||||
hir::ModuleDef::BuiltinType(_) => return None,
|
||||
};
|
||||
Some(res)
|
||||
match self {
|
||||
hir::ModuleDef::Module(it) => Some(it.to_nav(db)),
|
||||
hir::ModuleDef::Function(it) => it.try_to_nav(db),
|
||||
hir::ModuleDef::Adt(it) => it.try_to_nav(db),
|
||||
hir::ModuleDef::Variant(it) => it.try_to_nav(db),
|
||||
hir::ModuleDef::Const(it) => it.try_to_nav(db),
|
||||
hir::ModuleDef::Static(it) => it.try_to_nav(db),
|
||||
hir::ModuleDef::Trait(it) => it.try_to_nav(db),
|
||||
hir::ModuleDef::TypeAlias(it) => it.try_to_nav(db),
|
||||
hir::ModuleDef::BuiltinType(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,13 +270,13 @@ impl ToNavFromAst for hir::Trait {
|
|||
const KIND: SymbolKind = SymbolKind::Trait;
|
||||
}
|
||||
|
||||
impl<D> ToNav for D
|
||||
impl<D> TryToNav for D
|
||||
where
|
||||
D: HasSource + ToNavFromAst + Copy + HasAttrs,
|
||||
D::Ast: ast::NameOwner + ShortLabel,
|
||||
{
|
||||
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
|
||||
let src = self.source(db);
|
||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||
let src = self.source(db)?;
|
||||
let mut res = NavigationTarget::from_named(
|
||||
db,
|
||||
src.as_ref().map(|it| it as &dyn ast::NameOwner),
|
||||
|
@ -293,7 +284,7 @@ where
|
|||
);
|
||||
res.docs = self.docs(db);
|
||||
res.description = src.value.short_label();
|
||||
res
|
||||
Some(res)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,9 +303,9 @@ impl ToNav for hir::Module {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToNav for hir::Impl {
|
||||
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
|
||||
let src = self.source(db);
|
||||
impl TryToNav for hir::Impl {
|
||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||
let src = self.source(db)?;
|
||||
let derive_attr = self.is_builtin_derive(db);
|
||||
let frange = if let Some(item) = &derive_attr {
|
||||
item.syntax().original_file_range(db)
|
||||
|
@ -327,21 +318,21 @@ impl ToNav for hir::Impl {
|
|||
src.value.self_ty().map(|ty| src.with_value(ty.syntax()).original_file_range(db).range)
|
||||
};
|
||||
|
||||
NavigationTarget::from_syntax(
|
||||
Some(NavigationTarget::from_syntax(
|
||||
frange.file_id,
|
||||
"impl".into(),
|
||||
focus_range,
|
||||
frange.range,
|
||||
SymbolKind::Impl,
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNav for hir::Field {
|
||||
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
|
||||
let src = self.source(db);
|
||||
impl TryToNav for hir::Field {
|
||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||
let src = self.source(db)?;
|
||||
|
||||
match &src.value {
|
||||
let field_source = match &src.value {
|
||||
FieldSource::Named(it) => {
|
||||
let mut res =
|
||||
NavigationTarget::from_named(db, src.with_value(it), SymbolKind::Field);
|
||||
|
@ -359,13 +350,14 @@ impl ToNav for hir::Field {
|
|||
SymbolKind::Field,
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
Some(field_source)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNav for hir::MacroDef {
|
||||
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
|
||||
let src = self.source(db);
|
||||
impl TryToNav for hir::MacroDef {
|
||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||
let src = self.source(db)?;
|
||||
log::debug!("nav target {:#?}", src.value.syntax());
|
||||
let mut res = NavigationTarget::from_named(
|
||||
db,
|
||||
|
@ -373,26 +365,26 @@ impl ToNav for hir::MacroDef {
|
|||
SymbolKind::Macro,
|
||||
);
|
||||
res.docs = self.docs(db);
|
||||
res
|
||||
Some(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNav for hir::Adt {
|
||||
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
|
||||
impl TryToNav for hir::Adt {
|
||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||
match self {
|
||||
hir::Adt::Struct(it) => it.to_nav(db),
|
||||
hir::Adt::Union(it) => it.to_nav(db),
|
||||
hir::Adt::Enum(it) => it.to_nav(db),
|
||||
hir::Adt::Struct(it) => it.try_to_nav(db),
|
||||
hir::Adt::Union(it) => it.try_to_nav(db),
|
||||
hir::Adt::Enum(it) => it.try_to_nav(db),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNav for hir::AssocItem {
|
||||
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
|
||||
impl TryToNav for hir::AssocItem {
|
||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||
match self {
|
||||
AssocItem::Function(it) => it.to_nav(db),
|
||||
AssocItem::Const(it) => it.to_nav(db),
|
||||
AssocItem::TypeAlias(it) => it.to_nav(db),
|
||||
AssocItem::Function(it) => it.try_to_nav(db),
|
||||
AssocItem::Const(it) => it.try_to_nav(db),
|
||||
AssocItem::TypeAlias(it) => it.try_to_nav(db),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -446,9 +438,9 @@ impl ToNav for hir::Label {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToNav for hir::TypeParam {
|
||||
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
|
||||
let src = self.source(db);
|
||||
impl TryToNav for hir::TypeParam {
|
||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||
let src = self.source(db)?;
|
||||
let full_range = match &src.value {
|
||||
Either::Left(it) => it.syntax().text_range(),
|
||||
Either::Right(it) => it.syntax().text_range(),
|
||||
|
@ -457,7 +449,7 @@ impl ToNav for hir::TypeParam {
|
|||
Either::Left(_) => None,
|
||||
Either::Right(it) => it.name().map(|it| it.syntax().text_range()),
|
||||
};
|
||||
NavigationTarget {
|
||||
Some(NavigationTarget {
|
||||
file_id: src.file_id.original_file(db),
|
||||
name: self.name(db).to_string().into(),
|
||||
kind: Some(SymbolKind::TypeParam),
|
||||
|
@ -466,15 +458,15 @@ impl ToNav for hir::TypeParam {
|
|||
container_name: None,
|
||||
description: None,
|
||||
docs: None,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNav for hir::LifetimeParam {
|
||||
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
|
||||
let src = self.source(db);
|
||||
impl TryToNav for hir::LifetimeParam {
|
||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||
let src = self.source(db)?;
|
||||
let full_range = src.value.syntax().text_range();
|
||||
NavigationTarget {
|
||||
Some(NavigationTarget {
|
||||
file_id: src.file_id.original_file(db),
|
||||
name: self.name(db).to_string().into(),
|
||||
kind: Some(SymbolKind::LifetimeParam),
|
||||
|
@ -483,15 +475,15 @@ impl ToNav for hir::LifetimeParam {
|
|||
container_name: None,
|
||||
description: None,
|
||||
docs: None,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNav for hir::ConstParam {
|
||||
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
|
||||
let src = self.source(db);
|
||||
impl TryToNav for hir::ConstParam {
|
||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||
let src = self.source(db)?;
|
||||
let full_range = src.value.syntax().text_range();
|
||||
NavigationTarget {
|
||||
Some(NavigationTarget {
|
||||
file_id: src.file_id.original_file(db),
|
||||
name: self.name(db).to_string().into(),
|
||||
kind: Some(SymbolKind::ConstParam),
|
||||
|
@ -500,7 +492,7 @@ impl ToNav for hir::ConstParam {
|
|||
container_name: None,
|
||||
description: None,
|
||||
docs: None,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use hir::{Crate, Impl, Semantics};
|
|||
use ide_db::RootDatabase;
|
||||
use syntax::{algo::find_node_at_offset, ast, AstNode};
|
||||
|
||||
use crate::{display::ToNav, FilePosition, NavigationTarget, RangeInfo};
|
||||
use crate::{display::TryToNav, FilePosition, NavigationTarget, RangeInfo};
|
||||
|
||||
// Feature: Go to Implementation
|
||||
//
|
||||
|
@ -55,7 +55,7 @@ fn impls_for_def(
|
|||
impls
|
||||
.into_iter()
|
||||
.filter(|impl_def| ty.is_equal_for_find_impls(&impl_def.target_ty(sema.db)))
|
||||
.map(|imp| imp.to_nav(sema.db))
|
||||
.filter_map(|imp| imp.try_to_nav(sema.db))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ fn impls_for_trait(
|
|||
|
||||
let impls = Impl::for_trait(sema.db, krate, tr);
|
||||
|
||||
Some(impls.into_iter().map(|imp| imp.to_nav(sema.db)).collect())
|
||||
Some(impls.into_iter().filter_map(|imp| imp.try_to_nav(sema.db)).collect())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ide_db::RootDatabase;
|
||||
use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T};
|
||||
|
||||
use crate::{display::ToNav, FilePosition, NavigationTarget, RangeInfo};
|
||||
use crate::{display::TryToNav, FilePosition, NavigationTarget, RangeInfo};
|
||||
|
||||
// Feature: Go to Type Definition
|
||||
//
|
||||
|
@ -37,7 +37,7 @@ pub(crate) fn goto_type_definition(
|
|||
|
||||
let adt_def = ty.autoderef(db).filter_map(|ty| ty.as_adt()).last()?;
|
||||
|
||||
let nav = adt_def.to_nav(db);
|
||||
let nav = adt_def.try_to_nav(db)?;
|
||||
Some(RangeInfo::new(node.text_range(), vec![nav]))
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset,
|
|||
use test_utils::mark;
|
||||
|
||||
use crate::{
|
||||
display::{macro_label, ShortLabel, ToNav, TryToNav},
|
||||
display::{macro_label, ShortLabel, TryToNav},
|
||||
doc_links::{remove_links, rewrite_links},
|
||||
markdown_remove::remove_markdown,
|
||||
markup::Markup,
|
||||
|
@ -183,10 +183,10 @@ fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<Hov
|
|||
|
||||
match def {
|
||||
Definition::ModuleDef(it) => match it {
|
||||
ModuleDef::Adt(Adt::Struct(it)) => Some(to_action(it.to_nav(db))),
|
||||
ModuleDef::Adt(Adt::Union(it)) => Some(to_action(it.to_nav(db))),
|
||||
ModuleDef::Adt(Adt::Enum(it)) => Some(to_action(it.to_nav(db))),
|
||||
ModuleDef::Trait(it) => Some(to_action(it.to_nav(db))),
|
||||
ModuleDef::Adt(Adt::Struct(it)) => Some(to_action(it.try_to_nav(db)?)),
|
||||
ModuleDef::Adt(Adt::Union(it)) => Some(to_action(it.try_to_nav(db)?)),
|
||||
ModuleDef::Adt(Adt::Enum(it)) => Some(to_action(it.try_to_nav(db)?)),
|
||||
ModuleDef::Trait(it) => Some(to_action(it.try_to_nav(db)?)),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
|
@ -206,7 +206,8 @@ fn runnable_action(
|
|||
_ => None,
|
||||
},
|
||||
ModuleDef::Function(it) => {
|
||||
let src = it.source(sema.db);
|
||||
#[allow(deprecated)]
|
||||
let src = it.source(sema.db)?;
|
||||
if src.file_id != file_id.into() {
|
||||
mark::hit!(hover_macro_generated_struct_fn_doc_comment);
|
||||
mark::hit!(hover_macro_generated_struct_fn_doc_attr);
|
||||
|
@ -326,17 +327,12 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> {
|
|||
let mod_path = definition_mod_path(db, &def);
|
||||
return match def {
|
||||
Definition::Macro(it) => {
|
||||
// FIXME: Currently proc-macro do not have ast-node,
|
||||
// such that it does not have source
|
||||
// more discussion: https://github.com/rust-analyzer/rust-analyzer/issues/6913
|
||||
if it.is_proc_macro() {
|
||||
return None;
|
||||
}
|
||||
let label = macro_label(&it.source(db).value);
|
||||
let label = macro_label(&it.source(db)?.value);
|
||||
from_def_source_labeled(db, it, Some(label), mod_path)
|
||||
}
|
||||
Definition::Field(def) => {
|
||||
let src = def.source(db).value;
|
||||
#[allow(deprecated)]
|
||||
let src = def.source(db)?.value;
|
||||
if let FieldSource::Named(it) = src {
|
||||
from_def_source_labeled(db, def, it.short_label(), mod_path)
|
||||
} else {
|
||||
|
@ -385,7 +381,8 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> {
|
|||
D: HasSource<Ast = A> + HasAttrs + Copy,
|
||||
A: ShortLabel,
|
||||
{
|
||||
let short_label = def.source(db).value.short_label();
|
||||
#[allow(deprecated)]
|
||||
let short_label = def.source(db)?.value.short_label();
|
||||
from_def_source_labeled(db, def, short_label, mod_path)
|
||||
}
|
||||
|
||||
|
|
|
@ -121,31 +121,56 @@ impl Definition {
|
|||
|
||||
if let Definition::Local(var) = self {
|
||||
let range = match var.parent(db) {
|
||||
DefWithBody::Function(f) => f.source(db).value.syntax().text_range(),
|
||||
DefWithBody::Const(c) => c.source(db).value.syntax().text_range(),
|
||||
DefWithBody::Static(s) => s.source(db).value.syntax().text_range(),
|
||||
DefWithBody::Function(f) => {
|
||||
f.source(db).and_then(|src| Some(src.value.syntax().text_range()))
|
||||
}
|
||||
DefWithBody::Const(c) => {
|
||||
c.source(db).and_then(|src| Some(src.value.syntax().text_range()))
|
||||
}
|
||||
DefWithBody::Static(s) => {
|
||||
s.source(db).and_then(|src| Some(src.value.syntax().text_range()))
|
||||
}
|
||||
};
|
||||
let mut res = FxHashMap::default();
|
||||
res.insert(file_id, Some(range));
|
||||
res.insert(file_id, range);
|
||||
return SearchScope::new(res);
|
||||
}
|
||||
|
||||
if let Definition::LifetimeParam(param) = self {
|
||||
#[allow(deprecated)]
|
||||
let range = match param.parent(db) {
|
||||
hir::GenericDef::Function(it) => it.source(db).value.syntax().text_range(),
|
||||
hir::GenericDef::Function(it) => {
|
||||
it.source(db).and_then(|src| Some(src.value.syntax().text_range()))
|
||||
}
|
||||
hir::GenericDef::Adt(it) => match it {
|
||||
hir::Adt::Struct(it) => it.source(db).value.syntax().text_range(),
|
||||
hir::Adt::Union(it) => it.source(db).value.syntax().text_range(),
|
||||
hir::Adt::Enum(it) => it.source(db).value.syntax().text_range(),
|
||||
hir::Adt::Struct(it) => {
|
||||
it.source(db).and_then(|src| Some(src.value.syntax().text_range()))
|
||||
}
|
||||
hir::Adt::Union(it) => {
|
||||
it.source(db).and_then(|src| Some(src.value.syntax().text_range()))
|
||||
}
|
||||
hir::Adt::Enum(it) => {
|
||||
it.source(db).and_then(|src| Some(src.value.syntax().text_range()))
|
||||
}
|
||||
},
|
||||
hir::GenericDef::Trait(it) => it.source(db).value.syntax().text_range(),
|
||||
hir::GenericDef::TypeAlias(it) => it.source(db).value.syntax().text_range(),
|
||||
hir::GenericDef::Impl(it) => it.source(db).value.syntax().text_range(),
|
||||
hir::GenericDef::Variant(it) => it.source(db).value.syntax().text_range(),
|
||||
hir::GenericDef::Const(it) => it.source(db).value.syntax().text_range(),
|
||||
hir::GenericDef::Trait(it) => {
|
||||
it.source(db).and_then(|src| Some(src.value.syntax().text_range()))
|
||||
}
|
||||
hir::GenericDef::TypeAlias(it) => {
|
||||
it.source(db).and_then(|src| Some(src.value.syntax().text_range()))
|
||||
}
|
||||
hir::GenericDef::Impl(it) => {
|
||||
it.source(db).and_then(|src| Some(src.value.syntax().text_range()))
|
||||
}
|
||||
hir::GenericDef::Variant(it) => {
|
||||
it.source(db).and_then(|src| Some(src.value.syntax().text_range()))
|
||||
}
|
||||
hir::GenericDef::Const(it) => {
|
||||
it.source(db).and_then(|src| Some(src.value.syntax().text_range()))
|
||||
}
|
||||
};
|
||||
let mut res = FxHashMap::default();
|
||||
res.insert(file_id, Some(range));
|
||||
res.insert(file_id, range);
|
||||
return SearchScope::new(res);
|
||||
}
|
||||
|
||||
|
|
|
@ -161,11 +161,12 @@ impl AnalysisStatsCmd {
|
|||
}
|
||||
let mut msg = format!("processing: {}", full_name);
|
||||
if verbosity.is_verbose() {
|
||||
let src = f.source(db);
|
||||
let original_file = src.file_id.original_file(db);
|
||||
let path = vfs.file_path(original_file);
|
||||
let syntax_range = src.value.syntax().text_range();
|
||||
format_to!(msg, " ({} {:?})", path, syntax_range);
|
||||
if let Some(src) = f.source(db) {
|
||||
let original_file = src.file_id.original_file(db);
|
||||
let path = vfs.file_path(original_file);
|
||||
let syntax_range = src.value.syntax().text_range();
|
||||
format_to!(msg, " ({} {:?})", path, syntax_range);
|
||||
}
|
||||
}
|
||||
if verbosity.is_spammy() {
|
||||
bar.println(msg.to_string());
|
||||
|
|
Loading…
Reference in a new issue