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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//! Deterministic, language-tagged code topology built from one snapshot-bound
//! symbol-resolution result.
//!
//! The graph separates three relations a consumer would otherwise have to
//! reconstruct itself: logical containment, source association, and
//! certainty-carrying reference and dependency edges. It consumes already
//! validated in-memory facts and widens nothing: it loads no project, reads no
//! file, parses no source, invokes no build tool, and evaluates no policy.
//!
//! The snapshot must be the one the resolution was validated against, and a
//! successful build serializes to the compact version-1 JSON described below
//! through `serde_json::to_string`.
//!
//! ```no_run
//! # use pedant_core::resolution::rust::{RustResolutionSnapshot, RustTargetResolution};
//! # use pedant_graph::{CodeGraph, GraphBuildError};
//! # fn topology(
//! # snapshot: &RustResolutionSnapshot,
//! # resolution: &RustTargetResolution,
//! # ) -> Result<CodeGraph, GraphBuildError> {
//! pedant_graph::build_rust_graph(snapshot, resolution)
//! # }
//! ```
//!
//! # The version-1 shape
//!
//! One object with six keys, in this order:
//!
//! - `schema_version`: the integer [`CodeGraph::SCHEMA_VERSION`].
//! - `tier`: `"syntactic"` or `"semantic"`, taken from the supplied report.
//! - `nodes`: `id`, `language`, `name`, `kind`, `location`. `kind` is tagged by
//! `category`; `location` is `null` or tagged by `kind` as `file` or `span`.
//! - `containment`: `parent` and `child`, sorted by child then parent.
//! - `references`: `id`, `source`, `language`, `kind`, `text`, `span`, `gaps`,
//! `edges`, in mint order.
//! - `edges`: `id`, `source`, `target`, `kind`, `certainty`, `origin`, in mint
//! order. `origin` is tagged by `kind` as `reference` or `dependency`.
//!
//! Every identity is an integer equal to the record's position in its own
//! slice, and every graph-owned enum is one lower-snake-case string. No key
//! states a coordinate, a size, a color, or any other layout choice.
//! # Bounded queries over a built graph
//!
//! A caller states which edges to admit and what the answer may cost, then
//! asks. Nothing about the graph changes.
//!
//! ```no_run
//! # use pedant_graph::{
//! # CodeGraph, GraphAnalysis, GraphAnalysisError, GraphAnalysisLimits, GraphDirection,
//! # GraphEdgeSelection, GraphNeighbor, GraphNodeId,
//! # };
//! # fn callers_of(
//! # graph: &CodeGraph,
//! # node: GraphNodeId,
//! # ) -> Result<Box<[GraphNeighbor]>, GraphAnalysisError> {
//! let analysis = GraphAnalysis::new(
//! graph,
//! GraphEdgeSelection::code_relations(),
//! GraphAnalysisLimits::new(100_000, 400_000, 8, 50_000_000),
//! )?;
//! analysis.neighbors(node, 2, GraphDirection::Incoming)
//! # }
//! ```
//!
//! The same view answers the derived questions. Cohesion, modularity, affinity,
//! and boundary-crossing cycles are evidence about the partition the graph
//! declares; layout metadata is that evidence beside the degrees and weights a
//! ranker or a renderer would otherwise measure itself.
//!
//! ```no_run
//! # use pedant_graph::{
//! # CodeGraph, GraphAnalysis, GraphAnalysisError, GraphAnalysisLimits, GraphEdgeSelection,
//! # LayoutAssistMetadata,
//! # };
//! # fn described(graph: &CodeGraph) -> Result<LayoutAssistMetadata, GraphAnalysisError> {
//! let analysis = GraphAnalysis::new(
//! graph,
//! GraphEdgeSelection::code_relations(),
//! GraphAnalysisLimits::new(100_000, 400_000, 8, 50_000_000),
//! )?;
//! let evidence = analysis.divergence();
//! for module in evidence.cohesion() {
//! let _ = (module.root(), module.internal_edges(), module.score());
//! }
//! analysis.layout_assist()
//! # }
//! ```
//!
//! # Optional bounded reuse
//!
//! A caller that inspects successive repository states may keep a cache of the
//! work it already admitted. The cache builds nothing of its own: it takes the
//! same snapshot and validated resolution the direct builder takes, returns the
//! same graph, and states how many values it may retain. Zero disables a
//! category without disabling the computation behind it.
//!
//! ```no_run
//! # use pedant_core::resolution::rust::{RustResolutionSnapshot, RustTargetResolution};
//! # use pedant_graph::{
//! # GraphAnalysisError, GraphAnalysisLimits, GraphBuildError, GraphCache, GraphCacheLimits,
//! # GraphEdgeSelection, GraphLimits,
//! # };
//! # #[derive(Debug)]
//! # enum ReuseError {
//! # Build(GraphBuildError),
//! # Analysis(GraphAnalysisError),
//! # }
//! # impl From<GraphBuildError> for ReuseError {
//! # fn from(error: GraphBuildError) -> Self { Self::Build(error) }
//! # }
//! # impl From<GraphAnalysisError> for ReuseError {
//! # fn from(error: GraphAnalysisError) -> Self { Self::Analysis(error) }
//! # }
//! # fn reused(
//! # snapshot: &RustResolutionSnapshot,
//! # resolution: &RustTargetResolution,
//! # ) -> Result<(), ReuseError> {
//! let mut cache = GraphCache::new(GraphCacheLimits::new(4_096, 8, 4, 256));
//! let held = cache.build_rust_graph(snapshot, resolution, GraphLimits::default())?;
//! let analysis = held.analyze(
//! GraphEdgeSelection::code_relations(),
//! GraphAnalysisLimits::new(100_000, 400_000, 8, 50_000_000),
//! )?;
//! let _ = (analysis.divergence(), cache.stats().exact_graph_hits());
//! # Ok(())
//! # }
//! ```
//!
//! The returned handles are the caller's: a graph, an analysis, and every
//! product they answer with stay valid and immutable after eviction, after
//! `clear`, and after the cache itself is dropped. Nothing about the version-1
//! object above changes, and no cache value is serialized.
/// Derived analysis over one borrowed graph.
/// Optional caller-owned reuse of already admitted graph work.
/// The logical hierarchy relation.
/// Graph edges, their certainty, and their evidence.
/// Why a graph build refused.
/// The immutable graph value and its checked record store.
/// Dense typed identities into one graph's collections.
/// The configured ceilings a build refuses at.
/// Graph nodes, their categories, and their source locations.
/// Reference records and what they denote.
/// The Rust projection adapter.
pub use ;
pub use ;
pub use ContainmentEdge;
pub use ;
pub use GraphBuildError;
pub use CodeGraph;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;