Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/assists/src/handlers/fill_match_arms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
27 changes: 14 additions & 13 deletions crates/assists/src/handlers/fix_visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down
12 changes: 8 additions & 4 deletions crates/assists/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an interesting case! In the future(not this PR), we should add hir -> ast function which either uses an existing source, or just renders the hir directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. I've seen reference to using hir for more in a few comments in the codebase.

.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 {
Expand Down
5 changes: 3 additions & 2 deletions crates/completion/src/completions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
47 changes: 26 additions & 21 deletions crates/completion/src/completions/trait_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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);

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);
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());

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);
}
}
}

Expand Down
3 changes: 1 addition & 2 deletions crates/completion/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions crates/completion/src/render/const_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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> {
Expand Down
10 changes: 5 additions & 5 deletions crates/completion/src/render/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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 {
Expand Down
15 changes: 4 additions & 11 deletions crates/completion/src/render/macro_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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))
}
}

Expand Down
8 changes: 4 additions & 4 deletions crates/completion/src/render/type_alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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> {
Expand Down
10 changes: 2 additions & 8 deletions crates/hir/src/code_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);

Expand Down
Loading