forge_lint/sol/info/
low_level_calls.rs1use 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}