@@ -578,6 +578,7 @@ def LinkLibraryReferences(self):
578578 DEFAULT_LIBRARIES = ("std" ,)
579579
580580 for designUnit in self .IterateDesignUnits (DesignUnits .WithContext ):
581+ # All primary units supporting a context, have at least one library implicitly referenced
581582 if isinstance (designUnit , PrimaryUnit ):
582583 for libraryIdentifier in DEFAULT_LIBRARIES :
583584 designUnit ._referencedLibraries [libraryIdentifier ] = self ._libraries [libraryIdentifier ]
@@ -589,6 +590,7 @@ def LinkLibraryReferences(self):
589590 libraryIdentifier = workingLibrary .NormalizedIdentifier
590591 designUnit ._referencedLibraries [libraryIdentifier ] = self ._libraries [libraryIdentifier ]
591592 designUnit ._referencedPackages [libraryIdentifier ] = {}
593+ # All secondary units inherit referenced libraries from their primary units.
592594 else :
593595 if isinstance (designUnit , Architecture ):
594596 referencedLibraries = designUnit .Entity .Entity ._referencedLibraries
@@ -601,15 +603,16 @@ def LinkLibraryReferences(self):
601603 designUnit ._referencedLibraries [libraryIdentifier ] = library
602604
603605 for libraryReference in designUnit ._libraryReferences :
606+ # A library clause can have multiple comma-separated references
604607 for librarySymbol in libraryReference .Symbols :
605608 libraryIdentifier = librarySymbol .NormalizedIdentifier
606609 try :
607- lib = self ._libraries [libraryIdentifier ]
610+ library = self ._libraries [libraryIdentifier ]
608611 except KeyError :
609612 raise Exception (f"Library '{ librarySymbol .Identifier } ' referenced by library clause of design unit '{ designUnit .Identifier } ' doesn't exist in design." )
610613
611- librarySymbol .Library = lib
612- designUnit ._referencedLibraries [libraryIdentifier ] = lib
614+ librarySymbol .Library = library
615+ designUnit ._referencedLibraries [libraryIdentifier ] = library
613616 designUnit ._referencedPackages [libraryIdentifier ] = {}
614617 # TODO: warn duplicate library reference
615618
@@ -619,6 +622,7 @@ def LinkPackageReferences(self):
619622 )
620623
621624 for designUnit in self .IterateDesignUnits (DesignUnits .WithContext ):
625+ # All primary units supporting a context, have at least one package implicitly referenced
622626 if isinstance (designUnit , PrimaryUnit ):
623627 for lib in DEFAULT_PACKAGES :
624628 if lib [0 ] not in designUnit ._referencedLibraries :
@@ -627,6 +631,7 @@ def LinkPackageReferences(self):
627631 designUnit ._referencedPackages [lib [0 ]][pack ] = self ._libraries [lib [0 ]]._packages [pack ]
628632 # TODO: catch KeyError on self._libraries[lib[0]]._packages[pack]
629633 # TODO: warn duplicate package reference
634+ # All secondary units inherit referenced packages from their primary units.
630635 else :
631636 if isinstance (designUnit , Architecture ):
632637 referencedPackages = designUnit .Entity .Entity ._referencedPackages
@@ -639,13 +644,15 @@ def LinkPackageReferences(self):
639644 designUnit ._referencedPackages [packageIdentifier ] = package
640645
641646 for packageReference in designUnit .PackageReferences :
647+ # A use clause can have multiple comma-separated references
642648 for symbol in packageReference .Symbols :
643649 packageSymbol = symbol .Prefix
644650 librarySymbol = packageSymbol .Prefix
645651
646652 libraryIdentifier = librarySymbol .NormalizedIdentifier
647653 packageIdentifier = packageSymbol .NormalizedIdentifier
648654
655+ # In case work is used, resolve to the real library name.
649656 if libraryIdentifier == "work" :
650657 library : Library = designUnit .Library
651658 libraryIdentifier = library .NormalizedIdentifier
@@ -666,6 +673,7 @@ def LinkPackageReferences(self):
666673 librarySymbol .Library = library
667674 packageSymbol .Package = package
668675
676+ # TODO: update the namespace with visible members
669677 if isinstance (symbol , AllPackageMembersReferenceSymbol ):
670678 pass
671679
@@ -679,19 +687,68 @@ def LinkContextReferences(self):
679687
680688 def LinkContexts (self ):
681689 for context in self .IterateDesignUnits (DesignUnits .Context ):
690+ # Create entries in _referenced*** for the current working library under its real name.
691+ workingLibrary : Library = context .Library
692+ libraryIdentifier = workingLibrary .NormalizedIdentifier
693+ context ._referencedLibraries [libraryIdentifier ] = self ._libraries [libraryIdentifier ]
694+ context ._referencedPackages [libraryIdentifier ] = {}
695+
696+ # Process all library clauses
682697 for libraryReference in context ._libraryReferences :
698+ # A library clause can have multiple comma-separated references
683699 for librarySymbol in libraryReference .Symbols :
684700 libraryIdentifier = librarySymbol .NormalizedIdentifier
685701 try :
686- lib = self ._libraries [libraryIdentifier ]
702+ library = self ._libraries [libraryIdentifier ]
687703 except KeyError :
688704 raise Exception (f"Library '{ librarySymbol .Identifier } ' referenced by library clause of context '{ context .Identifier } ' doesn't exist in design." )
705+ # TODO: add position to these messages
689706
690- librarySymbol .Library = lib
691- context ._referencedLibraries [libraryIdentifier ] = lib
707+ librarySymbol .Library = library
708+ context ._referencedLibraries [libraryIdentifier ] = library
692709 context ._referencedPackages [libraryIdentifier ] = {}
693710 # TODO: warn duplicate library reference
694711
712+ # Process all use clauses
713+ for packageReference in context .PackageReferences :
714+ # A use clause can have multiple comma-separated references
715+ for symbol in packageReference .Symbols :
716+ packageSymbol = symbol .Prefix
717+ librarySymbol = packageSymbol .Prefix
718+
719+ libraryIdentifier = librarySymbol .NormalizedIdentifier
720+ packageIdentifier = packageSymbol .NormalizedIdentifier
721+
722+ # In case work is used, resolve to the real library name.
723+ if libraryIdentifier == "work" :
724+ library : Library = context .Library
725+ libraryIdentifier = library .NormalizedIdentifier
726+ elif libraryIdentifier not in context ._referencedLibraries :
727+ # TODO: This check doesn't trigger if it's the working library.
728+ raise Exception (f"Use clause references library '{ librarySymbol .Identifier } ', which was not referenced by a library clause." )
729+ else :
730+ library = self ._libraries [libraryIdentifier ]
731+
732+ try :
733+ package = library ._packages [packageIdentifier ]
734+ except KeyError :
735+ raise Exception (f"Package '{ packageSymbol .Identifier } ' not found in { 'working ' if librarySymbol .NormalizedIdentifier == 'work' else '' } library '{ library .Identifier } '." )
736+
737+ # TODO: warn duplicate package reference
738+ context ._referencedPackages [libraryIdentifier ][packageIdentifier ] = package
739+
740+ librarySymbol .Library = library
741+ packageSymbol .Package = package
742+
743+ # TODO: update the namespace with visible members
744+ if isinstance (symbol , AllPackageMembersReferenceSymbol ):
745+ pass
746+
747+ elif isinstance (symbol , PackageMembersReferenceSymbol ):
748+ raise NotImplementedError ()
749+ else :
750+ raise Exception ()
751+
695752 def LinkArchitectures (self ):
696753 for library in self ._libraries .values ():
697754 library .LinkArchitectures ()
@@ -793,6 +850,7 @@ def LinkArchitectures(self):
793850
794851 for architecture in architecturesPerEntity .values ():
795852 entity = self ._entities [entityName ]
853+ entity ._architectures .append (architecture ) # TODO: convert to dict
796854 architecture .Entity .Entity = entity
797855
798856 def LinkPackageBodies (self ):
0 commit comments