forge_lint/linter/
project.rs1use super::{Lint, LintContext, LinterConfig};
2use foundry_common::comments::inline_config::InlineConfig;
3use foundry_config::lint::LintSpecificConfig;
4use solar::{
5 ast,
6 interface::{Session, Span, diagnostics::DiagMsg, source_map::SourceFile},
7 sema::Gcx,
8};
9use std::{path::PathBuf, sync::Arc};
10
11pub struct ProjectSource<'ast> {
14 pub path: PathBuf,
15 pub file: Arc<SourceFile>,
16 pub ast: &'ast ast::SourceUnit<'ast>,
17 pub inline_config: InlineConfig<Vec<String>>,
18}
19
20pub trait ProjectLintPass<'ast>: Send + Sync {
26 fn check_project(&mut self, ctx: &ProjectLintEmitter<'_, '_>, sources: &[ProjectSource<'ast>]);
27}
28
29pub struct ProjectLintEmitter<'s, 'c> {
32 sess: &'s Session,
33 gcx: Gcx<'s>,
34 with_description: bool,
35 with_json_emitter: bool,
36 lint_specific: &'c LintSpecificConfig,
37 active_lints: Vec<&'static str>,
38}
39
40impl<'s, 'c> ProjectLintEmitter<'s, 'c> {
41 pub const fn new(
42 sess: &'s Session,
43 gcx: Gcx<'s>,
44 with_description: bool,
45 with_json_emitter: bool,
46 lint_specific: &'c LintSpecificConfig,
47 active_lints: Vec<&'static str>,
48 ) -> Self {
49 Self { sess, gcx, with_description, with_json_emitter, lint_specific, active_lints }
50 }
51
52 pub fn is_lint_enabled(&self, id: &'static str) -> bool {
55 self.active_lints.contains(&id)
56 }
57
58 pub const fn gcx(&self) -> Gcx<'s> {
60 self.gcx
61 }
62
63 pub fn emit<'a, 'ast, L: Lint>(
65 &'a self,
66 source: &'a ProjectSource<'ast>,
67 lint: &'static L,
68 span: Span,
69 ) where
70 'c: 'a,
71 {
72 self.build_ctx(source).emit(lint, span);
73 }
74
75 pub fn emit_with_msg<'a, 'ast, L: Lint>(
77 &'a self,
78 source: &'a ProjectSource<'ast>,
79 lint: &'static L,
80 span: Span,
81 msg: impl Into<DiagMsg>,
82 ) where
83 'c: 'a,
84 {
85 self.build_ctx(source).emit_with_msg(lint, span, msg);
86 }
87
88 fn build_ctx<'a, 'ast>(&'a self, source: &'a ProjectSource<'ast>) -> LintContext<'s, 'a>
89 where
90 'c: 'a,
91 {
92 LintContext::new(
93 self.sess,
94 self.with_description,
95 self.with_json_emitter,
96 LinterConfig { inline: &source.inline_config, lint_specific: self.lint_specific },
97 self.active_lints.clone(),
98 Some(source.file.clone()),
99 )
100 }
101}