Skip to content

Commit

Permalink
Improve AssistContextDiagnosticCode
Browse files Browse the repository at this point in the history
Summary:
- Bring it in line with DiagnosticCode in terms of providing a code and label
- Wrap the normal ELP DiagnosticCode too, so they also show up in the assist context
This is preparation for adding a fixme assist to specified diagnostics

Reviewed By: perehonchuk

Differential Revision: D55805517

fbshipit-source-id: c263156f9bcf748353067bbcba2b327b28bdfd81
  • Loading branch information
alanz authored and facebook-github-bot committed Apr 11, 2024
1 parent 825b4ec commit d4e0774
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 6 deletions.
101 changes: 95 additions & 6 deletions crates/ide_db/src/assists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,20 @@
//! want to compile `ide_assists` and `ide_diagnostics` in parallel though, so
//! we pull the common definitions upstream, to this crate.

use std::fmt;
use std::str::FromStr;

use elp_syntax::label::Label;
use elp_syntax::TextRange;
use fxhash::FxHashMap;
use lazy_static::lazy_static;
use serde::Deserialize;
use serde::Serialize;
use strum::IntoEnumIterator;
use strum_macros::EnumIter;

use crate::source_change::SourceChange;
use crate::DiagnosticCode;

#[derive(Debug, Clone)]
pub struct Assist {
Expand Down Expand Up @@ -147,25 +153,108 @@ impl AssistResolveStrategy {
}
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq, Eq, EnumIter)]
pub enum AssistContextDiagnosticCode {
DefaultCodeForEnumIter,
UndefinedFunction,
UnusedFunction,
UnusedVariable,
ElpDiagnostic(DiagnosticCode),
}

impl Default for AssistContextDiagnosticCode {
fn default() -> Self {
AssistContextDiagnosticCode::DefaultCodeForEnumIter
}
}

impl AssistContextDiagnosticCode {
pub fn as_labeled_code(&self) -> String {
match &self {
AssistContextDiagnosticCode::DefaultCodeForEnumIter => {
"DEFAULT-UNUSED-CONSTRUCTOR".to_string()
}
AssistContextDiagnosticCode::UndefinedFunction => self.make_labeled_code(),
AssistContextDiagnosticCode::UnusedFunction => self.make_labeled_code(),
AssistContextDiagnosticCode::UnusedVariable => self.make_labeled_code(),
AssistContextDiagnosticCode::ElpDiagnostic(code) => code.as_labeled_code(),
}
}

pub fn as_code(&self) -> String {
match &self {
AssistContextDiagnosticCode::DefaultCodeForEnumIter => {
"DEFAULT-UNUSED-CONSTRUCTOR".to_string()
}
AssistContextDiagnosticCode::UndefinedFunction => "L1227".to_string(),
AssistContextDiagnosticCode::UnusedFunction => "L1230".to_string(),
AssistContextDiagnosticCode::UnusedVariable => "L1268".to_string(),
AssistContextDiagnosticCode::ElpDiagnostic(code) => code.as_code(),
}
}

pub fn as_label(&self) -> String {
match &self {
AssistContextDiagnosticCode::DefaultCodeForEnumIter => {
"DEFAULT-UNUSED-CONSTRUCTOR".to_string()
}
AssistContextDiagnosticCode::UndefinedFunction => "undefined_function".to_string(),
AssistContextDiagnosticCode::UnusedFunction => "unused_function".to_string(),
AssistContextDiagnosticCode::UnusedVariable => "unused_var".to_string(),
AssistContextDiagnosticCode::ElpDiagnostic(code) => code.as_label(),
}
}

pub fn make_labeled_code(&self) -> String {
format!("{} ({})", self.as_code(), self.as_label())
}

pub fn maybe_from_string(s: &str) -> Option<AssistContextDiagnosticCode> {
DIAGNOSTIC_CODE_LOOKUPS.get(s).cloned().or_else(|| {
DiagnosticCode::from_str(s)
.ok()
.map(AssistContextDiagnosticCode::ElpDiagnostic)
})
}
}

lazy_static! {
static ref DIAGNOSTIC_CODE_LOOKUPS: FxHashMap<String, AssistContextDiagnosticCode> = {
let mut res = FxHashMap::default();
for code in AssistContextDiagnosticCode::iter() {
res.insert(code.as_code(), code.clone());
res.insert(code.as_label(), code.clone());
}
res
};
}

impl FromStr for AssistContextDiagnosticCode {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"L1227" => Ok(AssistContextDiagnosticCode::UndefinedFunction),
"L1230" => Ok(AssistContextDiagnosticCode::UnusedFunction),
"L1268" => Ok(AssistContextDiagnosticCode::UnusedVariable),
unknown => Err(format!("Unknown AssistContextDiagnosticCode: '{unknown}'")),
if let Some(code) = AssistContextDiagnosticCode::maybe_from_string(s) {
Ok(code)
} else {
Err(format!("Unknown DiagnosticCode: '{s}'"))
}
}
}

impl From<&str> for AssistContextDiagnosticCode {
fn from(str: &str) -> Self {
match AssistContextDiagnosticCode::from_str(str) {
Ok(c) => c,
Err(err) => panic!("{err}"),
}
}
}

impl fmt::Display for AssistContextDiagnosticCode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_code())
}
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GroupLabel(pub String);

Expand Down
41 changes: 41 additions & 0 deletions crates/ide_db/src/diagnostic_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,47 @@ impl DiagnosticCode {
_ => false,
}
}

pub fn allows_fixme_comment(&self) -> bool {
// Note: exhaustive match, to make sure new ones get categorized too.
match self {
// True list
DiagnosticCode::MisspelledAttribute => true,
DiagnosticCode::CrossNodeEval => true,
// False list
DiagnosticCode::DefaultCodeForEnumIter => false,
DiagnosticCode::HeadMismatch => false,
DiagnosticCode::MissingModule => false,
DiagnosticCode::ModuleMismatch => false,
DiagnosticCode::UnusedInclude => false,
DiagnosticCode::BoundVarInPattern => false,
DiagnosticCode::UnusedMacro => false,
DiagnosticCode::UnusedRecordField => false,
DiagnosticCode::MutableVarBug => false,
DiagnosticCode::SyntaxError => false,
DiagnosticCode::Missing(_) => false,
DiagnosticCode::StatementHasNoEffect => false,
DiagnosticCode::TrivialMatch => false,
DiagnosticCode::UnusedFunctionArg => false,
DiagnosticCode::RedundantAssignment => false,
DiagnosticCode::UnreachableTest => false,
DiagnosticCode::ApplicationGetEnv => false,
DiagnosticCode::MissingCompileWarnMissingSpec => false,
DiagnosticCode::DependentHeader => false,
DiagnosticCode::DeprecatedFunction => false,
DiagnosticCode::UndefinedFunction => false,
DiagnosticCode::Unexpected(_) => false,
DiagnosticCode::ExpressionCanBeSimplified => false,
DiagnosticCode::CannotEvaluateCTCallbacks => false,
DiagnosticCode::MeckMissingNoLinkInInitPerSuite => false,
DiagnosticCode::AtomsExhaustion => false,
DiagnosticCode::SlowFunction => false,
DiagnosticCode::ErlangService(_) => false,
DiagnosticCode::Eqwalizer(_) => false,
DiagnosticCode::AdHoc(_) => false,
DiagnosticCode::MetaOnly(_) => false,
}
}
}

lazy_static! {
Expand Down

0 comments on commit d4e0774

Please sign in to comment.