sinter_core/facts.rs
1use serde::{Deserialize, Serialize};
2
3use crate::edge::Edge;
4use crate::node::{CorpusScope, Node, NodeId};
5use crate::reference::{Embed, FieldBinding, LocalBinding, Reference, TraitImpl};
6
7/// Everything extraction produces for one file. Content-addressed: the hash
8/// is the incrementality key — same bytes, same facts. The persisted set of
9/// `FileFacts` is the source of truth every derived table rebuilds from.
10#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
11pub struct FileFacts {
12 /// Repo-relative path.
13 pub file: String,
14 /// blake3 of the source bytes, hex.
15 pub content_hash: String,
16 /// Tree-sitter reported syntax errors; facts are best-effort partial.
17 pub has_syntax_errors: bool,
18 /// File node plus every definition, content-bearing.
19 pub nodes: Vec<Node>,
20 /// Structural containment edges (Certain).
21 pub contains: Vec<Edge>,
22 /// Reference sites: calls, imports. Resolution input.
23 pub references: Vec<Reference>,
24 /// Local bindings that shadow outer names. Resolution suppression input.
25 pub locals: Vec<LocalBinding>,
26 /// Declared field types for field-receiver resolution.
27 pub fields: Vec<FieldBinding>,
28 /// Type embeddings (promoted members). Resolution lookup input.
29 pub embeds: Vec<Embed>,
30 /// Trait-impl blocks. Dynamic-dispatch edge input.
31 pub trait_impls: Vec<TraitImpl>,
32 /// Node-level scope overrides (sparse): nodes whose role differs from
33 /// their file's path-derived scope, e.g. a Rust `#[cfg(test)]` module's
34 /// members or a `@generated` header's file node.
35 pub scopes: Vec<(NodeId, CorpusScope)>,
36 /// Body-only identifier words per function/method (sparse): words the
37 /// body uses that the name, signature, and doc do not. Ranking evidence
38 /// for concept-phrased questions.
39 pub body_terms: Vec<(NodeId, Vec<String>)>,
40}