cairo_lint/lints/
duplicate_underscore_args.rs1use std::collections::HashSet;
2
3use crate::context::{CairoLintKind, Lint};
4use cairo_lang_defs::{ids::ModuleItemId, plugin::PluginDiagnostic};
5use cairo_lang_diagnostics::Severity;
6use cairo_lang_semantic::items::function_with_body::FunctionWithBodySemantic;
7
8use crate::queries::get_all_checkable_functions;
9use salsa::Database;
10
11pub struct DuplicateUnderscoreArgs;
12
13impl Lint for DuplicateUnderscoreArgs {
25 fn allowed_name(&self) -> &'static str {
26 "duplicate_underscore_args"
27 }
28
29 fn diagnostic_message(&self) -> &'static str {
30 "duplicate arguments, having another argument having almost the same name \
31 makes code comprehension and documentation more difficult"
32 }
33
34 fn kind(&self) -> CairoLintKind {
35 CairoLintKind::DuplicateUnderscoreArgs
36 }
37}
38
39#[tracing::instrument(skip_all, level = "trace")]
40pub fn check_duplicate_underscore_args<'db>(
41 db: &'db dyn Database,
42 item: &ModuleItemId<'db>,
43 diagnostics: &mut Vec<PluginDiagnostic<'db>>,
44) {
45 let functions = get_all_checkable_functions(db, item);
46
47 for function in functions {
48 let mut registered_names: HashSet<String> = HashSet::new();
49 let params = db
50 .function_with_body_signature(function)
51 .cloned()
52 .unwrap()
53 .params;
54
55 for param in params {
56 let name_string = param.name.to_string(db);
57 let stripped_name = name_string.strip_prefix('_').unwrap_or(&name_string);
58
59 if !registered_names.insert(stripped_name.to_string()) {
60 diagnostics.push(PluginDiagnostic {
61 stable_ptr: param.stable_ptr.0,
62 message: DuplicateUnderscoreArgs.diagnostic_message().to_string(),
63 severity: Severity::Warning,
64 inner_span: None,
65 error_code: None,
66 });
67 }
68 }
69 }
70}