use crate::review::signals::behavioral::{
BehavioralKind, BehavioralSignal, BehavioralSignalSource, truncate_str,
};
use tree_sitter::Node;
pub(super) fn match_csharp(
node: Node<'_>,
content: &str,
path_str: &str,
line: usize,
) -> Option<BehavioralSignal> {
let text = node.utf8_text(content.as_bytes()).unwrap_or("").trim();
match node.kind() {
"invocation_expression" | "object_creation_expression" => {
if text.contains("HttpClient") || text.contains("HttpWebRequest") {
return Some(BehavioralSignal {
kind: BehavioralKind::NetworkCallAdded,
path: path_str.to_string(),
line,
detail: truncate_str(text, 60),
source: BehavioralSignalSource::Ast,
});
}
if text.contains("Process.Start") {
return Some(BehavioralSignal {
kind: BehavioralKind::SubprocessAdded,
path: path_str.to_string(),
line,
detail: truncate_str(text, 60),
source: BehavioralSignalSource::Ast,
});
}
if text.contains("File.WriteAll")
|| text.contains("File.OpenWrite")
|| text.contains("StreamWriter")
{
return Some(BehavioralSignal {
kind: BehavioralKind::FsWriteAdded,
path: path_str.to_string(),
line,
detail: truncate_str(text, 60),
source: BehavioralSignalSource::Ast,
});
}
if text.contains("Environment.GetEnvironmentVariable") {
return Some(BehavioralSignal {
kind: BehavioralKind::EnvVarIntroduced,
path: path_str.to_string(),
line,
detail: truncate_str(text, 60),
source: BehavioralSignalSource::Ast,
});
}
}
"using_directive" => {
return Some(BehavioralSignal {
kind: BehavioralKind::DependencyImportAdded,
path: path_str.to_string(),
line,
detail: format!("Imported using namespace: {}", text.trim_end_matches(';')),
source: BehavioralSignalSource::Ast,
});
}
_ => {}
}
None
}