Coverage for pyVHDLModel/Declaration.py: 73%

91 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-09-11 23:50 +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. 

34 

35 

36""" 

37from enum import unique, Enum 

38from typing import List, Iterable, Union, Optional as Nullable 

39 

40from pyTooling.Decorators import export, readonly 

41 

42from pyVHDLModel.Base import ModelEntity, NamedEntityMixin, DocumentedEntityMixin 

43from pyVHDLModel.Expression import BaseExpression, QualifiedExpression, FunctionCall, TypeConversion, Literal 

44from pyVHDLModel.Name import Name 

45from pyVHDLModel.Symbol import Symbol, SubtypeSymbol 

46 

47 

48 

49ExpressionUnion = Union[ 

50 BaseExpression, 

51 QualifiedExpression, 

52 FunctionCall, 

53 TypeConversion, 

54 # ConstantOrSymbol, TODO: ObjectSymbol 

55 Literal, 

56] 

57 

58 

59@export 

60@unique 

61class EntityClass(Enum): 

62 """An ``EntityClass`` is an enumeration. It represents a VHDL language entity class (``entity``, ``label``, ...).""" 

63 

64 Entity = 0 #: Entity 

65 Architecture = 1 #: Architecture 

66 Configuration = 2 #: Configuration 

67 Procedure = 3 #: Procedure 

68 Function = 4 #: Function 

69 Package = 5 #: Package 

70 Type = 6 #: Type 

71 Subtype = 7 #: Subtype 

72 Constant = 8 #: Constant 

73 Signal = 9 #: Signal 

74 Variable = 10 #: Variable 

75 Component = 11 #: Component 

76 Label = 12 #: Label 

77 Literal = 13 #: Literal 

78 Units = 14 #: Units 

79 Group = 15 #: Group 

80 File = 16 #: File 

81 Property = 17 #: Property 

82 Sequence = 18 #: Sequence 

83 View = 19 #: View 

84 Others = 20 #: Others 

85 

86 

87@export 

88class Attribute(ModelEntity, NamedEntityMixin, DocumentedEntityMixin): 

89 """ 

90 Represents an attribute declaration. 

91 

92 .. admonition:: Example 

93 

94 .. code-block:: VHDL 

95 

96 attribute TotalBits : natural; 

97 """ 

98 

99 _subtype: Symbol #: Reference to the attribute's subtype. 

100 

101 def __init__( 

102 self, 

103 identifier: str, 

104 subtype: Symbol, 

105 documentation: Nullable[str] = None, 

106 parent: Nullable[ModelEntity] = None 

107 ) -> None: 

108 """ 

109 Initializes an attribute declaration. 

110 

111 :param identifier: The identifier of a model entity. 

112 :param subtype: Reference to the attribute's subtype. 

113 :param documentation: The documentation comment associated with this declaration. 

114 :param parent: The parent model entity of this entity. 

115 """ 

116 super().__init__(parent) 

117 NamedEntityMixin.__init__(self, identifier) 

118 DocumentedEntityMixin.__init__(self, documentation) 

119 

120 self._subtype = subtype 

121 subtype.Parent = self 

122 

123 @readonly 

124 def Subtype(self) -> None: 

125 """ 

126 Read-only property to access the subtype (:attr:`_subtype`). 

127 

128 :returns: The subtype. 

129 """ 

130 return self._subtype 

131 

132 def __str__(self) -> str: 

133 """ 

134 Formats the attribute declaration. 

135 

136 **Format:** ``attribute myAttribute: bit`` 

137 

138 :returns: Formatted attribute declaration. 

139 """ 

140 return f"attribute {self._identifier}: {self._subtype}" 

141 

142 

143@export 

144class AttributeSpecification(ModelEntity, DocumentedEntityMixin): 

145 """ 

146 Represents an attribute specification. 

147 

148 .. admonition:: Example 

149 

150 .. code-block:: VHDL 

151 

152 attribute TotalBits of BusType : subtype is 32; 

153 """ 

154 

155 _identifiers: List[Name] #: List of all names the attribute is specified for. 

156 _attribute: Name #: Reference to the specified attribute. 

157 _entityClass: EntityClass #: The entity class the named items belong to. 

158 _expression: ExpressionUnion #: The value assigned to the attribute. 

159 

160 def __init__( 

161 self, 

162 identifiers: Iterable[Name], 

163 attribute: Name, 

164 entityClass: EntityClass, 

165 expression: ExpressionUnion, 

166 documentation: Nullable[str] = None, 

167 parent: Nullable[ModelEntity] = None 

168 ) -> None: 

169 """ 

170 Initializes an attribute specification. 

171 

172 :param identifiers: List of all names the attribute is specified for. 

173 :param attribute: Reference to the specified attribute. 

174 :param entityClass: The entity class the named items belong to. 

175 :param expression: The value assigned to the attribute. 

176 :param documentation: The documentation comment associated with this declaration. 

177 :param parent: The parent model entity of this entity. 

