use crate::analysis::{AnalysisConfig, ImportSpec, Language, ParsedFile, ParsedFunction};
use crate::index::RepositoryIndex;
use crate::model::Finding;
use super::comments::comment_findings;
use super::go::{
alloc_findings, busy_findings, cancel_findings, concat_findings, coordination_findings,
ctx_findings, db_findings, deeper_goroutine_lifetime_findings, error_findings, fmt_findings,
go_file_findings, go_framework_patterns_file_findings, go_library_misuse_file_findings,
go_repo_findings, import_grouping_findings, json_findings, load_findings, mutex_findings,
n_squared_findings, package_name_consistency, propagate_findings, receiver_findings,
reflect_findings, shutdown_findings, sleep_findings, tag_findings,
};
use super::hallucination::hallucination_findings;
use super::naming::{generic_finding, overlong_finding, weak_finding};
use super::python::{python_file_findings, python_findings, python_repo_findings};
use super::rust::{
evaluate_rust_file_hygiene_findings, rust_api_design_file_findings,
rust_api_design_function_findings, rust_async_file_findings, rust_async_function_findings,
rust_boundary_file_findings, rust_boundary_function_findings, rust_domain_file_findings,
rust_import_resolution_findings, rust_local_call_findings, rust_module_surface_file_findings,
rust_performance_file_findings, rust_performance_function_findings, rust_runtime_file_findings,
rust_runtime_function_findings, rust_runtime_ownership_function_findings,
rust_security_file_findings, rust_security_function_findings, rust_unsafe_soundness_findings,
};
use super::security::{crypto_findings, pkg_secret_findings, secret_findings, sql_findings};
use super::test_quality::test_findings;
pub(crate) type FileRule = fn(&ParsedFile) -> Vec<Finding>;
pub(crate) type IndexedFileRule = fn(&ParsedFile, &RepositoryIndex) -> Vec<Finding>;
pub(crate) type FunctionRule = fn(&ParsedFile, &ParsedFunction) -> Vec<Finding>;
pub(crate) type OptionalFunctionRule = fn(&ParsedFile, &ParsedFunction) -> Option<Finding>;
pub(crate) type IndexedFunctionRule =
fn(&ParsedFile, &ParsedFunction, &RepositoryIndex) -> Vec<Finding>;
pub(crate) type FileFunctionRule = fn(&ParsedFile, &ParsedFunction, &[ImportSpec]) -> Vec<Finding>;
pub(crate) type ConfigurableFunctionRule = fn(&ParsedFile, &ParsedFunction, bool) -> Vec<Finding>;
pub(crate) type RepoRule = fn(&[&ParsedFile]) -> Vec<Finding>;
pub(crate) type IndexedRepoRule = fn(&[&ParsedFile], &RepositoryIndex) -> Vec<Finding>;
pub(crate) struct RuleExecutionSpec {
pub(crate) family: &'static str,
pub(crate) file_rules: &'static [FileRule],
pub(crate) indexed_file_rules: &'static [IndexedFileRule],
pub(crate) optional_function_rules: &'static [OptionalFunctionRule],
pub(crate) function_rules: &'static [FunctionRule],
pub(crate) file_function_rules: &'static [FileFunctionRule],
pub(crate) indexed_function_rules: &'static [IndexedFunctionRule],
pub(crate) configurable_function_rules: &'static [ConfigurableFunctionRule],
pub(crate) repo_rules: &'static [RepoRule],
pub(crate) indexed_repo_rules: &'static [IndexedRepoRule],
pub(crate) configurable_enabled: fn(&AnalysisConfig) -> bool,
}
const fn always_disabled(_: &AnalysisConfig) -> bool {
false
}
const fn go_semantic_enabled(config: &AnalysisConfig) -> bool {
config.enable_go_semantic
}
pub(crate) const SHARED_RULE_SPECS: &[RuleExecutionSpec] = &[
RuleExecutionSpec {
family: "security",
file_rules: &[pkg_secret_findings],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[secret_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "naming",
file_rules: &[],
indexed_file_rules: &[],
optional_function_rules: &[generic_finding, overlong_finding, weak_finding],
function_rules: &[],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "comments",
file_rules: &[],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[comment_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "test_quality",
file_rules: &[],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[test_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "hallucination",
file_rules: &[],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[],
file_function_rules: &[],
indexed_function_rules: &[hallucination_findings],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
];
const GO_RULE_SPECS: &[RuleExecutionSpec] = &[
RuleExecutionSpec {
family: "idioms",
file_rules: &[go_file_findings],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[go_repo_findings],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "consistency",
file_rules: &[tag_findings],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[receiver_findings],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "style",
file_rules: &[import_grouping_findings],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[package_name_consistency],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "errors",
file_rules: &[],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[error_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "context",
file_rules: &[],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[ctx_findings, cancel_findings, busy_findings, sleep_findings],
file_function_rules: &[],
indexed_function_rules: &[propagate_findings],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "concurrency",
file_rules: &[],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[
coordination_findings,
deeper_goroutine_lifetime_findings,
shutdown_findings,
],
file_function_rules: &[mutex_findings],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "performance",
file_rules: &[],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[
alloc_findings,
crypto_findings,
sql_findings,
fmt_findings,
reflect_findings,
concat_findings,
json_findings,
load_findings,
],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[n_squared_findings, db_findings],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: go_semantic_enabled,
},
RuleExecutionSpec {
family: "framework_patterns",
file_rules: &[go_framework_patterns_file_findings],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "library_misuse",
file_rules: &[go_library_misuse_file_findings],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
];
const PYTHON_RULE_SPECS: &[RuleExecutionSpec] = &[RuleExecutionSpec {
family: "python_specs",
file_rules: &[python_file_findings],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[python_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[python_repo_findings],
configurable_enabled: always_disabled,
}];
const RUST_RULE_SPECS: &[RuleExecutionSpec] = &[
RuleExecutionSpec {
family: "hygiene",
file_rules: &[],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[evaluate_rust_file_hygiene_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "api_design",
file_rules: &[rust_api_design_file_findings],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[rust_api_design_function_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "async_patterns",
file_rules: &[rust_async_file_findings],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[rust_async_function_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "domain_modeling",
file_rules: &[rust_domain_file_findings],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "performance",
file_rules: &[rust_performance_file_findings],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[rust_performance_function_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "runtime_boundary",
file_rules: &[],
indexed_file_rules: &[rust_runtime_file_findings],
optional_function_rules: &[],
function_rules: &[rust_runtime_function_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "unsafe_soundness",
file_rules: &[],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[rust_unsafe_soundness_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "boundary",
file_rules: &[rust_boundary_file_findings],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[rust_boundary_function_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "module_surface",
file_rules: &[rust_module_surface_file_findings],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "runtime_ownership",
file_rules: &[],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[rust_runtime_ownership_function_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "security_footguns",
file_rules: &[],
indexed_file_rules: &[rust_security_file_findings],
optional_function_rules: &[],
function_rules: &[rust_security_function_findings],
file_function_rules: &[],
indexed_function_rules: &[],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
RuleExecutionSpec {
family: "resolution",
file_rules: &[],
indexed_file_rules: &[],
optional_function_rules: &[],
function_rules: &[],
file_function_rules: &[],
indexed_function_rules: &[rust_import_resolution_findings, rust_local_call_findings],
configurable_function_rules: &[],
repo_rules: &[],
indexed_repo_rules: &[],
configurable_enabled: always_disabled,
},
];
pub(crate) fn shared_rule_specs() -> &'static [RuleExecutionSpec] {
SHARED_RULE_SPECS
}
pub(crate) fn language_rule_specs(language: Language) -> &'static [RuleExecutionSpec] {
match language {
Language::Go => GO_RULE_SPECS,
Language::Python => PYTHON_RULE_SPECS,
Language::Rust => RUST_RULE_SPECS,
}
}