Coverage for pyVHDLModel/Namespace.py: 37%
84 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-10 23:46 +0000
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-10 23:46 +0000
1# ==================================================================================================================== #
2# __ ___ _ ____ _ __ __ _ _ #
3# _ __ _ \ \ / / | | | _ \| | | \/ | ___ __| | ___| | #
4# | '_ \| | | \ \ / /| |_| | | | | | | |\/| |/ _ \ / _` |/ _ \ | #
5# | |_) | |_| |\ V / | _ | |_| | |___| | | | (_) | (_| | __/ | #
6# | .__/ \__, | \_/ |_| |_|____/|_____|_| |_|\___/ \__,_|\___|_| #
7# |_| |___/ #
8# ==================================================================================================================== #
9# Authors: #
10# Patrick Lehmann #
11# #
12# License: #
13# ==================================================================================================================== #
14# Copyright 2017-2024 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.
35A helper class to implement namespaces and scopes.
36"""
37from typing import TypeVar, Generic, Dict, Optional as Nullable
39from pyTooling.Decorators import readonly
41from pyVHDLModel.Object import Obj, Signal, Constant, Variable
42from pyVHDLModel.Symbol import ComponentInstantiationSymbol, Symbol, PossibleReference
43from pyVHDLModel.Type import Subtype, FullType, BaseType
45K = TypeVar("K")
46O = TypeVar("O")
49class Namespace(Generic[K, O]):
50 _name: str
51 _parentNamespace: 'Namespace'
52 _subNamespaces: Dict[str, 'Namespace']
53 _elements: Dict[K, O]
55 def __init__(self, name: str, parentNamespace: Nullable["Namespace"] = None) -> None:
56 self._name = name
57 self._parentNamespace = parentNamespace
58 self._subNamespaces = {}
59 self._elements = {}
61 @readonly
62 def Name(self) -> str:
63 return self._name
65 @readonly
66 def ParentNamespace(self) -> 'Namespace':
67 return self._parentNamespace
69 @ParentNamespace.setter
70 def ParentNamespace(self, value: 'Namespace'):
71 self._parentNamespace = value
72 value._subNamespaces[self._name] = self
74 @readonly
75 def SubNamespaces(self) -> Dict[str, 'Namespace']:
76 return self._subNamespaces
78 def Elements(self) -> Dict[K, O]:
79 return self._elements
81 def FindComponent(self, componentSymbol: ComponentInstantiationSymbol) -> 'Component':
82 from pyVHDLModel.DesignUnit import Component
84 try:
85 element = self._elements[componentSymbol._name._normalizedIdentifier]
86 if isinstance(element, Component):
87 return element
88 else:
89 raise TypeError(f"Found element '{componentSymbol._name._identifier}', but it is not a component.")
90 except KeyError:
91 parentNamespace = self._parentNamespace
92 if parentNamespace is None:
93 raise KeyError(f"Component '{componentSymbol._name._identifier}' not found in '{self._name}'.")
95 return parentNamespace.FindComponent(componentSymbol)
97 def FindSubtype(self, subtypeSymbol: Symbol) -> BaseType:
98 try:
99 element = self._elements[subtypeSymbol._name._normalizedIdentifier]
100 if isinstance(element, Subtype):
101 if PossibleReference.Subtype in subtypeSymbol._possibleReferences: 101 ↛ 104line 101 didn't jump to line 104 because the condition on line 101 was always true
102 return element
103 else:
104 raise TypeError(f"Found subtype '{subtypeSymbol._name._identifier}', but it was not expected.")
105 elif isinstance(element, FullType): 105 ↛ 111line 105 didn't jump to line 111 because the condition on line 105 was always true
106 if PossibleReference.Type in subtypeSymbol._possibleReferences: 106 ↛ 109line 106 didn't jump to line 109 because the condition on line 106 was always true
107 return element
108 else:
109 raise TypeError(f"Found type '{subtypeSymbol._name._identifier}', but it was not expected.")
110 else:
111 raise TypeError(f"Found element '{subtypeSymbol._name._identifier}', but it is not a type or subtype.")
112 except KeyError:
113 parentNamespace = self._parentNamespace
114 if parentNamespace is None:
115 raise KeyError(f"Subtype '{subtypeSymbol._name._identifier}' not found in '{self._name}'.")
117 return parentNamespace.FindSubtype(subtypeSymbol)
119 def FindObject(self, objectSymbol: Symbol) -> Obj:
120 try:
121 element = self._elements[objectSymbol._name._normalizedIdentifier]
122 if isinstance(element, Signal):
123 if PossibleReference.Signal in objectSymbol._possibleReferences:
124 return element
125 elif PossibleReference.SignalAttribute in objectSymbol._possibleReferences:
126 return element
127 else:
128 raise TypeError(f"Found signal '{objectSymbol._name._identifier}', but it was not expected.")
129 elif isinstance(element, Constant):
130 if PossibleReference.Constant in objectSymbol._possibleReferences:
131 return element
132 else:
133 raise TypeError(f"Found constant '{objectSymbol._name._identifier}', but it was not expected.")
134 elif isinstance(element, Variable):
135 if PossibleReference.Variable in objectSymbol._possibleReferences:
136 return element
137 else:
138 raise TypeError(f"Found variable '{objectSymbol._name._identifier}', but it was not expected.")
139 else:
140 raise TypeError(f"Found element '{objectSymbol._name._identifier}', but it is not a type or subtype.")
141 except KeyError:
142 parentNamespace = self._parentNamespace
143 if parentNamespace is None:
144 raise KeyError(f"Subtype '{objectSymbol._name._identifier}' not found in '{self._name}'.")
146 return parentNamespace.FindObject(objectSymbol)