1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::collections::HashMap;
use std::sync::Arc;
use mir_types::Union;
// MirDatabase trait
/// Salsa database trait for mir incremental analysis.
#[salsa::db]
pub trait MirDatabase: salsa::Database {
/// The PHP version configured for this analysis run.
fn php_version_str(&self) -> Arc<str>;
/// Look up the [`ClassNode`] handle registered for `fqcn`, if any.
///
/// This is an untracked read — the DashMap holds Salsa input *handles*
/// (cheap IDs), not data. Changes to a class's *fields* (parent,
/// interfaces, active state) are tracked through the `ClassNode` input
/// itself, so downstream queries are still correctly invalidated.
fn lookup_class_node(&self, fqcn: &str) -> Option<ClassNode>;
/// Look up the [`FunctionNode`] handle registered for `fqn`, if any.
fn lookup_function_node(&self, fqn: &str) -> Option<FunctionNode>;
/// Look up the [`MethodNode`] for `(fqcn, method_name_lower)`, if any.
///
/// `method_name_lower` must already be lowercased. This is an untracked
/// read — changes to a method's fields are tracked through the `MethodNode`
/// input itself.
fn lookup_method_node(&self, fqcn: &str, method_name_lower: &str) -> Option<MethodNode>;
/// Look up the [`PropertyNode`] for `(fqcn, prop_name)`, if any.
fn lookup_property_node(&self, fqcn: &str, prop_name: &str) -> Option<PropertyNode>;
/// Look up the [`ClassConstantNode`] for `(fqcn, const_name)`, if any.
fn lookup_class_constant_node(&self, fqcn: &str, const_name: &str)
-> Option<ClassConstantNode>;
/// Look up the [`GlobalConstantNode`] for `fqn`, if any.
fn lookup_global_constant_node(&self, fqn: &str) -> Option<GlobalConstantNode>;
/// Return all own-method nodes for `fqcn`. Empty if no class is
/// registered. Untracked iteration of a per-class HashMap.
fn class_own_methods(&self, fqcn: &str) -> Vec<MethodNode>;
/// Return all own-property nodes for `fqcn`. Empty if no class is
/// registered. Untracked iteration of a per-class HashMap.
fn class_own_properties(&self, fqcn: &str) -> Vec<PropertyNode>;
/// Return all class-FQCNs currently registered as active `ClassNode`s,
/// optionally filtered by kind. Untracked snapshot — callers should
/// treat the returned `Vec` as a one-shot view.
fn active_class_node_fqcns(&self) -> Vec<Arc<str>>;
/// Return all function-FQNs currently registered as active
/// `FunctionNode`s. Untracked snapshot.
fn active_function_node_fqns(&self) -> Vec<Arc<str>>;
/// Return this file's first declared namespace, if any.
fn file_namespace(&self, file: &str) -> Option<Arc<str>>;
/// Return this file's `use` alias map.
fn file_imports(&self, file: &str) -> HashMap<String, String>;
/// Return the known type for a PHP global variable.
fn global_var_type(&self, name: &str) -> Option<Union>;
/// Return `(file, imports)` snapshots for every known file.
fn file_import_snapshots(&self) -> Vec<(Arc<str>, HashMap<String, String>)>;
/// Return the defining file for a symbol, if known.
fn symbol_defining_file(&self, symbol: &str) -> Option<Arc<str>>;
/// Return all symbols whose defining file is `file`.
fn symbols_defined_in_file(&self, file: &str) -> Vec<Arc<str>>;
/// Record a reference-location entry.
fn record_reference_location(&self, loc: RefLoc);
/// Replay reference locations for one file from cache.
fn replay_reference_locations(&self, file: Arc<str>, locs: &[(String, u32, u16, u16)]);
/// Extract reference locations for one file in cache-storage shape.
fn extract_file_reference_locations(&self, file: &str) -> Vec<(Arc<str>, u32, u16, u16)>;
/// Return all reference locations for one public symbol key.
fn reference_locations(&self, symbol: &str) -> Vec<(Arc<str>, u32, u16, u16)>;
/// Whether the public symbol key has at least one recorded reference.
fn has_reference(&self, symbol: &str) -> bool;
/// Clear reference locations for a file before re-analysis.
fn clear_file_references(&self, file: &str);
}
// Re-export all public items from sub-modules to preserve the flat db::* namespace.
pub use self::ancestors::*;
pub use self::mirdb::{ClassNodeFields, MirDb};
pub use self::nodes::*;
pub use self::queries::*;
pub use self::reference_locations::*;
// Sub-modules
mod ancestors;
mod mirdb;
mod nodes;
mod queries;
mod reference_locations;
#[cfg(test)]
pub mod tests;