1use crate::{
5 config::{is_rdf_definition_allowed_in_module, is_typeclass_definition_allowed_in_module},
6 load::ModuleLoader,
7 model::{
8 annotations::{Annotation, HasAnnotations},
9 check::{MaybeIncomplete, Validate},
10 definitions::{
11 DatatypeDef, EntityDef, EnumDef, EventDef, PropertyDef, StructureDef, UnionDef,
12 },
13 definitions::{Definition, RdfDef, TypeClassDef},
14 identifiers::{Identifier, IdentifierReference, QualifiedIdentifier},
15 HasName, HasSourceSpan, References, Span,
16 },
17 store::{InMemoryModuleCache, ModuleStore},
18 syntax::PC_MODULE_PATH_SEPARATOR,
19};
20use sdml_errors::{
21 diagnostics::functions::{
22 definition_not_found, imported_module_not_found, invalid_module_base_uri,
23 invalid_module_version_uri, library_definition_not_allowed_in, module_is_incomplete,
24 module_version_info_empty, module_version_mismatch, module_version_not_found,
25 IdentifierCaseConvention,
26 },
27 Error, FileId,
28};
29use std::{
30 collections::BTreeMap,
31 collections::BTreeSet,
32 fmt::{Debug, Display},
33 hash::Hash,
34 path::PathBuf,
35 str::FromStr,
36};
37use url::Url;
38
39#[cfg(feature = "serde")]
40use serde::{Deserialize, Serialize};
41
42#[derive(Clone, Debug)]
50#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
51pub struct Module {
52 #[cfg_attr(feature = "serde", serde(skip))]
53 source_file: Option<PathBuf>,
54 #[cfg_attr(feature = "serde", serde(skip))]
55 file_id: Option<FileId>,
56 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
57 span: Option<Span>,
58 name: Identifier,
59 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
60 base_uri: Option<HeaderValue<Url>>,
61 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
62 version_info: Option<HeaderValue<String>>,
63 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
64 version_uri: Option<HeaderValue<Url>>,
65 imports: Vec<ImportStatement>,
66 annotations: Vec<Annotation>,
67 definitions: BTreeMap<Identifier, Definition>,
68}
69
70#[derive(Clone, Debug)]
71#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
72pub struct HeaderValue<T> {
73 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
74 span: Option<Span>,
75 value: T,
76}
77
78#[derive(Clone, Debug, Default)]
86#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
87pub struct ImportStatement {
88 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
89 span: Option<Span>,
90 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
91 from_clause: Option<ModulePath>,
92 imports: Vec<Import>,
93}
94
95#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
107#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
108pub struct ModulePath {
109 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
110 span: Option<Span>,
111 is_absolute: bool,
112 segments: Vec<Identifier>,
113}
114
115#[derive(Clone, Debug, PartialEq, Eq, Hash)]
119#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
120pub enum Import {
121 Module(ModuleImport),
123 Member(MemberImport),
125}
126
127#[derive(Clone, Debug)]
131#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
132pub struct ModuleImport {
133 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
134 span: Option<Span>,
135 name: Identifier,
136 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
137 version_uri: Option<HeaderValue<Url>>,
138 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
139 renamed_as: Option<Identifier>,
140}
141
142#[derive(Clone, Debug)]
146#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
147pub struct MemberImport {
148 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
149 span: Option<Span>,
150 name: QualifiedIdentifier,
151 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
152 renamed_as: Option<Identifier>,
153}
154
155impl HasSourceSpan for Module {
160 fn with_source_span(self, span: Span) -> Self {
161 let mut self_mut = self;
162 self_mut.span = Some(span);
163 self_mut
164 }
165
166 fn source_span(&self) -> Option<&Span> {
167 self.span.as_ref()
168 }
169
170 fn set_source_span(&mut self, span: Span) {
171 self.span = Some(span);
172 }
173
174 fn unset_source_span(&mut self) {
175 self.span = None;
176 }
177}
178
179impl HasName for Module {
180 fn name(&self) -> &Identifier {
181 &self.name
182 }
183
184 fn set_name(&mut self, name: Identifier) {
185 self.name = name;
186 }
187}
188
189impl HasAnnotations for Module {
190 fn has_annotations(&self) -> bool {
191 !self.annotations.is_empty()
192 }
193
194 fn annotation_count(&self) -> usize {
195 self.annotations.len()
196 }
197
198 fn annotations(&self) -> impl Iterator<Item = &Annotation> {
199 self.annotations.iter()
200 }
201
202 fn annotations_mut(&mut self) -> impl Iterator<Item = &mut Annotation> {
203 self.annotations.iter_mut()
204 }
205
206 fn add_to_annotations<I>(&mut self, value: I)
207 where
208 I: Into<Annotation>,
209 {
210 self.annotations.push(value.into())
211 }
212
213 fn extend_annotations<I>(&mut self, extension: I)
214 where
215 I: IntoIterator<Item = Annotation>,
216 {
217 self.annotations.extend(extension)
218 }
219}
220
221impl References for Module {
222 fn referenced_types<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
223 self.definitions()
224 .for_each(|def| def.referenced_types(names))
225 }
226
227 fn referenced_annotations<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
228 self.definitions()
229 .for_each(|def| def.referenced_annotations(names));
230 }
231}
232
233impl Module {
234 pub fn new(name: Identifier) -> Self {
239 Self {
240 source_file: Default::default(),
241 file_id: Default::default(),
242 span: Default::default(),
243 name,
244 base_uri: Default::default(),
245 version_info: Default::default(),
246 version_uri: Default::default(),
247 imports: Default::default(),
248 annotations: Default::default(),
249 definitions: Default::default(),
250 }
251 }
252
253 pub fn with_source_file(self, source_file: PathBuf) -> Self {
258 let mut self_mut = self;
259 self_mut.source_file = Some(source_file);
260 self_mut
261 }
262
263 pub const fn has_source_file(&self) -> bool {
264 self.source_file.is_some()
265 }
266
267 pub const fn source_file(&self) -> Option<&PathBuf> {
268 self.source_file.as_ref()
269 }
270
271 pub fn set_source_file(&mut self, source_file: PathBuf) {
272 self.source_file = Some(source_file);
273 }
274
275 pub fn unset_source_file(&mut self) {
276 self.source_file = None;
277 }
278
279 pub const fn has_file_id(&self) -> bool {
284 self.file_id.is_some()
285 }
286
287 pub const fn file_id(&self) -> Option<&FileId> {
288 self.file_id.as_ref()
289 }
290
291 pub fn set_file_id(&mut self, file_id: FileId) {
292 self.file_id = Some(file_id);
293 }
294
295 pub fn unset_file_id(&mut self) {
296 self.file_id = None;
297 }
298
299 pub fn with_base_uri(self, base_uri: Url) -> Self {
304 let mut self_mut = self;
305 self_mut.base_uri = Some(base_uri.into());
306 self_mut
307 }
308
309 pub const fn has_base_uri(&self) -> bool {
310 self.base_uri.is_some()
311 }
312
313 pub const fn base_uri(&self) -> Option<&HeaderValue<Url>> {
314 self.base_uri.as_ref()
315 }
316
317 pub fn set_base_uri(&mut self, base_uri: HeaderValue<Url>) {
318 self.base_uri = Some(base_uri);
320 }
321
322 pub fn unset_base_uri(&mut self) {
323 self.base_uri = None;
324 }
325
326 pub fn with_version_info<S>(self, version_info: S) -> Self
331 where
332 S: Into<String>,
333 {
334 let mut self_mut = self;
335 self_mut.version_info = Some(HeaderValue::from(version_info.into()));
336 self_mut
337 }
338
339 pub const fn has_version_info(&self) -> bool {
340 self.version_info.is_some()
341 }
342
343 pub const fn version_info(&self) -> Option<&HeaderValue<String>> {
344 self.version_info.as_ref()
345 }
346
347 pub fn set_version_info(&mut self, version_info: HeaderValue<String>) {
348 self.version_info = Some(version_info);
349 }
350
351 pub fn unset_version_info(&mut self) {
352 self.version_info = None;
353 }
354
355 pub fn with_version_uri(self, version_uri: Url) -> Self {
360 let mut self_mut = self;
361 self_mut.version_uri = Some(version_uri.into());
362 self_mut
363 }
364
365 pub const fn has_version_uri(&self) -> bool {
366 self.version_uri.is_some()
367 }
368
369 pub const fn version_uri(&self) -> Option<&HeaderValue<Url>> {
370 self.version_uri.as_ref()
371 }
372
373 pub fn set_version_uri(&mut self, version_uri: HeaderValue<Url>) {
374 self.version_uri = Some(version_uri);
376 }
377
378 pub fn unset_version_uri(&mut self) {
379 self.version_uri = None;
380 }
381
382 pub fn with_imports<I>(self, import_statements: I) -> Self
387 where
388 I: IntoIterator<Item = ImportStatement>,
389 {
390 let mut self_mut = self;
391 self_mut.extend_imports(import_statements);
392 self_mut
393 }
394
395 pub fn has_imports(&self) -> bool {
396 !self.imports.is_empty()
397 }
398
399 pub fn imports_len(&self) -> usize {
400 self.imports.len()
401 }
402
403 pub fn imports(&self) -> impl Iterator<Item = &ImportStatement> {
404 self.imports.iter()
405 }
406
407 pub fn imports_mut(&mut self) -> impl Iterator<Item = &mut ImportStatement> {
408 self.imports.iter_mut()
409 }
410
411 pub fn add_to_imports<I>(&mut self, value: I)
412 where
413 I: Into<ImportStatement>,
414 {
415 self.imports.push(value.into())
416 }
417
418 pub fn extend_imports<I>(&mut self, extension: I)
419 where
420 I: IntoIterator<Item = ImportStatement>,
421 {
422 self.imports.extend(extension)
423 }
424
425 pub fn with_definitions<I>(self, definitions: I) -> Self
430 where
431 I: IntoIterator<Item = Definition>,
432 {
433 let mut self_mut = self;
434 self_mut.extend_definitions(definitions).unwrap();
435 self_mut
436 }
437
438 pub fn has_definitions(&self) -> bool {
439 !self.definitions.is_empty()
440 }
441
442 pub fn definition_count(&self) -> usize {
443 self.definitions.len()
444 }
445
446 pub fn contains_definition(&self, name: &Identifier) -> bool {
447 self.definitions.contains_key(name)
448 }
449
450 pub fn definition(&self, name: &Identifier) -> Option<&Definition> {
451 self.definitions.get(name)
452 }
453
454 pub fn definition_mut(&mut self, name: &Identifier) -> Option<&mut Definition> {
455 self.definitions.get_mut(name)
456 }
457
458 pub fn definitions(&self) -> impl Iterator<Item = &Definition> {
459 self.definitions.values()
460 }
461
462 pub fn definitions_mut(&mut self) -> impl Iterator<Item = &mut Definition> {
463 self.definitions.values_mut()
464 }
465
466 pub fn definition_names(&self) -> impl Iterator<Item = &Identifier> {
467 self.definitions.keys()
468 }
469
470 pub fn add_to_definitions<I>(&mut self, value: I) -> Result<(), Error>
471 where
472 I: Into<Definition>,
473 {
474 let definition = value.into();
475
476 if (matches!(definition, Definition::Rdf(_))
477 && !is_rdf_definition_allowed_in_module(&self.name))
478 || (matches!(definition, Definition::TypeClass(_))
479 && !is_typeclass_definition_allowed_in_module(&self.name))
480 {
481 Err(library_definition_not_allowed_in(
482 self.file_id.unwrap_or_default(),
483 definition.source_span().map(|s| s.into()),
484 definition.name(),
485 self.name(),
486 )
487 .into())
488 } else {
489 self.definitions
490 .insert(definition.name().clone(), definition);
491 Ok(())
492 }
493 }
494
495 pub fn extend_definitions<I>(&mut self, extension: I) -> Result<(), Error>
496 where
497 I: IntoIterator<Item = Definition>,
498 {
499 for definition in extension.into_iter() {
501 self.add_to_definitions(definition)?;
502 }
503 Ok(())
504 }
505
506 fn is_incomplete(&self, cache: &impl ModuleStore) -> bool {
511 if !self.is_library_module() {
512 self.definitions()
513 .any(|elem| elem.is_incomplete(self, cache))
514 } else {
515 false }
517 }
518
519 pub fn validate(
529 &self,
530 cache: &InMemoryModuleCache,
531 loader: &impl ModuleLoader,
532 check_constraints: bool,
533 ) {
534 fn is_namespace_safe(uri: &Url) -> bool {
535 uri.fragment() == Some("") || (uri.path().ends_with("/") && uri.query().is_none())
536 }
537 if !self.is_library_module() {
538 self.name
539 .validate(self, loader, Some(IdentifierCaseConvention::Module));
540 if let Some(base_uri) = self.base_uri() {
541 let uri = base_uri.value();
542 if !is_namespace_safe(uri) {
543 loader
544 .report(&invalid_module_base_uri(
545 self.file_id().copied().unwrap_or_default(),
546 base_uri.source_span().map(|span| span.byte_range()),
547 uri.to_string(),
548 ))
549 .unwrap();
550 }
551 }
552 if let Some(version_uri) = self.version_uri() {
553 let uri = version_uri.value();
554 if !is_namespace_safe(uri) {
555 loader
556 .report(&invalid_module_version_uri(
557 self.file_id().copied().unwrap_or_default(),
558 version_uri.source_span().map(|span| span.byte_range()),
559 uri.to_string(),
560 ))
561 .unwrap();
562 }
563 }
564 if let Some(version_info) = self.version_info() {
565 if version_info.as_ref().is_empty() {
566 loader
567 .report(&module_version_info_empty(
568 self.file_id().copied().unwrap_or_default(),
569 version_info.source_span().map(|span| span.byte_range()),
570 ))
571 .unwrap();
572 }
573 }
574 self.validate(cache, loader, check_constraints);
575 if self.is_incomplete(cache) {
576 loader
577 .report(&module_is_incomplete(
578 self.file_id().copied().unwrap_or_default(),
579 self.source_span().map(|span| span.byte_range()),
580 self.name(),
581 ))
582 .unwrap()
583 }
584 self.imports()
585 .for_each(|imp| imp.validate(self, cache, loader, check_constraints));
586 self.annotations()
588 .for_each(|ann| ann.validate(self, cache, loader, check_constraints));
589 self.definitions()
590 .for_each(|def| def.validate(self, cache, loader, check_constraints));
591 }
592 }
593
594 pub const fn is_versioned(&self) -> bool {
599 self.has_version_info() || self.has_version_uri()
600 }
601
602 pub fn is_library_module(&self) -> bool {
605 Identifier::is_library_module_name(self.name().as_ref())
606 }
607
608 pub fn resolve_local(&self, name: &Identifier) -> Option<&Definition> {
609 self.definitions().find(|def| def.name() == name)
610 }
611
612 pub fn imported_modules(&self) -> BTreeSet<&Identifier> {
615 self.imports()
616 .flat_map(|stmt| stmt.imported_modules())
617 .collect()
618 }
619
620 pub fn imported_module_versions(&self) -> BTreeMap<&Identifier, Option<&HeaderValue<Url>>> {
621 self.imports()
622 .flat_map(|stmt| stmt.imported_module_versions())
623 .collect()
624 }
625
626 pub fn imported_types(&self) -> BTreeSet<&QualifiedIdentifier> {
627 self.imports()
628 .flat_map(|stmt| stmt.imported_types())
629 .collect()
630 }
631
632 #[inline]
635 pub fn get_definition(&self, name: &Identifier) -> Option<&Definition> {
636 self.definitions().find(|d| d.name() == name)
637 }
638
639 #[inline]
640 pub fn datatype_definitions(&self) -> impl Iterator<Item = &DatatypeDef> {
641 self.definitions().filter_map(|d| match d {
642 Definition::Datatype(v) => Some(v),
643 _ => None,
644 })
645 }
646
647 #[inline]
648 pub fn entity_definitions(&self) -> impl Iterator<Item = &EntityDef> {
649 self.definitions().filter_map(|d| match d {
650 Definition::Entity(v) => Some(v),
651 _ => None,
652 })
653 }
654
655 #[inline]
656 pub fn enum_definitions(&self) -> impl Iterator<Item = &EnumDef> {
657 self.definitions().filter_map(|d| match d {
658 Definition::Enum(v) => Some(v),
659 _ => None,
660 })
661 }
662
663 #[inline]
664 pub fn event_definitions(&self) -> impl Iterator<Item = &EventDef> {
665 self.definitions().filter_map(|d| match d {
666 Definition::Event(v) => Some(v),
667 _ => None,
668 })
669 }
670
671 #[inline]
672 pub fn property_definitions(&self) -> impl Iterator<Item = &PropertyDef> {
673 self.definitions().filter_map(|d| match d {
674 Definition::Property(v) => Some(v),
675 _ => None,
676 })
677 }
678
679 #[inline]
680 pub fn rdf_definitions(&self) -> impl Iterator<Item = &RdfDef> {
681 self.definitions().filter_map(|d| match d {
682 Definition::Rdf(v) => Some(v),
683 _ => None,
684 })
685 }
686
687 #[inline]
688 pub fn structure_definitions(&self) -> impl Iterator<Item = &StructureDef> {
689 self.definitions().filter_map(|d| match d {
690 Definition::Structure(v) => Some(v),
691 _ => None,
692 })
693 }
694
695 #[inline]
696 pub fn type_class_definitions(&self) -> impl Iterator<Item = &TypeClassDef> {
697 self.definitions().filter_map(|d| match d {
698 Definition::TypeClass(v) => Some(v),
699 _ => None,
700 })
701 }
702
703 #[inline]
704 pub fn union_definitions(&self) -> impl Iterator<Item = &UnionDef> {
705 self.definitions().filter_map(|d| match d {
706 Definition::Union(v) => Some(v),
707 _ => None,
708 })
709 }
710
711 pub fn defined_names(&self) -> BTreeSet<&Identifier> {
712 self.definitions().map(|def| def.name()).collect()
713 }
714}
715
716impl<T> AsRef<T> for HeaderValue<T> {
721 fn as_ref(&self) -> &T {
722 &self.value
723 }
724}
725
726impl<T> From<T> for HeaderValue<T> {
727 fn from(value: T) -> Self {
728 Self { span: None, value }
729 }
730}
731
732impl<T: Display> Display for HeaderValue<T> {
733 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
734 write!(f, "{}", self.value)
735 }
736}
737
738impl<T: PartialEq> PartialEq for HeaderValue<T> {
739 fn eq(&self, other: &Self) -> bool {
740 self.value == other.value
741 }
742}
743
744impl<T: PartialEq> PartialEq<T> for HeaderValue<T> {
745 fn eq(&self, other: &T) -> bool {
746 self.value == *other
747 }
748}
749
750impl<T: Eq> Eq for HeaderValue<T> {}
751
752impl<T: Hash> Hash for HeaderValue<T> {
753 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
754 self.value.hash(state);
756 }
757}
758
759impl<T> HasSourceSpan for HeaderValue<T> {
760 fn with_source_span(self, span: Span) -> Self {
761 Self {
762 span: Some(span),
763 ..self
764 }
765 }
766
767 fn source_span(&self) -> Option<&Span> {
768 self.span.as_ref()
769 }
770
771 fn set_source_span(&mut self, span: Span) {
772 self.span = Some(span);
773 }
774
775 fn unset_source_span(&mut self) {
776 self.span = None;
777 }
778}
779
780impl<T: PartialEq> HeaderValue<T> {
781 pub fn eq_with_span(&self, other: &Self) -> bool {
782 self.span == other.span && self.value == other.value
783 }
784}
785
786impl<T> HeaderValue<T> {
787 pub const fn value(&self) -> &T {
788 &self.value
789 }
790
791 pub fn set_value(&mut self, value: T) {
792 self.value = value;
793 }
794}
795
796impl From<Import> for ImportStatement {
801 fn from(value: Import) -> Self {
802 Self::new(vec![value])
803 }
804}
805
806impl From<Vec<Import>> for ImportStatement {
807 fn from(value: Vec<Import>) -> Self {
808 Self::new(value)
809 }
810}
811
812impl FromIterator<Import> for ImportStatement {
813 fn from_iter<T: IntoIterator<Item = Import>>(iter: T) -> Self {
814 Self::new(Vec::from_iter(iter))
815 }
816}
817
818impl From<ImportStatement> for Vec<Import> {
819 fn from(value: ImportStatement) -> Self {
820 value.imports
821 }
822}
823
824impl HasSourceSpan for ImportStatement {
825 fn with_source_span(self, span: Span) -> Self {
826 let mut self_mut = self;
827 self_mut.span = Some(span);
828 self_mut
829 }
830
831 fn source_span(&self) -> Option<&Span> {
832 self.span.as_ref()
833 }
834
835 fn set_source_span(&mut self, span: Span) {
836 self.span = Some(span);
837 }
838
839 fn unset_source_span(&mut self) {
840 self.span = None;
841 }
842}
843
844impl Validate for ImportStatement {
845 fn validate(
859 &self,
860 top: &Module,
861 cache: &impl ModuleStore,
862 loader: &impl ModuleLoader,
863 _: bool,
864 ) {
865 for import in self.imports() {
866 match import {
867 Import::Module(module_ref) => {
868 module_ref.effective_name().validate(
869 top,
870 loader,
871 Some(IdentifierCaseConvention::Module),
872 );
873 if let Some(actual_module) = cache.get(module_ref.name()) {
874 match (module_ref.version_uri(), actual_module.version_uri()) {
875 (None, _) => {}
876 (Some(expected), Some(actual)) => {
877 if actual != expected {
878 loader
879 .report(&module_version_mismatch(
880 top.file_id().copied().unwrap_or_default(),
881 expected.source_span().map(|s| s.byte_range()),
882 expected.as_ref().to_string(),
883 actual_module.file_id().copied().unwrap_or_default(),
884 actual.source_span().map(|s| s.byte_range()),
885 actual.as_ref().to_string(),
886 ))
887 .unwrap();
888 }
889 }
890 (Some(expected), None) => {
891 loader
892 .report(&module_version_not_found(
893 top.file_id().copied().unwrap_or_default(),
894 module_ref.source_span().map(|s| s.byte_range()),
895 expected.as_ref().to_string(),
896 actual_module.file_id().copied().unwrap_or_default(),
897 actual_module.source_span().map(|s| s.byte_range()),
898 actual_module.name(),
899 ))
900 .unwrap();
901 }
902 }
903 } else {
904 loader
905 .report(&imported_module_not_found(
906 top.file_id().copied().unwrap_or_default(),
907 module_ref.source_span().map(|s| s.byte_range()),
908 module_ref.name(),
909 ))
910 .unwrap();
911 }
912 }
913 Import::Member(member_ref) => {
914 let id_ref = member_ref.name();
915 if let Some(actual_module) = cache.get(id_ref.module()) {
918 if actual_module.resolve_local(id_ref.member()).is_none() {
919 loader
920 .report(&definition_not_found(
921 top.file_id().copied().unwrap_or_default(),
922 id_ref.source_span().map(|s| s.byte_range()),
923 id_ref,
924 ))
925 .unwrap();
926 }
927 } else {
928 loader
929 .report(&imported_module_not_found(
930 top.file_id().copied().unwrap_or_default(),
931 id_ref.source_span().map(|s| s.byte_range()),
932 id_ref,
933 ))
934 .unwrap();
935 }
936 }
937 }
938 }
939 }
940}
941
942impl ImportStatement {
943 pub const fn new(imports: Vec<Import>) -> Self {
948 Self {
949 span: None,
950 from_clause: None,
951 imports,
952 }
953 }
954
955 pub fn new_module(import: Identifier) -> Self {
956 Self {
957 span: None,
958 from_clause: None,
959 imports: vec![Import::from(ModuleImport::from(import))],
960 }
961 }
962
963 pub fn new_module_with_version_uri(import: Identifier, version_uri: Url) -> Self {
964 Self {
965 span: None,
966 from_clause: None,
967 imports: vec![Import::from(
968 ModuleImport::from(import).with_version_uri(version_uri.into()),
969 )],
970 }
971 }
972
973 pub fn new_member(import: QualifiedIdentifier) -> Self {
974 Self {
975 span: None,
976 from_clause: None,
977 imports: vec![Import::from(import)],
978 }
979 }
980
981 pub fn has_from_module_path(&self) -> bool {
989 self.from_clause.is_some()
990 }
991
992 pub fn from_module_path(&self) -> Option<&ModulePath> {
993 self.from_clause.as_ref()
994 }
995
996 pub fn set_from_module_path(&mut self, path: ModulePath) {
997 self.from_clause = Some(path);
998 }
999
1000 pub fn unset_from_module_path(&mut self) {
1001 self.from_clause = None;
1002 }
1003
1004 pub fn has_imports(&self) -> bool {
1007 !self.imports.is_empty()
1008 }
1009
1010 pub fn imports_len(&self) -> usize {
1011 self.imports.len()
1012 }
1013
1014 pub fn imports(&self) -> impl Iterator<Item = &Import> {
1015 self.imports.iter()
1016 }
1017
1018 pub fn imports_mut(&mut self) -> impl Iterator<Item = &mut Import> {
1019 self.imports.iter_mut()
1020 }
1021
1022 pub fn add_to_imports<I>(&mut self, value: I)
1023 where
1024 I: Into<Import>,
1025 {
1026 self.imports.push(value.into())
1027 }
1028
1029 pub fn extend_imports<I>(&mut self, extension: I)
1030 where
1031 I: IntoIterator<Item = Import>,
1032 {
1033 self.imports.extend(extension)
1034 }
1035
1036 pub fn as_slice(&self) -> &[Import] {
1039 self.imports.as_slice()
1040 }
1041
1042 pub fn imported_modules(&self) -> BTreeSet<&Identifier> {
1045 self.imports()
1046 .map(|imp| match imp {
1047 Import::Module(v) => v.name(),
1048 Import::Member(v) => v.module(),
1049 })
1050 .collect()
1051 }
1052
1053 pub fn imported_module_versions(&self) -> BTreeMap<&Identifier, Option<&HeaderValue<Url>>> {
1054 BTreeMap::from_iter(self.imports().map(|imp| match imp {
1055 Import::Module(v) => (v.name(), v.version_uri()),
1056 Import::Member(v) => (v.module(), None),
1057 }))
1058 }
1059
1060 pub fn imported_types(&self) -> BTreeSet<&QualifiedIdentifier> {
1061 self.imports()
1062 .filter_map(|imp| {
1063 if let Import::Member(imp) = imp {
1064 Some(imp.name())
1065 } else {
1066 None
1067 }
1068 })
1069 .collect()
1070 }
1071}
1072
1073impl Display for ModulePath {
1076 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1077 write!(
1078 f,
1079 "{}{}",
1080 if self.is_absolute() {
1081 PC_MODULE_PATH_SEPARATOR
1082 } else {
1083 ""
1084 },
1085 self.segments()
1086 .map(|i| i.to_string())
1087 .collect::<Vec<String>>()
1088 .join(PC_MODULE_PATH_SEPARATOR),
1089 )
1090 }
1091}
1092
1093impl FromStr for ModulePath {
1094 type Err = Error;
1095
1096 fn from_str(s: &str) -> Result<Self, Self::Err> {
1097 const PREFIX_OFFSET: usize = PC_MODULE_PATH_SEPARATOR.len();
1098 if s.is_empty() {
1099 Ok(ModulePath::default())
1100 } else if s == PC_MODULE_PATH_SEPARATOR {
1101 Ok(ModulePath::root())
1102 } else {
1103 let (absolute, modules) = if s.starts_with(PC_MODULE_PATH_SEPARATOR) {
1104 (true, s[PREFIX_OFFSET..].split(PC_MODULE_PATH_SEPARATOR))
1105 } else {
1106 (false, s.split(PC_MODULE_PATH_SEPARATOR))
1107 };
1108 Ok(ModulePath::new(
1109 absolute,
1110 modules
1111 .map(Identifier::from_str)
1112 .collect::<Result<Vec<Identifier>, Self::Err>>()?,
1113 ))
1114 }
1115 }
1116}
1117
1118impl HasSourceSpan for ModulePath {
1119 fn with_source_span(self, span: Span) -> Self {
1120 let mut self_mut = self;
1121 self_mut.span = Some(span);
1122 self_mut
1123 }
1124
1125 fn source_span(&self) -> Option<&Span> {
1126 self.span.as_ref()
1127 }
1128
1129 fn set_source_span(&mut self, span: Span) {
1130 self.span = Some(span);
1131 }
1132
1133 fn unset_source_span(&mut self) {
1134 self.span = None;
1135 }
1136}
1137
1138impl Validate for ModulePath {
1139 fn validate(
1140 &self,
1141 _top: &Module,
1142 _cache: &impl ModuleStore,
1143 _loader: &impl ModuleLoader,
1144 _check_constraints: bool,
1145 ) {
1146 todo!()
1148 }
1149}
1150
1151impl ModulePath {
1152 pub fn new<T>(is_absolute: bool, segments: T) -> Self
1153 where
1154 T: Into<Vec<Identifier>>,
1155 {
1156 Self {
1157 span: None,
1158 is_absolute,
1159 segments: segments.into(),
1160 }
1161 }
1162
1163 pub fn new_unchecked(is_absolute: bool, segments: &[&str]) -> Self {
1164 Self {
1165 span: None,
1166 is_absolute,
1167 segments: segments
1168 .iter()
1169 .map(|id| Identifier::new_unchecked(id))
1170 .collect(),
1171 }
1172 }
1173
1174 pub fn root() -> Self {
1175 Self {
1176 span: None,
1177 is_absolute: true,
1178 segments: Vec::default(),
1179 }
1180 }
1181
1182 pub fn absolute<T>(modules: T) -> Self
1183 where
1184 T: Into<Vec<Identifier>>,
1185 {
1186 Self {
1187 span: None,
1188 is_absolute: true,
1189 segments: modules.into(),
1190 }
1191 }
1192
1193 pub fn absolute_one(module: Identifier) -> Self {
1194 Self::absolute(vec![module])
1195 }
1196
1197 pub fn relative<T>(modules: T) -> Self
1198 where
1199 T: Into<Vec<Identifier>>,
1200 {
1201 Self {
1202 span: None,
1203 is_absolute: false,
1204 segments: modules.into(),
1205 }
1206 }
1207
1208 pub fn relative_one(module: Identifier) -> Self {
1209 Self::relative(vec![module])
1210 }
1211
1212 pub fn is_absolute(&self) -> bool {
1213 self.is_absolute
1214 }
1215
1216 pub fn set_absolute(&mut self, is_absolute: bool) {
1217 self.is_absolute = is_absolute;
1218 }
1219
1220 pub fn is_root(&self) -> bool {
1221 self.is_absolute() && !self.has_segments()
1222 }
1223
1224 pub fn has_segments(&self) -> bool {
1225 !self.segments.is_empty()
1226 }
1227
1228 pub fn segment_count(&self) -> usize {
1229 self.segments.len()
1230 }
1231
1232 pub fn segments(&self) -> impl Iterator<Item = &Identifier> {
1233 self.segments.iter()
1234 }
1235
1236 pub fn segments_mut(&mut self) -> impl Iterator<Item = &mut Identifier> {
1237 self.segments.iter_mut()
1238 }
1239
1240 pub fn add_to_segments<I>(&mut self, value: I)
1241 where
1242 I: Into<Identifier>,
1243 {
1244 self.segments.push(value.into())
1245 }
1246
1247 pub fn extend_segments<I>(&mut self, extension: I)
1248 where
1249 I: IntoIterator<Item = Identifier>,
1250 {
1251 self.segments.extend(extension)
1252 }
1253}
1254
1255impl From<&Identifier> for Import {
1258 fn from(v: &Identifier) -> Self {
1259 Self::Module(ModuleImport::from(v.clone()))
1260 }
1261}
1262
1263impl From<Identifier> for Import {
1264 fn from(v: Identifier) -> Self {
1265 Self::Module(ModuleImport::from(v))
1266 }
1267}
1268
1269impl From<&ModuleImport> for Import {
1270 fn from(v: &ModuleImport) -> Self {
1271 Self::Module(v.clone())
1272 }
1273}
1274
1275impl From<ModuleImport> for Import {
1276 fn from(v: ModuleImport) -> Self {
1277 Self::Module(v)
1278 }
1279}
1280
1281impl From<&QualifiedIdentifier> for Import {
1282 fn from(v: &QualifiedIdentifier) -> Self {
1283 Self::Member(MemberImport::from(v.clone()))
1284 }
1285}
1286
1287impl From<QualifiedIdentifier> for Import {
1288 fn from(v: QualifiedIdentifier) -> Self {
1289 Self::Member(MemberImport::from(v))
1290 }
1291}
1292
1293impl From<&MemberImport> for Import {
1294 fn from(v: &MemberImport) -> Self {
1295 Self::Member(v.clone())
1296 }
1297}
1298
1299impl From<MemberImport> for Import {
1300 fn from(v: MemberImport) -> Self {
1301 Self::Member(v)
1302 }
1303}
1304
1305impl std::fmt::Display for Import {
1306 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1307 write!(
1308 f,
1309 "{}",
1310 match self {
1311 Self::Module(v) => v.to_string(),
1312 Self::Member(v) => v.to_string(),
1313 }
1314 )
1315 }
1316}
1317
1318impl HasSourceSpan for Import {
1319 #[inline]
1320 fn with_source_span(self, span: Span) -> Self {
1321 match self {
1322 Self::Module(v) => Self::Module(v.with_source_span(span)),
1323 Self::Member(v) => Self::Member(v.with_source_span(span)),
1324 }
1325 }
1326
1327 #[inline]
1328 fn source_span(&self) -> Option<&Span> {
1329 match self {
1330 Self::Module(v) => v.source_span(),
1331 Self::Member(v) => v.source_span(),
1332 }
1333 }
1334
1335 #[inline]
1336 fn set_source_span(&mut self, span: Span) {
1337 match self {
1338 Self::Module(v) => v.set_source_span(span),
1339 Self::Member(v) => v.set_source_span(span),
1340 }
1341 }
1342
1343 #[inline]
1344 fn unset_source_span(&mut self) {
1345 match self {
1346 Self::Module(v) => v.unset_source_span(),
1347 Self::Member(v) => v.unset_source_span(),
1348 }
1349 }
1350}
1351
1352impl Import {
1353 pub fn module(&self) -> &Identifier {
1354 match self {
1355 Import::Module(v) => v.name(),
1356 Import::Member(v) => v.module(),
1357 }
1358 }
1359 pub fn member(&self) -> Option<&Identifier> {
1360 match self {
1361 Import::Module(_) => None,
1362 Import::Member(v) => Some(v.member()),
1363 }
1364 }
1365}
1366
1367impl From<&Identifier> for ModuleImport {
1372 fn from(value: &Identifier) -> Self {
1373 Self::new(value.clone())
1374 }
1375}
1376
1377impl From<Identifier> for ModuleImport {
1378 fn from(value: Identifier) -> Self {
1379 Self::new(value)
1380 }
1381}
1382
1383impl PartialEq for ModuleImport {
1384 fn eq(&self, other: &Self) -> bool {
1385 self.name == other.name
1386 && self.version_uri == other.version_uri
1387 && self.renamed_as == other.renamed_as
1388 }
1389}
1390
1391impl Eq for ModuleImport {}
1392
1393impl Hash for ModuleImport {
1394 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1395 self.name.hash(state);
1397 self.version_uri.hash(state);
1398 self.renamed_as.hash(state);
1399 }
1400}
1401
1402impl Display for ModuleImport {
1403 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1404 write!(
1405 f,
1406 "{}{}",
1407 if let Some(version_uri) = self.version_uri() {
1408 format!("{} version {}", self.name(), version_uri)
1409 } else {
1410 self.name().to_string()
1411 },
1412 if let Some(renamed_as) = &self.renamed_as {
1413 format!(" as {renamed_as}")
1414 } else {
1415 String::new()
1416 }
1417 )
1418 }
1419}
1420
1421impl HasSourceSpan for ModuleImport {
1422 fn with_source_span(self, span: Span) -> Self {
1423 let mut self_mut = self;
1424 self_mut.span = Some(span);
1425 self_mut
1426 }
1427
1428 fn source_span(&self) -> Option<&Span> {
1429 self.span.as_ref()
1430 }
1431
1432 fn set_source_span(&mut self, span: Span) {
1433 self.span = Some(span);
1434 }
1435
1436 fn unset_source_span(&mut self) {
1437 self.span = None;
1438 }
1439}
1440
1441impl ModuleImport {
1442 pub const fn new(name: Identifier) -> Self {
1446 Self {
1447 span: None,
1448 name,
1449 version_uri: None,
1450 renamed_as: None,
1451 }
1452 }
1453
1454 pub fn with_version_uri(self, version_uri: HeaderValue<Url>) -> Self {
1455 let mut self_mut = self;
1456 self_mut.version_uri = Some(version_uri);
1457 self_mut
1458 }
1459
1460 pub fn with_rename(self, renamed_as: Identifier) -> Self {
1461 let mut self_mut = self;
1462 self_mut.renamed_as = Some(renamed_as);
1463 self_mut
1464 }
1465
1466 pub const fn name(&self) -> &Identifier {
1471 &self.name
1472 }
1473
1474 pub fn set_name(&mut self, name: Identifier) {
1475 self.name = name;
1476 }
1477
1478 pub const fn has_version_uri(&self) -> bool {
1481 self.version_uri.is_some()
1482 }
1483
1484 pub const fn version_uri(&self) -> Option<&HeaderValue<Url>> {
1485 self.version_uri.as_ref()
1486 }
1487
1488 pub fn set_version_uri(&mut self, version_uri: HeaderValue<Url>) {
1489 self.version_uri = Some(version_uri);
1490 }
1491
1492 pub fn unset_version_uri(&mut self) {
1493 self.version_uri = None;
1494 }
1495
1496 pub fn effective_name(&self) -> Identifier {
1499 if let Some(rename) = self.renamed_as() {
1500 rename.clone()
1501 } else {
1502 self.name().clone()
1503 }
1504 }
1505
1506 pub const fn has_been_renamed(&self) -> bool {
1509 self.renamed_as.is_some()
1510 }
1511
1512 pub const fn renamed_as(&self) -> Option<&Identifier> {
1513 self.renamed_as.as_ref()
1514 }
1515
1516 pub fn set_rename_as(&mut self, renamed_as: Identifier) {
1517 self.renamed_as = Some(renamed_as);
1518 }
1519
1520 pub fn unset_rename_as(&mut self) {
1521 self.renamed_as = None;
1522 }
1523
1524 pub fn eq_with_span(&self, other: &Self) -> bool {
1529 self.span == other.span
1530 && self.name == other.name
1531 && self.version_uri == other.version_uri
1532 && self.renamed_as == other.renamed_as
1533 }
1534}
1535
1536impl From<&QualifiedIdentifier> for MemberImport {
1541 fn from(value: &QualifiedIdentifier) -> Self {
1542 Self::new(value.clone())
1543 }
1544}
1545
1546impl From<QualifiedIdentifier> for MemberImport {
1547 fn from(value: QualifiedIdentifier) -> Self {
1548 Self::new(value)
1549 }
1550}
1551
1552impl PartialEq for MemberImport {
1553 fn eq(&self, other: &Self) -> bool {
1554 self.name == other.name && self.renamed_as == other.renamed_as
1555 }
1556}
1557
1558impl Eq for MemberImport {}
1559
1560impl Hash for MemberImport {
1561 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1562 self.name.hash(state);
1564 self.renamed_as.hash(state);
1565 }
1566}
1567
1568impl Display for MemberImport {
1569 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1570 write!(
1571 f,
1572 "{}{}",
1573 self.name(),
1574 if let Some(renamed_as) = &self.renamed_as {
1575 format!(" as {renamed_as}")
1576 } else {
1577 String::new()
1578 }
1579 )
1580 }
1581}
1582
1583impl HasSourceSpan for MemberImport {
1584 fn with_source_span(self, span: Span) -> Self {
1585 let mut self_mut = self;
1586 self_mut.span = Some(span);
1587 self_mut
1588 }
1589
1590 fn source_span(&self) -> Option<&Span> {
1591 self.span.as_ref()
1592 }
1593
1594 fn set_source_span(&mut self, span: Span) {
1595 self.span = Some(span);
1596 }
1597
1598 fn unset_source_span(&mut self) {
1599 self.span = None;
1600 }
1601}
1602
1603impl MemberImport {
1604 pub const fn new(name: QualifiedIdentifier) -> Self {
1608 Self {
1609 span: None,
1610 name,
1611 renamed_as: None,
1612 }
1613 }
1614
1615 pub fn with_rename(self, renamed_as: Identifier) -> Self {
1616 let mut self_mut = self;
1617 self_mut.renamed_as = Some(renamed_as);
1618 self_mut
1619 }
1620
1621 pub const fn name(&self) -> &QualifiedIdentifier {
1626 &self.name
1627 }
1628
1629 pub fn set_name(&mut self, name: QualifiedIdentifier) {
1630 self.name = name;
1631 }
1632
1633 pub const fn module(&self) -> &Identifier {
1636 self.name().module()
1637 }
1638
1639 pub const fn member(&self) -> &Identifier {
1640 self.name().member()
1641 }
1642
1643 pub fn effective_name(&self) -> IdentifierReference {
1646 if let Some(rename) = self.renamed_as() {
1647 rename.clone().into()
1648 } else {
1649 self.name().clone().into()
1650 }
1651 }
1652
1653 pub const fn has_been_renamed(&self) -> bool {
1656 self.renamed_as.is_some()
1657 }
1658
1659 pub const fn renamed_as(&self) -> Option<&Identifier> {
1660 self.renamed_as.as_ref()
1661 }
1662
1663 pub fn set_rename_as(&mut self, renamed_as: Identifier) {
1664 self.renamed_as = Some(renamed_as);
1665 }
1666
1667 pub fn unset_rename_as(&mut self) {
1668 self.renamed_as = None;
1669 }
1670
1671 pub fn eq_with_span(&self, other: &Self) -> bool {
1676 self.span == other.span && self.name == other.name && self.renamed_as == other.renamed_as
1677 }
1678}
1679
1680#[cfg(test)]
1685mod tests {
1686 use super::*;
1687
1688 #[test]
1689 fn test_module_path_from_str_default() {
1690 let path = ModulePath::from_str("").unwrap();
1691 assert!(!path.is_root());
1692 assert!(!path.is_absolute());
1693 assert!(!path.has_segments());
1694 assert_eq!(path.segment_count(), 0);
1695 }
1696
1697 #[test]
1698 fn test_module_path_from_str_root() {
1699 let path = ModulePath::from_str("::").unwrap();
1700 assert!(path.is_root());
1701 assert!(path.is_absolute());
1702 assert!(!path.has_segments());
1703 assert_eq!(path.segment_count(), 0);
1704 }
1705
1706 #[test]
1707 fn test_module_path_from_str_absolute() {
1708 let path = ModulePath::from_str("::one").unwrap();
1709 assert!(!path.is_root());
1710 assert!(path.is_absolute());
1711 assert!(path.has_segments());
1712 assert_eq!(path.segment_count(), 1);
1713 }
1714
1715 #[test]
1716 fn test_module_path_from_str_absolute_two() {
1717 let path = ModulePath::from_str("::one::two").unwrap();
1718 assert!(!path.is_root());
1719 assert!(path.is_absolute());
1720 assert!(path.has_segments());
1721 assert_eq!(path.segment_count(), 2);
1722 }
1723
1724 #[test]
1725 fn test_module_path_from_str_relative() {
1726 let path = ModulePath::from_str("one").unwrap();
1727 assert!(!path.is_root());
1728 assert!(!path.is_absolute());
1729 assert!(path.has_segments());
1730 assert_eq!(path.segment_count(), 1);
1731 }
1732
1733 #[test]
1734 fn test_module_path_from_str_relative_two() {
1735 let path = ModulePath::from_str("one::two").unwrap();
1736 assert!(!path.is_root());
1737 assert!(!path.is_absolute());
1738 assert!(path.has_segments());
1739 assert_eq!(path.segment_count(), 2);
1740 }
1741
1742 #[test]
1743 fn test_module_path_display_default() {
1744 let path = ModulePath::default();
1745 assert_eq!(&path.to_string(), "");
1746 }
1747
1748 #[test]
1749 fn test_module_path_display_root() {
1750 let path = ModulePath::root();
1751 assert_eq!(&path.to_string(), "::");
1752 }
1753
1754 #[test]
1755 fn test_module_path_display_absolute() {
1756 let path = ModulePath::absolute(vec![Identifier::from_str("one").unwrap()]);
1757 assert_eq!(&path.to_string(), "::one");
1758 }
1759
1760 #[test]
1761 fn test_module_path_display_absolute_two() {
1762 let path = ModulePath::absolute(vec![
1763 Identifier::from_str("one").unwrap(),
1764 Identifier::from_str("two").unwrap(),
1765 ]);
1766 assert_eq!(&path.to_string(), "::one::two");
1767 }
1768 #[test]
1769 fn test_module_path_display_relative() {
1770 let path = ModulePath::relative(vec![Identifier::from_str("one").unwrap()]);
1771 assert_eq!(&path.to_string(), "one");
1772 }
1773
1774 #[test]
1775 fn test_module_path_display_relative_two() {
1776 let path = ModulePath::relative(vec![
1777 Identifier::from_str("one").unwrap(),
1778 Identifier::from_str("two").unwrap(),
1779 ]);
1780 assert_eq!(&path.to_string(), "one::two");
1781 }
1782}