diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-02-05 17:18:02 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-05 17:18:02 +0000 |
| commit | 80ab753d7e0bf59b81df317d6ddda43cb919ec83 (patch) | |
| tree | 934a7ae2d8b549cd9d5d82a137156c0a71220973 | |
| parent | 941f9157f5561868c4683d54fdf98378383f64b8 (diff) | |
| parent | 2cf161266941eac300ae66a633ead26f5109ea16 (diff) | |
Merge #7572
7572: Add `find_or_create_impl_block` to assist utils r=matklad a=yoshuawuyts This is another continuation of https://github.com/rust-analyzer/rust-analyzer/pull/7562, introducing a small util to either find an `impl` block, or create a new one if none exists. I copied this code from the `generate_new` assist into https://github.com/rust-analyzer/rust-analyzer/pull/7562, and this unifies both into a helper. It doesn't feel super polished in its current state, but my hope is that this is enough of a starting point that it can be expanded on later. For example something that would be useful would be a flag which either returns the index of the start of the block, or the end of the block. Anyway, I hope this is useful. Thanks! Co-authored-by: Yoshua Wuyts <yoshuawuyts@gmail.com>
| -rw-r--r-- | crates/assists/src/handlers/generate_enum_match_method.rs | 20 | ||||
| -rw-r--r-- | crates/assists/src/handlers/generate_new.rs | 21 | ||||
| -rw-r--r-- | crates/assists/src/utils.rs | 18 |
3 files changed, 30 insertions, 29 deletions
diff --git a/crates/assists/src/handlers/generate_enum_match_method.rs b/crates/assists/src/handlers/generate_enum_match_method.rs index ee89d420854..4cf66b5d5c1 100644 --- a/crates/assists/src/handlers/generate_enum_match_method.rs +++ b/crates/assists/src/handlers/generate_enum_match_method.rs @@ -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 // @@ -63,7 +66,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, " /// Returns `true` if the {} is [`{}`]. @@ -78,17 +80,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() diff --git a/crates/assists/src/handlers/generate_new.rs b/crates/assists/src/handlers/generate_new.rs index 84832273f49..307f2e228c9 100644 --- a/crates/assists/src/handlers/generate_new.rs +++ b/crates/assists/src/handlers/generate_new.rs @@ -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 diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index 3842558d8da..8045aac40cd 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs @@ -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) +} |
