Skip to content
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

Option to ignore warnings from dependencies in foundry.toml #69

Merged
merged 19 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 13 additions & 20 deletions src/artifacts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
#![allow(ambiguous_glob_reexports)]

use crate::{
compile::*, error::SolcIoError, remappings::Remapping, utils, ProjectPathsConfig, SolcError,
compile::*, error::SolcIoError, output::ErrorFilter, remappings::Remapping, utils,
ProjectPathsConfig, SolcError,
};
use alloy_primitives::hex;
use md5::Digest;
Expand All @@ -16,7 +17,6 @@ use std::{
str::FromStr,
sync::Arc,
};

loocapro marked this conversation as resolved.
Show resolved Hide resolved
pub mod error;
pub use error::*;

Expand Down Expand Up @@ -1572,30 +1572,23 @@ impl CompilerOutput {

/// Checks if there are any compiler warnings that are not ignored by the specified error codes
/// and file paths.
pub fn has_warning(&self, ignored_error_codes: &[u64], ignored_file_paths: &[PathBuf]) -> bool {
pub fn has_warning(&self, filter: ErrorFilter<'_>) -> bool {
self.errors.iter().any(|error| {
if !error.severity.is_warning() {
return false;
}
let is_code_ignored =
error.error_code.map_or(false, |code| ignored_error_codes.contains(&code));

let is_file_ignored = self.is_file_ignored(error, ignored_file_paths);
is_code_ignored || is_file_ignored
})
}
let is_code_ignored = filter.is_code_ignored(error.error_code);
let is_file_ignored = match &error.source_location {
Some(location) => filter.is_file_ignored(Path::new(&location.file)),
None => false,
};

/// Determines if the error's file path is not ignored based on a list of ignored file paths.
fn is_file_ignored(&self, error: &Error, ignored_file_paths: &[PathBuf]) -> bool {
match &error.source_location {
Some(location) => {
// Convert the error's file location to a PathBuf for comparison
let error_path = PathBuf::from(&location.file);
// Check if the error path is not in the list of ignored paths
ignored_file_paths.iter().any(|ignored_path| error_path.starts_with(ignored_path))
}
None => false,
}
// Only consider warnings that are not ignored by either code or file path.
// Hence, return `true` for warnings that are not ignored, making the function
// return `true` if any such warnings exist.
!(is_code_ignored || is_file_ignored)
})
}

/// Finds the _first_ contract with the given name
Expand Down
72 changes: 51 additions & 21 deletions src/compile/output/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use contracts::{VersionedContract, VersionedContracts};
use semver::Version;
use serde::{Deserialize, Serialize};
use std::{
borrow::Cow,
collections::BTreeMap,
fmt,
path::{Path, PathBuf},
Expand Down Expand Up @@ -260,7 +261,10 @@ impl<T: ArtifactOutput> ProjectCompileOutput<T> {

/// Returns whether any warnings were emitted by the compiler.
pub fn has_compiler_warnings(&self) -> bool {
self.compiler_output.has_warning(&self.ignored_error_codes, &self.ignored_file_paths)
self.compiler_output.has_warning(ErrorFilter::from((
self.ignored_error_codes.as_slice(),
self.ignored_file_paths.as_slice(),
)))
}

/// Panics if any errors were emitted by the compiler.
Expand Down Expand Up @@ -498,6 +502,36 @@ pub struct AggregatedCompilerOutput {
pub build_infos: BTreeMap<Version, RawBuildInfo>,
}

pub struct ErrorFilter<'a> {
error_codes: Cow<'a, [u64]>,
ignored_file_paths: Cow<'a, [PathBuf]>,
loocapro marked this conversation as resolved.
Show resolved Hide resolved
}

impl<'a> ErrorFilter<'a> {
loocapro marked this conversation as resolved.
Show resolved Hide resolved
// Helper function to check if an error code is ignored
pub(crate) fn is_code_ignored(&self, code: Option<u64>) -> bool {
match code {
Some(code) => self.error_codes.contains(&code),
None => false,
}
}

// Helper function to check if an error's file path is ignored
pub(crate) fn is_file_ignored(&self, file_path: &Path) -> bool {
self.ignored_file_paths.iter().any(|ignored_path| file_path.starts_with(ignored_path))
}
}

impl<'a> From<(&'a [u64], &'a [PathBuf])> for ErrorFilter<'a> {
loocapro marked this conversation as resolved.
Show resolved Hide resolved
loocapro marked this conversation as resolved.
Show resolved Hide resolved
fn from(tuple: (&'a [u64], &'a [PathBuf])) -> Self {
let (error_codes, ignored_file_paths) = tuple;
ErrorFilter {
error_codes: Cow::Borrowed(error_codes),
ignored_file_paths: Cow::Borrowed(ignored_file_paths),
}
}
}

impl AggregatedCompilerOutput {
/// Converts all `\\` separators in _all_ paths to `/`
pub fn slash_paths(&mut self) {
Expand All @@ -516,7 +550,8 @@ impl AggregatedCompilerOutput {
if compiler_severity_filter.ge(&err.severity) {
if compiler_severity_filter.is_warning() {
// skip ignored error codes and file path from warnings
return self.has_warning(ignored_error_codes, ignored_file_paths);
return self
.has_warning(ErrorFilter::from((ignored_error_codes, ignored_file_paths)));
}
return true;
}
Expand All @@ -526,30 +561,24 @@ impl AggregatedCompilerOutput {

/// Checks if there are any compiler warnings that are not ignored by the specified error codes
/// and file paths.
pub fn has_warning(&self, ignored_error_codes: &[u64], ignored_file_paths: &[PathBuf]) -> bool {
pub fn has_warning(&self, filter: ErrorFilter<'_>) -> bool {
self.errors.iter().any(|error| {
if !error.severity.is_warning() {
return false;
}
let is_code_not_ignored =
error.error_code.map_or(false, |code| !ignored_error_codes.contains(&code));

let is_file_not_ignored = self.is_file_not_ignored(error, ignored_file_paths);
is_code_not_ignored && is_file_not_ignored
})
}
let is_code_ignored = filter.is_code_ignored(error.error_code);

/// Determines if the error's file path is not ignored based on a list of ignored file paths.
fn is_file_not_ignored(&self, error: &Error, ignored_file_paths: &[PathBuf]) -> bool {
match &error.source_location {
Some(location) => {
// Convert the error's file location to a PathBuf for comparison
let error_path = PathBuf::from(&location.file);
// Check if the error path is not in the list of ignored paths
!ignored_file_paths.iter().any(|ignored_path| error_path.starts_with(ignored_path))
}
None => false,
}
let is_file_ignored = match &error.source_location {
loocapro marked this conversation as resolved.
Show resolved Hide resolved
Some(location) => filter.is_file_ignored(&PathBuf::from(&location.file)),
None => false,
};

// Only consider warnings that are not ignored by either code or file path.
// Hence, return `true` for warnings that are not ignored, making the function
// return `true` if any such warnings exist.
!(is_code_ignored || is_file_ignored)
})
}

pub fn diagnostics<'a>(
Expand Down Expand Up @@ -841,7 +870,8 @@ impl<'a> OutputDiagnostics<'a> {

/// Returns true if there is at least one warning
pub fn has_warning(&self) -> bool {
self.compiler_output.has_warning(self.ignored_error_codes, self.ignored_file_paths)
self.compiler_output
.has_warning(ErrorFilter::from((self.ignored_error_codes, self.ignored_file_paths)))
}

/// Returns true if the contract is a expected to be a test
Expand Down