Skip to main content

code_moniker_core/lang/sdk/
emit.rs

1use crate::core::code_graph::{CodeGraph, DefAttrs, GraphError, RefAttrs};
2
3use super::model::{DiscoveredFile, ResolvedRef};
4
5#[derive(Debug)]
6pub enum EmitError {
7	Graph(GraphError),
8}
9
10impl std::fmt::Display for EmitError {
11	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12		match self {
13			Self::Graph(err) => write!(f, "{err}"),
14		}
15	}
16}
17
18impl std::error::Error for EmitError {}
19
20impl From<GraphError> for EmitError {
21	fn from(value: GraphError) -> Self {
22		Self::Graph(value)
23	}
24}
25
26pub struct GraphEmitter;
27
28impl GraphEmitter {
29	pub fn emit(discovered: &DiscoveredFile, refs: &[ResolvedRef]) -> Result<CodeGraph, EmitError> {
30		let mut builder = GraphBuilder::new(discovered, refs.len());
31		builder.emit_defs(discovered)?;
32		builder.emit_refs(refs)?;
33		Ok(builder.finish())
34	}
35}
36
37struct GraphBuilder {
38	graph: CodeGraph,
39}
40
41impl GraphBuilder {
42	fn new(discovered: &DiscoveredFile, ref_count: usize) -> Self {
43		Self {
44			graph: CodeGraph::with_capacity(
45				discovered.root.clone(),
46				discovered.root_kind,
47				discovered.defs.len() + 1,
48				ref_count,
49			),
50		}
51	}
52
53	fn emit_defs(&mut self, discovered: &DiscoveredFile) -> Result<(), EmitError> {
54		for def in &discovered.defs {
55			let attrs = DefAttrs {
56				visibility: def.visibility,
57				signature: &def.signature,
58				call_name: &def.call_name,
59				call_arity: def.call_arity,
60				..DefAttrs::default()
61			};
62			self.graph.add_def_attrs(
63				def.moniker.clone(),
64				def.kind,
65				&def.parent,
66				def.position,
67				&attrs,
68			)?;
69		}
70		Ok(())
71	}
72
73	fn emit_refs(&mut self, refs: &[ResolvedRef]) -> Result<(), EmitError> {
74		for reference in refs {
75			let attrs = RefAttrs {
76				receiver_hint: &reference.hints.receiver_hint,
77				alias: &reference.hints.alias,
78				confidence: reference.confidence,
79				call_name: &reference.hints.call_name,
80				call_arity: reference.hints.call_arity,
81				..RefAttrs::default()
82			};
83			self.graph.add_ref_attrs(
84				&reference.source,
85				reference.target.clone(),
86				reference.kind,
87				reference.position,
88				&attrs,
89			)?;
90		}
91		Ok(())
92	}
93
94	fn finish(self) -> CodeGraph {
95		self.graph
96	}
97}