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 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(())
}

View File

@ -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<GroupLabel>,
/// 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<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.
///
/// 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 {

View File

@ -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<String>,
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 }
}
}

View File

@ -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},

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.
pub mod label;
pub mod line_index;
pub mod symbol_index;
pub mod change;

View File

@ -782,10 +782,9 @@ fn handle_fixes(
.filter_map(|d| d.fix)
.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 action = lsp_ext::CodeAction {
title,
title: fix.label.to_string(),
id: None,
group: None,
kind: Some(CodeActionKind::QUICKFIX),

View File

@ -704,7 +704,7 @@ pub(crate) fn unresolved_code_action(
index: usize,
) -> Result<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())),
group: assist.group.filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0),
kind: Some(code_action_kind(assist.id.1)),