178 """ 

179 super().__init__(parent) 

180 DocumentedEntityMixin.__init__(self, documentation) 

181 

182 self._identifiers = [] # TODO: convert to dict 

183 for identifier in identifiers: 

184 self._identifiers.append(identifier) 

185 identifier.Parent = self 

186 

187 self._attribute = attribute 

188 attribute.Parent = self 

189 

190 self._entityClass = entityClass 

191 

192 self._expression = expression 

193 expression.Parent = self 

194 

195 @readonly 

196 def Identifiers(self) -> List[Name]: 

197 """ 

198 Read-only property to access the identifiers (:attr:`_identifiers`). 

199 

200 :returns: List of identifiers. 

201 """ 

202 return self._identifiers 

203 

204 @readonly 

205 def Attribute(self) -> Name: 

206 """ 

207 Read-only property to access the attribute (:attr:`_attribute`). 

208 

209 :returns: The attribute. 

210 """ 

211 return self._attribute 

212 

213 @readonly 

214 def EntityClass(self) -> EntityClass: 

215 """ 

216 Read-only property to access the entity class (:attr:`_entityClass`). 

217 

218 :returns: The entity class. 

219 """ 

220 return self._entityClass 

221 

222 @readonly 

223 def Expression(self) -> ExpressionUnion: 

224 """ 

225 Read-only property to access the expression (:attr:`_expression`). 

226 

227 :returns: The expression. 

228 """ 

229 return self._expression 

230 

231 

232# TODO: move somewhere else 

233@export 

234class Alias(ModelEntity, NamedEntityMixin, DocumentedEntityMixin): 

235 """ 

236 Represents an alias declaration. 

237 

238 :attr:`Name` is a :class:`~pyVHDLModel.Symbol.Symbol` - like every other cross-reference in this 

239 model - rather than a bare :class:`~pyVHDLModel.Name.Name`, so it participates in the usual 

240 resolve-later mechanism (:attr:`~pyVHDLModel.Symbol.Symbol.Reference` / 

241 :attr:`~pyVHDLModel.Symbol.Symbol.IsResolved`). Unlike ``PackageReferenceSymbol`` and similar, 

242 there is no single fixed :class:`~pyVHDLModel.Symbol.PossibleReference` value that always fits: an 

243 alias without a subtype indication can refer to almost anything nameable (an object, a type, a 

244 subprogram, a literal, ...), while an alias *with* a subtype indication can - per the LRM - only 

245 ever refer to an object (a constant, variable, signal, or file); the ``possibleReferences`` passed 

246 to the ``Symbol`` should reflect whichever case applies. 

247 

248 .. admonition:: Example 

249 

250 .. code-block:: VHDL 

251 

252 alias a : bit_vector(3 downto 0) is s(3 downto 0); 

253 -- ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ 

254 -- optional Subtype Name 

255 

256 alias b is s; 

257 -- ^ 

258 -- Name 

259 """ 

260 

261 _name: Symbol #: Reference to the name being aliased. 

262 _subtype: Nullable[SubtypeSymbol] #: Reference to the alias' subtype, or ``None`` if none was given. 

263 

264 def __init__( 

265 self, 

266 identifier: str, 

267 name: Symbol, 

268 subtype: Nullable[SubtypeSymbol] = None, 

269 documentation: Nullable[str] = None, 

270 parent: Nullable[ModelEntity] = None 

271 ) -> None: 

272 """ 

273 Initializes an alias declaration. 

274 

275 :param identifier: The identifier of a model entity. 

276 :param name: Reference to the name being aliased. 

277 :param subtype: Reference to the alias' subtype, or ``None`` if none was given. 

278 :param documentation: The documentation comment associated with this declaration. 

279 :param parent: The parent model entity of this entity. 

280 """ 

281 super().__init__(parent) 

282 NamedEntityMixin.__init__(self, identifier) 

283 DocumentedEntityMixin.__init__(self, documentation) 

284 

285 self._name = name 

286 name.Parent = self 

287 

288 self._subtype = subtype 

289 if subtype is not None: 

290 subtype.Parent = self 

291 

292 @readonly 

293 def Name(self) -> Symbol: 

294 """ 

295 Read-only property to access the name (:attr:`_name`). 

296 

297 :returns: The name. 

298 """ 

299 return self._name 

300 

301 @readonly 

302 def Subtype(self) -> Nullable[SubtypeSymbol]: 

303 """ 

304 Read-only property to access the subtype (:attr:`_subtype`). 

305 

306 :returns: The subtype, or ``None`` if not set. 

307 """ 

308 return self._subtype 

309 

310 def __str__(self) -> str: 

311 """ 

312 Formats the alias declaration. 

313 

314 **Format:** ``alias myAlias : bit is target``, or without the subtype when none was given 

315 

316 :returns: Formatted alias declaration. 

317 """ 

318 subtype = f" : {self._subtype}" if self._subtype is not None else "" 

319 return f"alias {self._identifier}{subtype} is {self._name}"