1#[macro_export]
18macro_rules! declare_forge_lint {
19 ($id:ident, $severity:expr, $str_id:expr, $desc:expr) => {
20 pub static $id: SolLint = SolLint {
22 id: $str_id,
23 severity: $severity,
24 description: $desc,
25 help: concat!("https://getfoundry.sh/forge/linting/", $str_id),
26 };
27 };
28}
29
30#[macro_export]
46macro_rules! register_lints {
47 ( @declare_structs $( ($pass_id:ident, $pass_type:ident, ($($lint:expr),* $(,)?) $(, $constructor:expr)? ) ),* $(,)? ) => {
49 $(
50 #[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
51 pub struct $pass_id;
52
53 impl $pass_id {
54 const LINT_IDS: &'static [&'static str] = &[$($lint.id),*];
56 }
57 )*
58 };
59
60 ( @declare_consts $( ($pass_id:ident, $pass_type:ident, ($($lint:expr),* $(,)?) $(, $constructor:expr)? ) ),* $(,)? ) => {
62 pub const REGISTERED_LINTS: &[SolLint] = &[
63 $(
64 $($lint,)*
65 )*
66 ];
67 };
68
69 ( @declare_funcs $( ($pass_id:ident, $pass_type:ident, $lints:tt $(, $constructor:expr)?) ),* $(,)? ) => {
71 pub fn register_lints(
72 registry: &mut solar_lint::LintRegistry,
73 config: &std::sync::Arc<foundry_config::lint::LintSpecificConfig>,
74 ) {
75 let _ = config;
76 $(
77 register_lints!(@register_early registry, config, $pass_id, $pass_type $(, $constructor)?);
78 register_lints!(@register_late registry, config, $pass_id, $pass_type $(, $constructor)?);
79 register_lints!(@register_project registry, config, $pass_id, $pass_type $(, $constructor)?);
80 )*
81 }
82 };
83
84 (@register_early $registry:ident, $config:ident, $_pass_id:ident, late $(, $constructor:expr)?) => {};
86 (@register_early $registry:ident, $config:ident, $_pass_id:ident, project $(, $constructor:expr)?) => {};
87 (@register_early $registry:ident, $config:ident, $pass_id:ident, $_other:ident, $constructor:expr) => {{
88 let config = std::sync::Arc::clone($config);
89 $registry.register_early_pass(
90 $pass_id::LINT_IDS,
91 move || ($constructor)(std::sync::Arc::clone(&config)),
92 );
93 }};
94 (@register_early $registry:ident, $config:ident, $pass_id:ident, $_other:ident) => {
95 $registry.register_early_pass($pass_id::LINT_IDS, $pass_id::default);
96 };
97
98 (@register_late $registry:ident, $config:ident, $_pass_id:ident, early $(, $constructor:expr)?) => {};
99 (@register_late $registry:ident, $config:ident, $_pass_id:ident, project $(, $constructor:expr)?) => {};
100 (@register_late $registry:ident, $config:ident, $pass_id:ident, $_other:ident, $constructor:expr) => {{
101 let config = std::sync::Arc::clone($config);
102 $registry.register_late_pass(
103 $pass_id::LINT_IDS,
104 move || ($constructor)(std::sync::Arc::clone(&config)),
105 );
106 }};
107 (@register_late $registry:ident, $config:ident, $pass_id:ident, $_other:ident) => {
108 $registry.register_late_pass($pass_id::LINT_IDS, $pass_id::default);
109 };
110
111 (@register_project $registry:ident, $config:ident, $_pass_id:ident, early $(, $constructor:expr)?) => {};
112 (@register_project $registry:ident, $config:ident, $_pass_id:ident, late $(, $constructor:expr)?) => {};
113 (@register_project $registry:ident, $config:ident, $_pass_id:ident, both $(, $constructor:expr)?) => {};
114 (@register_project $registry:ident, $config:ident, $pass_id:ident, $_other:ident, $constructor:expr) => {{
115 let config = std::sync::Arc::clone($config);
116 $registry.register_project_pass(
117 $pass_id::LINT_IDS,
118 move || ($constructor)(std::sync::Arc::clone(&config)),
119 );
120 }};
121 (@register_project $registry:ident, $config:ident, $pass_id:ident, $_other:ident) => {
122 $registry.register_project_pass($pass_id::LINT_IDS, $pass_id::default);
123 };
124
125 ( $($tokens:tt)* ) => {
127 register_lints! { @declare_structs $($tokens)* }
128 register_lints! { @declare_consts $($tokens)* }
129 register_lints! { @declare_funcs $($tokens)* }
130 };
131}