Skip to main content

forge_lint/sol/info/
low_level_calls.rs

1use super::LowLevelCalls;
2use crate::{
3    linter::{EarlyLintPass, LintContext},
4    sol::{Severity, SolLint, calls::is_low_level_call},
5};
6use solar::ast::{Expr, ItemFunction, visit::Visit};
7use std::ops::ControlFlow;
8
9declare_forge_lint!(
10    LOW_LEVEL_CALLS,
11    Severity::Info,
12    "low-level-calls",
13    "Low-level calls should be avoided"
14);
15
16impl<'ast> EarlyLintPass<'ast> for LowLevelCalls {
17    fn check_item_function(&mut self, ctx: &LintContext, func: &'ast ItemFunction<'ast>) {
18        if let Some(body) = &func.body {
19            let mut checker = LowLevelCallsChecker { ctx };
20            let _ = checker.visit_block(body);
21        }
22    }
23}
24
25struct LowLevelCallsChecker<'a, 's> {
26    ctx: &'a LintContext<'s, 'a>,
27}
28
29impl<'ast> Visit<'ast> for LowLevelCallsChecker<'_, '_> {
30    type BreakValue = ();
31
32    fn visit_expr(&mut self, expr: &'ast Expr<'ast>) -> ControlFlow<Self::BreakValue> {
33        if is_low_level_call(expr) {
34            self.ctx.emit(&LOW_LEVEL_CALLS, expr.span);
35        }
36        self.walk_expr(expr)
37    }
38}