petr_resolve/
resolved.rs

1use std::collections::BTreeMap;
2
3use petr_bind::{BindingId, FunctionId};
4use petr_utils::{SymbolInterner, TypeId};
5
6use crate::resolver::{Binding, Function, TypeDeclaration};
7/// Contains things that have already been resolved.
8/// Resolved items cannot be queried during resolution. This is because the resolution
9/// stage should only query the binder, then the type checking stage can query
10/// the [QueryableResolved] to get the resolved items -- [QueryableResolvedItems] is the
11/// immutable result of resolution, and resolved items can no longer be mutated.
12pub(crate) struct ResolvedItems {
13    pub resolved_functions: BTreeMap<FunctionId, Function>,
14    pub resolved_types:     BTreeMap<TypeId, TypeDeclaration>,
15    pub bindings:           BTreeMap<BindingId, Binding>,
16}
17
18impl ResolvedItems {
19    pub fn insert_function(
20        &mut self,
21        id: FunctionId,
22        function: Function,
23    ) {
24        self.resolved_functions.insert(id, function);
25    }
26
27    pub fn insert_type(
28        &mut self,
29        id: TypeId,
30        type_decl: TypeDeclaration,
31    ) {
32        self.resolved_types.insert(id, type_decl);
33    }
34
35    pub(crate) fn new() -> Self {
36        Self {
37            resolved_functions: Default::default(),
38            resolved_types:     Default::default(),
39            bindings:           Default::default(),
40        }
41    }
42}
43
44pub struct QueryableResolvedItems {
45    resolved_functions: BTreeMap<FunctionId, Function>,
46    resolved_types:     BTreeMap<TypeId, TypeDeclaration>,
47    pub interner:       SymbolInterner,
48}
49
50impl QueryableResolvedItems {
51    pub fn new(
52        resolved_functions: BTreeMap<FunctionId, Function>,
53        resolved_types: BTreeMap<TypeId, TypeDeclaration>,
54        interner: SymbolInterner,
55    ) -> Self {
56        Self {
57            resolved_functions,
58            resolved_types,
59            interner,
60        }
61    }
62
63    pub fn get_function(
64        &self,
65        id: FunctionId,
66    ) -> &Function {
67        self.resolved_functions
68            .get(&id)
69            .expect("function IDs should always correspond to resolved functions")
70    }
71
72    pub fn get_type(
73        &self,
74        id: TypeId,
75    ) -> &TypeDeclaration {
76        self.resolved_types.get(&id).expect("type IDs should always correspond to resolved types")
77    }
78
79    // TODO  The cloning of the below iterators (`functions` and `types`) is not ideal.
80    pub fn functions(&self) -> impl Iterator<Item = (FunctionId, Function)> {
81        self.resolved_functions
82            .iter()
83            .map(|(id, decl)| (*id, decl.clone()))
84            .collect::<Vec<_>>()
85            .into_iter()
86    }
87
88    pub fn types(&self) -> impl Iterator<Item = (TypeId, TypeDeclaration)> {
89        self.resolved_types
90            .iter()
91            .map(|(id, decl)| (*id, decl.clone()))
92            .collect::<Vec<_>>()
93            .into_iter()
94    }
95}