1use crate::external_map::ExternalMap;
8use crate::ir::{TypeDeclaration, TypeKind};
9use crate::parse::scope::{PendingImport, ScopeArena, ScopeId};
10use crate::util::diagnostics::DiagnosticCollector;
11
12#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
14pub struct TypeId(u32);
15
16impl TypeId {
17 pub fn index(self) -> usize {
19 self.0 as usize
20 }
21}
22
23#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
25pub struct ModuleId(u32);
26
27#[derive(Clone, Debug)]
29pub struct ParsedModule {
30 pub specifier: String,
32 pub scope: ScopeId,
34 pub types: Vec<TypeId>,
36}
37
38#[derive(Clone, Debug)]
49pub struct GlobalContext {
50 pub scopes: ScopeArena,
51 pub diagnostics: DiagnosticCollector,
52 pub external_map: ExternalMap,
53 pub pending_imports: Vec<PendingImport>,
55 types: Vec<TypeDeclaration>,
56 modules: Vec<ParsedModule>,
57 module_index: std::collections::HashMap<String, ModuleId>,
59}
60
61impl GlobalContext {
62 pub fn new() -> Self {
63 Self {
64 scopes: ScopeArena::new(),
65 diagnostics: DiagnosticCollector::new(),
66 external_map: ExternalMap::new(),
67 pending_imports: Vec::new(),
68 types: Vec::new(),
69 modules: Vec::new(),
70 module_index: std::collections::HashMap::new(),
71 }
72 }
73
74 pub fn warn(&mut self, message: impl Into<String>) {
76 self.diagnostics.warn(message);
77 }
78
79 pub fn info(&mut self, message: impl Into<String>) {
81 self.diagnostics.info(message);
82 }
83
84 pub fn create_root_scope(&mut self) -> ScopeId {
88 self.scopes.create_root()
89 }
90
91 pub fn create_child_scope(&mut self, parent: ScopeId) -> ScopeId {
93 self.scopes.create_child(parent)
94 }
95
96 pub fn register_module(&mut self, specifier: String, scope: ScopeId) -> ModuleId {
100 let id = ModuleId(self.modules.len() as u32);
101 self.module_index.insert(specifier.clone(), id);
102 self.modules.push(ParsedModule {
103 specifier,
104 scope,
105 types: Vec::new(),
106 });
107 id
108 }
109
110 pub fn find_module(&self, specifier: &str) -> Option<ModuleId> {
112 self.module_index.get(specifier).copied()
113 }
114
115 pub fn get_module(&self, id: ModuleId) -> &ParsedModule {
117 &self.modules[id.0 as usize]
118 }
119
120 pub fn get_module_mut(&mut self, id: ModuleId) -> &mut ParsedModule {
122 &mut self.modules[id.0 as usize]
123 }
124
125 pub fn insert_type(&mut self, decl: TypeDeclaration) -> TypeId {
129 let id = TypeId(self.types.len() as u32);
130 self.types.push(decl);
131 id
132 }
133
134 pub fn get_type(&self, id: TypeId) -> &TypeDeclaration {
136 &self.types[id.index()]
137 }
138
139 pub fn type_arena(&self) -> &[TypeDeclaration] {
141 &self.types
142 }
143
144 pub fn resolve_path(&self, scope: ScopeId, path: &str) -> Option<TypeId> {
149 let mut segments = path.split('.');
150 let first = segments.next()?;
151
152 let mut current_id = self.scopes.resolve(scope, first)?;
153
154 for segment in segments {
155 let decl = self.get_type(current_id);
156 match &decl.kind {
157 TypeKind::Namespace(ns) => {
158 current_id = self.scopes.resolve(ns.child_scope, segment)?;
159 }
160 _ => return None, }
162 }
163
164 Some(current_id)
165 }
166
167 pub fn iter_types(&self) -> impl Iterator<Item = (TypeId, &TypeDeclaration)> {
169 self.types
170 .iter()
171 .enumerate()
172 .map(|(i, d)| (TypeId(i as u32), d))
173 }
174}
175
176impl Default for GlobalContext {
177 fn default() -> Self {
178 Self::new()
179 }
180}