Skip to content

Commit

Permalink
Move glob::Pattern creation away from hot paths
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Jul 2, 2024
1 parent 34062a4 commit 7b5a2c7
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 93 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ path = "src/main.rs"
[dependencies]
hakana-cli = { path = "src/cli" }
hakana-analyzer = { path = "src/analyzer" }
hakana-str = { path = "src/str" }
hakana-language-server = { path = "src/language_server" }
hakana-workhorse = { path = "src/file_scanner_analyzer" }
mimalloc = { version = "*", default-features = false }
Expand Down
65 changes: 36 additions & 29 deletions src/analyzer/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ pub struct Config {
pub issues_to_fix: FxHashSet<IssueKind>,
pub graph_kind: GraphKind,
pub ignore_files: Vec<String>,
pub test_files: Vec<String>,
pub ignore_issue_files: FxHashMap<IssueKind, Vec<String>>,
pub ignore_all_issues_in_files: Vec<String>,
pub test_files: Vec<glob::Pattern>,
pub ignore_issue_patterns: FxHashMap<IssueKind, Vec<glob::Pattern>>,
pub ignore_all_issues_in_patterns: Vec<glob::Pattern>,
pub banned_builtin_functions: FxHashMap<StrId, StrId>,
pub security_config: SecurityConfig,
pub root_dir: String,
Expand All @@ -39,8 +39,8 @@ pub struct Config {

#[derive(Clone, Debug)]
pub struct SecurityConfig {
ignore_files: Vec<String>,
ignore_sink_files: FxHashMap<String, Vec<String>>,
ignore_patterns: Vec<glob::Pattern>,
ignore_sink_files: FxHashMap<String, Vec<glob::Pattern>>,
pub max_depth: u8,
}

Expand All @@ -53,7 +53,7 @@ impl Default for SecurityConfig {
impl SecurityConfig {
pub fn new() -> Self {
Self {
ignore_files: Vec::new(),
ignore_patterns: Vec::new(),
ignore_sink_files: FxHashMap::default(),
max_depth: 40,
}
Expand All @@ -72,8 +72,8 @@ impl Config {
graph_kind: GraphKind::FunctionBody,
ignore_files: Vec::new(),
test_files: Vec::new(),
ignore_issue_files: FxHashMap::default(),
ignore_all_issues_in_files: vec![],
ignore_issue_patterns: FxHashMap::default(),
ignore_all_issues_in_patterns: vec![],
security_config: SecurityConfig::new(),
issues_to_fix: FxHashSet::default(),
hooks: vec![],
Expand Down Expand Up @@ -104,23 +104,28 @@ impl Config {
self.test_files = json_config
.test_files
.into_iter()
.map(|v| format!("{}/{}", cwd, v))
.map(|v| glob::Pattern::new(&format!("{}/{}", cwd, v)).unwrap())
.collect();

self.ignore_issue_files = json_config
self.ignore_issue_patterns = json_config
.ignore_issue_files
.iter()
.filter(|(k, _)| *k != "*")
.map(|(k, v)| {
(
IssueKind::from_str_custom(k.as_str(), &self.all_custom_issues).unwrap(),
v.iter().map(|v| format!("{}/{}", cwd, v)).collect(),
v.iter()
.map(|v| glob::Pattern::new(&format!("{}/{}", cwd, v)).unwrap())
.collect(),
)
})
.collect();

if let Some(v) = json_config.ignore_issue_files.get("*") {
self.ignore_all_issues_in_files = v.iter().map(|v| format!("{}/{}", cwd, v)).collect();
self.ignore_all_issues_in_patterns = v
.iter()
.map(|v| glob::Pattern::new(&format!("{}/{}", cwd, v)).unwrap())
.collect();
}

self.allowed_issues = if json_config.allowed_issues.is_empty() {
Expand All @@ -143,17 +148,24 @@ impl Config {
.map(|(k, v)| (interner.intern(k), interner.intern(v)))
.collect();

self.security_config.ignore_files = json_config
self.security_config.ignore_patterns = json_config
.security_analysis
.ignore_files
.into_iter()
.map(|v| format!("{}/{}", cwd, v))
.map(|v| glob::Pattern::new(&format!("{}/{}", cwd, v)).unwrap())
.collect();
self.security_config.ignore_sink_files = json_config
.security_analysis
.ignore_sink_files
.into_iter()
.map(|(k, v)| (k, v.into_iter().map(|v| format!("{}/{}", cwd, v)).collect()))
.map(|(k, v)| {
(
k,
v.into_iter()
.map(|v| glob::Pattern::new(&format!("{}/{}", cwd, v)).unwrap())
.collect(),
)
})
.collect();

Ok(())
Expand All @@ -170,8 +182,8 @@ impl Config {
}

pub fn allow_issues_in_file(&self, file: &str) -> bool {
for ignore_file_path in &self.ignore_all_issues_in_files {
if glob::Pattern::new(ignore_file_path).unwrap().matches(file) {
for ignore_pattern in &self.ignore_all_issues_in_patterns {
if ignore_pattern.matches(file) {
return false;
}
}
Expand All @@ -180,9 +192,9 @@ impl Config {
}

pub fn allow_issue_kind_in_file(&self, issue_kind: &IssueKind, file: &str) -> bool {
if let Some(issue_entries) = self.ignore_issue_files.get(issue_kind) {
for ignore_file_path in issue_entries {
if glob::Pattern::new(ignore_file_path).unwrap().matches(file) {
if let Some(issue_entries) = self.ignore_issue_patterns.get(issue_kind) {
for ignore_file_pattern in issue_entries {
if ignore_file_pattern.matches(file) {
return false;
}
}
Expand All @@ -192,8 +204,8 @@ impl Config {
}

pub fn allow_taints_in_file(&self, file: &str) -> bool {
for ignore_file_path in &self.security_config.ignore_files {
if glob::Pattern::new(ignore_file_path).unwrap().matches(file) {
for ignore_file_pattern in &self.security_config.ignore_patterns {
if ignore_file_pattern.matches(file) {
return false;
}
}
Expand All @@ -210,17 +222,12 @@ impl Config {
) -> bool {
let str_type = source_type.to_string() + " -> " + &sink_type.to_string();

if let Some(issue_entries) = self.security_config.ignore_sink_files.get(&str_type) {
let ignore_patterns = issue_entries
.iter()
.map(|ignore_file_path| glob::Pattern::new(ignore_file_path).unwrap())
.collect::<Vec<_>>();

if let Some(ignore_patterns) = self.security_config.ignore_sink_files.get(&str_type) {
let mut previous = node;

loop {
if let Some(pos) = &previous.pos {
for ignore_pattern in &ignore_patterns {
for ignore_pattern in ignore_patterns {
if ignore_pattern.matches(interner.lookup(&pos.file_path.0)) {
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions src/analyzer/expr/binop/assignment_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ use crate::expression_analyzer::expr_has_logic;
use crate::expression_analyzer::find_expr_logic_issues;
use crate::formula_generator;
use crate::function_analysis_data::FunctionAnalysisData;
use crate::scope_analyzer::ScopeAnalyzer;
use crate::scope::BlockContext;
use crate::scope_analyzer::ScopeAnalyzer;
use crate::statements_analyzer::StatementsAnalyzer;
use crate::stmt_analyzer::AnalysisError;
use hakana_algebra::Clause;
Expand Down Expand Up @@ -194,7 +194,7 @@ pub(crate) fn analyze(
for parent_node in &existing_var_type.parent_nodes {
origin_node_ids.extend(analysis_data.data_flow_graph.get_origin_node_ids(
&parent_node.id,
&vec![],
&[],
false,
));
}
Expand Down
53 changes: 26 additions & 27 deletions src/analyzer/expr/call/existing_atomic_method_call_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ use crate::{
fetch::array_fetch_analyzer::handle_array_access_on_dict,
},
function_analysis_data::FunctionAnalysisData,
scope_analyzer::ScopeAnalyzer,
scope::BlockContext,
scope_analyzer::ScopeAnalyzer,
statements_analyzer::StatementsAnalyzer,
};

Expand Down Expand Up @@ -85,41 +85,40 @@ pub(crate) fn analyze(
false,
);

if method_id != declaring_method_id {
if codebase.class_or_trait_extends(&method_id.0, &declaring_method_id.0) {
let mut child_storage = classlike_storage;
let mut child_class_name = classlike_name;
loop {
if method_id != declaring_method_id
&& codebase.class_or_trait_extends(&method_id.0, &declaring_method_id.0)
{
let mut child_storage = classlike_storage;
let mut child_class_name = classlike_name;
loop {
analysis_data
.symbol_references
.add_reference_to_class_member(
&context.function_context,
(child_class_name, method_id.1),
false,
);

for used_trait in &child_storage.used_traits {
analysis_data
.symbol_references
.add_reference_to_class_member(
&context.function_context,
(child_class_name, method_id.1),
(*used_trait, method_id.1),
false,
);
}

for used_trait in &child_storage.used_traits {
analysis_data
.symbol_references
.add_reference_to_class_member(
&context.function_context,
(*used_trait, method_id.1),
false,
);
if let Some(parent_class) = child_storage.direct_parent_class {
if parent_class == declaring_method_id.0 {
break;
}

if let Some(parent_class) = child_storage.direct_parent_class {
if parent_class == declaring_method_id.0 {
break;
}

if let Some(parent_class_storage) = codebase.classlike_infos.get(&parent_class)
{
child_storage = parent_class_storage;
child_class_name = parent_class;
} else {
break;
}
if let Some(parent_class_storage) = codebase.classlike_infos.get(&parent_class) {
child_storage = parent_class_storage;
child_class_name = parent_class;
} else {
break;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/analyzer/functionlike_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ impl<'a> FunctionLikeAnalyzer<'a> {
.get_config()
.migration_symbols
.contains_key(
&calling_functionlike_id.to_string(&self.file_analyzer.interner),
&calling_functionlike_id.to_string(self.file_analyzer.interner),
)
} else {
false
Expand Down
6 changes: 1 addition & 5 deletions src/analyzer/reconciler/assertion_reconciler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,11 +906,7 @@ fn intersect_enum_with_literal(
type_1_name: &StrId,
type_2_atomic: &TAtomic,
) -> Option<TAtomic> {
let enum_storage = if let Some(c) = codebase.classlike_infos.get(type_1_name) {
c
} else {
return None;
};
let enum_storage = codebase.classlike_infos.get(type_1_name)?;

let mut all_inferred = true;

Expand Down
10 changes: 5 additions & 5 deletions src/code_info/data_flow/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ impl DataFlowGraph {
pub fn get_origin_node_ids(
&self,
assignment_node_id: &DataFlowNodeId,
ignore_paths: &Vec<PathKind>,
ignore_paths: &[PathKind],
var_ids_only: bool,
) -> Vec<DataFlowNodeId> {
let mut visited_child_ids = FxHashSet::default();
Expand Down Expand Up @@ -245,7 +245,7 @@ impl DataFlowGraph {
}

pub fn add_mixed_data(&mut self, assignment_node: &DataFlowNode, pos: &Pos) {
let origin_node_ids = self.get_origin_node_ids(&assignment_node.id, &vec![], false);
let origin_node_ids = self.get_origin_node_ids(&assignment_node.id, &[], false);

for origin_node_id in origin_node_ids {
if let DataFlowNodeId::CallTo(..) | DataFlowNodeId::SpecializedCallTo(..) =
Expand All @@ -266,7 +266,7 @@ impl DataFlowGraph {
pub fn get_source_functions(
&self,
expr_type: &TUnion,
ignore_paths: &Vec<PathKind>,
ignore_paths: &[PathKind],
) -> Vec<FunctionLikeIdentifier> {
let mut origin_node_ids = vec![];

Expand Down Expand Up @@ -297,7 +297,7 @@ impl DataFlowGraph {
let mut origin_node_ids = vec![];

for parent_node in &expr_type.parent_nodes {
origin_node_ids.extend(self.get_origin_node_ids(&parent_node.id, &vec![], false));
origin_node_ids.extend(self.get_origin_node_ids(&parent_node.id, &[], false));
}

let mut source_properties = vec![];
Expand All @@ -317,7 +317,7 @@ impl DataFlowGraph {
pub fn is_from_param(&self, stmt_var_type: &TUnion) -> bool {
let mut origin_node_ids = vec![];
for parent_node in &stmt_var_type.parent_nodes {
origin_node_ids.extend(self.get_origin_node_ids(&parent_node.id, &vec![], false));
origin_node_ids.extend(self.get_origin_node_ids(&parent_node.id, &[], false));
}
let has_param_source = origin_node_ids.iter().any(|id| {
let node = &self.get_node(id).unwrap();
Expand Down
4 changes: 1 addition & 3 deletions src/code_info/symbol_references.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,9 +439,7 @@ impl SymbolReferences {

let mut expense = 0;

while !new_invalid_symbols.is_empty() {
let new_invalid_symbol = new_invalid_symbols.pop().unwrap();

while let Some(new_invalid_symbol) = new_invalid_symbols.pop() {
if seen_symbols.contains(&new_invalid_symbol) {
continue;
}
Expand Down
18 changes: 2 additions & 16 deletions src/file_scanner_analyzer/scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,19 +278,6 @@ pub fn scan_files(
group_size = 1;
}

let mut test_patterns = vec![];

for ignore_file in &config.test_files {
match glob::Pattern::new(ignore_file) {
Ok(glob) => {
test_patterns.push(glob);
}
Err(error) => {
panic!("Parsing {} resulted in error {}", ignore_file, error);
}
}
}

for (i, str_path) in files_to_scan.into_iter().enumerate() {
let group = i % group_size;
path_groups
Expand Down Expand Up @@ -322,7 +309,7 @@ pub fn scan_files(
&mut new_interner,
empty_name_context.clone(),
analyze_map.contains(&str_path),
!test_patterns.iter().any(|p| p.matches(&str_path)),
!config.test_files.iter().any(|p| p.matches(&str_path)),
&logger,
) {
Ok(scanner_result) => {
Expand Down Expand Up @@ -375,7 +362,6 @@ pub fn scan_files(
let resolved_names = resolved_names.clone();

let config = config.clone();
let test_patterns = test_patterns.clone();
let logger = logger.clone();
let invalid_files = invalid_files.clone();

Expand All @@ -401,7 +387,7 @@ pub fn scan_files(
&mut new_interner,
empty_name_context.clone(),
analyze_map.contains(&str_path),
!test_patterns.iter().any(|p| p.matches(&str_path)),
!config.test_files.iter().any(|p| p.matches(&str_path)),
&logger.clone(),
) {
local_resolved_names.insert(*file_path, scanner_result);
Expand Down
Loading

0 comments on commit 7b5a2c7

Please sign in to comment.