Coverage for pyVHDLModel/Namespace.py: 37%

84 statements  

« prev     ^ index     » next       coverage.py v7.6.7, created at 2024-11-22 22:15 +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. 

34 

35A helper class to implement namespaces and scopes. 

36""" 

37from typing import TypeVar, Generic, Dict, Optional as Nullable 

38 

39from pyTooling.Decorators import readonly 

40 

41from pyVHDLModel.Object import Obj, Signal, Constant, Variable 

42from pyVHDLModel.Symbol import ComponentInstantiationSymbol, Symbol, PossibleReference 

43from pyVHDLModel.Type import Subtype, FullType, BaseType 

44 

45K = TypeVar("K") 

46O = TypeVar("O") 

47 

48 

49class Namespace(Generic[K, O]): 

50 _name: str 

51 _parentNamespace: 'Namespace' 

52 _subNamespaces: Dict[str, 'Namespace'] 

53 _elements: Dict[K, O] 

54 

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 = {} 

60 

61 @readonly 

62 def Name(self) -> str: 

63 return self._name 

64 

65 @readonly 

66 def ParentNamespace(self) -> 'Namespace': 

67 return self._parentNamespace 

68 

69 @ParentNamespace.setter 

70 def ParentNamespace(self, value: 'Namespace'): 

71 self._parentNamespace = value 

72 value._subNamespaces[self._name] = self 

73 

74 @readonly 

75 def SubNamespaces(self) -> Dict[str, 'Namespace']: 

76 return self._subNamespaces 

77 

78 def Elements(self) -> Dict[K, O]: 

79 return self._elements 

80 

81 def FindComponent(self, componentSymbol: ComponentInstantiationSymbol) -> 'Component': 

82 from pyVHDLModel.DesignUnit import Component 

83 

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}'.") 

94 

95 return parentNamespace.FindComponent(componentSymbol) 

96 

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}'.") 

116 

117 return parentNamespace.FindSubtype(subtypeSymbol) 

118 

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}'.") 

145 

146 return parentNamespace.FindObject(objectSymbol)