Report incorrect case for fn inner items

This commit is contained in:
Ryo Yoshida 2023-07-21 14:26:08 +09:00
parent cc2f0ec32c
commit b53a07835b
No known key found for this signature in database
GPG key ID: E25698A930586171
3 changed files with 52 additions and 30 deletions

View file

@ -14,13 +14,12 @@ mod case_conv;
use std::fmt; use std::fmt;
use base_db::CrateId;
use hir_def::{ use hir_def::{
data::adt::VariantData, data::adt::VariantData,
hir::{Pat, PatId}, hir::{Pat, PatId},
src::HasSource, src::HasSource,
AdtId, AttrDefId, ConstId, EnumId, FunctionId, ItemContainerId, Lookup, ModuleDefId, StaticId, AdtId, AttrDefId, ConstId, DefWithBodyId, EnumId, FunctionId, ItemContainerId, Lookup,
StructId, ModuleDefId, StaticId, StructId,
}; };
use hir_expand::{ use hir_expand::{
name::{AsName, Name}, name::{AsName, Name},
@ -44,13 +43,9 @@ mod allow {
pub(super) const NON_CAMEL_CASE_TYPES: &str = "non_camel_case_types"; pub(super) const NON_CAMEL_CASE_TYPES: &str = "non_camel_case_types";
} }
pub fn incorrect_case( pub fn incorrect_case(db: &dyn HirDatabase, owner: ModuleDefId) -> Vec<IncorrectCase> {
db: &dyn HirDatabase,
krate: CrateId,
owner: ModuleDefId,
) -> Vec<IncorrectCase> {
let _p = profile::span("validate_module_item"); let _p = profile::span("validate_module_item");
let mut validator = DeclValidator::new(db, krate); let mut validator = DeclValidator::new(db);
validator.validate_item(owner); validator.validate_item(owner);
validator.sink validator.sink
} }
@ -120,7 +115,6 @@ pub struct IncorrectCase {
pub(super) struct DeclValidator<'a> { pub(super) struct DeclValidator<'a> {
db: &'a dyn HirDatabase, db: &'a dyn HirDatabase,
krate: CrateId,
pub(super) sink: Vec<IncorrectCase>, pub(super) sink: Vec<IncorrectCase>,
} }
@ -132,8 +126,8 @@ struct Replacement {
} }
impl<'a> DeclValidator<'a> { impl<'a> DeclValidator<'a> {
pub(super) fn new(db: &'a dyn HirDatabase, krate: CrateId) -> DeclValidator<'a> { pub(super) fn new(db: &'a dyn HirDatabase) -> DeclValidator<'a> {
DeclValidator { db, krate, sink: Vec::new() } DeclValidator { db, sink: Vec::new() }
} }
pub(super) fn validate_item(&mut self, item: ModuleDefId) { pub(super) fn validate_item(&mut self, item: ModuleDefId) {
@ -206,17 +200,7 @@ impl<'a> DeclValidator<'a> {
return; return;
} }
let body = self.db.body(func.into()); self.validate_body_inner_items(func.into());
// Recursively validate inner scope items, such as static variables and constants.
for (_, block_def_map) in body.blocks(self.db.upcast()) {
for (_, module) in block_def_map.modules() {
for def_id in module.scope.declarations() {
let mut validator = DeclValidator::new(self.db, self.krate);
validator.validate_item(def_id);
}
}
}
// Check whether non-snake case identifiers are allowed for this function. // Check whether non-snake case identifiers are allowed for this function.
if self.allowed(func.into(), allow::NON_SNAKE_CASE, false) { if self.allowed(func.into(), allow::NON_SNAKE_CASE, false) {
@ -231,6 +215,8 @@ impl<'a> DeclValidator<'a> {
expected_case: CaseType::LowerSnakeCase, expected_case: CaseType::LowerSnakeCase,
}); });
let body = self.db.body(func.into());
// Check the patterns inside the function body. // Check the patterns inside the function body.
// This includes function parameters. // This includes function parameters.
let pats_replacements = body let pats_replacements = body
@ -707,4 +693,16 @@ impl<'a> DeclValidator<'a> {
self.sink.push(diagnostic); self.sink.push(diagnostic);
} }
/// Recursively validates inner scope items, such as static variables and constants.
fn validate_body_inner_items(&mut self, body_id: DefWithBodyId) {
let body = self.db.body(body_id);
for (_, block_def_map) in body.blocks(self.db.upcast()) {
for (_, module) in block_def_map.modules() {
for def_id in module.scope.declarations() {
self.validate_item(def_id);
}
}
}
}
} }

View file

@ -378,11 +378,6 @@ impl ModuleDef {
ModuleDef::BuiltinType(_) | ModuleDef::Macro(_) => return Vec::new(), ModuleDef::BuiltinType(_) | ModuleDef::Macro(_) => return Vec::new(),
}; };
let module = match self.module(db) {
Some(it) => it,
None => return Vec::new(),
};
let mut acc = Vec::new(); let mut acc = Vec::new();
match self.as_def_with_body() { match self.as_def_with_body() {
@ -390,7 +385,7 @@ impl ModuleDef {
def.diagnostics(db, &mut acc); def.diagnostics(db, &mut acc);
} }
None => { None => {
for diag in hir_ty::diagnostics::incorrect_case(db, module.id.krate(), id) { for diag in hir_ty::diagnostics::incorrect_case(db, id) {
acc.push(diag.into()) acc.push(diag.into())
} }
} }
@ -1820,7 +1815,7 @@ impl DefWithBody {
// FIXME: don't ignore diagnostics for in type const // FIXME: don't ignore diagnostics for in type const
DefWithBody::InTypeConst(_) => return, DefWithBody::InTypeConst(_) => return,
}; };
for diag in hir_ty::diagnostics::incorrect_case(db, krate, def.into()) { for diag in hir_ty::diagnostics::incorrect_case(db, def.into()) {
acc.push(diag.into()) acc.push(diag.into())
} }
} }

View file

@ -545,4 +545,33 @@ pub static SomeStatic: u8 = 10;
"#, "#,
); );
} }
#[test]
fn fn_inner_items() {
check_diagnostics(
r#"
fn main() {
const foo: bool = true;
//^^^ 💡 warn: Constant `foo` should have UPPER_SNAKE_CASE name, e.g. `FOO`
static bar: bool = true;
//^^^ 💡 warn: Static variable `bar` should have UPPER_SNAKE_CASE name, e.g. `BAR`
fn BAZ() {
//^^^ 💡 warn: Function `BAZ` should have snake_case name, e.g. `baz`
const foo: bool = true;
//^^^ 💡 warn: Constant `foo` should have UPPER_SNAKE_CASE name, e.g. `FOO`
static bar: bool = true;
//^^^ 💡 warn: Static variable `bar` should have UPPER_SNAKE_CASE name, e.g. `BAR`
fn BAZ() {
//^^^ 💡 warn: Function `BAZ` should have snake_case name, e.g. `baz`
let INNER_INNER = 42;
//^^^^^^^^^^^ 💡 warn: Variable `INNER_INNER` should have snake_case name, e.g. `inner_inner`
}
let INNER_LOCAL = 42;
//^^^^^^^^^^^ 💡 warn: Variable `INNER_LOCAL` should have snake_case name, e.g. `inner_local`
}
}
"#,
);
}
} }