incorrect case diagnostics for trait name

This commit is contained in:
davidsemakula 2024-02-01 23:22:24 +03:00
parent 8f6a72871e
commit 5fe3b75677
2 changed files with 49 additions and 4 deletions

View file

@ -20,7 +20,7 @@ use hir_def::{
hir::{Pat, PatId}, hir::{Pat, PatId},
src::HasSource, src::HasSource,
AdtId, AttrDefId, ConstId, EnumId, FunctionId, ItemContainerId, Lookup, ModuleDefId, ModuleId, AdtId, AttrDefId, ConstId, EnumId, FunctionId, ItemContainerId, Lookup, ModuleDefId, ModuleId,
StaticId, StructId, StaticId, StructId, TraitId,
}; };
use hir_expand::{ use hir_expand::{
name::{AsName, Name}, name::{AsName, Name},
@ -79,12 +79,13 @@ pub enum IdentType {
Enum, Enum,
Field, Field,
Function, Function,
Module,
Parameter, Parameter,
StaticVariable, StaticVariable,
Structure, Structure,
Trait,
Variable, Variable,
Variant, Variant,
Module,
} }
impl fmt::Display for IdentType { impl fmt::Display for IdentType {
@ -94,12 +95,13 @@ impl fmt::Display for IdentType {
IdentType::Enum => "Enum", IdentType::Enum => "Enum",
IdentType::Field => "Field", IdentType::Field => "Field",
IdentType::Function => "Function", IdentType::Function => "Function",
IdentType::Module => "Module",
IdentType::Parameter => "Parameter", IdentType::Parameter => "Parameter",
IdentType::StaticVariable => "Static variable", IdentType::StaticVariable => "Static variable",
IdentType::Structure => "Structure", IdentType::Structure => "Structure",
IdentType::Trait => "Trait",
IdentType::Variable => "Variable", IdentType::Variable => "Variable",
IdentType::Variant => "Variant", IdentType::Variant => "Variant",
IdentType::Module => "Module",
}; };
repr.fmt(f) repr.fmt(f)
@ -136,6 +138,7 @@ impl<'a> DeclValidator<'a> {
pub(super) fn validate_item(&mut self, item: ModuleDefId) { pub(super) fn validate_item(&mut self, item: ModuleDefId) {
match item { match item {
ModuleDefId::ModuleId(module_id) => self.validate_module(module_id), ModuleDefId::ModuleId(module_id) => self.validate_module(module_id),
ModuleDefId::TraitId(trait_id) => self.validate_trait(trait_id),
ModuleDefId::FunctionId(func) => self.validate_func(func), ModuleDefId::FunctionId(func) => self.validate_func(func),
ModuleDefId::AdtId(adt) => self.validate_adt(adt), ModuleDefId::AdtId(adt) => self.validate_adt(adt),
ModuleDefId::ConstId(const_id) => self.validate_const(const_id), ModuleDefId::ConstId(const_id) => self.validate_const(const_id),
@ -283,6 +286,47 @@ impl<'a> DeclValidator<'a> {
} }
} }
fn validate_trait(&mut self, trait_id: TraitId) {
// Check whether non-snake case identifiers are allowed for this trait.
if self.allowed(trait_id.into(), allow::NON_CAMEL_CASE_TYPES, false) {
return;
}
// Check the trait name.
let data = self.db.trait_data(trait_id);
let trait_name = data.name.display(self.db.upcast()).to_string();
let trait_name_replacement = to_camel_case(&trait_name).map(|new_name| Replacement {
current_name: data.name.clone(),
suggested_text: new_name,
expected_case: CaseType::UpperCamelCase,
});
if let Some(replacement) = trait_name_replacement {
let trait_loc = trait_id.lookup(self.db.upcast());
let trait_src = trait_loc.source(self.db.upcast());
let Some(ast_ptr) = trait_src.value.name() else {
never!(
"Replacement ({:?}) was generated for a trait without a name: {:?}",
replacement,
trait_src
);
return;
};
let diagnostic = IncorrectCase {
file: trait_src.file_id,
ident_type: IdentType::Trait,
ident: AstPtr::new(&ast_ptr),
expected_case: replacement.expected_case,
ident_text: trait_name,
suggested_text: replacement.suggested_text,
};
self.sink.push(diagnostic);
}
}
fn validate_func(&mut self, func: FunctionId) { fn validate_func(&mut self, func: FunctionId) {
let data = self.db.function_data(func); let data = self.db.function_data(func);
if matches!(func.lookup(self.db.upcast()).container, ItemContainerId::ExternBlockId(_)) { if matches!(func.lookup(self.db.upcast()).container, ItemContainerId::ExternBlockId(_)) {

View file

@ -462,12 +462,13 @@ extern {
} }
#[test] #[test]
fn bug_traits_arent_checked() { fn incorrect_trait_and_assoc_item_names() {
// FIXME: Traits and functions in traits aren't currently checked by // FIXME: Traits and functions in traits aren't currently checked by
// r-a, even though rustc will complain about them. // r-a, even though rustc will complain about them.
check_diagnostics( check_diagnostics(
r#" r#"
trait BAD_TRAIT { trait BAD_TRAIT {
// ^^^^^^^^^ 💡 warn: Trait `BAD_TRAIT` should have CamelCase name, e.g. `BadTrait`
fn BAD_FUNCTION(); fn BAD_FUNCTION();
fn BadFunction(); fn BadFunction();
} }