Add find_or_create_impl_block to assist utils

This commit is contained in:
Yoshua Wuyts 2021-02-05 16:32:34 +01:00
parent ae7bee70a1
commit 2cf1612669
3 changed files with 30 additions and 29 deletions

View file

@ -1,9 +1,12 @@
use stdx::{format_to, to_lower_snake_case};
use syntax::ast::VisibilityOwner;
use syntax::ast::{self, AstNode, NameOwner};
use syntax::{ast::VisibilityOwner, T};
use test_utils::mark;
use crate::{utils::find_struct_impl, AssistContext, AssistId, AssistKind, Assists};
use crate::{
utils::{find_impl_block, find_struct_impl},
AssistContext, AssistId, AssistKind, Assists,
};
// Assist: generate_enum_match_method
//
@ -61,7 +64,6 @@ pub(crate) fn generate_enum_match_method(acc: &mut Assists, ctx: &AssistContext)
}
let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{} ", v));
format_to!(
buf,
" {}fn is_{}(&self) -> bool {{
@ -73,17 +75,7 @@ pub(crate) fn generate_enum_match_method(acc: &mut Assists, ctx: &AssistContext)
);
let start_offset = impl_def
.and_then(|impl_def| {
buf.push('\n');
let start = impl_def
.syntax()
.descendants_with_tokens()
.find(|t| t.kind() == T!['{'])?
.text_range()
.end();
Some(start)
})
.and_then(|impl_def| find_impl_block(impl_def, &mut buf))
.unwrap_or_else(|| {
buf = generate_impl_text(&parent_enum, &buf);
parent_enum.syntax().text_range().end()

View file

@ -2,10 +2,13 @@ use itertools::Itertools;
use stdx::format_to;
use syntax::{
ast::{self, AstNode, GenericParamsOwner, NameOwner, StructKind, VisibilityOwner},
SmolStr, T,
SmolStr,
};
use crate::{utils::find_struct_impl, AssistContext, AssistId, AssistKind, Assists};
use crate::{
utils::{find_impl_block, find_struct_impl},
AssistContext, AssistId, AssistKind, Assists,
};
// Assist: generate_new
//
@ -58,17 +61,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields);
let start_offset = impl_def
.and_then(|impl_def| {
buf.push('\n');
let start = impl_def
.syntax()
.descendants_with_tokens()
.find(|t| t.kind() == T!['{'])?
.text_range()
.end();
Some(start)
})
.and_then(|impl_def| find_impl_block(impl_def, &mut buf))
.unwrap_or_else(|| {
buf = generate_impl_text(&strukt, &buf);
strukt.syntax().text_range().end()
@ -93,7 +86,7 @@ fn generate_impl_text(strukt: &ast::Struct, code: &str) -> String {
if let Some(type_params) = &type_params {
format_to!(buf, "{}", type_params.syntax());
}
buf.push_str(" ");
buf.push(' ');
buf.push_str(strukt.name().unwrap().text());
if let Some(type_params) = type_params {
let lifetime_params = type_params

View file

@ -274,10 +274,11 @@ pub(crate) fn does_pat_match_variant(pat: &ast::Pat, var: &ast::Pat) -> bool {
// Uses a syntax-driven approach to find any impl blocks for the struct that
// exist within the module/file
//
// Returns `None` if we've found an existing `new` fn
// Returns `None` if we've found an existing fn
//
// FIXME: change the new fn checking to a more semantic approach when that's more
// viable (e.g. we process proc macros, etc)
// FIXME: this partially overlaps with `find_impl_block`
pub(crate) fn find_struct_impl(
ctx: &AssistContext,
strukt: &ast::AdtDef,
@ -338,3 +339,18 @@ fn has_fn(imp: &ast::Impl, rhs_name: &str) -> bool {
false
}
/// Find the start of the `impl` block for the given `ast::Impl`.
//
// FIXME: add a way to find the end of the `impl` block.
// FIXME: this partially overlaps with `find_struct_impl`
pub(crate) fn find_impl_block(impl_def: ast::Impl, buf: &mut String) -> Option<TextSize> {
buf.push('\n');
let start = impl_def
.syntax()
.descendants_with_tokens()
.find(|t| t.kind() == T!['{'])?
.text_range()
.end();
Some(start)
}