mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Add find_impl_block_end
assist helper
This commit is contained in:
parent
cf44953210
commit
ac959b82b3
6 changed files with 171 additions and 18 deletions
|
@ -4,7 +4,7 @@ use syntax::ast::{self, AstNode, NameOwner};
|
||||||
use test_utils::mark;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
utils::{find_impl_block, find_struct_impl, generate_impl_text},
|
utils::{find_impl_block_end, find_struct_impl, generate_impl_text},
|
||||||
AssistContext, AssistId, AssistKind, Assists,
|
AssistContext, AssistId, AssistKind, Assists,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ pub(crate) fn generate_enum_match_method(acc: &mut Assists, ctx: &AssistContext)
|
||||||
);
|
);
|
||||||
|
|
||||||
let start_offset = impl_def
|
let start_offset = impl_def
|
||||||
.and_then(|impl_def| find_impl_block(impl_def, &mut buf))
|
.and_then(|impl_def| find_impl_block_end(impl_def, &mut buf))
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
buf = generate_impl_text(&ast::Adt::Enum(parent_enum.clone()), &buf);
|
buf = generate_impl_text(&ast::Adt::Enum(parent_enum.clone()), &buf);
|
||||||
parent_enum.syntax().text_range().end()
|
parent_enum.syntax().text_range().end()
|
||||||
|
@ -197,6 +197,43 @@ impl Variant {
|
||||||
pub(crate) fn is_minor(&self) -> bool {
|
pub(crate) fn is_minor(&self) -> bool {
|
||||||
matches!(self, Self::Minor)
|
matches!(self, Self::Minor)
|
||||||
}
|
}
|
||||||
|
}"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_multiple_generate_enum_match_from_variant() {
|
||||||
|
check_assist(
|
||||||
|
generate_enum_match_method,
|
||||||
|
r#"
|
||||||
|
enum Variant {
|
||||||
|
Undefined,
|
||||||
|
Minor,
|
||||||
|
Major$0,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Variant {
|
||||||
|
/// Returns `true` if the variant is [`Minor`].
|
||||||
|
fn is_minor(&self) -> bool {
|
||||||
|
matches!(self, Self::Minor)
|
||||||
|
}
|
||||||
|
}"#,
|
||||||
|
r#"enum Variant {
|
||||||
|
Undefined,
|
||||||
|
Minor,
|
||||||
|
Major,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Variant {
|
||||||
|
/// Returns `true` if the variant is [`Minor`].
|
||||||
|
fn is_minor(&self) -> bool {
|
||||||
|
matches!(self, Self::Minor)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the variant is [`Major`].
|
||||||
|
fn is_major(&self) -> bool {
|
||||||
|
matches!(self, Self::Major)
|
||||||
|
}
|
||||||
}"#,
|
}"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use syntax::ast::VisibilityOwner;
|
||||||
use syntax::ast::{self, AstNode, NameOwner};
|
use syntax::ast::{self, AstNode, NameOwner};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
utils::{find_impl_block, find_struct_impl, generate_impl_text},
|
utils::{find_impl_block_end, find_struct_impl, generate_impl_text},
|
||||||
AssistContext, AssistId, AssistKind, Assists,
|
AssistContext, AssistId, AssistKind, Assists,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ pub(crate) fn generate_getter(acc: &mut Assists, ctx: &AssistContext) -> Option<
|
||||||
);
|
);
|
||||||
|
|
||||||
let start_offset = impl_def
|
let start_offset = impl_def
|
||||||
.and_then(|impl_def| find_impl_block(impl_def, &mut buf))
|
.and_then(|impl_def| find_impl_block_end(impl_def, &mut buf))
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf);
|
buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf);
|
||||||
strukt.syntax().text_range().end()
|
strukt.syntax().text_range().end()
|
||||||
|
@ -150,6 +150,42 @@ impl<T: Clone> Context<T> {
|
||||||
pub(crate) fn data(&self) -> &T {
|
pub(crate) fn data(&self) -> &T {
|
||||||
&self.data
|
&self.data
|
||||||
}
|
}
|
||||||
|
}"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_multiple_generate_getter() {
|
||||||
|
check_assist(
|
||||||
|
generate_getter,
|
||||||
|
r#"
|
||||||
|
struct Context<T: Clone> {
|
||||||
|
data: T,
|
||||||
|
cou$0nt: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> Context<T> {
|
||||||
|
/// Get a reference to the context's data.
|
||||||
|
fn data(&self) -> &T {
|
||||||
|
&self.data
|
||||||
|
}
|
||||||
|
}"#,
|
||||||
|
r#"
|
||||||
|
struct Context<T: Clone> {
|
||||||
|
data: T,
|
||||||
|
count: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> Context<T> {
|
||||||
|
/// Get a reference to the context's data.
|
||||||
|
fn data(&self) -> &T {
|
||||||
|
&self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a reference to the context's count.
|
||||||
|
fn count(&self) -> &usize {
|
||||||
|
&self.count
|
||||||
|
}
|
||||||
}"#,
|
}"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use syntax::ast::VisibilityOwner;
|
||||||
use syntax::ast::{self, AstNode, NameOwner};
|
use syntax::ast::{self, AstNode, NameOwner};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
utils::{find_impl_block, find_struct_impl, generate_impl_text},
|
utils::{find_impl_block_end, find_struct_impl, generate_impl_text},
|
||||||
AssistContext, AssistId, AssistKind, Assists,
|
AssistContext, AssistId, AssistKind, Assists,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ pub(crate) fn generate_getter_mut(acc: &mut Assists, ctx: &AssistContext) -> Opt
|
||||||
);
|
);
|
||||||
|
|
||||||
let start_offset = impl_def
|
let start_offset = impl_def
|
||||||
.and_then(|impl_def| find_impl_block(impl_def, &mut buf))
|
.and_then(|impl_def| find_impl_block_end(impl_def, &mut buf))
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf);
|
buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf);
|
||||||
strukt.syntax().text_range().end()
|
strukt.syntax().text_range().end()
|
||||||
|
@ -153,6 +153,42 @@ impl<T: Clone> Context<T> {
|
||||||
pub(crate) fn data_mut(&mut self) -> &mut T {
|
pub(crate) fn data_mut(&mut self) -> &mut T {
|
||||||
&mut self.data
|
&mut self.data
|
||||||
}
|
}
|
||||||
|
}"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_multiple_generate_getter_mut() {
|
||||||
|
check_assist(
|
||||||
|
generate_getter_mut,
|
||||||
|
r#"
|
||||||
|
struct Context<T: Clone> {
|
||||||
|
data: T,
|
||||||
|
cou$0nt: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> Context<T> {
|
||||||
|
/// Get a mutable reference to the context's data.
|
||||||
|
fn data_mut(&mut self) -> &mut T {
|
||||||
|
&mut self.data
|
||||||
|
}
|
||||||
|
}"#,
|
||||||
|
r#"
|
||||||
|
struct Context<T: Clone> {
|
||||||
|
data: T,
|
||||||
|
count: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> Context<T> {
|
||||||
|
/// Get a mutable reference to the context's data.
|
||||||
|
fn data_mut(&mut self) -> &mut T {
|
||||||
|
&mut self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a mutable reference to the context's count.
|
||||||
|
fn count_mut(&mut self) -> &mut usize {
|
||||||
|
&mut self.count
|
||||||
|
}
|
||||||
}"#,
|
}"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use stdx::format_to;
|
||||||
use syntax::ast::{self, AstNode, NameOwner, StructKind, VisibilityOwner};
|
use syntax::ast::{self, AstNode, NameOwner, StructKind, VisibilityOwner};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
utils::{find_impl_block, find_struct_impl, generate_impl_text},
|
utils::{find_impl_block_start, find_struct_impl, generate_impl_text},
|
||||||
AssistContext, AssistId, AssistKind, Assists,
|
AssistContext, AssistId, AssistKind, Assists,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
|
||||||
format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields);
|
format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields);
|
||||||
|
|
||||||
let start_offset = impl_def
|
let start_offset = impl_def
|
||||||
.and_then(|impl_def| find_impl_block(impl_def, &mut buf))
|
.and_then(|impl_def| find_impl_block_start(impl_def, &mut buf))
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
buf = generate_impl_text(&Adt::Struct(strukt.clone()), &buf);
|
buf = generate_impl_text(&Adt::Struct(strukt.clone()), &buf);
|
||||||
strukt.syntax().text_range().end()
|
strukt.syntax().text_range().end()
|
||||||
|
|
|
@ -3,7 +3,7 @@ use syntax::ast::VisibilityOwner;
|
||||||
use syntax::ast::{self, AstNode, NameOwner};
|
use syntax::ast::{self, AstNode, NameOwner};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
utils::{find_impl_block, find_struct_impl, generate_impl_text},
|
utils::{find_impl_block_end, find_struct_impl, generate_impl_text},
|
||||||
AssistContext, AssistId, AssistKind, Assists,
|
AssistContext, AssistId, AssistKind, Assists,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ pub(crate) fn generate_setter(acc: &mut Assists, ctx: &AssistContext) -> Option<
|
||||||
);
|
);
|
||||||
|
|
||||||
let start_offset = impl_def
|
let start_offset = impl_def
|
||||||
.and_then(|impl_def| find_impl_block(impl_def, &mut buf))
|
.and_then(|impl_def| find_impl_block_end(impl_def, &mut buf))
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf);
|
buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf);
|
||||||
strukt.syntax().text_range().end()
|
strukt.syntax().text_range().end()
|
||||||
|
@ -156,6 +156,42 @@ impl<T: Clone> Person<T> {
|
||||||
pub(crate) fn set_data(&mut self, data: T) {
|
pub(crate) fn set_data(&mut self, data: T) {
|
||||||
self.data = data;
|
self.data = data;
|
||||||
}
|
}
|
||||||
|
}"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_multiple_generate_setter() {
|
||||||
|
check_assist(
|
||||||
|
generate_setter,
|
||||||
|
r#"
|
||||||
|
struct Context<T: Clone> {
|
||||||
|
data: T,
|
||||||
|
cou$0nt: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> Context<T> {
|
||||||
|
/// Set the context's data.
|
||||||
|
fn set_data(&mut self, data: T) {
|
||||||
|
self.data = data;
|
||||||
|
}
|
||||||
|
}"#,
|
||||||
|
r#"
|
||||||
|
struct Context<T: Clone> {
|
||||||
|
data: T,
|
||||||
|
count: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> Context<T> {
|
||||||
|
/// Set the context's data.
|
||||||
|
fn set_data(&mut self, data: T) {
|
||||||
|
self.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the context's count.
|
||||||
|
fn set_count(&mut self, count: usize) {
|
||||||
|
self.count = count;
|
||||||
|
}
|
||||||
}"#,
|
}"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,7 +279,7 @@ pub(crate) fn does_pat_match_variant(pat: &ast::Pat, var: &ast::Pat) -> bool {
|
||||||
//
|
//
|
||||||
// FIXME: change the new fn checking to a more semantic approach when that's more
|
// FIXME: change the new fn checking to a more semantic approach when that's more
|
||||||
// viable (e.g. we process proc macros, etc)
|
// viable (e.g. we process proc macros, etc)
|
||||||
// FIXME: this partially overlaps with `find_impl_block`
|
// FIXME: this partially overlaps with `find_impl_block_*`
|
||||||
pub(crate) fn find_struct_impl(
|
pub(crate) fn find_struct_impl(
|
||||||
ctx: &AssistContext,
|
ctx: &AssistContext,
|
||||||
strukt: &ast::Adt,
|
strukt: &ast::Adt,
|
||||||
|
@ -343,17 +343,25 @@ fn has_fn(imp: &ast::Impl, rhs_name: &str) -> bool {
|
||||||
|
|
||||||
/// Find the start of the `impl` block for the given `ast::Impl`.
|
/// 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`
|
// FIXME: this partially overlaps with `find_struct_impl`
|
||||||
pub(crate) fn find_impl_block(impl_def: ast::Impl, buf: &mut String) -> Option<TextSize> {
|
pub(crate) fn find_impl_block_start(impl_def: ast::Impl, buf: &mut String) -> Option<TextSize> {
|
||||||
buf.push('\n');
|
buf.push('\n');
|
||||||
let start = impl_def
|
let start = impl_def.assoc_item_list().and_then(|it| it.l_curly_token())?.text_range().end();
|
||||||
.syntax()
|
Some(start)
|
||||||
.descendants_with_tokens()
|
}
|
||||||
.find(|t| t.kind() == T!['{'])?
|
|
||||||
|
/// Find the end of the `impl` block for the given `ast::Impl`.
|
||||||
|
//
|
||||||
|
// FIXME: this partially overlaps with `find_struct_impl`
|
||||||
|
pub(crate) fn find_impl_block_end(impl_def: ast::Impl, buf: &mut String) -> Option<TextSize> {
|
||||||
|
buf.push('\n');
|
||||||
|
let end = impl_def
|
||||||
|
.assoc_item_list()
|
||||||
|
.and_then(|it| it.r_curly_token())?
|
||||||
|
.prev_sibling_or_token()?
|
||||||
.text_range()
|
.text_range()
|
||||||
.end();
|
.end();
|
||||||
Some(start)
|
Some(end)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates the surrounding `impl Type { <code> }` including type and lifetime
|
// Generates the surrounding `impl Type { <code> }` including type and lifetime
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue