Skip to content

Commit 21dd704

Browse files
committed
Check structure fields to be snake_case
1 parent 3296261 commit 21dd704

File tree

1 file changed

+65
-46
lines changed

1 file changed

+65
-46
lines changed

crates/hir_ty/src/diagnostics/decl_check.rs

Lines changed: 65 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ use hir_def::{
2323
src::HasSource,
2424
AdtId, EnumId, FunctionId, Lookup, ModuleDefId, StructId,
2525
};
26-
use hir_expand::{diagnostics::DiagnosticSink, name::Name};
26+
use hir_expand::{
27+
diagnostics::DiagnosticSink,
28+
name::{AsName, Name},
29+
};
2730
use syntax::{
2831
ast::{self, NameOwner},
2932
AstPtr,
@@ -288,58 +291,64 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
288291
self.sink.push(diagnostic);
289292
}
290293

291-
// let fn_params_list = match fn_src.value.param_list() {
292-
// Some(params) => params,
293-
// None => {
294-
// if !fn_param_replacements.is_empty() {
295-
// log::error!(
296-
// "Replacements ({:?}) were generated for a function parameters which had no parameters list: {:?}",
297-
// fn_param_replacements, fn_src
298-
// );
299-
// }
300-
// return;
301-
// }
302-
// };
303-
// let mut fn_params_iter = fn_params_list.params();
304-
// for param_to_rename in fn_param_replacements {
305-
// // We assume that parameters in replacement are in the same order as in the
306-
// // actual params list, but just some of them (ones that named correctly) are skipped.
307-
// let ast_ptr = loop {
308-
// match fn_params_iter.next() {
309-
// Some(element)
310-
// if pat_equals_to_name(element.pat(), &param_to_rename.current_name) =>
311-
// {
312-
// break element.pat().unwrap()
313-
// }
314-
// Some(_) => {}
315-
// None => {
316-
// log::error!(
317-
// "Replacement ({:?}) was generated for a function parameter which was not found: {:?}",
318-
// param_to_rename, fn_src
319-
// );
320-
// return;
321-
// }
322-
// }
323-
// };
324-
325-
// let diagnostic = IncorrectCase {
326-
// file: fn_src.file_id,
327-
// ident_type: "Argument".to_string(),
328-
// ident: AstPtr::new(&ast_ptr).into(),
329-
// expected_case: param_to_rename.expected_case,
330-
// ident_text: param_to_rename.current_name.to_string(),
331-
// suggested_text: param_to_rename.suggested_text,
332-
// };
333-
334-
// self.sink.push(diagnostic);
335-
// }
294+
let struct_fields_list = match struct_src.value.field_list() {
295+
Some(ast::FieldList::RecordFieldList(fields)) => fields,
296+
_ => {
297+
if !struct_fields_replacements.is_empty() {
298+
log::error!(
299+
"Replacements ({:?}) were generated for a structure fields which had no fields list: {:?}",
300+
struct_fields_replacements, struct_src
301+
);
302+
}
303+
return;
304+
}
305+
};
306+
let mut struct_fields_iter = struct_fields_list.fields();
307+
for field_to_rename in struct_fields_replacements {
308+
// We assume that parameters in replacement are in the same order as in the
309+
// actual params list, but just some of them (ones that named correctly) are skipped.
310+
let ast_ptr = loop {
311+
match struct_fields_iter.next() {
312+
Some(element) if names_equal(element.name(), &field_to_rename.current_name) => {
313+
break element.name().unwrap()
314+
}
315+
Some(_) => {}
316+
None => {
317+
log::error!(
318+
"Replacement ({:?}) was generated for a function parameter which was not found: {:?}",
319+
field_to_rename, struct_src
320+
);
321+
return;
322+
}
323+
}
324+
};
325+
326+
let diagnostic = IncorrectCase {
327+
file: struct_src.file_id,
328+
ident_type: "Field".to_string(),
329+
ident: AstPtr::new(&ast_ptr).into(),
330+
expected_case: field_to_rename.expected_case,
331+
ident_text: field_to_rename.current_name.to_string(),
332+
suggested_text: field_to_rename.suggested_text,
333+
};
334+
335+
self.sink.push(diagnostic);
336+
}
336337
}
337338

338339
fn validate_enum(&mut self, db: &dyn HirDatabase, enum_id: EnumId) {
339340
let data = db.enum_data(enum_id);
340341
}
341342
}
342343

344+
fn names_equal(left: Option<ast::Name>, right: &Name) -> bool {
345+
if let Some(left) = left {
346+
&left.as_name() == right
347+
} else {
348+
false
349+
}
350+
}
351+
343352
fn pat_equals_to_name(pat: Option<ast::Pat>, name: &Name) -> bool {
344353
if let Some(ast::Pat::IdentPat(ident)) = pat {
345354
ident.to_string() == name.to_string()
@@ -381,6 +390,16 @@ fn foo2(ok_param: &str, CAPS_PARAM: u8) {}
381390
r#"
382391
struct non_camel_case_name {}
383392
// ^^^^^^^^^^^^^^^^^^^ Structure `non_camel_case_name` should have a CamelCase name, e.g. `NonCamelCaseName`
393+
"#,
394+
);
395+
}
396+
397+
#[test]
398+
fn incorrect_struct_field() {
399+
check_diagnostics(
400+
r#"
401+
struct SomeStruct { SomeField: u8 }
402+
// ^^^^^^^^^ Field `SomeField` should have a snake_case name, e.g. `some_field`
384403
"#,
385404
);
386405
}

0 commit comments

Comments
 (0)