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: Box<[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, copied from the report record.
56 pub(crate) gaps: Box<[ResolutionGap]>,
57}
58
59impl GraphReference {
60 pub(crate) fn new(
61 id: GraphReferenceId,
62 draft: ReferenceDraft,
63 edges: Box<[GraphEdgeId]>,
64 ) -> Self {
65 Self {
66 id,
67 source: draft.source,
68 language: draft.language,
69 kind: draft.kind,
70 text: draft.text,
71 span: draft.span,
72 gaps: draft.gaps,
73 edges,
74 }
75 }
76
77 /// This record's dense identity, equal to its position in the graph.
78 pub fn id(&self) -> GraphReferenceId {
79 self.id
80 }
81
82 /// The node every edge this record produced starts at.
83 pub fn source(&self) -> GraphNodeId {
84 self.source
85 }
86
87 /// The language of the unit this site sits in.
88 pub fn language(&self) -> Language {
89 self.language
90 }
91
92 /// What this site denotes at the graph layer.
93 pub fn kind(&self) -> GraphReferenceKind {
94 self.kind
95 }
96
97 /// The exact source text of the site.
98 pub fn text(&self) -> &str {
99 &self.text
100 }
101
102 /// Where the site sits.
103 pub fn span(&self) -> &SourceSpan {
104 &self.span
105 }
106
107 /// Why the answer is incomplete, in report order.
108 pub fn gaps(&self) -> &[ResolutionGap] {
109 &self.gaps
110 }
111
112 /// The edges this record's candidates produced, in candidate order.
113 pub fn edges(&self) -> &[GraphEdgeId] {
114 &self.edges
115 }
116}