forge_lint/sol/info/
redundant_base_constructor_call.rs1use super::RedundantBaseConstructorCall;
2use crate::{
3 linter::{LateLintPass, LintContext, Suggestion},
4 sol::{Severity, SolLint},
5};
6use solar::{
7 interface::{BytePos, Span, diagnostics::Applicability},
8 sema::{Gcx, hir},
9};
10
11declare_forge_lint!(
12 REDUNDANT_BASE_CONSTRUCTOR_CALL,
13 Severity::Info,
14 "redundant-base-constructor-call",
15 "explicit empty base-constructor arguments are redundant"
16);
17
18impl<'gcx> LateLintPass<'gcx> for RedundantBaseConstructorCall {
19 fn check_contract(
20 &mut self,
21 ctx: &LintContext,
22 gcx: Gcx<'gcx>,
23 contract: &'gcx hir::Contract<'gcx>,
24 ) {
25 for m in contract.bases_args {
27 try_emit(ctx, &gcx.hir, m, m.args.span);
28 }
29 }
30
31 fn check_function(
32 &mut self,
33 ctx: &LintContext,
34 gcx: Gcx<'gcx>,
35 func: &'gcx hir::Function<'gcx>,
36 ) {
37 if func.kind == hir::FunctionKind::Constructor {
41 for m in func.modifiers {
42 try_emit(ctx, &gcx.hir, m, expand_to_leading_ws(ctx, m.span));
43 }
44 }
45 }
46}
47
48fn try_emit(ctx: &LintContext, hir: &hir::Hir<'_>, m: &hir::Modifier<'_>, fix_span: Span) {
49 let hir::ItemId::Contract(base_id) = m.id else { return };
52 if m.args.is_dummy() || !m.args.is_empty() {
53 return;
54 }
55 if hir.contract(base_id).ctor.is_some_and(|c| !hir.function(c).parameters.is_empty()) {
58 return;
59 }
60 if ctx.span_to_snippet(m.args.span).is_some_and(|s| s.trim() == "()") {
63 ctx.emit_with_suggestion(
64 &REDUNDANT_BASE_CONSTRUCTOR_CALL,
65 m.args.span,
66 Suggestion::fix(String::new(), Applicability::MachineApplicable)
67 .with_span(fix_span)
68 .with_desc("remove redundant base-constructor call"),
69 );
70 } else {
71 ctx.emit(&REDUNDANT_BASE_CONSTRUCTOR_CALL, m.args.span);
72 }
73}
74
75fn expand_to_leading_ws(ctx: &LintContext, span: Span) -> Span {
77 if span.is_dummy() || span.lo() == BytePos(0) {
78 return span;
79 }
80 let lo = span.lo() - BytePos(1);
81 match ctx.span_to_snippet(Span::new(lo, span.lo())).as_deref() {
82 Some(" " | "\t") => span.with_lo(lo),
83 _ => span,
84 }
85}