Skip to content

feat(forge): forge lint #10405

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

Open
wants to merge 114 commits into
base: master
Choose a base branch
from
Open

Conversation

0xrusowsky
Copy link

this PR builds on top of the work that @0xKitsune did on #9590.

the proposed changes maintain most of the initial traits and structs + uses trait EarlyLintPass to adopt 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 would probably be optimized 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)

@jenpaff jenpaff added this to the v1.2.0 milestone May 5, 2025
@grandizzy grandizzy moved this from In Progress to Ready For Review in Foundry May 6, 2025
@jenpaff jenpaff linked an issue May 6, 2025 that may be closed by this pull request
@zerosnacks zerosnacks requested review from zerosnacks and DaniPopes May 6, 2025 15:29
@0xrusowsky 0xrusowsky requested review from DaniPopes and grandizzy May 8, 2025 16:18
@grandizzy
Copy link
Collaborator

the ui tests for win are failing, I think is due to path in stderr? (like --> D:\a\foundry\foundry\crates\lint\testdata\DivideBeforeMultiply.sol:3:9)?

mattsse pushed a commit to foundry-rs/compilers that referenced this pull request May 12, 2025
- prereq for forge lint PR
foundry-rs/foundry#10405
- solar 0.1.3 requires rust 1.86 so this breaks compatibility with older
rust versions - bump msrv
mattsse pushed a commit to foundry-rs/block-explorers that referenced this pull request May 12, 2025
@grandizzy grandizzy modified the milestones: v1.2.0, v1.3.0 May 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Ready For Review
Development

Successfully merging this pull request may close these issues.

Add forge lint
6 participants