Skip to main content

cairo_lint/lints/
duplicate_underscore_args.rs

1use 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
13/// ## What it does
14///
15/// Checks for functions that have the same argument name but prefix with `_`.
16///
17/// ## Example
18///
19/// This code will raise a warning because it can be difficult to differentiate between `test` and `_test`.
20///
21/// ```cairo
22/// fn foo(test: u32, _test: u32) {}
23/// ```
24impl 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}