Coverage for pyVHDLModel/Symbol.py: 99%
458 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-25 10:05 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-25 10:05 +0000
1# ==================================================================================================================== #
2# __ ___ _ ____ _ __ __ _ _ #
3# _ __ _ \ \ / / | | | _ \| | | \/ | ___ __| | ___| | #
4# | '_ \| | | \ \ / /| |_| | | | | | | |\/| |/ _ \ / _` |/ _ \ | #
5# | |_) | |_| |\ V / | _ | |_| | |___| | | | (_) | (_| | __/ | #
6# | .__/ \__, | \_/ |_| |_|____/|_____|_| |_|\___/ \__,_|\___|_| #
7# |_| |___/ #
8# ==================================================================================================================== #
9# Authors: #
10# Patrick Lehmann #
11# #
12# License: #
13# ==================================================================================================================== #
14# Copyright 2017-2026 Patrick Lehmann - Boetzingen, Germany #
15# Copyright 2016-2017 Patrick Lehmann - Dresden, Germany #
16# #
17# Licensed under the Apache License, Version 2.0 (the "License"); #
18# you may not use this file except in compliance with the License. #
19# You may obtain a copy of the License at #
20# #
21# http://www.apache.org/licenses/LICENSE-2.0 #
22# #
23# Unless required by applicable law or agreed to in writing, software #
24# distributed under the License is distributed on an "AS IS" BASIS, #
25# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
26# See the License for the specific language governing permissions and #
27# limitations under the License. #
28# #
29# SPDX-License-Identifier: Apache-2.0 #
30# ==================================================================================================================== #
31#
32"""
33This module contains parts of an abstract document language model for VHDL.
35Symbols are entity specific wrappers for names that reference VHDL language entities.
36"""
37from __future__ import annotations
39from enum import Flag, auto
40from typing import TYPE_CHECKING, Any, Optional as Nullable, Iterable, Mapping, Self
42from pyTooling.Common import getTypeName
43from pyTooling.Decorators import export, notimplemented, readonly
44from pyTooling.MetaClasses import ExtendedType, abstractclass
46from pyVHDLModel.Base import Range
47from pyVHDLModel.Name import Name, AllName
48if TYPE_CHECKING: 48 ↛ 49line 48 didn't jump to line 49 because the condition on line 48 was never true
49 from pyVHDLModel.Visitor import Visitor
52@export
53class PossibleReference(Flag):
54 """
55 Is an enumeration, representing possible targets for a reference in a :class:`~pyVHDLModel.Symbol.Symbol`.
56 """
58 Unknown = 0
59 Library = auto() #: Library
60 Entity = auto() #: Entity
61 Architecture = auto() #: Architecture
62 Component = auto() #: Component
63 Package = auto() #: Package
64 Configuration = auto() #: Configuration
65 Context = auto() #: Context
66 Type = auto() #: Type
67 Subtype = auto() #: Subtype
68 ScalarType = auto() #: ScalarType
69 ArrayType = auto() #: ArrayType
70 RecordType = auto() #: RecordType
71 RecordElement = auto() #: RecordElement
72 AccessType = auto() #: AccessType
73 ProtectedType = auto() #: ProtectedType
74 FileType = auto() #: FileType
75# Alias = auto() # TODO: Is this needed?
76 Attribute = auto() #: Attribute
77 TypeAttribute = auto() #: TypeAttribute
78 ValueAttribute = auto() #: ValueAttribute
79 SignalAttribute = auto() #: SignalAttribute
80 RangeAttribute = auto() #: RangeAttribute
81 ViewAttribute = auto() #: ViewAttribute
82 Constant = auto() #: Constant
83 Variable = auto() #: Variable
84 Signal = auto() #: Signal
85 File = auto() #: File
86# Object = auto() # TODO: Is this needed?
87 EnumLiteral = auto() #: EnumLiteral
88 Procedure = auto() #: Procedure
89 Function = auto() #: Function
90 Label = auto() #: Label
91 View = auto() #: View
93 AnyType = ScalarType | ArrayType | RecordType | ProtectedType | AccessType | FileType | Subtype #: Any possible type incl. subtypes.
94 Object = Constant | Variable | Signal # | File #: Any object
95 SubProgram = Procedure | Function #: Any subprogram
96 PackageMember = AnyType | Object | SubProgram | Component #: Any member of a package
97 SimpleNameInExpression = Constant | Variable | Signal | ScalarType | EnumLiteral | Function #: Any possible item in an expression.
100# QUESTION: Why is it not a ModelEntity?
101@export
102class Symbol(metaclass=ExtendedType):
103 """
104 Base-class for all symbol classes.
105 """
107 _name: Name #: The name to reference the language entity.
108 _possibleReferences: PossibleReference #: An enumeration to filter possible references.
109 _reference: Nullable[Any] #: The resolved language entity, otherwise ``None``.
111 def __init__(self, name: Name, possibleReferences: PossibleReference) -> None:
112 """
113 Initializes a symbol.
115 :param name: The name to reference the language entity.
116 :param possibleReferences: An enumeration to filter possible references.
117 """
118 self._name = name
119 self._possibleReferences = possibleReferences
120 self._reference = None
122 @readonly
123 def Name(self) -> Name:
124 """
125 Read-only property to access the name (:attr:`_name`).
127 :returns: The name.
128 """
129 return self._name
131 @readonly
132 def Reference(self) -> Nullable[Any]:
133 """
134 Read-only property to access the reference (:attr:`_reference`).
136 :returns: The reference, or ``None`` if not set.
137 """
138 return self._reference
140 @readonly
141 def IsResolved(self) -> bool:
142 """
143 Check if the symbol is resolved, i.e. :attr:`_reference` is set.
145 :returns: ``True``, if the symbol is resolved.
146 """
147 return self._reference is not None
149 def __bool__(self) -> bool:
150 """
151 Reports whether this symbol has been resolved.
153 :returns: ``True`` if the symbol references a model entity.
154 """
155 return self._reference is not None
157 def Copy(self) -> Self:
158 """
159 Create a copy of this symbol.
161 The name is copied; the reference, if resolved, is the same.
163 :returns: The new symbol.
164 """
165 copy = self.__class__(self._name.Copy(), self._possibleReferences)
166 copy._reference = self._reference
167 return copy
169 def Visit(self, visitor: Visitor) -> None:
170 """
171 Walk this symbol and its name with a visitor.
173 :param visitor: The visitor receiving the events.
174 """
175 visitor.VisitSymbol(self)
176 self._name.Visit(visitor)
177 visitor.DepartSymbol(self)
179 def __repr__(self) -> str:
180 """
181 Formats a representation of the symbol.
183 **Format:** ``SignalSymbol: 'clk' -> <signal>``, or ``... -> ?`` while unresolved
185 :returns: String representation of the symbol.
186 """
187 if self._reference is not None:
188 return f"{getTypeName(self)}: '{self._name!s}' -> {self._reference!s}"
190 return f"{getTypeName(self)}: '{self._name!s}' -> unresolved"
192 def __str__(self) -> str:
193 """
194 Formats the symbol.
196 **Format:** the referenced model entity once resolved, else the name plus ``?``
198 :returns: Formatted symbol.
199 """
200 if self._reference is not None:
201 return str(self._reference)
203 return f"{self._name!s}?"
206@export
207class LibraryReferenceSymbol(Symbol):
208 """
209 Represents a reference (name) to a library.
211 The internal name will be a :class:`~pyVHDLModel.Name.SimpleName`.
213 .. admonition:: Example
215 .. code-block:: VHDL
217 library ieee;
218 -- ^^^^
219 """
221 def __init__(self, name: Name) -> None:
222 """
223 Initializes a reference (name) to a library.
225 :param name: The name to reference the language entity.
226 """
227 super().__init__(name, PossibleReference.Library)
229 @property
230 def Library(self) -> Nullable[Library]:
231 """
232 Property to access the library (:attr:`_reference`).
234 :returns: The library, or ``None`` if not set.
235 """
236 return self._reference
238 @Library.setter
239 def Library(self, value: Library) -> None:
240 self._reference = value
242 def Copy(self) -> Self:
243 """
244 Create a copy of this library reference symbol.
246 The name is copied; the reference, if resolved, is the same.
248 :returns: The new library reference symbol.
249 """
250 copy = self.__class__(self._name.Copy())
251 copy._reference = self._reference
252 return copy
255@export
256class PackageReferenceSymbol(Symbol):
257 """
258 Represents a reference (name) to a package.
260 The internal name will be a :class:`~pyVHDLModel.Name.SelectedName`.
262 .. admonition:: Example
264 .. code-block:: VHDL
266 use ieee.numeric_std;
267 -- ^^^^^^^^^^^^^^^^
268 """
270 def __init__(self, name: Name) -> None:
271 """
272 Initializes a reference (name) to a package.
274 :param name: The name to reference the language entity.
275 """
276 super().__init__(name, PossibleReference.Package)
278 @property
279 def Package(self) -> Nullable[Package]:
280 """
281 Property to access the package (:attr:`_reference`).
283 :returns: The package, or ``None`` if not set.
284 """
285 return self._reference
287 @Package.setter
288 def Package(self, value: Package) -> None:
289 self._reference = value
291 def Copy(self) -> Self:
292 """
293 Create a copy of this package reference symbol.
295 The name is copied; the reference, if resolved, is the same.
297 :returns: The new package reference symbol.
298 """
299 copy = self.__class__(self._name.Copy())
300 copy._reference = self._reference
301 return copy
304@export
305class ModeViewSymbol(Symbol):
306 """
307 Represents a reference to a mode view (VHDL-2019).
309 The referenced mode view is available as :data:`Reference` once resolved. A reference may also
310 select the converse view.
312 .. admonition:: Example
314 Referencing a mode view:
316 .. code-block:: VHDL
318 port (p : view MasterView);
319 -- ^^^^^^^^^^ <- Name
321 Referencing its converse:
323 .. code-block:: VHDL
325 port (p : view MasterView'converse);
326 -- ^^^^^^^^^^^^^^^^^^^ <- Name
327 """
329 def __init__(self, name: Name) -> None:
330 """
331 Initializes a reference to a mode view (VHDL-2019).
333 :param name: The name to reference the language entity.
334 """
335 super().__init__(name, PossibleReference.View)
337 @property
338 def ModeView(self) -> Nullable[ModeViewDeclaration]:
339 """
340 Property to access the mode view (:attr:`_reference`).
342 :returns: The mode view, or ``None`` if not set.
343 """
344 return self._reference
346 @ModeView.setter
347 def ModeView(self, value: ModeViewDeclaration) -> None:
348 self._reference = value
350 def Copy(self) -> Self:
351 """
352 Create a copy of this mode view symbol.
354 The name is copied; the reference, if resolved, is the same.
356 :returns: The new mode view symbol.
357 """
358 copy = self.__class__(self._name.Copy())
359 copy._reference = self._reference
360 return copy
363@export
364class SubprogramReferenceSymbol(Symbol):
365 """
366 Represents a reference to a subprogram.
368 The referenced subprogram is available as :data:`Reference` once resolved.
370 .. admonition:: Example
372 .. code-block:: VHDL
374 function f is new gen_fun generic map (N => 1);
375 -- ^^^^^^^ <- Name
376 """
378 def __init__(self, name: Name) -> None:
379 """
380 Initializes a reference to a subprogram.
382 :param name: The name to reference the language entity.
383 """
384 super().__init__(name, PossibleReference.SubProgram)
386 @property
387 def Subprogram(self) -> Nullable[Subprogram]:
388 """
389 Property to access the subprogram (:attr:`_reference`).
391 :returns: The subprogram, or ``None`` if not set.
392 """
393 return self._reference
395 @Subprogram.setter
396 def Subprogram(self, value: Subprogram) -> None:
397 self._reference = value
399 def Copy(self) -> Self:
400 """
401 Create a copy of this subprogram reference symbol.
403 The name is copied; the reference, if resolved, is the same.
405 :returns: The new subprogram reference symbol.
406 """
407 copy = self.__class__(self._name.Copy())
408 copy._reference = self._reference
409 return copy
412@export
413class ConfigurationSymbol(Symbol):
414 """
415 Represents a reference to a configuration.
417 The referenced configuration is available as :data:`Reference` once resolved.
419 .. admonition:: Example
421 .. code-block:: VHDL
423 for U1 : comp use configuration work.cfg;
424 -- ^^^^^^^^ <- Name
425 """
427 def __init__(self, name: Name) -> None:
428 """
429 Initializes a reference to a configuration.
431 :param name: The name to reference the language entity.
432 """
433 super().__init__(name, PossibleReference.Configuration)
435 @property
436 def Configuration(self) -> Nullable[Configuration]:
437 """
438 Property to access the configuration (:attr:`_reference`).
440 :returns: The configuration, or ``None`` if not set.
441 """
442 return self._reference
444 @Configuration.setter
445 def Configuration(self, value: Configuration) -> None:
446 self._reference = value
448 def Copy(self) -> Self:
449 """
450 Create a copy of this configuration symbol.
452 The name is copied; the reference, if resolved, is the same.
454 :returns: The new configuration symbol.
455 """
456 copy = self.__class__(self._name.Copy())
457 copy._reference = self._reference
458 return copy
461@export
462class VariableSymbol(Symbol):
463 """
464 Represents a reference (name) to a variable.
466 The target of a variable assignment is such a reference.
468 .. admonition:: Example
470 .. code-block:: VHDL
472 v := '1';
473 --^
474 """
476 def __init__(self, name: Name) -> None:
477 """
478 Initializes a variable symbol.
480 :param name: The name to reference the language entity.
481 """
482 super().__init__(name, PossibleReference.Variable)
484 @property
485 def Variable(self) -> Nullable[Variable]:
486 """
487 Property to access the variable (:attr:`_reference`).
489 :returns: The variable, or ``None`` if not set.
490 """
491 return self._reference
493 @Variable.setter
494 def Variable(self, value: Variable) -> None:
495 self._reference = value
497 def Copy(self) -> Self:
498 """
499 Create a copy of this variable symbol.
501 The name is copied; the reference, if resolved, is the same.
503 :returns: The new variable symbol.
504 """
505 copy = self.__class__(self._name.Copy())
506 copy._reference = self._reference
507 return copy
510@export
511class SignalSymbol(Symbol):
512 """
513 Represents a reference (name) to a signal.
515 The target of a signal assignment is such a reference.
517 .. admonition:: Example
519 .. code-block:: VHDL
521 s <= '1';
522 --^
523 """
525 def __init__(self, name: Name) -> None:
526 """
527 Initializes a signal symbol.
529 :param name: The name to reference the language entity.
530 """
531 super().__init__(name, PossibleReference.Signal)
533 @property
534 def Signal(self) -> Nullable[Signal]:
535 """
536 Property to access the signal (:attr:`_reference`).
538 :returns: The signal, or ``None`` if not set.
539 """
540 return self._reference
542 @Signal.setter
543 def Signal(self, value: Signal) -> None:
544 self._reference = value
546 def Copy(self) -> Self:
547 """
548 Create a copy of this signal symbol.
550 The name is copied; the reference, if resolved, is the same.
552 :returns: The new signal symbol.
553 """
554 copy = self.__class__(self._name.Copy())
555 copy._reference = self._reference
556 return copy
559@export
560class ContextReferenceSymbol(Symbol):
561 """
562 Represents a reference (name) to a context.
564 The internal name will be a :class:`~pyVHDLModel.Name.SelectedName`.
566 .. admonition:: Example
568 .. code-block:: VHDL
570 context ieee.ieee_std_context;
571 -- ^^^^^^^^^^^^^^^^^^^^^
572 """
574 def __init__(self, name: Name) -> None:
575 """
576 Initializes a reference (name) to a context.
578 :param name: The name to reference the language entity.
579 """
580 super().__init__(name, PossibleReference.Context)
582 @property
583 def Context(self) -> Context:
584 """
585 Property to access the context (:attr:`_reference`).
587 :returns: The context.
588 """
589 return self._reference
591 @Context.setter
592 def Context(self, value: Context) -> None:
593 self._reference = value
595 def Copy(self) -> Self:
596 """
597 Create a copy of this context reference symbol.
599 The name is copied; the reference, if resolved, is the same.
601 :returns: The new context reference symbol.
602 """
603 copy = self.__class__(self._name.Copy())
604 copy._reference = self._reference
605 return copy
608@export
609class PackageMemberReferenceSymbol(Symbol):
610 """
611 Represents a reference (name) to a package member.
613 The internal name will be a :class:`~pyVHDLModel.Name.SelectedName`.
615 .. admonition:: Example
617 .. code-block:: VHDL
619 use ieee.numeric_std.unsigned;
620 -- ^^^^^^^^^^^^^^^^^^^^^^^^^
621 """
623 def __init__(self, name: Name) -> None:
624 """
625 Initializes a reference (name) to a package member.
627 :param name: The name to reference the language entity.
628 """
629 super().__init__(name, PossibleReference.PackageMember)
631 @property
632 def Member(self) -> Nullable[Package]: # TODO: typehint
633 """
634 Property to access the member (:attr:`_reference`).
636 :returns: The member, or ``None`` if not set.
637 """
638 return self._reference
640 @Member.setter
641 def Member(self, value: Package) -> None: # TODO: typehint
642 self._reference = value
644 def Copy(self) -> Self:
645 """
646 Create a copy of this package member reference symbol.
648 The name is copied; the reference, if resolved, is the same.
650 :returns: The new package member reference symbol.
651 """
652 copy = self.__class__(self._name.Copy())
653 copy._reference = self._reference
654 return copy
657@export
658class AllPackageMembersReferenceSymbol(Symbol):
659 """
660 Represents a reference (name) to all package members.
662 The internal name will be a :class:`~pyVHDLModel.Name.AllName`.
664 .. admonition:: Example
666 .. code-block:: VHDL
668 use ieee.numeric_std.all;
669 -- ^^^^^^^^^^^^^^^^^^^^
670 """
672 def __init__(self, name: AllName) -> None:
673 """
674 Initializes a reference (name) to all package members.
676 :param name: The name to reference the language entity.
677 """
678 super().__init__(name, PossibleReference.PackageMember)
680 @property
681 def Members(self) -> Package: # TODO: typehint
682 """
683 Property to access the members (:attr:`_reference`).
685 :returns: The members.
686 """
687 return self._reference
689 @Members.setter
690 def Members(self, value: Package) -> None: # TODO: typehint
691 self._reference = value
693 def Copy(self) -> Self:
694 """
695 Create a copy of this all package members reference symbol.
697 The name is copied; the reference, if resolved, is the same.
699 :returns: The new all package members reference symbol.
700 """
701 copy = self.__class__(self._name.Copy())
702 copy._reference = self._reference
703 return copy
706@export
707class EntityInstantiationSymbol(Symbol):
708 """
709 Represents a reference (name) to an entity in a direct entity instantiation.
711 The internal name will be a :class:`~pyVHDLModel.Name.SimpleName` or :class:`~pyVHDLModel.Name.SelectedName`.
713 .. admonition:: Example
715 .. code-block:: VHDL
717 inst : entity work.Counter;
718 -- ^^^^^^^^^^^^
719 """
721 def __init__(self, name: Name) -> None:
722 """
723 Initializes a reference (name) to an entity in a direct entity instantiation.
725 :param name: The name to reference the language entity.
726 """
727 super().__init__(name, PossibleReference.Entity)
729 @property
730 def Entity(self) -> Entity:
731 """
732 Property to access the entity (:attr:`_reference`).
734 :returns: The entity.
735 """
736 return self._reference
738 @Entity.setter
739 def Entity(self, value: Entity) -> None:
740 self._reference = value
742 def Copy(self) -> Self:
743 """
744 Create a copy of this entity instantiation symbol.
746 The name is copied; the reference, if resolved, is the same.
748 :returns: The new entity instantiation symbol.
749 """
750 copy = self.__class__(self._name.Copy())
751 copy._reference = self._reference
752 return copy
755@export
756class ComponentInstantiationSymbol(Symbol):
757 """
758 Represents a reference (name) to an entity in a component instantiation.
760 The internal name will be a :class:`~pyVHDLModel.Name.SimpleName` or :class:`~pyVHDLModel.Name.SelectedName`.
762 .. admonition:: Example
764 .. code-block:: VHDL
766 inst : component Counter;
767 -- ^^^^^^^
768 """
770 def __init__(self, name: Name) -> None:
771 """
772 Initializes a reference (name) to an entity in a component instantiation.
774 :param name: The name to reference the language entity.
775 """
776 super().__init__(name, PossibleReference.Component)
778 @property
779 def Component(self) -> Component:
780 """
781 Property to access the component (:attr:`_reference`).
783 :returns: The component.
784 """
785 return self._reference
787 @Component.setter
788 def Component(self, value: Component) -> None:
789 self._reference = value
791 def Copy(self) -> Self:
792 """
793 Create a copy of this component instantiation symbol.
795 The name is copied; the reference, if resolved, is the same.
797 :returns: The new component instantiation symbol.
798 """
799 copy = self.__class__(self._name.Copy())
800 copy._reference = self._reference
801 return copy
804@export
805class ConfigurationInstantiationSymbol(Symbol):
806 """
807 Represents a reference (name) to an entity in a configuration instantiation.
809 The internal name will be a :class:`~pyVHDLModel.Name.SimpleName` or :class:`~pyVHDLModel.Name.SelectedName`.
811 .. admonition:: Example
813 .. code-block:: VHDL
815 inst : configuration Counter;
816 -- ^^^^^^^
817 """
819 def __init__(self, name: Name) -> None:
820 """
821 Initializes a reference (name) to an entity in a configuration instantiation.
823 :param name: The name to reference the language entity.
824 """
825 super().__init__(name, PossibleReference.Configuration)
827 @property
828 def Configuration(self) -> Configuration:
829 """
830 Property to access the configuration (:attr:`_reference`).
832 :returns: The configuration.
833 """
834 return self._reference
836 @Configuration.setter
837 def Configuration(self, value: Configuration) -> None:
838 self._reference = value
840 def Copy(self) -> Self:
841 """
842 Create a copy of this configuration instantiation symbol.
844 The name is copied; the reference, if resolved, is the same.
846 :returns: The new configuration instantiation symbol.
847 """
848 copy = self.__class__(self._name.Copy())
849 copy._reference = self._reference
850 return copy
853@export
854class EntitySymbol(Symbol):
855 """
856 Represents a reference (name) to an entity in an architecture declaration.
858 The internal name will be a :class:`~pyVHDLModel.Name.SimpleName` or :class:`~pyVHDLModel.Name.SelectedName`.
860 .. admonition:: Example
862 .. code-block:: VHDL
864 architecture rtl of Counter is
865 -- ^^^^^^^
866 begin
867 end architecture;
868 """
870 def __init__(self, name: Name) -> None:
871 """
872 Initializes a reference (name) to an entity in an architecture declaration.
874 :param name: The name to reference the language entity.
875 """
876 super().__init__(name, PossibleReference.Entity)
878 @property
879 def Entity(self) -> Entity:
880 """
881 Property to access the entity (:attr:`_reference`).
883 :returns: The entity.
884 """
885 return self._reference
887 @Entity.setter
888 def Entity(self, value: Entity) -> None:
889 self._reference = value
891 def Copy(self) -> Self:
892 """
893 Create a copy of this entity symbol.
895 The name is copied; the reference, if resolved, is the same.
897 :returns: The new entity symbol.
898 """
899 copy = self.__class__(self._name.Copy())
900 copy._reference = self._reference
901 return copy
904@export
905class ArchitectureSymbol(Symbol):
906 """An entity reference in an entity instantiation with architecture name."""
908 def __init__(self, name: Name) -> None:
909 """
910 Initializes an architecture symbol.
912 :param name: The name to reference the language entity.
913 """
914 super().__init__(name, PossibleReference.Architecture)
916 @property
917 def Architecture(self) -> Architecture:
918 """
919 Property to access the architecture (:attr:`_reference`).
921 :returns: The architecture.
922 """
923 return self._reference
925 @Architecture.setter
926 def Architecture(self, value: Architecture) -> None:
927 self._reference = value
929 def Copy(self) -> Self:
930 """
931 Create a copy of this architecture symbol.
933 The name is copied; the reference, if resolved, is the same.
935 :returns: The new architecture symbol.
936 """
937 copy = self.__class__(self._name.Copy())
938 copy._reference = self._reference
939 return copy
942@export
943class PackageSymbol(Symbol):
944 """
945 Represents a reference (name) to a package in a package body declaration.
947 The internal name will be a :class:`~pyVHDLModel.Name.SimpleName` or :class:`~pyVHDLModel.Name.SelectedName`.
949 .. admonition:: Example
951 .. code-block:: VHDL
953 package body Utilities is
954 -- ^^^^^^^^^
955 end package body;
956 """
958 def __init__(self, name: Name) -> None:
959 """
960 Initializes a reference (name) to a package in a package body declaration.
962 :param name: The name to reference the language entity.
963 """
964 super().__init__(name, PossibleReference.Package)
966 @property
967 def Package(self) -> Package:
968 """
969 Property to access the package (:attr:`_reference`).
971 :returns: The package.
972 """
973 return self._reference
975 @Package.setter
976 def Package(self, value: Package) -> None:
977 self._reference = value
979 def Copy(self) -> Self:
980 """
981 Create a copy of this package symbol.
983 The name is copied; the reference, if resolved, is the same.
985 :returns: The new package symbol.
986 """
987 copy = self.__class__(self._name.Copy())
988 copy._reference = self._reference
989 return copy
992@export
993class RecordElementSymbol(Symbol):
994 """
995 Represents a reference to a record element.
997 The referenced language entity is available as :data:`Reference` once resolved.
999 .. admonition:: Example
1001 .. code-block:: VHDL
1003 r := (a => '1', b => '0');
1004 -- ^ <- Name
1005 """
1006 def __init__(self, name: Name) -> None:
1007 """
1008 Initializes a reference to a record element.
1010 :param name: The name to reference the language entity.
1011 """
1012 super().__init__(name, PossibleReference.RecordElement)
1014 def Copy(self) -> Self:
1015 """
1016 Create a copy of this record element symbol.
1018 The name is copied; the reference, if resolved, is the same.
1020 :returns: The new record element symbol.
1021 """
1022 copy = self.__class__(self._name.Copy())
1023 copy._reference = self._reference
1024 return copy
1027@export
1028class RangeAttributeSymbol(Symbol):
1029 """
1030 A symbol referencing a range attribute.
1032 ``vector'range`` is such a reference.
1033 """
1035 def __init__(self, name: Name) -> None:
1036 """
1037 Initialize a range attribute symbol.
1039 :param name: The attribute name referencing the range.
1040 """
1041 super().__init__(name, PossibleReference.RangeAttribute)
1043 def Copy(self) -> Self:
1044 """
1045 Create a copy of this range attribute symbol.
1047 The name is copied; the reference, if resolved, is the same.
1049 :returns: The new range attribute symbol.
1050 """
1051 copy = self.__class__(self._name.Copy())
1052 copy._reference = self._reference
1053 return copy
1056@export
1057class SubtypeSymbol(Symbol):
1058 """
1059 Represents the base-class of all references to a type or subtype.
1061 The referenced language entity is available as :data:`Reference` once resolved.
1063 .. seealso::
1065 * :class:`Simple subtype symbol <pyVHDLModel.Symbol.SimpleSubtypeSymbol>`
1066 * :class:`Constrained scalar subtype symbol <pyVHDLModel.Symbol.ConstrainedScalarSubtypeSymbol>`
1067 * :class:`Constrained composite subtype symbol <pyVHDLModel.Symbol.ConstrainedCompositeSubtypeSymbol>`
1068 """
1069 def __init__(self, name: Name) -> None:
1070 """
1071 Initializes a subtype symbol.
1073 :param name: The name to reference the language entity.
1074 """
1075 super().__init__(name, PossibleReference.Type | PossibleReference.Subtype)
1077 @readonly
1078 def TypeMark(self) -> str:
1079 """
1080 Read-only property to return the type mark's name, as written: its identifiers joined by dots.
1082 A simple name gives its identifier (``natural``), a selected name the identifiers of its prefixes too
1083 (``ieee.numeric_std.unsigned``). The model doesn't resolve type marks yet, so this isn't the fully qualified name of
1084 the denoted type.
1086 :returns: The type mark's name.
1087 """
1088 name = self._name
1089 identifiers = [name._identifier]
1090 while name._prefix is not None:
1091 name = name._prefix
1092 identifiers.append(name._identifier)
1094 return ".".join(reversed(identifiers))
1096 @property
1097 def Subtype(self) -> Subtype:
1098 """
1099 Property to access the subtype (:attr:`_reference`).
1101 :returns: The subtype.
1102 """
1103 return self._reference
1105 @Subtype.setter
1106 def Subtype(self, value: Subtype) -> None:
1107 self._reference = value
1109 def Copy(self) -> Self:
1110 """
1111 Create a copy of this subtype symbol.
1113 The name is copied; the reference, if resolved, is the same.
1115 :returns: The new subtype symbol.
1116 """
1117 copy = self.__class__(self._name.Copy())
1118 copy._reference = self._reference
1119 return copy
1122@export
1123class SimpleSubtypeSymbol(SubtypeSymbol):
1124 """
1125 Represents a reference to a type or subtype by its type mark.
1127 The referenced language entity is available as :data:`Reference` once resolved.
1129 .. admonition:: Example
1131 .. code-block:: VHDL
1133 signal s : bit := '0';
1134 -- ^^^ <- Name
1135 """
1136 pass
1139@export
1140class Constraint(metaclass=ExtendedType, mixin=True):
1141 """
1142 A mixin-class for symbols carrying a constraint.
1144 .. seealso::
1146 * :class:`Scalar constraint <pyVHDLModel.Symbol.ScalarConstraint>`
1147 * :class:`Array constraint <pyVHDLModel.Symbol.ArrayConstraint>`
1148 * :class:`Record constraint <pyVHDLModel.Symbol.RecordConstraint>`
1149 """
1150 pass
1153@export
1154class ScalarConstraint(Constraint, mixin=True):
1155 """
1156 A mixin-class for a scalar constraint: a range.
1158 The range is available as :data:`Constraint`.
1160 .. seealso::
1162 * :class:`Constrained scalar subtype symbol <pyVHDLModel.Symbol.ConstrainedScalarSubtypeSymbol>`
1163 """
1164 _constraint: Range #: The range constraining the scalar subtype.
1166 def __init__(self, constraint: Range) -> None:
1167 """
1168 Initializes a scalar constraint.
1170 :param constraint: The range constraining the scalar subtype.
1171 """
1172 self._constraint = constraint
1174 @readonly
1175 def Constraint(self) -> Range:
1176 """
1177 Read-only property to access the scalar type's range constraint (:attr:`_constraint`).
1179 :returns: The constraint of the scalar subtype.
1180 """
1181 return self._constraint
1184@export
1185class ConstrainedScalarSubtypeSymbol(SubtypeSymbol, ScalarConstraint):
1186 """
1187 Represents a reference to a scalar subtype narrowed by a range.
1189 The referenced language entity is available as :data:`Reference` once resolved. The range is
1190 mandatory: a type mark without a range constraint is a :class:`~pyVHDLModel.Symbol.SimpleSubtypeSymbol`.
1192 .. admonition:: Example
1194 .. code-block:: VHDL
1196 for i in integer range 0 to 3 loop
1197 -- ^^^^^^^ <- Name
1198 -- ^^^^^^ <- Constraint
1200 A range constraint written as a range attribute is a :class:`~pyVHDLModel.Base.RangeFromName`
1201 referring to a :class:`~pyVHDLModel.Symbol.RangeAttributeSymbol`:
1203 .. code-block:: VHDL
1205 subtype index is natural range vector'range;
1206 -- ^^^^^^^ <- Name
1207 -- ^^^^^^^^^^^^ <- Constraint
1208 """
1210 def __init__(self, name: Name, constraint: Range) -> None:
1211 """
1212 Initializes a reference to a scalar subtype narrowed by a range.
1214 :param name: The name to reference the language entity.
1215 :param constraint: The range constraining the scalar subtype.
1216 """
1217 super().__init__(name)
1218 ScalarConstraint.__init__(self, constraint)
1220 def Copy(self) -> Self:
1221 """
1222 Create a copy of this constrained scalar subtype symbol.
1224 The name and the range are copied; the reference, if resolved, is the same.
1226 :returns: The new constrained scalar subtype symbol.
1227 """
1228 copy = self.__class__(self._name.Copy(), self._constraint.Copy())
1229 copy._reference = self._reference
1230 return copy
1232 def Visit(self, visitor: Visitor) -> None:
1233 """
1234 Walk this constrained scalar subtype symbol, its name and its range constraint with a visitor.
1236 :param visitor: The visitor receiving the events.
1237 """
1238 visitor.VisitConstrainedScalarSubtypeSymbol(self)
1239 self._name.Visit(visitor)
1240 visitor.VisitRangeConstraint(self)
1241 self._constraint.Visit(visitor)
1242 visitor.DepartRangeConstraint(self)
1243 visitor.DepartConstrainedScalarSubtypeSymbol(self)
1246@export
1247class ArrayConstraint(Constraint, mixin=True):
1248 """
1249 A mixin-class for an array constraint: one range per dimension.
1251 The ranges are available as :data:`Constraints`.
1253 .. seealso::
1255 * :class:`Constrained array subtype symbol <pyVHDLModel.Symbol.ConstrainedArraySubtypeSymbol>`
1256 """
1257 _constraints: list[Range] #: List of all index ranges, one per dimension.
1259 def __init__(self, constraints: Iterable[Range]) -> None:
1260 """
1261 Initializes an array constraint.
1263 :param constraints: List of all index ranges, one per dimension.
1264 """
1265 self._constraints = list(constraints)
1267 @readonly
1268 def Constraints(self) -> list[Range]:
1269 """
1270 Read-only property to access the constraints (:attr:`_constraints`).
1272 :returns: List of constraints.
1273 """
1274 return self._constraints
1277@export
1278class RecordConstraint(Constraint, mixin=True):
1279 """
1280 A mixin-class for a record constraint: one constraint per element.
1282 The constraints are available as :data:`Constraints`.
1284 .. seealso::
1286 * :class:`Constrained record subtype symbol <pyVHDLModel.Symbol.ConstrainedRecordSubtypeSymbol>`
1287 """
1288 _constraints: dict[RecordElementSymbol, Range] #: Dictionary of the constraint per constrained record element.
1290 def __init__(self, constraints: Mapping[RecordElementSymbol, Range]) -> None:
1291 """
1292 Initializes a record constraint.
1294 :param constraints: Dictionary of the constraint per constrained record element.
1295 """
1296 self._constraints = dict(constraints)
1298 @readonly
1299 def Constraints(self) -> dict[RecordElementSymbol, Range]:
1300 """
1301 Read-only property to access the constraints (:attr:`_constraints`).
1303 :returns: Dictionary of constraints.
1304 """
1305 return self._constraints
1308@export
1309@abstractclass
1310class ConstrainedCompositeSubtypeSymbol(SubtypeSymbol):
1311 """
1312 Represents the base-class of references to constrained composite subtypes.
1314 The referenced language entity is available as :data:`Reference` once resolved.
1316 .. seealso::
1318 * :class:`Constrained array subtype symbol <pyVHDLModel.Symbol.ConstrainedArraySubtypeSymbol>`
1319 * :class:`Constrained record subtype symbol <pyVHDLModel.Symbol.ConstrainedRecordSubtypeSymbol>`
1320 """
1321 @notimplemented("Model element has no walk for a visitor.")
1322 def Visit(self, visitor: Visitor) -> None:
1323 """
1324 Walk this constrained composite subtype symbol with a visitor.
1326 The walk of its base class would drop the constraint; the array and record subclasses walk their constraint.
1328 :param visitor: The visitor receiving the events.
1329 :raises NotImplementedError: Always, because a subclass without a walk of its own can't walk its constraint.
1330 """
1333@export
1334class ConstrainedArraySubtypeSymbol(ConstrainedCompositeSubtypeSymbol, ArrayConstraint):
1335 """
1336 Represents a reference to an array subtype narrowed by index ranges.
1338 The referenced language entity is available as :data:`Reference` once resolved.
1340 .. admonition:: Example
1342 .. code-block:: VHDL
1344 signal v : bit_vector(7 downto 0);
1345 -- ^^^^^^^^^^ <- Name
1346 -- ^^^^^^^^^^ <- Constraints
1347 """
1348 _constraints: list #: List of all index ranges, one per dimension.
1350 def __init__(self, name: Name, constraints: Iterable) -> None:
1351 """
1352 Initializes a reference to an array subtype narrowed by index ranges.
1354 :param name: The name to reference the language entity.
1355 :param constraints: List of all index ranges, one per dimension.
1356 """
1357 super().__init__(name)
1358 ArrayConstraint.__init__(self, constraints)
1360 def Copy(self) -> Self:
1361 """
1362 Create a copy of this constrained array subtype symbol.
1364 The name and the index ranges are copied; the reference, if resolved, is the same.
1366 :returns: The new constrained array subtype symbol.
1367 """
1368 copy = self.__class__(self._name.Copy(), [constraint.Copy() for constraint in self._constraints])
1369 copy._reference = self._reference
1370 return copy
1372 def Visit(self, visitor: Visitor) -> None:
1373 """
1374 Walk this constrained array subtype symbol, its name and its index constraint with a visitor.
1376 :param visitor: The visitor receiving the events.
1377 """
1378 visitor.VisitConstrainedArraySubtypeSymbol(self)
1379 self._name.Visit(visitor)
1380 visitor.VisitIndexConstraint(self)
1381 for index, constraint in enumerate(self._constraints):
1382 if index > 0:
1383 visitor.VisitComma(self)
1385 constraint.Visit(visitor)
1387 visitor.DepartIndexConstraint(self)
1388 visitor.DepartConstrainedArraySubtypeSymbol(self)
1391@export
1392class ConstrainedRecordSubtypeSymbol(ConstrainedCompositeSubtypeSymbol, RecordConstraint):
1393 """
1394 Represents a reference to a record subtype with constrained elements.
1396 The referenced language entity is available as :data:`Reference` once resolved.
1397 """
1398 _constraints: dict[RecordElementSymbol, Any] #: Dictionary of the constraint per constrained record element.
1400 def __init__(self, name: Name, constraints: Mapping) -> None:
1401 """
1402 Initializes a reference to a record subtype with constrained elements.
1404 :param name: The name to reference the language entity.
1405 :param constraints: Dictionary of the constraint per constrained record element.
1406 """
1407 super().__init__(name)
1408 RecordConstraint.__init__(self, constraints)
1410 def Copy(self) -> Self:
1411 """
1412 Create a copy of this constrained record subtype symbol.
1414 The name, the record elements and their constraints are copied; the reference, if resolved, is the same.
1416 :returns: The new constrained record subtype symbol.
1417 """
1418 constraints = {
1419 element.Copy(): None if constraint is None else constraint.Copy()
1420 for element, constraint in self._constraints.items()
1421 }
1422 copy = self.__class__(self._name.Copy(), constraints)
1423 copy._reference = self._reference
1424 return copy
1426 def Visit(self, visitor: Visitor) -> None:
1427 """
1428 Walk this constrained record subtype symbol, its name and its record constraint with a visitor.
1430 Each record element constraint is walked as the element's name followed by an index constraint.
1432 :param visitor: The visitor receiving the events.
1433 """
1434 visitor.VisitConstrainedRecordSubtypeSymbol(self)
1435 self._name.Visit(visitor)
1436 visitor.VisitRecordConstraint(self)
1437 for index, (element, constraint) in enumerate(self._constraints.items()):
1438 if index > 0:
1439 visitor.VisitComma(self)
1441 element.Visit(visitor)
1442 visitor.VisitIndexConstraint(self)
1443 constraint.Visit(visitor)
1444 visitor.DepartIndexConstraint(self)
1446 visitor.DepartRecordConstraint(self)
1447 visitor.DepartConstrainedRecordSubtypeSymbol(self)
1450@export
1451class SimpleObjectOrFunctionCallSymbol(Symbol):
1452 """
1453 Represents a reference that is either an object or a parameterless function call.
1455 Which of the two it is cannot be decided before the name is resolved. The referenced language
1456 entity is available as :data:`Reference` once resolved.
1457 """
1458 def __init__(self, name: Name) -> None:
1459 """
1460 Initializes a reference that is either an object or a parameterless function call.
1462 :param name: The name to reference the language entity.
1463 """
1464 super().__init__(name, PossibleReference.SimpleNameInExpression)
1466 def Copy(self) -> Self:
1467 """
1468 Create a copy of this simple object or function call symbol.
1470 The name is copied; the reference, if resolved, is the same.
1472 :returns: The new simple object or function call symbol.
1473 """
1474 copy = self.__class__(self._name.Copy())
1475 copy._reference = self._reference
1476 return copy
1479@export
1480class IndexedObjectOrFunctionCallSymbol(Symbol):
1481 """
1482 Represents a reference that is either an indexed object, a function call or a type conversion.
1484 The referenced language entity is available as :data:`Reference` once resolved.
1486 .. attention::
1488 All three are written the same way - ``arr(0)``, ``f(0)`` and ``integer(0)`` are indistinguishable
1489 as syntax, so a parser produces one shape for them and only name resolution tells them apart.
1491 .. seealso::
1493 * :class:`Type conversion <pyVHDLModel.Expression.TypeConversion>`
1494 * :class:`Simple object or function call <pyVHDLModel.Symbol.SimpleObjectOrFunctionCallSymbol>`
1495 """
1496 def __init__(self, name: Name) -> None:
1497 """
1498 Initializes a reference that is either an indexed object, a function call or a type conversion.
1500 :param name: The name to reference the language entity.
1501 """
1502 super().__init__(
1503 name,
1504 PossibleReference.Object | PossibleReference.Function | PossibleReference.Type | PossibleReference.Subtype
1505 )
1507 def Copy(self) -> Self:
1508 """
1509 Create a copy of this indexed object or function call symbol.
1511 The name is copied; the reference, if resolved, is the same.
1513 :returns: The new indexed object or function call symbol.
1514 """
1515 copy = self.__class__(self._name.Copy())
1516 copy._reference = self._reference
1517 return copy