Skip to main content

pedant_graph/
reference.rs

1//! A reference record: one naming site, its evidence, and what it produced.
2
3use std::sync::Arc;
4
5use pedant_types::{Language, ResolutionGap, SourceSpan};
6use serde::Serialize;
7
8use crate::id::{GraphEdgeId, GraphNodeId, GraphReferenceId};
9
10/// What a naming site denotes at the graph layer.
11///
12/// A language's finer reference vocabulary collapses into these four: a module
13/// declaration and a type mention are both general source relations here.
14#[derive(Serialize, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
15#[serde(rename_all = "snake_case")]
16pub enum GraphReferenceKind {
17    /// A call site.
18    Call,
19    /// An import site, including a rename, a group member, or a re-export.
20    Import,
21    /// An implementation naming its type or its trait.
22    Implementation,
23    /// Any other source relation between a site and a definition.
24    Reference,
25}
26
27/// One naming site, its copied evidence, and the edges its candidates produced.
28///
29/// A site with no candidate keeps its record and its gaps, so unresolved
30/// evidence never disappears from the graph.
31#[derive(Serialize, Clone, Debug, PartialEq, Eq)]
32pub struct GraphReference {
33    id: GraphReferenceId,
34    source: GraphNodeId,
35    language: Language,
36    kind: GraphReferenceKind,
37    text: Arc<str>,
38    span: SourceSpan,
39    gaps: Arc<[ResolutionGap]>,
40    edges: Box<[GraphEdgeId]>,
41}
42
43/// Everything a projection states about one site before it has an identity.
44pub(crate) struct ReferenceDraft {
45    /// The enclosing definition node, or the unit-qualified span file node.
46    pub(crate) source: GraphNodeId,
47    /// The language of the unit the site sits in.
48    pub(crate) language: Language,
49    /// What the site denotes at the graph layer.
50    pub(crate) kind: GraphReferenceKind,
51    /// The exact source text of the site.
52    pub(crate) text: Arc<str>,
53    /// Where the site sits.
54    pub(crate) span: SourceSpan,
55    /// Why the answer is incomplete, shared with the projection that stated it.
56    ///
57    /// A retained projection drafts its records again on every build that
58    /// reuses it, so the answer travels as one allocation rather than a copy
59    /// per build.
60    pub(crate) gaps: Arc<[ResolutionGap]>,
61}
62
63impl GraphReference {
64    pub(crate) fn new(
65        id: GraphReferenceId,
66        draft: ReferenceDraft,
67        edges: Box<[GraphEdgeId]>,
68    ) -> Self {
69        Self {
70            id,
71            source: draft.source,
72            language: draft.language,
73            kind: draft.kind,
74            text: draft.text,
75            span: draft.span,
76            gaps: draft.gaps,
77            edges,
78        }
79    }
80
81    /// This record's dense identity, equal to its position in the graph.
82    pub fn id(&self) -> GraphReferenceId {
83        self.id
84    }
85
86    /// The node every edge this record produced starts at.
87    pub fn source(&self) -> GraphNodeId {
88        self.source
89    }
90
91    /// The language of the unit this site sits in.
92    pub fn language(&self) -> Language {
93        self.language
94    }
95
96    /// What this site denotes at the graph layer.
97    pub fn kind(&self) -> GraphReferenceKind {
98        self.kind
99    }
100
101    /// The exact source text of the site.
102    pub fn text(&self) -> &str {
103        &self.text
104    }
105
106    /// Where the site sits.
107    pub fn span(&self) -> &SourceSpan {
108        &self.span
109    }
110
111    /// Why the answer is incomplete, in report order.
112    pub fn gaps(&self) -> &[ResolutionGap] {
113        &self.gaps
114    }
115
116    /// The edges this record's candidates produced, in candidate order.
117    pub fn edges(&self) -> &[GraphEdgeId] {
118        &self.edges
119    }
120}