Skip to content

feat(forge): forge lint #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 90 commits into from
Closed

feat(forge): forge lint #1

wants to merge 90 commits into from

Conversation

0xrusowsky
Copy link
Owner

@0xrusowsky 0xrusowsky commented Apr 28, 2025

this PR builds on top of foundry-rs#9590.

the proposed changes maintain most of the traits that @0xKitsune created + uses trait EarlyLintPass to incorporates the clippy-like architecture that @DaniPopes requested.

relevant changes:

  • the Visit trait is implemented by the helper struct EarlyLintVisitor rather than the individual lints.
  • diagnostics aren't tracked by the linter anymore.

considerations:

  • i was unable to find any methods on the solar Session to get the warning/note counts (just errors), so for tests, i manually counted the occurrences from the buffer.
    since i wanted to minimize code duplication, i added an unnecessary boolean to the SolidityLinter which allows it write to the local buffer rather than stderr:

    /// Linter implementation to analyze Solidity source code responsible for identifying
    /// vulnerabilities gas optimizations, and best practices.
    #[derive(Debug, Clone, Default)]
    pub struct SolidityLinter {
        severity: Option<Vec<Severity>>,
        lints_included: Option<Vec<SolLint>>,
        lints_excluded: Option<Vec<SolLint>>,
        with_description: bool,
        // This field is only used for testing purposes, in production it will always be false.
        with_buffer_emitter: bool,
    }

    imo it should be fine, as the runtime overhead should be minimal and it could potentially be "optimized out" by the compiler:

     #[cfg(test)]
     pub(crate) fn with_buffer_emitter(mut self, with: bool) -> Self {
         self.with_buffer_emitter = with;
         self
     }
    
     // Helper function to ease testing, despite `fn lint` being the public API for the `Linter`
     pub(crate) fn lint_file(&self, file: &Path) -> Option<EmittedDiagnostics> {
         let mut sess = if self.with_buffer_emitter {
             Session::builder().with_buffer_emitter(ColorChoice::Never).build()
         } else {
             Session::builder().with_stderr_emitter().build()
         };
         // rest of the code
     }

    however, if this feels unacceptable, i could leave a clean SolidityLinter and implement a TestSolidityLinter with duplicate the logic

  • if the changes are validated i can add more lints and tests (so far i only added a minimal logic for incorrect-shift)

  • i haven't tested the CLI logic, as i didn't see unit tests for it

@DaniPopes
Copy link

Is this PR a mistake? foundry-rs#10405 is enough.

@0xrusowsky
Copy link
Owner Author

Is this PR a mistake? foundry-rs#10405 is enough.

definitely, i was convinced i was pointing to my local main 🤔

i usually do that to write the desc and double check things

will close it

@0xrusowsky 0xrusowsky closed this Apr 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants