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
//! The retained fact inventory one snapshotted Go source states.
//!
//! `pedant-syntax` extracts one [`GoFileFacts`] bound to the exact string its
//! tree indexes. A snapshot outlives that string's parse, so it retains the
//! same claims with their names owned. Nothing here reads a grammar node: the
//! whole inventory is a projection of the one Go grammar authority, so a fact
//! this crate states is a fact that crate extracted.
use pedant_syntax::go::{GoFactSpan, GoFileFacts, GoScopeFact};
use super::binding_fact::GoBindingRecord;
use super::declaration_fact::GoDeclarationRecord;
use super::import_fact::GoImportRecord;
use super::reference_fact::GoReferenceRecord;
use super::signature_fact::GoSignatureTermRecord;
/// Every structured Go grammar fact one snapshotted source states.
///
/// Sealed on construction and read through borrows, so a consumer reads what
/// the extraction claimed and cannot restate it as something the walk never
/// saw. Every list keeps the source order the extraction produced, because the
/// indexes records carry — parents, receivers, scopes, declarations — select
/// positions inside these lists.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GoSourceFacts {
package: Option<(Box<str>, GoFactSpan)>,
imports: Box<[GoImportRecord]>,
declarations: Box<[GoDeclarationRecord]>,
signatures: Box<[GoSignatureTermRecord]>,
references: Box<[GoReferenceRecord]>,
scopes: Box<[GoScopeFact]>,
bindings: Box<[GoBindingRecord]>,
}
impl GoSourceFacts {
/// Retain one extracted inventory.
pub(super) fn of(facts: &GoFileFacts<'_>) -> Self {
Self {
package: facts
.package_name()
.zip(facts.package_span())
.map(|(name, span)| (Box::from(name), span)),
imports: facts.imports().iter().map(GoImportRecord::of).collect(),
declarations: facts
.declarations()
.iter()
.map(GoDeclarationRecord::of)
.collect(),
signatures: facts
.signature_terms()
.iter()
.map(GoSignatureTermRecord::of)
.collect(),
references: facts
.references()
.iter()
.map(GoReferenceRecord::of)
.collect(),
scopes: Box::from(facts.scopes()),
bindings: facts.bindings().iter().map(GoBindingRecord::of).collect(),
}
}
/// The declared package name, absent when the source states no clause.
pub fn package_name(&self) -> Option<&str> {
self.package.as_ref().map(|(name, _)| &**name)
}
/// The extent of the declared package name.
pub fn package_span(&self) -> Option<GoFactSpan> {
self.package.as_ref().map(|(_, span)| *span)
}
/// Every import specification, in source order.
pub fn imports(&self) -> &[GoImportRecord] {
&self.imports
}
/// Every declaration, in source order.
pub fn declarations(&self) -> &[GoDeclarationRecord] {
&self.declarations
}
/// Every signature term, in the order the callables that state them are
/// declared.
pub fn signature_terms(&self) -> &[GoSignatureTermRecord] {
&self.signatures
}
/// Every reference site, in source order.
pub fn references(&self) -> &[GoReferenceRecord] {
&self.references
}
/// Every lexical scope, in source order, opening with the file scope.
pub fn scopes(&self) -> &[GoScopeFact] {
&self.scopes
}
/// Every bound name, in source order.
pub fn bindings(&self) -> &[GoBindingRecord] {
&self.bindings
}
}