Coverage for pyVHDLModel/Predefined.py: 97%
51 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-22 19:31 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-22 19:31 +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"""This module contains base-classes for predefined library and package declarations."""
33from typing import Iterable, Optional as Nullable
35from pyTooling.Common import getTypeName
36from pyTooling.Decorators import export
37from pyTooling.MetaClasses import ExtendedType, abstractclass
39from pyVHDLModel import Library, Package, PackageBody, AllPackageMembersReferenceSymbol, PackageMemberReferenceSymbol
40from pyVHDLModel.Name import SimpleName, SelectedName, AllName
41from pyVHDLModel.Symbol import LibraryReferenceSymbol, PackageSymbol
42from pyVHDLModel.DesignUnit import LibraryClause, UseClause
45@export
46@abstractclass
47class PredefinedLibrary(Library):
48 """
49 A base-class for predefined VHDL libraries.
51 VHDL defines 2 predefined libraries:
53 * :class:`~pyVHDLModel.STD.Std`
54 * :class:`~pyVHDLModel.IEEE.Ieee`
56 .. seealso::
58 * :class:`Ieee <pyVHDLModel.IEEE.Ieee>`
59 * :class:`Std <pyVHDLModel.STD.Std>`
60 """
62 def __init__(self, packages, documentation: Nullable[str] = None) -> None:
63 """
64 Initializes a predefined library.
66 :param packages: Dictionary of all packages defined in a library.
67 :param documentation: Documentation of this library, if the caller has one to supply. VHDL defines
68 none for a predefined library, so it is empty unless supplied from outside.
69 """
70 super().__init__(getTypeName(self), documentation)
72 self.AddPackages(packages)
74 def AddPackages(self, packages) -> None:
75 for packageType, packageBodyType in packages:
76 package: Package = packageType()
77 package.Library = self
78 self._packages[package.NormalizedIdentifier] = package
80 if packageBodyType is not None:
81 packageBody: PackageBody = packageBodyType()
82 packageBody.Library = self
83 self._packageBodies[packageBody.NormalizedIdentifier] = packageBody
86@export
87class PredefinedPackageMixin(
88 metaclass=ExtendedType,
89 mixin=True,
90 expects=("AddContextItem",)
91):
92 """
93 A mixin-class for predefined VHDL packages and package bodies.
95 The host class provides ``AddContextItem(contextItem)``, called to add a library clause or a use clause.
97 .. seealso::
99 * :class:`Predefined package <pyVHDLModel.Predefined.PredefinedPackage>`
100 * :class:`Predefined package body <pyVHDLModel.Predefined.PredefinedPackageBody>`
101 """
103 def _AddLibraryClause(self, libraries: Iterable[str]) -> None:
104 symbols = [LibraryReferenceSymbol(SimpleName(libName)) for libName in libraries]
105 libraryClause = LibraryClause(symbols)
107 self.AddContextItem(libraryClause)
109 def _AddPackageClause(self, packages: Iterable[str]) -> None:
110 symbols = []
111 for qualifiedPackageName in packages:
112 libName, packName, members = qualifiedPackageName.split(".")
114 packageName = SelectedName(packName, SimpleName(libName))
115 if members.lower() == "all": 115 ↛ 118line 115 didn't jump to line 118 because the condition on line 115 was always true
116 symbols.append(AllPackageMembersReferenceSymbol(AllName(packageName)))
117 else:
118 symbols.append(PackageMemberReferenceSymbol(SelectedName(members, packageName)))
120 useClause = UseClause(symbols)
121 self.AddContextItem(useClause)
124@export
125@abstractclass
126class PredefinedPackage(Package, PredefinedPackageMixin):
127 """
128 A base-class for predefined VHDL packages.
129 """
131 def __init__(self, identifier: Nullable[str] = None) -> None:
132 """
133 Initializes a predefined package.
135 By default the VHDL package name is the Python class name. Pass ``identifier`` when the two must
136 differ - e.g. when two vendor flavors of the same VHDL package need distinct Python classes.
138 :param identifier: The VHDL package name, or ``None`` to use the class name.
139 """
140 super().__init__(getTypeName(self) if identifier is None else identifier)
143@export
144@abstractclass
145class PredefinedPackageBody(PackageBody, PredefinedPackageMixin):
146 """
147 A base-class for predefined VHDL package bodies.
148 """
150 def __init__(self, packageIdentifier: Nullable[str] = None) -> None:
151 """
152 Initializes a predefined package body.
154 By default the VHDL package name is the Python class name with the trailing ``_Body`` removed.
155 Pass ``packageIdentifier`` when the two must differ.
157 :param packageIdentifier: The VHDL name of the package this body implements, or ``None`` to derive
158 it from the class name.
159 """
160 identifier = getTypeName(self)[:-5] if packageIdentifier is None else packageIdentifier
161 packageSymbol = PackageSymbol(SimpleName(identifier))
162 super().__init__(packageSymbol)