Introduce Label

This commit is contained in:
Aleksey Kladov 2020-08-18 16:41:21 +02:00
parent eb81731600
commit aa1a7a5414
8 changed files with 68 additions and 30 deletions

View file

@ -6,6 +6,7 @@ use algo::find_covering_element;
use base_db::{FileId, FileRange}; use base_db::{FileId, FileRange};
use hir::Semantics; use hir::Semantics;
use ide_db::{ use ide_db::{
label::Label,
source_change::{SourceChange, SourceFileEdit}, source_change::{SourceChange, SourceFileEdit},
RootDatabase, RootDatabase,
}; };
@ -157,8 +158,9 @@ impl Assists {
if !self.is_allowed(&id) { if !self.is_allowed(&id) {
return None; return None;
} }
let label = Assist::new(id, label.into(), None, target); let label = Label::new(label.into());
self.add_impl(label, f) let assist = Assist { id, label, group: None, target };
self.add_impl(assist, f)
} }
pub(crate) fn add_group( pub(crate) fn add_group(
@ -172,12 +174,12 @@ impl Assists {
if !self.is_allowed(&id) { if !self.is_allowed(&id) {
return None; return None;
} }
let label = Label::new(label.into());
let label = Assist::new(id, label.into(), Some(group.clone()), target); let assist = Assist { id, label, group: Some(group.clone()), target };
self.add_impl(label, f) 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 source_change = if self.resolve {
let mut builder = AssistBuilder::new(self.file); let mut builder = AssistBuilder::new(self.file);
f(&mut builder); f(&mut builder);
@ -186,7 +188,7 @@ impl Assists {
None None
}; };
self.buf.push((label, source_change)); self.buf.push((assist, source_change));
Some(()) Some(())
} }

View file

@ -19,7 +19,7 @@ pub mod ast_transform;
use base_db::FileRange; use base_db::FileRange;
use hir::Semantics; use hir::Semantics;
use ide_db::{source_change::SourceChange, RootDatabase}; use ide_db::{label::Label, source_change::SourceChange, RootDatabase};
use syntax::TextRange; use syntax::TextRange;
pub(crate) use crate::assist_context::{AssistContext, Assists}; pub(crate) use crate::assist_context::{AssistContext, Assists};
@ -68,7 +68,7 @@ pub struct GroupLabel(pub String);
pub struct Assist { pub struct Assist {
pub id: AssistId, pub id: AssistId,
/// Short description of the assist, as shown in the UI. /// Short description of the assist, as shown in the UI.
label: String, pub label: Label,
pub group: Option<GroupLabel>, pub group: Option<GroupLabel>,
/// Target ranges are used to sort assists: the smaller the target range, /// Target ranges are used to sort assists: the smaller the target range,
/// the more specific assist is, and so it should be sorted first. /// the more specific assist is, and so it should be sorted first.
@ -82,11 +82,6 @@ pub struct ResolvedAssist {
} }
impl Assist { impl Assist {
fn new(id: AssistId, label: String, group: Option<GroupLabel>, target: TextRange) -> Assist {
assert!(label.starts_with(char::is_uppercase));
Assist { id, label, group, target }
}
/// Return all the assists applicable at the given position. /// Return all the assists applicable at the given position.
/// ///
/// Assists are returned in the "unresolved" state, that is only labels are /// Assists are returned in the "unresolved" state, that is only labels are
@ -118,10 +113,6 @@ impl Assist {
}); });
acc.finish_resolved() acc.finish_resolved()
} }
pub fn label(&self) -> &str {
self.label.as_str()
}
} }
mod handlers { mod handlers {

View file

@ -19,7 +19,7 @@ use syntax::{
}; };
use text_edit::TextEdit; use text_edit::TextEdit;
use crate::{FileId, SourceChange, SourceFileEdit}; use crate::{FileId, Label, SourceChange, SourceFileEdit};
use self::fixes::DiagnosticWithFix; use self::fixes::DiagnosticWithFix;
@ -34,20 +34,15 @@ pub struct Diagnostic {
#[derive(Debug)] #[derive(Debug)]
pub struct Fix { pub struct Fix {
pub label: String, pub label: Label,
pub source_change: SourceChange, pub source_change: SourceChange,
/// Allows to trigger the fix only when the caret is in the range given /// Allows to trigger the fix only when the caret is in the range given
pub fix_trigger_range: TextRange, pub fix_trigger_range: TextRange,
} }
impl Fix { impl Fix {
fn new( fn new(label: &str, source_change: SourceChange, fix_trigger_range: TextRange) -> Self {
label: impl Into<String>, let label = Label::new(label);
source_change: SourceChange,
fix_trigger_range: TextRange,
) -> Self {
let label = label.into();
assert!(label.starts_with(char::is_uppercase) && !label.ends_with('.'));
Self { label, source_change, fix_trigger_range } Self { label, source_change, fix_trigger_range }
} }
} }

View file

@ -88,6 +88,7 @@ pub use base_db::{
pub use hir::{Documentation, Semantics}; pub use hir::{Documentation, Semantics};
pub use ide_db::{ pub use ide_db::{
change::AnalysisChange, change::AnalysisChange,
label::Label,
line_index::{LineCol, LineIndex}, line_index::{LineCol, LineIndex},
search::SearchScope, search::SearchScope,
source_change::{FileSystemEdit, SourceChange, SourceFileEdit}, source_change::{FileSystemEdit, SourceChange, SourceFileEdit},

View file

@ -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<str> 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<Label> for String {
fn from(label: Label) -> String {
label.0
}
}
impl Label {
pub fn new(label: impl Into<String>) -> Label {
let label = label.into();
assert!(label.starts_with(char::is_uppercase) && !label.ends_with('.'));
Label(label)
}
}
impl fmt::Display for Label {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
impl fmt::Debug for Label {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}

View file

@ -2,6 +2,7 @@
//! //!
//! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search. //! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search.
pub mod label;
pub mod line_index; pub mod line_index;
pub mod symbol_index; pub mod symbol_index;
pub mod change; pub mod change;

View file

@ -782,10 +782,9 @@ fn handle_fixes(
.filter_map(|d| d.fix) .filter_map(|d| d.fix)
.filter(|fix| fix.fix_trigger_range.intersect(range).is_some()) .filter(|fix| fix.fix_trigger_range.intersect(range).is_some())
{ {
let title = fix.label;
let edit = to_proto::snippet_workspace_edit(&snap, fix.source_change)?; let edit = to_proto::snippet_workspace_edit(&snap, fix.source_change)?;
let action = lsp_ext::CodeAction { let action = lsp_ext::CodeAction {
title, title: fix.label.to_string(),
id: None, id: None,
group: None, group: None,
kind: Some(CodeActionKind::QUICKFIX), kind: Some(CodeActionKind::QUICKFIX),

View file

@ -704,7 +704,7 @@ pub(crate) fn unresolved_code_action(
index: usize, index: usize,
) -> Result<lsp_ext::CodeAction> { ) -> Result<lsp_ext::CodeAction> {
let res = lsp_ext::CodeAction { let res = lsp_ext::CodeAction {
title: assist.label().to_string(), title: assist.label.to_string(),
id: Some(format!("{}:{}", assist.id.0, index.to_string())), id: Some(format!("{}:{}", assist.id.0, index.to_string())),
group: assist.group.filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0), group: assist.group.filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0),
kind: Some(code_action_kind(assist.id.1)), kind: Some(code_action_kind(assist.id.1)),