From aa1a7a5414e59c7f1c6e74002df1b6a04937459e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Aug 2020 16:41:21 +0200 Subject: Introduce Label --- crates/assists/src/assist_context.rs | 16 ++++++------ crates/assists/src/lib.rs | 13 ++-------- crates/ide/src/diagnostics.rs | 13 +++------- crates/ide/src/lib.rs | 1 + crates/ide_db/src/label.rs | 49 ++++++++++++++++++++++++++++++++++++ crates/ide_db/src/lib.rs | 1 + crates/rust-analyzer/src/handlers.rs | 3 +-- crates/rust-analyzer/src/to_proto.rs | 2 +- 8 files changed, 68 insertions(+), 30 deletions(-) create mode 100644 crates/ide_db/src/label.rs (limited to 'crates') diff --git a/crates/assists/src/assist_context.rs b/crates/assists/src/assist_context.rs index 79574b9ac..11c171fc2 100644 --- a/crates/assists/src/assist_context.rs +++ b/crates/assists/src/assist_context.rs @@ -6,6 +6,7 @@ use algo::find_covering_element; use base_db::{FileId, FileRange}; use hir::Semantics; use ide_db::{ + label::Label, source_change::{SourceChange, SourceFileEdit}, RootDatabase, }; @@ -157,8 +158,9 @@ impl Assists { if !self.is_allowed(&id) { return None; } - let label = Assist::new(id, label.into(), None, target); - self.add_impl(label, f) + let label = Label::new(label.into()); + let assist = Assist { id, label, group: None, target }; + self.add_impl(assist, f) } pub(crate) fn add_group( @@ -172,12 +174,12 @@ impl Assists { if !self.is_allowed(&id) { return None; } - - let label = Assist::new(id, label.into(), Some(group.clone()), target); - self.add_impl(label, f) + let label = Label::new(label.into()); + let assist = Assist { id, label, group: Some(group.clone()), target }; + self.add_impl(assist, f) } - fn add_impl(&mut self, label: Assist, f: impl FnOnce(&mut AssistBuilder)) -> Option<()> { + fn add_impl(&mut self, assist: Assist, f: impl FnOnce(&mut AssistBuilder)) -> Option<()> { let source_change = if self.resolve { let mut builder = AssistBuilder::new(self.file); f(&mut builder); @@ -186,7 +188,7 @@ impl Assists { None }; - self.buf.push((label, source_change)); + self.buf.push((assist, source_change)); Some(()) } diff --git a/crates/assists/src/lib.rs b/crates/assists/src/lib.rs index c589b08dc..14834480a 100644 --- a/crates/assists/src/lib.rs +++ b/crates/assists/src/lib.rs @@ -19,7 +19,7 @@ pub mod ast_transform; use base_db::FileRange; use hir::Semantics; -use ide_db::{source_change::SourceChange, RootDatabase}; +use ide_db::{label::Label, source_change::SourceChange, RootDatabase}; use syntax::TextRange; pub(crate) use crate::assist_context::{AssistContext, Assists}; @@ -68,7 +68,7 @@ pub struct GroupLabel(pub String); pub struct Assist { pub id: AssistId, /// Short description of the assist, as shown in the UI. - label: String, + pub label: Label, pub group: Option, /// Target ranges are used to sort assists: the smaller the target range, /// the more specific assist is, and so it should be sorted first. @@ -82,11 +82,6 @@ pub struct ResolvedAssist { } impl Assist { - fn new(id: AssistId, label: String, group: Option, target: TextRange) -> Assist { - assert!(label.starts_with(char::is_uppercase)); - Assist { id, label, group, target } - } - /// Return all the assists applicable at the given position. /// /// Assists are returned in the "unresolved" state, that is only labels are @@ -118,10 +113,6 @@ impl Assist { }); acc.finish_resolved() } - - pub fn label(&self) -> &str { - self.label.as_str() - } } mod handlers { diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index 1f85805d2..3c36c0e15 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs @@ -19,7 +19,7 @@ use syntax::{ }; use text_edit::TextEdit; -use crate::{FileId, SourceChange, SourceFileEdit}; +use crate::{FileId, Label, SourceChange, SourceFileEdit}; use self::fixes::DiagnosticWithFix; @@ -34,20 +34,15 @@ pub struct Diagnostic { #[derive(Debug)] pub struct Fix { - pub label: String, + pub label: Label, pub source_change: SourceChange, /// Allows to trigger the fix only when the caret is in the range given pub fix_trigger_range: TextRange, } impl Fix { - fn new( - label: impl Into, - source_change: SourceChange, - fix_trigger_range: TextRange, - ) -> Self { - let label = label.into(); - assert!(label.starts_with(char::is_uppercase) && !label.ends_with('.')); + fn new(label: &str, source_change: SourceChange, fix_trigger_range: TextRange) -> Self { + let label = Label::new(label); Self { label, source_change, fix_trigger_range } } } diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index f37119e28..e3af6d5bc 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -88,6 +88,7 @@ pub use base_db::{ pub use hir::{Documentation, Semantics}; pub use ide_db::{ change::AnalysisChange, + label::Label, line_index::{LineCol, LineIndex}, search::SearchScope, source_change::{FileSystemEdit, SourceChange, SourceFileEdit}, diff --git a/crates/ide_db/src/label.rs b/crates/ide_db/src/label.rs new file mode 100644 index 000000000..c0e89e72f --- /dev/null +++ b/crates/ide_db/src/label.rs @@ -0,0 +1,49 @@ +//! See `Label` +use std::fmt; + +/// A type to specify UI label, like an entry in the list of assists. Enforces +/// proper casing: +/// +/// Frobnicate bar +/// +/// Note the upper-case first letter and the absence of `.` at the end. +#[derive(Clone)] +pub struct Label(String); + +impl PartialEq for Label { + fn eq(&self, other: &str) -> bool { + self.0 == other + } +} + +impl PartialEq<&'_ str> for Label { + fn eq(&self, other: &&str) -> bool { + self == *other + } +} + +impl From