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