1use crate::load::ModuleLoader;
5use crate::model::definitions::{
6 DatatypeDef, EntityDef, EnumDef, EventDef, PropertyDef, StructureDef, UnionDef,
7};
8use crate::model::References;
9use crate::model::{
10 annotations::{Annotation, HasAnnotations},
11 check::{MaybeIncomplete, Validate},
12 definitions::{Definition, RdfDef, TypeClassDef},
13 identifiers::{Identifier, IdentifierReference, QualifiedIdentifier},
14 HasBody, HasName, HasSourceSpan, Span,
15};
16use crate::store::{InMemoryModuleCache, ModuleStore};
17use sdml_errors::diagnostics::functions::{
18 definition_not_found, imported_module_not_found, library_definition_not_allowed,
19 module_is_incomplete, module_version_info_empty, module_version_mismatch,
20 module_version_not_found, IdentifierCaseConvention,
21};
22use sdml_errors::{Error, FileId};
23use std::collections::BTreeMap;
24use std::fmt::Display;
25use std::hash::Hash;
26use std::path::PathBuf;
27use std::{collections::BTreeSet, fmt::Debug};
28use url::Url;
29
30#[cfg(feature = "serde")]
31use serde::{Deserialize, Serialize};
32
33#[derive(Clone, Debug)]
41#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
42pub struct Module {
43 #[cfg_attr(feature = "serde", serde(skip))]
44 source_file: Option<PathBuf>,
45 #[cfg_attr(feature = "serde", serde(skip))]
46 file_id: Option<FileId>,
47 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
48 span: Option<Span>,
49 name: Identifier,
50 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
51 base_uri: Option<HeaderValue<Url>>,
52 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
53 version_info: Option<HeaderValue<String>>,
54 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
55 version_uri: Option<HeaderValue<Url>>,
56 body: ModuleBody,
57}
58
59#[derive(Clone, Debug)]
60#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
61pub struct HeaderValue<T> {
62 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
63 span: Option<Span>,
64 value: T,
65}
66
67#[derive(Clone, Debug, Default)]
71#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
72pub struct ModuleBody {
73 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
74 span: Option<Span>,
75 file_id: Option<FileId>, is_library: bool, imports: Vec<ImportStatement>,
78 annotations: Vec<Annotation>,
79 definitions: BTreeMap<Identifier, Definition>,
80}
81
82#[derive(Clone, Debug, Default)]
90#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
91pub struct ImportStatement {
92 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
93 span: Option<Span>,
94 imports: Vec<Import>,
95}
96
97#[derive(Clone, Debug, PartialEq, Eq, Hash)]
101#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
102pub enum Import {
103 Module(ModuleImport),
105 Member(MemberImport),
107}
108
109#[derive(Clone, Debug)]
113#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
114pub struct ModuleImport {
115 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
116 span: Option<Span>,
117 name: Identifier,
118 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
119 version_uri: Option<HeaderValue<Url>>,
120 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
121 renamed_as: Option<Identifier>,
122}
123
124#[derive(Clone, Debug)]
128#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
129pub struct MemberImport {
130 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
131 span: Option<Span>,
132 name: QualifiedIdentifier,
133 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
134 renamed_as: Option<Identifier>,
135}
136
137impl HasSourceSpan for Module {
142 fn with_source_span(self, span: Span) -> Self {
143 let mut self_mut = self;
144 self_mut.span = Some(span);
145 self_mut
146 }
147
148 fn source_span(&self) -> Option<&Span> {
149 self.span.as_ref()
150 }
151
152 fn set_source_span(&mut self, span: Span) {
153 self.span = Some(span);
154 }
155
156 fn unset_source_span(&mut self) {
157 self.span = None;
158 }
159}
160
161impl HasName for Module {
162 fn name(&self) -> &Identifier {
163 &self.name
164 }
165
166 fn set_name(&mut self, name: Identifier) {
167 self.name = name;
168 }
169}
170
171impl HasBody for Module {
172 type Body = ModuleBody;
173
174 fn body(&self) -> &Self::Body {
175 &self.body
176 }
177
178 fn body_mut(&mut self) -> &mut Self::Body {
179 &mut self.body
180 }
181
182 fn set_body(&mut self, body: Self::Body) {
183 let mut body_mut = body;
184 body_mut.file_id = self.file_id;
185 body_mut.set_library_status(self.name());
186 self.body = body_mut;
187 }
188}
189
190impl References for Module {
191 fn referenced_types<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
192 self.body.referenced_types(names);
193 }
194
195 fn referenced_annotations<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
196 self.body.referenced_annotations(names);
197 }
198}
199
200impl Module {
201 pub fn empty(name: Identifier) -> Self {
206 Self::new(name, ModuleBody::default())
207 }
208
209 pub fn new(name: Identifier, body: ModuleBody) -> Self {
210 let mut body = body;
211 body.set_library_status(&name);
212 Self {
213 source_file: None,
214 file_id: None,
215 span: None,
216 name,
217 base_uri: None,
218 version_info: None,
219 version_uri: None,
220 body,
221 }
222 }
223
224 pub fn with_source_file(self, source_file: PathBuf) -> Self {
229 Self {
230 source_file: Some(source_file),
231 ..self
232 }
233 }
234
235 pub fn with_base_uri(self, base_uri: Url) -> Self {
236 Self {
237 base_uri: Some(base_uri.into()),
238 ..self
239 }
240 }
241
242 pub fn with_version_info<S>(self, version_info: S) -> Self
243 where
244 S: Into<String>,
245 {
246 Self {
247 version_info: Some(HeaderValue::from(version_info.into())),
248 ..self
249 }
250 }
251
252 pub fn with_version_uri(self, version_uri: Url) -> Self {
253 Self {
254 version_uri: Some(version_uri.into()),
255 ..self
256 }
257 }
258
259 pub const fn has_source_file(&self) -> bool {
260 self.source_file.is_some()
261 }
262 pub const fn source_file(&self) -> Option<&PathBuf> {
263 self.source_file.as_ref()
264 }
265 pub fn set_source_file(&mut self, source_file: PathBuf) {
266 self.source_file = Some(source_file);
267 }
268 pub fn unset_source_file(&mut self) {
269 self.source_file = None;
270 }
271
272 pub const fn has_base_uri(&self) -> bool {
273 self.base_uri.is_some()
274 }
275 pub const fn base_uri(&self) -> Option<&HeaderValue<Url>> {
276 self.base_uri.as_ref()
277 }
278 pub fn set_base_uri(&mut self, base_uri: HeaderValue<Url>) {
279 self.base_uri = Some(base_uri);
280 }
281 pub fn unset_base_uri(&mut self) {
282 self.base_uri = None;
283 }
284
285 pub const fn has_version_info(&self) -> bool {
286 self.version_info.is_some()
287 }
288 pub const fn version_info(&self) -> Option<&HeaderValue<String>> {
289 self.version_info.as_ref()
290 }
291 pub fn set_version_info(&mut self, version_info: HeaderValue<String>) {
292 self.version_info = Some(version_info);
293 }
294 pub fn unset_version_info(&mut self) {
295 self.version_info = None;
296 }
297
298 pub const fn has_version_uri(&self) -> bool {
299 self.version_uri.is_some()
300 }
301 pub const fn version_uri(&self) -> Option<&HeaderValue<Url>> {
302 self.version_uri.as_ref()
303 }
304 pub fn set_version_uri(&mut self, version_uri: HeaderValue<Url>) {
305 self.version_uri = Some(version_uri);
306 }
307 pub fn unset_version_uri(&mut self) {
308 self.version_uri = None;
309 }
310
311 pub const fn has_file_id(&self) -> bool {
312 self.file_id.is_some()
313 }
314 pub const fn file_id(&self) -> Option<&FileId> {
315 self.file_id.as_ref()
316 }
317 pub fn set_file_id(&mut self, file_id: FileId) {
318 self.file_id = Some(file_id);
319 }
320 pub fn unset_file_id(&mut self) {
321 self.file_id = None;
322 }
323
324 #[inline(always)]
327 pub fn imported_modules(&self) -> BTreeSet<&Identifier> {
328 self.body.imported_modules()
329 }
330
331 #[inline(always)]
332 pub fn imported_module_versions(&self) -> BTreeMap<&Identifier, Option<&HeaderValue<Url>>> {
333 self.body.imported_module_versions()
334 }
335
336 #[inline(always)]
337 pub fn imported_types(&self) -> BTreeSet<&QualifiedIdentifier> {
338 self.body.imported_types()
339 }
340
341 #[inline(always)]
342 pub fn defined_names(&self) -> BTreeSet<&Identifier> {
343 self.body.defined_names()
344 }
345
346 pub fn is_incomplete(&self, cache: &InMemoryModuleCache) -> bool {
351 if !self.is_library_module() {
352 self.body.is_incomplete(self, cache)
353 } else {
354 false
355 }
356 }
357
358 pub fn validate(
368 &self,
369 cache: &InMemoryModuleCache,
370 loader: &impl ModuleLoader,
371 check_constraints: bool,
372 ) {
373 if !self.is_library_module() {
374 self.name
375 .validate(self, loader, Some(IdentifierCaseConvention::Module));
376 if let Some(version_info) = self.version_info() {
377 if version_info.as_ref().is_empty() {
378 loader
379 .report(&module_version_info_empty(
380 self.file_id().copied().unwrap_or_default(),
381 version_info.source_span().map(|span| span.byte_range()),
382 ))
383 .unwrap();
384 }
385 }
386 self.body.validate(self, cache, loader, check_constraints);
387 if self.is_incomplete(cache) {
388 loader
389 .report(&module_is_incomplete(
390 self.file_id().copied().unwrap_or_default(),
391 self.source_span().map(|span| span.byte_range()),
392 self.name(),
393 ))
394 .unwrap()
395 }
396 }
397 }
398
399 pub fn is_library_module(&self) -> bool {
404 Identifier::is_library_module_name(self.name().as_ref())
405 }
406
407 pub fn resolve_local(&self, name: &Identifier) -> Option<&Definition> {
408 self.body().definitions().find(|def| def.name() == name)
409 }
410}
411
412impl<T> AsRef<T> for HeaderValue<T> {
417 fn as_ref(&self) -> &T {
418 &self.value
419 }
420}
421
422impl<T> From<T> for HeaderValue<T> {
423 fn from(value: T) -> Self {
424 Self { span: None, value }
425 }
426}
427
428impl<T: Display> Display for HeaderValue<T> {
429 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
430 write!(f, "{}", self.value)
431 }
432}
433
434impl<T: PartialEq> PartialEq for HeaderValue<T> {
435 fn eq(&self, other: &Self) -> bool {
436 self.value == other.value
437 }
438}
439
440impl<T: PartialEq> PartialEq<T> for HeaderValue<T> {
441 fn eq(&self, other: &T) -> bool {
442 self.value == *other
443 }
444}
445
446impl<T: Eq> Eq for HeaderValue<T> {}
447
448impl<T: Hash> Hash for HeaderValue<T> {
449 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
450 self.value.hash(state);
452 }
453}
454
455impl<T> HasSourceSpan for HeaderValue<T> {
456 fn with_source_span(self, span: Span) -> Self {
457 Self {
458 span: Some(span),
459 ..self
460 }
461 }
462
463 fn source_span(&self) -> Option<&Span> {
464 self.span.as_ref()
465 }
466
467 fn set_source_span(&mut self, span: Span) {
468 self.span = Some(span);
469 }
470
471 fn unset_source_span(&mut self) {
472 self.span = None;
473 }
474}
475
476impl<T: PartialEq> HeaderValue<T> {
477 pub fn eq_with_span(&self, other: &Self) -> bool {
478 self.span == other.span && self.value == other.value
479 }
480}
481
482impl<T> HeaderValue<T> {
483 pub const fn value(&self) -> &T {
484 &self.value
485 }
486
487 pub fn set_value(&mut self, value: T) {
488 self.value = value;
489 }
490}
491
492impl HasSourceSpan for ModuleBody {
497 fn with_source_span(self, span: Span) -> Self {
498 let mut self_mut = self;
499 self_mut.span = Some(span);
500 self_mut
501 }
502
503 fn source_span(&self) -> Option<&Span> {
504 self.span.as_ref()
505 }
506
507 fn set_source_span(&mut self, span: Span) {
508 self.span = Some(span);
509 }
510
511 fn unset_source_span(&mut self) {
512 self.span = None;
513 }
514}
515
516impl HasAnnotations for ModuleBody {
517 fn has_annotations(&self) -> bool {
518 !self.annotations.is_empty()
519 }
520
521 fn annotation_count(&self) -> usize {
522 self.annotations.len()
523 }
524
525 fn annotations(&self) -> impl Iterator<Item = &Annotation> {
526 self.annotations.iter()
527 }
528
529 fn annotations_mut(&mut self) -> impl Iterator<Item = &mut Annotation> {
530 self.annotations.iter_mut()
531 }
532
533 fn add_to_annotations<I>(&mut self, value: I)
534 where
535 I: Into<Annotation>,
536 {
537 self.annotations.push(value.into())
538 }
539
540 fn extend_annotations<I>(&mut self, extension: I)
541 where
542 I: IntoIterator<Item = Annotation>,
543 {
544 self.annotations.extend(extension)
545 }
546}
547
548impl References for ModuleBody {
549 fn referenced_types<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
550 self.definitions()
551 .for_each(|def| def.referenced_types(names))
552 }
553
554 fn referenced_annotations<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
555 self.definitions()
556 .for_each(|def| def.referenced_annotations(names));
557 }
558}
559
560impl MaybeIncomplete for ModuleBody {
561 fn is_incomplete(&self, top: &Module, cache: &impl ModuleStore) -> bool {
562 self.definitions()
563 .any(|elem| elem.is_incomplete(top, cache))
564 }
565}
566
567impl Validate for ModuleBody {
568 fn validate(
576 &self,
577 top: &Module,
578 cache: &impl ModuleStore,
579 loader: &impl ModuleLoader,
580 check_constraints: bool,
581 ) {
582 self.imports()
583 .for_each(|imp| imp.validate(top, cache, loader, check_constraints));
584 self.annotations()
585 .for_each(|ann| ann.validate(top, cache, loader, check_constraints));
586 self.definitions()
587 .for_each(|def| def.validate(top, cache, loader, check_constraints));
588 }
589}
590
591impl ModuleBody {
592 pub fn with_imports<I>(self, import_statements: I) -> Self
597 where
598 I: IntoIterator<Item = ImportStatement>,
599 {
600 let mut self_mut = self;
601 self_mut.extend_imports(import_statements);
602 self_mut
603 }
604
605 pub fn with_definitions<I>(self, definitions: I) -> Self
606 where
607 I: IntoIterator<Item = Definition>,
608 {
609 let mut self_mut = self;
610 self_mut.extend_definitions(definitions).unwrap();
611 self_mut
612 }
613
614 pub fn set_library_status(&mut self, module_name: &Identifier) {
619 self.is_library = Identifier::is_library_module_name(module_name);
620 }
621
622 pub fn has_imports(&self) -> bool {
625 !self.imports.is_empty()
626 }
627
628 pub fn imports_len(&self) -> usize {
629 self.imports.len()
630 }
631
632 pub fn imports(&self) -> impl Iterator<Item = &ImportStatement> {
633 self.imports.iter()
634 }
635
636 pub fn imports_mut(&mut self) -> impl Iterator<Item = &mut ImportStatement> {
637 self.imports.iter_mut()
638 }
639
640 pub fn add_to_imports<I>(&mut self, value: I)
641 where
642 I: Into<ImportStatement>,
643 {
644 self.imports.push(value.into())
645 }
646
647 pub fn extend_imports<I>(&mut self, extension: I)
648 where
649 I: IntoIterator<Item = ImportStatement>,
650 {
651 self.imports.extend(extension)
652 }
653
654 pub fn has_definitions(&self) -> bool {
657 !self.definitions.is_empty()
658 }
659
660 pub fn definition_count(&self) -> usize {
661 self.definitions.len()
662 }
663
664 pub fn contains_definition(&self, name: &Identifier) -> bool {
665 self.definitions.contains_key(name)
666 }
667
668 pub fn definition(&self, name: &Identifier) -> Option<&Definition> {
669 self.definitions.get(name)
670 }
671
672 pub fn definition_mut(&mut self, name: &Identifier) -> Option<&mut Definition> {
673 self.definitions.get_mut(name)
674 }
675
676 pub fn definitions(&self) -> impl Iterator<Item = &Definition> {
677 self.definitions.values()
678 }
679
680 pub fn definitions_mut(&mut self) -> impl Iterator<Item = &mut Definition> {
681 self.definitions.values_mut()
682 }
683
684 pub fn definition_names(&self) -> impl Iterator<Item = &Identifier> {
685 self.definitions.keys()
686 }
687
688 pub fn add_to_definitions<I>(&mut self, value: I) -> Result<(), Error>
689 where
690 I: Into<Definition>,
691 {
692 let definition = value.into();
693 if !self.is_library && matches!(definition, Definition::Rdf(_) | Definition::TypeClass(_)) {
694 Err(library_definition_not_allowed(
695 self.file_id.unwrap_or_default(),
696 definition.source_span().map(|s| s.into()),
697 definition.name(),
698 )
699 .into())
700 } else {
701 self.definitions
702 .insert(definition.name().clone(), definition);
703 Ok(())
704 }
705 }
706
707 pub fn extend_definitions<I>(&mut self, extension: I) -> Result<(), Error>
708 where
709 I: IntoIterator<Item = Definition>,
710 {
711 for definition in extension.into_iter() {
713 self.add_to_definitions(definition)?;
714 }
715 Ok(())
716 }
717
718 pub fn imported_modules(&self) -> BTreeSet<&Identifier> {
723 self.imports()
724 .flat_map(|stmt| stmt.imported_modules())
725 .collect()
726 }
727
728 pub fn imported_module_versions(&self) -> BTreeMap<&Identifier, Option<&HeaderValue<Url>>> {
729 self.imports()
730 .flat_map(|stmt| stmt.imported_module_versions())
731 .collect()
732 }
733
734 pub fn imported_types(&self) -> BTreeSet<&QualifiedIdentifier> {
735 self.imports()
736 .flat_map(|stmt| stmt.imported_types())
737 .collect()
738 }
739
740 #[inline]
743 pub fn get_definition(&self, name: &Identifier) -> Option<&Definition> {
744 self.definitions().find(|d| d.name() == name)
745 }
746
747 #[inline]
748 pub fn datatype_definitions(&self) -> impl Iterator<Item = &DatatypeDef> {
749 self.definitions().filter_map(|d| match d {
750 Definition::Datatype(v) => Some(v),
751 _ => None,
752 })
753 }
754
755 #[inline]
756 pub fn entity_definitions(&self) -> impl Iterator<Item = &EntityDef> {
757 self.definitions().filter_map(|d| match d {
758 Definition::Entity(v) => Some(v),
759 _ => None,
760 })
761 }
762
763 #[inline]
764 pub fn enum_definitions(&self) -> impl Iterator<Item = &EnumDef> {
765 self.definitions().filter_map(|d| match d {
766 Definition::Enum(v) => Some(v),
767 _ => None,
768 })
769 }
770
771 #[inline]
772 pub fn event_definitions(&self) -> impl Iterator<Item = &EventDef> {
773 self.definitions().filter_map(|d| match d {
774 Definition::Event(v) => Some(v),
775 _ => None,
776 })
777 }
778
779 #[inline]
780 pub fn property_definitions(&self) -> impl Iterator<Item = &PropertyDef> {
781 self.definitions().filter_map(|d| match d {
782 Definition::Property(v) => Some(v),
783 _ => None,
784 })
785 }
786
787 #[inline]
788 pub fn rdf_definitions(&self) -> impl Iterator<Item = &RdfDef> {
789 self.definitions().filter_map(|d| match d {
790 Definition::Rdf(v) => Some(v),
791 _ => None,
792 })
793 }
794
795 #[inline]
796 pub fn structure_definitions(&self) -> impl Iterator<Item = &StructureDef> {
797 self.definitions().filter_map(|d| match d {
798 Definition::Structure(v) => Some(v),
799 _ => None,
800 })
801 }
802
803 #[inline]
804 pub fn type_class_definitions(&self) -> impl Iterator<Item = &TypeClassDef> {
805 self.definitions().filter_map(|d| match d {
806 Definition::TypeClass(v) => Some(v),
807 _ => None,
808 })
809 }
810
811 #[inline]
812 pub fn union_definitions(&self) -> impl Iterator<Item = &UnionDef> {
813 self.definitions().filter_map(|d| match d {
814 Definition::Union(v) => Some(v),
815 _ => None,
816 })
817 }
818
819 pub fn defined_names(&self) -> BTreeSet<&Identifier> {
820 self.definitions().map(|def| def.name()).collect()
821 }
822}
823
824impl From<Import> for ImportStatement {
829 fn from(value: Import) -> Self {
830 Self::new(vec![value])
831 }
832}
833
834impl From<Vec<Import>> for ImportStatement {
835 fn from(value: Vec<Import>) -> Self {
836 Self::new(value)
837 }
838}
839
840impl FromIterator<Import> for ImportStatement {
841 fn from_iter<T: IntoIterator<Item = Import>>(iter: T) -> Self {
842 Self::new(Vec::from_iter(iter))
843 }
844}
845
846impl From<ImportStatement> for Vec<Import> {
847 fn from(value: ImportStatement) -> Self {
848 value.imports
849 }
850}
851
852impl HasSourceSpan for ImportStatement {
853 fn with_source_span(self, span: Span) -> Self {
854 let mut self_mut = self;
855 self_mut.span = Some(span);
856 self_mut
857 }
858
859 fn source_span(&self) -> Option<&Span> {
860 self.span.as_ref()
861 }
862
863 fn set_source_span(&mut self, span: Span) {
864 self.span = Some(span);
865 }
866
867 fn unset_source_span(&mut self) {
868 self.span = None;
869 }
870}
871
872impl Validate for ImportStatement {
873 fn validate(
887 &self,
888 top: &Module,
889 cache: &impl ModuleStore,
890 loader: &impl ModuleLoader,
891 _: bool,
892 ) {
893 for import in self.imports() {
894 match import {
895 Import::Module(module_ref) => {
896 module_ref.effective_name().validate(
897 top,
898 loader,
899 Some(IdentifierCaseConvention::Module),
900 );
901 if let Some(actual_module) = cache.get(module_ref.name()) {
902 match (module_ref.version_uri(), actual_module.version_uri()) {
903 (None, _) => {}
904 (Some(expected), Some(actual)) => {
905 if actual != expected {
906 loader
907 .report(&module_version_mismatch(
908 top.file_id().copied().unwrap_or_default(),
909 expected.source_span().map(|s| s.byte_range()),
910 expected.as_ref().to_string(),
911 actual_module.file_id().copied().unwrap_or_default(),
912 actual.source_span().map(|s| s.byte_range()),
913 actual.as_ref().to_string(),
914 ))
915 .unwrap();
916 }
917 }
918 (Some(expected), None) => {
919 loader
920 .report(&module_version_not_found(
921 top.file_id().copied().unwrap_or_default(),
922 module_ref.source_span().map(|s| s.byte_range()),
923 expected.as_ref().to_string(),
924 actual_module.file_id().copied().unwrap_or_default(),
925 actual_module.source_span().map(|s| s.byte_range()),
926 actual_module.name(),
927 ))
928 .unwrap();
929 }
930 }
931 } else {
932 loader
933 .report(&imported_module_not_found(
934 top.file_id().copied().unwrap_or_default(),
935 module_ref.source_span().map(|s| s.byte_range()),
936 module_ref.name(),
937 ))
938 .unwrap();
939 }
940 }
941 Import::Member(member_ref) => {
942 let id_ref = member_ref.name();
943 if let Some(actual_module) = cache.get(id_ref.module()) {
946 if actual_module.resolve_local(id_ref.member()).is_none() {
947 loader
948 .report(&definition_not_found(
949 top.file_id().copied().unwrap_or_default(),
950 id_ref.source_span().map(|s| s.byte_range()),
951 id_ref,
952 ))
953 .unwrap();
954 }
955 } else {
956 loader
957 .report(&imported_module_not_found(
958 top.file_id().copied().unwrap_or_default(),
959 id_ref.source_span().map(|s| s.byte_range()),
960 id_ref,
961 ))
962 .unwrap();
963 }
964 }
965 }
966 }
967 }
968}
969
970impl ImportStatement {
971 pub const fn new(imports: Vec<Import>) -> Self {
976 Self {
977 span: None,
978 imports,
979 }
980 }
981
982 pub fn new_module(import: Identifier) -> Self {
983 Self {
984 span: None,
985 imports: vec![Import::from(ModuleImport::from(import))],
986 }
987 }
988
989 pub fn new_module_with_version_uri(import: Identifier, version_uri: Url) -> Self {
990 Self {
991 span: None,
992 imports: vec![Import::from(
993 ModuleImport::from(import).with_version_uri(version_uri.into()),
994 )],
995 }
996 }
997
998 pub fn new_member(import: QualifiedIdentifier) -> Self {
999 Self {
1000 span: None,
1001 imports: vec![Import::from(import)],
1002 }
1003 }
1004
1005 pub fn has_imports(&self) -> bool {
1010 !self.imports.is_empty()
1011 }
1012
1013 pub fn imports_len(&self) -> usize {
1014 self.imports.len()
1015 }
1016
1017 pub fn imports(&self) -> impl Iterator<Item = &Import> {
1018 self.imports.iter()
1019 }
1020
1021 pub fn imports_mut(&mut self) -> impl Iterator<Item = &mut Import> {
1022 self.imports.iter_mut()
1023 }
1024
1025 pub fn add_to_imports<I>(&mut self, value: I)
1026 where
1027 I: Into<Import>,
1028 {
1029 self.imports.push(value.into())
1030 }
1031
1032 pub fn extend_imports<I>(&mut self, extension: I)
1033 where
1034 I: IntoIterator<Item = Import>,
1035 {
1036 self.imports.extend(extension)
1037 }
1038
1039 pub fn as_slice(&self) -> &[Import] {
1042 self.imports.as_slice()
1043 }
1044
1045 pub fn imported_modules(&self) -> BTreeSet<&Identifier> {
1048 self.imports()
1049 .map(|imp| match imp {
1050 Import::Module(v) => v.name(),
1051 Import::Member(v) => v.module(),
1052 })
1053 .collect()
1054 }
1055
1056 pub fn imported_module_versions(&self) -> BTreeMap<&Identifier, Option<&HeaderValue<Url>>> {
1057 BTreeMap::from_iter(self.imports().map(|imp| match imp {
1058 Import::Module(v) => (v.name(), v.version_uri()),
1059 Import::Member(v) => (v.module(), None),
1060 }))
1061 }
1062
1063 pub fn imported_types(&self) -> BTreeSet<&QualifiedIdentifier> {
1064 self.imports()
1065 .filter_map(|imp| {
1066 if let Import::Member(imp) = imp {
1067 Some(imp.name())
1068 } else {
1069 None
1070 }
1071 })
1072 .collect()
1073 }
1074}
1075
1076impl From<&Identifier> for Import {
1079 fn from(v: &Identifier) -> Self {
1080 Self::Module(ModuleImport::from(v.clone()))
1081 }
1082}
1083
1084impl From<Identifier> for Import {
1085 fn from(v: Identifier) -> Self {
1086 Self::Module(ModuleImport::from(v))
1087 }
1088}
1089
1090impl From<&ModuleImport> for Import {
1091 fn from(v: &ModuleImport) -> Self {
1092 Self::Module(v.clone())
1093 }
1094}
1095
1096impl From<ModuleImport> for Import {
1097 fn from(v: ModuleImport) -> Self {
1098 Self::Module(v)
1099 }
1100}
1101
1102impl From<&QualifiedIdentifier> for Import {
1103 fn from(v: &QualifiedIdentifier) -> Self {
1104 Self::Member(MemberImport::from(v.clone()))
1105 }
1106}
1107
1108impl From<QualifiedIdentifier> for Import {
1109 fn from(v: QualifiedIdentifier) -> Self {
1110 Self::Member(MemberImport::from(v))
1111 }
1112}
1113
1114impl From<&MemberImport> for Import {
1115 fn from(v: &MemberImport) -> Self {
1116 Self::Member(v.clone())
1117 }
1118}
1119
1120impl From<MemberImport> for Import {
1121 fn from(v: MemberImport) -> Self {
1122 Self::Member(v)
1123 }
1124}
1125
1126impl std::fmt::Display for Import {
1127 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1128 write!(
1129 f,
1130 "{}",
1131 match self {
1132 Self::Module(v) => v.to_string(),
1133 Self::Member(v) => v.to_string(),
1134 }
1135 )
1136 }
1137}
1138
1139impl HasSourceSpan for Import {
1140 #[inline]
1141 fn with_source_span(self, span: Span) -> Self {
1142 match self {
1143 Self::Module(v) => Self::Module(v.with_source_span(span)),
1144 Self::Member(v) => Self::Member(v.with_source_span(span)),
1145 }
1146 }
1147
1148 #[inline]
1149 fn source_span(&self) -> Option<&Span> {
1150 match self {
1151 Self::Module(v) => v.source_span(),
1152 Self::Member(v) => v.source_span(),
1153 }
1154 }
1155
1156 #[inline]
1157 fn set_source_span(&mut self, span: Span) {
1158 match self {
1159 Self::Module(v) => v.set_source_span(span),
1160 Self::Member(v) => v.set_source_span(span),
1161 }
1162 }
1163
1164 #[inline]
1165 fn unset_source_span(&mut self) {
1166 match self {
1167 Self::Module(v) => v.unset_source_span(),
1168 Self::Member(v) => v.unset_source_span(),
1169 }
1170 }
1171}
1172
1173impl Import {
1174 pub fn module(&self) -> &Identifier {
1175 match self {
1176 Import::Module(v) => v.name(),
1177 Import::Member(v) => v.module(),
1178 }
1179 }
1180 pub fn member(&self) -> Option<&Identifier> {
1181 match self {
1182 Import::Module(_) => None,
1183 Import::Member(v) => Some(v.member()),
1184 }
1185 }
1186}
1187
1188impl From<&Identifier> for ModuleImport {
1193 fn from(value: &Identifier) -> Self {
1194 Self::new(value.clone())
1195 }
1196}
1197
1198impl From<Identifier> for ModuleImport {
1199 fn from(value: Identifier) -> Self {
1200 Self::new(value)
1201 }
1202}
1203
1204impl PartialEq for ModuleImport {
1205 fn eq(&self, other: &Self) -> bool {
1206 self.name == other.name
1207 && self.version_uri == other.version_uri
1208 && self.renamed_as == other.renamed_as
1209 }
1210}
1211
1212impl Eq for ModuleImport {}
1213
1214impl Hash for ModuleImport {
1215 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1216 self.name.hash(state);
1218 self.version_uri.hash(state);
1219 self.renamed_as.hash(state);
1220 }
1221}
1222
1223impl Display for ModuleImport {
1224 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1225 write!(
1226 f,
1227 "{}{}",
1228 if let Some(version_uri) = self.version_uri() {
1229 format!("{} version {}", self.name(), version_uri)
1230 } else {
1231 self.name().to_string()
1232 },
1233 if let Some(renamed_as) = &self.renamed_as {
1234 format!(" as {renamed_as}")
1235 } else {
1236 String::new()
1237 }
1238 )
1239 }
1240}
1241
1242impl HasSourceSpan for ModuleImport {
1243 fn with_source_span(self, span: Span) -> Self {
1244 let mut self_mut = self;
1245 self_mut.span = Some(span);
1246 self_mut
1247 }
1248
1249 fn source_span(&self) -> Option<&Span> {
1250 self.span.as_ref()
1251 }
1252
1253 fn set_source_span(&mut self, span: Span) {
1254 self.span = Some(span);
1255 }
1256
1257 fn unset_source_span(&mut self) {
1258 self.span = None;
1259 }
1260}
1261
1262impl ModuleImport {
1263 pub const fn new(name: Identifier) -> Self {
1267 Self {
1268 span: None,
1269 name,
1270 version_uri: None,
1271 renamed_as: None,
1272 }
1273 }
1274
1275 pub fn with_version_uri(self, version_uri: HeaderValue<Url>) -> Self {
1276 let mut self_mut = self;
1277 self_mut.version_uri = Some(version_uri);
1278 self_mut
1279 }
1280
1281 pub fn with_rename(self, renamed_as: Identifier) -> Self {
1282 let mut self_mut = self;
1283 self_mut.renamed_as = Some(renamed_as);
1284 self_mut
1285 }
1286
1287 pub const fn name(&self) -> &Identifier {
1292 &self.name
1293 }
1294
1295 pub fn set_name(&mut self, name: Identifier) {
1296 self.name = name;
1297 }
1298
1299 pub const fn has_version_uri(&self) -> bool {
1302 self.version_uri.is_some()
1303 }
1304
1305 pub const fn version_uri(&self) -> Option<&HeaderValue<Url>> {
1306 self.version_uri.as_ref()
1307 }
1308
1309 pub fn set_version_uri(&mut self, version_uri: HeaderValue<Url>) {
1310 self.version_uri = Some(version_uri);
1311 }
1312
1313 pub fn unset_version_uri(&mut self) {
1314 self.version_uri = None;
1315 }
1316
1317 pub fn effective_name(&self) -> Identifier {
1320 if let Some(rename) = self.renamed_as() {
1321 rename.clone()
1322 } else {
1323 self.name().clone()
1324 }
1325 }
1326
1327 pub const fn has_been_renamed(&self) -> bool {
1330 self.renamed_as.is_some()
1331 }
1332
1333 pub const fn renamed_as(&self) -> Option<&Identifier> {
1334 self.renamed_as.as_ref()
1335 }
1336
1337 pub fn set_rename_as(&mut self, renamed_as: Identifier) {
1338 self.renamed_as = Some(renamed_as);
1339 }
1340
1341 pub fn unset_rename_as(&mut self) {
1342 self.renamed_as = None;
1343 }
1344
1345 pub fn eq_with_span(&self, other: &Self) -> bool {
1350 self.span == other.span
1351 && self.name == other.name
1352 && self.version_uri == other.version_uri
1353 && self.renamed_as == other.renamed_as
1354 }
1355}
1356
1357impl From<&QualifiedIdentifier> for MemberImport {
1362 fn from(value: &QualifiedIdentifier) -> Self {
1363 Self::new(value.clone())
1364 }
1365}
1366
1367impl From<QualifiedIdentifier> for MemberImport {
1368 fn from(value: QualifiedIdentifier) -> Self {
1369 Self::new(value)
1370 }
1371}
1372
1373impl PartialEq for MemberImport {
1374 fn eq(&self, other: &Self) -> bool {
1375 self.name == other.name && self.renamed_as == other.renamed_as
1376 }
1377}
1378
1379impl Eq for MemberImport {}
1380
1381impl Hash for MemberImport {
1382 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1383 self.name.hash(state);
1385 self.renamed_as.hash(state);
1386 }
1387}
1388
1389impl Display for MemberImport {
1390 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1391 write!(
1392 f,
1393 "{}{}",
1394 self.name().to_string(),
1395 if let Some(renamed_as) = &self.renamed_as {
1396 format!(" as {renamed_as}")
1397 } else {
1398 String::new()
1399 }
1400 )
1401 }
1402}
1403
1404impl HasSourceSpan for MemberImport {
1405 fn with_source_span(self, span: Span) -> Self {
1406 let mut self_mut = self;
1407 self_mut.span = Some(span);
1408 self_mut
1409 }
1410
1411 fn source_span(&self) -> Option<&Span> {
1412 self.span.as_ref()
1413 }
1414
1415 fn set_source_span(&mut self, span: Span) {
1416 self.span = Some(span);
1417 }
1418
1419 fn unset_source_span(&mut self) {
1420 self.span = None;
1421 }
1422}
1423
1424impl MemberImport {
1425 pub const fn new(name: QualifiedIdentifier) -> Self {
1429 Self {
1430 span: None,
1431 name,
1432 renamed_as: None,
1433 }
1434 }
1435
1436 pub fn with_rename(self, renamed_as: Identifier) -> Self {
1437 let mut self_mut = self;
1438 self_mut.renamed_as = Some(renamed_as);
1439 self_mut
1440 }
1441
1442 pub const fn name(&self) -> &QualifiedIdentifier {
1447 &self.name
1448 }
1449
1450 pub fn set_name(&mut self, name: QualifiedIdentifier) {
1451 self.name = name;
1452 }
1453
1454 pub const fn module(&self) -> &Identifier {
1457 self.name().module()
1458 }
1459
1460 pub const fn member(&self) -> &Identifier {
1461 &self.name().member()
1462 }
1463
1464 pub fn effective_name(&self) -> IdentifierReference {
1467 if let Some(rename) = self.renamed_as() {
1468 rename.clone().into()
1469 } else {
1470 self.name().clone().into()
1471 }
1472 }
1473
1474 pub const fn has_been_renamed(&self) -> bool {
1477 self.renamed_as.is_some()
1478 }
1479
1480 pub const fn renamed_as(&self) -> Option<&Identifier> {
1481 self.renamed_as.as_ref()
1482 }
1483
1484 pub fn set_rename_as(&mut self, renamed_as: Identifier) {
1485 self.renamed_as = Some(renamed_as);
1486 }
1487
1488 pub fn unset_rename_as(&mut self) {
1489 self.renamed_as = None;
1490 }
1491
1492 pub fn eq_with_span(&self, other: &Self) -> bool {
1497 self.span == other.span && self.name == other.name && self.renamed_as == other.renamed_as
1498 }
1499}