context_creator/core/semantic/
mod.rs1#![allow(clippy::new_without_default)]
9
10pub mod analyzer;
11pub mod cache;
12pub mod cycle_detector;
13pub mod dependency_types;
14pub mod graph_builder;
15pub mod graph_traverser;
16pub mod languages;
17pub mod parallel_analyzer;
18pub mod parser_pool;
19pub mod path_validator;
20pub mod query_engine;
21pub mod resolver;
22pub mod type_resolver;
23
24#[cfg(test)]
25mod rust_function_call_test;
26
27pub use cache::AstCacheV2;
29
30#[cfg(test)]
31mod javascript_test;
32#[cfg(test)]
33mod python_test;
34#[cfg(test)]
35mod test;
36
37pub use analyzer::{LanguageAnalyzer, SemanticContext, SemanticResult};
38pub use resolver::{ModuleResolver, ResolvedPath};
39
40use crate::utils::error::ContextCreatorError;
41use std::path::Path;
42
43#[derive(Debug, Clone)]
45pub struct SemanticOptions {
46 pub trace_imports: bool,
48 pub include_callers: bool,
50 pub include_types: bool,
52 pub semantic_depth: usize,
54}
55
56impl SemanticOptions {
57 pub fn from_config(config: &crate::cli::Config) -> Self {
59 Self {
60 trace_imports: config.trace_imports,
61 include_callers: config.include_callers,
62 include_types: config.include_types,
63 semantic_depth: config.semantic_depth,
64 }
65 }
66
67 pub fn is_enabled(&self) -> bool {
69 self.trace_imports || self.include_callers || self.include_types
70 }
71}
72
73pub fn get_analyzer_for_file(
75 path: &Path,
76) -> Result<Option<Box<dyn LanguageAnalyzer>>, ContextCreatorError> {
77 let extension = path.extension().and_then(|ext| ext.to_str()).unwrap_or("");
78
79 let analyzer: Option<Box<dyn LanguageAnalyzer>> = match extension {
80 "rs" => Some(Box::new(languages::rust::RustAnalyzer::new())),
81 "py" => Some(Box::new(languages::python::PythonAnalyzer::new())),
82 "js" | "jsx" => Some(Box::new(languages::javascript::JavaScriptAnalyzer::new())),
83 "ts" | "tsx" => Some(Box::new(languages::typescript::TypeScriptAnalyzer::new())),
84 "go" => Some(Box::new(languages::go::GoAnalyzer::new())),
85 "java" => Some(Box::new(languages::java::JavaAnalyzer::new())),
86 "cpp" | "cc" | "cxx" | "hpp" | "h" => Some(Box::new(languages::cpp::CppAnalyzer::new())),
87 "c" => Some(Box::new(languages::c::CAnalyzer::new())),
88 "cs" => Some(Box::new(languages::csharp::CSharpAnalyzer::new())),
89 "rb" => Some(Box::new(languages::ruby::RubyAnalyzer::new())),
90 "php" => Some(Box::new(languages::php::PhpAnalyzer::new())),
91 "swift" => Some(Box::new(languages::swift::SwiftAnalyzer::new())),
92 "kt" | "kts" => Some(Box::new(languages::kotlin::KotlinAnalyzer::new())),
93 "scala" | "sc" => Some(Box::new(languages::scala::ScalaAnalyzer::new())),
94 "dart" => Some(Box::new(languages::dart::DartAnalyzer::new())),
95 "lua" => Some(Box::new(languages::lua::LuaAnalyzer::new())),
96 "r" | "R" => Some(Box::new(languages::r::RAnalyzer::new())),
97 "jl" => Some(Box::new(languages::julia::JuliaAnalyzer::new())),
98 "ex" | "exs" => Some(Box::new(languages::elixir::ElixirAnalyzer::new())),
99 "elm" => Some(Box::new(languages::elm::ElmAnalyzer::new())),
100 _ => None,
101 };
102
103 Ok(analyzer)
104}
105
106pub fn get_resolver_for_file(
108 path: &Path,
109) -> Result<Option<Box<dyn ModuleResolver>>, ContextCreatorError> {
110 let extension = path.extension().and_then(|ext| ext.to_str()).unwrap_or("");
111
112 let resolver: Option<Box<dyn ModuleResolver>> = match extension {
113 "rs" => Some(Box::new(languages::rust::RustModuleResolver)),
114 "py" => Some(Box::new(languages::python::PythonModuleResolver)),
115 "js" | "jsx" => Some(Box::new(languages::javascript::JavaScriptModuleResolver)),
116 "ts" | "tsx" => Some(Box::new(languages::typescript::TypeScriptModuleResolver)),
117 _ => None,
118 };
119
120 Ok(resolver)
121}