1pub mod extractor;
15pub mod hits;
16pub mod inverted;
17mod macro_lexical;
18pub mod resolver;
19pub mod syntax;
20
21use crate::graph_support::CppSource;
22use brokk_bifrost_core::analyzer::capabilities::{TypeAliasProvider, TypeHierarchyProvider};
23use brokk_bifrost_core::analyzer::fq_name::FqName;
24use brokk_bifrost_core::analyzer::model::{CppFieldLinkage, SignatureMetadata};
25use brokk_bifrost_core::analyzer::query_token::QueryToken;
26use brokk_bifrost_core::analyzer::{CodeUnit, CodeUnitIndex, ProjectFile, Range};
27use std::collections::BTreeSet;
28
29pub trait CppWorkspaceSource {
37 fn import_statements(&self, file: &ProjectFile) -> Vec<String>;
39
40 fn definitions_by_name(&self, token: QueryToken<'_>, name: &FqName) -> Vec<CodeUnit>;
44
45 fn definitions_by_identifier(&self, token: QueryToken<'_>, name: &FqName) -> Vec<CodeUnit>;
48}
49
50#[derive(Clone, Copy)]
57pub struct CppWorkspaceDefinitions<'a>(&'a dyn CppWorkspaceSource, QueryToken<'a>);
58
59impl<'a> CppWorkspaceDefinitions<'a> {
60 pub fn exact(&self, name: &FqName) -> Vec<CodeUnit> {
61 self.0.definitions_by_name(self.1, name)
62 }
63
64 pub fn identifier(&self, name: &FqName) -> Vec<CodeUnit> {
65 self.0.definitions_by_identifier(self.1, name)
66 }
67}
68
69#[derive(Clone, Copy)]
80pub struct CppGraphSource<'a> {
81 pub index: &'a dyn CodeUnitIndex,
82 pub cpp: Option<&'a dyn CppSource>,
83 pub aliases: Option<&'a dyn TypeAliasProvider>,
84 pub hierarchy: Option<&'a dyn TypeHierarchyProvider>,
85 pub workspace: &'a dyn CppWorkspaceSource,
86 pub token: QueryToken<'a>,
91}
92
93impl<'a> CppGraphSource<'a> {
94 pub fn from_source(source: &'a dyn CppSource, token: QueryToken<'a>) -> Self {
101 Self {
102 index: source,
103 cpp: Some(source),
104 aliases: Some(source),
105 hierarchy: Some(source),
106 workspace: source,
107 token,
108 }
109 }
110
111 pub fn type_alias_provider(&self) -> Option<&'a dyn TypeAliasProvider> {
112 self.aliases
113 }
114
115 pub fn type_hierarchy_provider(&self) -> Option<&'a dyn TypeHierarchyProvider> {
116 self.hierarchy
117 }
118
119 pub fn import_statements(&self, file: &ProjectFile) -> Vec<String> {
120 self.workspace.import_statements(file)
121 }
122
123 pub fn workspace_definitions(&self) -> CppWorkspaceDefinitions<'a> {
124 CppWorkspaceDefinitions(self.workspace, self.token)
125 }
126
127 pub fn parent_of(&self, code_unit: &CodeUnit) -> Option<CodeUnit> {
128 self.index.parent_of(code_unit)
129 }
130
131 pub fn ranges(&self, code_unit: &CodeUnit) -> Vec<Range> {
132 self.index.ranges(code_unit)
133 }
134
135 pub fn enclosing_code_unit(&self, file: &ProjectFile, range: &Range) -> Option<CodeUnit> {
136 self.index.enclosing_code_unit(file, range)
137 }
138
139 pub fn signature_metadata(&self, code_unit: &CodeUnit) -> Vec<SignatureMetadata> {
140 self.index.signature_metadata(code_unit)
141 }
142
143 pub fn cpp_field_linkage(&self, code_unit: &CodeUnit) -> Option<CppFieldLinkage> {
144 self.cpp?.cpp_field_linkage(code_unit)
145 }
146
147 pub fn signatures(&self, code_unit: &CodeUnit) -> Vec<String> {
148 self.index.signatures(code_unit)
149 }
150
151 pub fn get_source(&self, code_unit: &CodeUnit, include_comments: bool) -> Option<String> {
152 self.index.get_source(code_unit, include_comments)
153 }
154
155 pub fn indexed_source(&self, file: &ProjectFile) -> Option<String> {
156 self.index.indexed_source(file)
157 }
158
159 pub fn declarations(&self, file: &ProjectFile) -> BTreeSet<CodeUnit> {
160 self.index.declarations(file)
161 }
162
163 pub fn reference_uses_c_semantics(&self, file: &ProjectFile) -> bool {
169 match self.cpp {
170 Some(cpp) => resolver::reference_uses_c_semantics(cpp, file),
171 None => resolver::is_c_source_file(file),
172 }
173 }
174
175 pub fn declarations_in_reading(
178 &self,
179 file: &ProjectFile,
180 c_semantics: bool,
181 ) -> BTreeSet<CodeUnit> {
182 match self.cpp {
183 Some(cpp) if c_semantics => cpp.declarations_in_reading(file, true),
184 _ => self.index.declarations(file),
185 }
186 }
187
188 pub fn site_equivalent_units(&self, code_unit: &CodeUnit) -> Vec<CodeUnit> {
191 match self.cpp {
192 Some(cpp) => cpp.site_equivalent_units(code_unit),
193 None => Vec::new(),
194 }
195 }
196
197 pub fn direct_children(&self, code_unit: &CodeUnit) -> Vec<CodeUnit> {
198 self.index.direct_children(code_unit)
199 }
200
201 pub fn definitions(&self, fq_name: &str) -> Box<dyn Iterator<Item = CodeUnit> + '_> {
202 self.index.definitions(fq_name)
203 }
204}
205
206pub fn callable_definitions_share_identity_evidence(
215 analyzer: &CppGraphSource<'_>,
216 left: &CodeUnit,
217 right: &CodeUnit,
218) -> bool {
219 crate::identity::cpp_callable_definitions_share_identity_evidence(
220 analyzer.index,
221 left,
222 right,
223 |left_source, right_source| {
224 let Some(cpp) = analyzer.cpp else {
225 return false;
226 };
227 crate::identity::cpp_header_body_files_are_related(
228 cpp,
229 analyzer.token,
230 left_source,
231 right_source,
232 )
233 },
234 )
235}
236
237pub fn callable_definitions_share_identity_evidence_with_visibility(
243 analyzer: &CppGraphSource<'_>,
244 visibility: &resolver::VisibilityIndex<'_>,
245 left: &CodeUnit,
246 right: &CodeUnit,
247) -> bool {
248 crate::identity::cpp_callable_definitions_share_identity_evidence_with_visibility(
249 analyzer,
250 visibility,
251 left,
252 right,
253 |left_source, right_source| {
254 let Some(cpp) = analyzer.cpp else {
255 return false;
256 };
257 crate::identity::cpp_header_body_files_are_related(
258 cpp,
259 analyzer.token,
260 left_source,
261 right_source,
262 )
263 },
264 )
265}