Coverage for pyVHDLModel/Regions.py: 91%

216 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-08-29 03:29 +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 

35tbd. 

36""" 

37from typing import TYPE_CHECKING, List, Dict, Iterable, Optional as Nullable, Any 

38 

39from pyTooling.Decorators import export, readonly 

40from pyTooling.MetaClasses import ExtendedType 

41from pyTooling.Warning import WarningCollector 

42 

43from pyVHDLModel.Base import normalizedIdentifiersOf 

44from pyVHDLModel.Exception import NotImplementedWarning 

45from pyVHDLModel.Namespace import Namespace 

46from pyVHDLModel.Object import Constant, SharedVariable, File, Variable, Signal 

47if TYPE_CHECKING: 47 ↛ 48line 47 didn't jump to line 48 because the condition on line 47 was never true

48 from pyVHDLModel.Type import Subtype, FullType 

49 

50# `pyVHDLModel.Subprogram` imports this module (Subprogram is a sequential declaration region), so 

51# `Function`/`Procedure` are quoted in annotations and imported lazily where they're needed at runtime. 

52 

53 

54 

55@export 

56class DeclarationRegionMixin(metaclass=ExtendedType, mixin=True): 

57 """ 

58 A base-class for the concurrent and sequential declaration region mixins. 

59 

60 It carries what both regions share: adding interface items to the region's namespace, and the hook for 

61 declared items neither region handles itself. 

62 

63 An interface item shares the declarative region of the declarative part beside it - VHDL rejects 

64 ``port (g : in bit)`` beside ``generic (g : integer)``, ``signal x`` beside ``port (x : in bit)``, and a 

65 subprogram variable named like one of its parameters, all as "identifier already used for a 

66 declaration". So they belong in the region's *own* namespace, not a separate one. 

67 

68 Which of the three a region has is known statically by the class that declares them, so each derived 

69 class calls the ones it needs from its own :meth:`IndexDeclaredItems` before delegating upwards. 

70 Interface items are added to the namespace only - ``GenericItems``/``PortItems``/``ParameterItems`` 

71 already expose them as ordered lists, so no extra lookup table is needed. 

72 

73 .. seealso:: 

74 

75 * :class:`Concurrent declaration region mixin <pyVHDLModel.Regions.ConcurrentDeclarationRegionMixin>` 

76 * :class:`Sequential declaration region mixin <pyVHDLModel.Regions.SequentialDeclarationRegionMixin>` 

77 """ 

78 

79 def _IndexGenericItems(self) -> None: 

80 """Add this region's generics to its namespace.""" 

81 for item in self._genericItems: 

82 for normalizedIdentifier in normalizedIdentifiersOf(item): 

83 self._namespace.AddElement(normalizedIdentifier, item) 

84 

85 def _IndexPortItems(self) -> None: 

86 """Add this region's ports to its namespace.""" 

87 for item in self._portItems: 

88 for normalizedIdentifier in normalizedIdentifiersOf(item): 

89 self._namespace.AddElement(normalizedIdentifier, item) 

90 

91 def _IndexParameterItems(self) -> None: 

92 """Add this region's parameters to its namespace.""" 

93 for item in self._parameterItems: 

94 for normalizedIdentifier in normalizedIdentifiersOf(item): 

95 self._namespace.AddElement(normalizedIdentifier, item) 

96 

97 def _IndexOtherDeclaredItem(self, item) -> None: 

98 """Hook for declared items the region doesn't handle itself. Derived classes may override it.""" 

99 pass 

100 

101 

102@export 

103class ConcurrentDeclarationRegionMixin(DeclarationRegionMixin, mixin=True): 

104 # FIXME: define list prefix type e.g. via Union 

105 """ 

106 A mixin-class for concurrent declaration regions. 

107 

108 Entities, architectures, packages, blocks and generate bodies declare items concurrently. Beside 

109 the namespace, the region keeps a lookup table per kind of declared item (:data:`Types`, 

110 :data:`Signals`, :data:`Constants`, ...). 

111 

112 .. seealso:: 

113 

114 * :class:`Concurrent block statement <pyVHDLModel.Concurrent.ConcurrentBlockStatement>` 

115 * :class:`Generate branch <pyVHDLModel.Concurrent.GenerateBranch>` 

116 * :class:`Concurrent case <pyVHDLModel.Concurrent.ConcurrentCase>` 

117 * :class:`For generate statement <pyVHDLModel.Concurrent.ForGenerateStatement>` 

118 * :class:`Package <pyVHDLModel.DesignUnit.Package>` 

119 * :class:`Package body <pyVHDLModel.DesignUnit.PackageBody>` 

120 * :class:`Entity <pyVHDLModel.DesignUnit.Entity>` 

121 * :class:`Architecture <pyVHDLModel.DesignUnit.Architecture>` 

122 * :class:`Sequential declaration region <pyVHDLModel.Regions.SequentialDeclarationRegionMixin>` 

123 * :class:`Namespace <pyVHDLModel.Namespace.Namespace>` 

124 """ 

125 _declaredItems: List #: List of all declared items in this concurrent declaration region. 

126 

127 # _attributes: Dict[str, Attribute] 

128 # _aliases: Dict[str, Alias] 

129 _types: Dict[str, 'FullType'] #: Dictionary of all types declared in this concurrent declaration region. 

130 _subtypes: Dict[str, 'Subtype'] #: Dictionary of all subtypes declared in this concurrent declaration region. 

131 # _objects: Dict[str, Union[Constant, Variable, Signal]] 

132 _constants: Dict[str, Constant] #: Dictionary of all constants declared in this concurrent declaration region. 

133 _signals: Dict[str, Signal] #: Dictionary of all signals declared in this concurrent declaration region. 

134 _sharedVariables: Dict[str, SharedVariable] #: Dictionary of all shared variables declared in this concurrent declaration region. 

135 _files: Dict[str, File] #: Dictionary of all files declared in this concurrent declaration region. 

136 # _subprograms: Dict[str, List[Subprogram]] #: Dictionary of all subprograms declared in this concurrent declaration region. 

137 # FIXME: overloads are only collected into a list, not matched/resolved by signature. 

138 _functions: Dict[str, List['Function']] #: Dictionary of all functions declared in this concurrent declaration region, indexed by name; each entry is a list of overloads. 

139 _procedures: Dict[str, List['Procedure']] #: Dictionary of all procedures declared in this concurrent declaration region, indexed by name; each entry is a list of overloads. 

140 _components: Dict[str, Any] #: Dictionary of all components declared in this concurrent declaration region. 

141 

142 def __init__(self, declaredItems: Nullable[Iterable] = None) -> None: 

143 # TODO: extract to mixin 

144 """ 

145 Initializes a concurrent declaration region. 

146 

147 :param declaredItems: List of all declared items in this concurrent declaration region. 

148 """ 

149 self._declaredItems = [] # TODO: convert to dict 

150 if declaredItems is not None: 

151 for item in declaredItems: 

152 self._declaredItems.append(item) 

153 item.Parent = self 

154 

155 self._types = {} 

156 self._subtypes = {} 

157 # self._objects = {} 

158 self._constants = {} 

159 self._signals = {} 

160 self._sharedVariables = {} 

161 self._files = {} 

162 # self._subprograms = {} 

163 self._functions = {} 

164 self._procedures = {} 

165 self._components = {} 

166 

167 @readonly 

168 def DeclaredItems(self) -> List: 

169 """ 

170 Read-only property to access the declared items (:attr:`_declaredItems`). 

171 

172 :returns: List of declared items. 

173 """ 

174 return self._declaredItems 

175 

176 @readonly 

177 def Types(self) -> Dict[str, 'FullType']: 

178 """ 

179 Read-only property to access the types (:attr:`_types`). 

180 

181 :returns: Dictionary of types, indexed by normalized identifier. 

182 """ 

183 return self._types 

184 

185 @readonly 

186 def Subtypes(self) -> Dict[str, 'Subtype']: 

187 """ 

188 Read-only property to access the subtypes (:attr:`_subtypes`). 

189 

190 :returns: Dictionary of subtypes, indexed by normalized identifier. 

191 """ 

192 return self._subtypes 

193 

194 # @readonly 

195 # def Objects(self) -> Dict[str, Union[Constant, SharedVariable, Signal, File]]: 

196 # return self._objects 

197 

198 @readonly 

199 def Constants(self) -> Dict[str, Constant]: 

200 """ 

201 Read-only property to access the constants (:attr:`_constants`). 

202 

203 :returns: Dictionary of constants, indexed by normalized identifier. 

204 """ 

205 return self._constants 

206 

207 @readonly 

208 def Signals(self) -> Dict[str, Signal]: 

209 """ 

210 Read-only property to access the signals (:attr:`_signals`). 

211 

212 :returns: Dictionary of signals, indexed by normalized identifier. 

213 """ 

214 return self._signals 

215 

216 @readonly 

217 def SharedVariables(self) -> Dict[str, SharedVariable]: 

218 """ 

219 Read-only property to access the shared variables (:attr:`_sharedVariables`). 

220 

221 :returns: Dictionary of shared variables, indexed by normalized identifier. 

222 """ 

223 return self._sharedVariables 

224 

225 @readonly 

226 def Files(self) -> Dict[str, File]: 

227 """ 

228 Read-only property to access the files (:attr:`_files`). 

229 

230 :returns: Dictionary of files, indexed by normalized identifier. 

231 """ 

232 return self._files 

233 

234 # @readonly 

235 # def Subprograms(self) -> Dict[str, Subprogram]: 

236 # return self._subprograms 

237 

238 @readonly 

239 def Functions(self) -> Dict[str, List['Function']]: 

240 """ 

241 Read-only property to access the functions (:attr:`_functions`). 

242 

243 :returns: Dictionary of functions, indexed by normalized identifier; each entry is a list of overloads. 

244 """ 

245 return self._functions 

246 

247 @readonly 

248 def Procedures(self) -> Dict[str, List['Procedure']]: 

249 """ 

250 Read-only property to access the procedures (:attr:`_procedures`). 

251 

252 :returns: Dictionary of procedures, indexed by normalized identifier; each entry is a list of overloads. 

253 """ 

254 return self._procedures 

255 

256 @readonly 

257 def Components(self) -> Dict[str, Any]: 

258 """ 

259 Read-only property to access the components (:attr:`_components`). 

260 

261 :returns: Dictionary of components, indexed by normalized identifier. 

262 """ 

263 return self._components 

264 

265 def IndexDeclaredItems(self) -> None: 

266 """ 

267 Index declared items listed in the concurrent declaration region. 

268 

269 .. rubric:: Algorithm 

270 

271 1. Iterate all declared items: 

272 

273 * Every declared item is added to :attr:`_namespace`. 

274 * If the declared item is a :class:`~pyVHDLModel.Type.FullType`, then add an entry to :attr:`_types`. 

275 * If the declared item is a :class:`~pyVHDLModel.Type.Subtype`, then add an entry to :attr:`_subtypes`. 

276 * If the declared item is a :class:`~pyVHDLModel.Subprogram.Function`, then add an entry to :attr:`_functions`. 

277 * If the declared item is a :class:`~pyVHDLModel.Subprogram.Procedure`, then add an entry to :attr:`_procedures`. 

278 * If the declared item is a :class:`~pyVHDLModel.Object.Constant`, then add an entry to :attr:`_constants`. 

279 * If the declared item is a :class:`~pyVHDLModel.Object.Signal`, then add an entry to :attr:`_signals`. 

280 * If the declared item is a :class:`~pyVHDLModel.Object.Variable`, TODO. 

281 * If the declared item is a :class:`~pyVHDLModel.Object.SharedVariable`, then add an entry to :attr:`_sharedVariables`. 

282 * If the declared item is a :class:`~pyVHDLModel.Object.File`, then add an entry to :attr:`_files`. 

283 * If the declared item is neither of these types, call :meth:`_IndexOtherDeclaredItem`. |br| 

284 Derived classes may override this virtual function. 

285 

286 .. seealso:: 

287 

288 :meth:`pyVHDLModel.Design.IndexPackages` 

289 Iterate all packages in the design and index declared items. 

290 :meth:`pyVHDLModel.Library.IndexPackages` 

291 Iterate all packages in the library and index declared items. 

292 :meth:`pyVHDLModel.Library._IndexOtherDeclaredItem` 

293 Iterate all packages in the library and index declared items. 

294 """ 

295 from pyVHDLModel.DesignUnit import Component 

296 from pyVHDLModel.Subprogram import Function, Procedure 

297 from pyVHDLModel.Type import Subtype, FullType 

298 

299 for item in self._declaredItems: 

300 if isinstance(item, FullType): 

301 self._types[item._normalizedIdentifier] = item 

302 self._namespace.AddElement(item._normalizedIdentifier, item) 

303 elif isinstance(item, Subtype): 

304 self._subtypes[item._normalizedIdentifier] = item 

305 self._namespace.AddElement(item._normalizedIdentifier, item) 

306 elif isinstance(item, Function): 

307 # FIXME: overloads are only appended to a list, not matched/resolved by signature (no 

308 # real overload resolution yet). 

309 self._functions.setdefault(item._normalizedIdentifier, []).append(item) 

310 self._namespace.AddElement(item._normalizedIdentifier, item, overloadable=True) 

311 elif isinstance(item, Procedure): 

312 # FIXME: overloads are only appended to a list, not matched/resolved by signature (no 

313 # real overload resolution yet). 

314 self._procedures.setdefault(item._normalizedIdentifier, []).append(item) 

315 self._namespace.AddElement(item._normalizedIdentifier, item, overloadable=True) 

316 elif isinstance(item, Constant): 

317 for normalizedIdentifier in item._normalizedIdentifiers: 

318 self._constants[normalizedIdentifier] = item 

319 self._namespace.AddElement(normalizedIdentifier, item) 

320 # self._objects[normalizedIdentifier] = item 

321 elif isinstance(item, Signal): 

322 for normalizedIdentifier in item._normalizedIdentifiers: 

323 self._signals[normalizedIdentifier] = item 

324 self._namespace.AddElement(normalizedIdentifier, item) 

325 elif isinstance(item, Variable): 

326 # TODO: variables declared in a concurrent declaration region (e.g. shared variables outside a 

327 # protected type) are not yet indexed into a dedicated namespace/lookup table. 

328 identifiers = ", ".join(f"'{i}'" for i in item._identifiers) 

329 WarningCollector.Raise(NotImplementedWarning(f"IndexDeclaredItems: variable(s) {identifiers} are not yet indexed.")) 

330 elif isinstance(item, SharedVariable): 

331 for normalizedIdentifier in item._normalizedIdentifiers: 

332 self._sharedVariables[normalizedIdentifier] = item 

333 self._namespace.AddElement(normalizedIdentifier, item) 

334 elif isinstance(item, File): 

335 for normalizedIdentifier in item._normalizedIdentifiers: 

336 self._files[normalizedIdentifier] = item 

337 self._namespace.AddElement(normalizedIdentifier, item) 

338 elif isinstance(item, Component): 

339 self._components[item._normalizedIdentifier] = item 

340 self._namespace.AddElement(item._normalizedIdentifier, item) 

341 else: 

342 self._IndexOtherDeclaredItem(item) 

343 

344 

345@export 

346class SequentialDeclarationRegionMixin(DeclarationRegionMixin, mixin=True): 

347 """ 

348 A mixin-class for sequential declaration regions: process statements and subprogram bodies. 

349 

350 .. note:: 

351 

352 VHDL's ``process_declarative_item`` and ``subprogram_declarative_item`` rules are identical, so both 

353 regions share this implementation. Compared to a concurrent region 

354 (:class:`ConcurrentDeclarationRegionMixin`, ``block_declarative_item``), a sequential region can 

355 declare a **variable**, but no signal, shared variable, component or mode view, and none of the 

356 specifications. 

357 

358 .. seealso:: 

359 

360 * :class:`Process statement <pyVHDLModel.Concurrent.ProcessStatement>` 

361 * :class:`Subprogram <pyVHDLModel.Subprogram.Subprogram>` 

362 * :class:`Concurrent declaration region <pyVHDLModel.Regions.ConcurrentDeclarationRegionMixin>` 

363 * :class:`Namespace <pyVHDLModel.Namespace.Namespace>` 

364 """ 

365 

366 _declaredItems: List #: List of all declared items in this sequential declaration region. 

367 _namespace: Namespace #: The namespace of this sequential declaration region. 

368 

369 _types: Dict[str, 'FullType'] #: Dictionary of all types declared in this sequential declaration region. 

370 _subtypes: Dict[str, 'Subtype'] #: Dictionary of all subtypes declared in this sequential declaration region. 

371 _constants: Dict[str, Constant] #: Dictionary of all constants declared in this sequential declaration region. 

372 _variables: Dict[str, Variable] #: Dictionary of all variables declared in this sequential declaration region. 

373 _files: Dict[str, File] #: Dictionary of all files declared in this sequential declaration region. 

374 # FIXME: overloads are only collected into a list, not matched/resolved by signature. 

375 _functions: Dict[str, List['Function']] #: Dictionary of all functions declared in this sequential declaration region, indexed by name; each entry is a list of overloads. 

376 _procedures: Dict[str, List['Procedure']] #: Dictionary of all procedures declared in this sequential declaration region, indexed by name; each entry is a list of overloads. 

377 

378 def __init__(self, namespaceName: Nullable[str] = None, declaredItems: Nullable[Iterable] = None) -> None: 

379 """ 

380 Initialize a sequential declaration region. 

381 

382 :param namespaceName: Name of this region's namespace, usually the host's label or identifier. 

383 :param declaredItems: The items declared in this region. 

384 """ 

385 self._namespace = Namespace(namespaceName) 

386 

387 self._declaredItems = [] # TODO: convert to dict 

388 if declaredItems is not None: 

389 for item in declaredItems: 

390 self._declaredItems.append(item) 

391 item.Parent = self 

392 

393 self._types = {} 

394 self._subtypes = {} 

395 self._constants = {} 

396 self._variables = {} 

397 self._files = {} 

398 self._functions = {} 

399 self._procedures = {} 

400 

401 @readonly 

402 def DeclaredItems(self) -> List: 

403 """ 

404 Read-only property to access the declared items (:attr:`_declaredItems`). 

405 

406 :returns: List of declared items. 

407 """ 

408 return self._declaredItems 

409 

410 @readonly 

411 def Namespace(self) -> Namespace: 

412 """ 

413 Read-only property to access this region's namespace (:attr:`_namespace`). 

414 

415 :returns: The namespace. 

416 """ 

417 return self._namespace 

418 

419 @readonly 

420 def Types(self) -> Dict[str, 'FullType']: 

421 """ 

422 Read-only property to access the declared types (:attr:`_types`). 

423 

424 :returns: Dictionary of types, indexed by normalized identifier. 

425 """ 

426 return self._types 

427 

428 @readonly 

429 def Subtypes(self) -> Dict[str, 'Subtype']: 

430 """ 

431 Read-only property to access the declared subtypes (:attr:`_subtypes`). 

432 

433 :returns: Dictionary of subtypes, indexed by normalized identifier. 

434 """ 

435 return self._subtypes 

436 

437 @readonly 

438 def Constants(self) -> Dict[str, Constant]: 

439 """ 

440 Read-only property to access the declared constants (:attr:`_constants`). 

441 

442 :returns: Dictionary of constants, indexed by normalized identifier. 

443 """ 

444 return self._constants 

445 

446 @readonly 

447 def Variables(self) -> Dict[str, Variable]: 

448 """ 

449 Read-only property to access the declared variables (:attr:`_variables`). 

450 

451 :returns: Dictionary of variables, indexed by normalized identifier. 

452 """ 

453 return self._variables 

454 

455 @readonly 

456 def Files(self) -> Dict[str, File]: 

457 """ 

458 Read-only property to access the declared files (:attr:`_files`). 

459 

460 :returns: Dictionary of files, indexed by normalized identifier. 

461 """ 

462 return self._files 

463 

464 @readonly 

465 def Functions(self) -> Dict[str, List['Function']]: 

466 """ 

467 Read-only property to access the declared functions (:attr:`_functions`). 

468 

469 :returns: Dictionary of functions, indexed by normalized identifier; each entry is a list of overloads. 

470 """ 

471 return self._functions 

472 

473 @readonly 

474 def Procedures(self) -> Dict[str, List['Procedure']]: 

475 """ 

476 Read-only property to access the declared procedures (:attr:`_procedures`). 

477 

478 :returns: Dictionary of procedures, indexed by normalized identifier; each entry is a list of overloads. 

479 """ 

480 return self._procedures 

481 

482 def IndexDeclaredItems(self) -> None: 

483 """ 

484 Index declared items listed in the sequential declaration region. 

485 

486 Every declared item is added to :attr:`_namespace`, and additionally to the lookup table matching its 

487 kind. Items of an unhandled kind are passed to :meth:`_IndexOtherDeclaredItem`. 

488 

489 .. seealso:: 

490 

491 :meth:`ConcurrentDeclarationRegionMixin.IndexDeclaredItems` 

492 The same algorithm for a concurrent declaration region. 

493 """ 

494 from pyVHDLModel.Subprogram import Function, Procedure 

495 from pyVHDLModel.Type import Subtype, FullType 

496 

497 for item in self._declaredItems: 

498 if isinstance(item, FullType): 

499 self._types[item._normalizedIdentifier] = item 

500 self._namespace.AddElement(item._normalizedIdentifier, item) 

501 elif isinstance(item, Subtype): 501 ↛ 502line 501 didn't jump to line 502 because the condition on line 501 was never true

502 self._subtypes[item._normalizedIdentifier] = item 

503 self._namespace.AddElement(item._normalizedIdentifier, item) 

504 elif isinstance(item, Function): 504 ↛ 507line 504 didn't jump to line 507 because the condition on line 504 was never true

505 # FIXME: overloads are only appended to a list, not matched/resolved by signature (no 

506 # real overload resolution yet). 

507 self._functions.setdefault(item._normalizedIdentifier, []).append(item) 

508 self._namespace.AddElement(item._normalizedIdentifier, item, overloadable=True) 

509 elif isinstance(item, Procedure): 

510 # FIXME: overloads are only appended to a list, not matched/resolved by signature (no 

511 # real overload resolution yet). 

512 self._procedures.setdefault(item._normalizedIdentifier, []).append(item) 

513 self._namespace.AddElement(item._normalizedIdentifier, item, overloadable=True) 

514 elif isinstance(item, Constant): 

515 for normalizedIdentifier in item._normalizedIdentifiers: 

516 self._constants[normalizedIdentifier] = item 

517 self._namespace.AddElement(normalizedIdentifier, item) 

518 elif isinstance(item, Variable): 518 ↛ 522line 518 didn't jump to line 522 because the condition on line 518 was always true

519 for normalizedIdentifier in item._normalizedIdentifiers: 

520 self._variables[normalizedIdentifier] = item 

521 self._namespace.AddElement(normalizedIdentifier, item) 

522 elif isinstance(item, File): 

523 for normalizedIdentifier in item._normalizedIdentifiers: 

524 self._files[normalizedIdentifier] = item 

525 self._namespace.AddElement(normalizedIdentifier, item) 

526 else: 

527 self._IndexOtherDeclaredItem(item) 

528 

529 

530@export 

531class ProtectedTypeDeclarationRegionMixin(DeclarationRegionMixin, mixin=True): 

532 """ 

533 A mixin-class for the declarative region of a protected type declaration. 

534 

535 VHDL's ``protected_type_declarative_item`` rule admits subprogram declarations only, making this the 

536 narrowest declarative region in the language. A protected type *body* differs: its declarative part 

537 matches a subprogram's, so it uses :class:`SequentialDeclarationRegionMixin`. 

538 

539 .. seealso:: 

540 

541 * :class:`Protected type <pyVHDLModel.Type.ProtectedType>` 

542 * :class:`Protected type body <pyVHDLModel.Type.ProtectedTypeBody>` 

543 * :class:`Sequential declaration region <pyVHDLModel.Regions.SequentialDeclarationRegionMixin>` 

544 * :class:`Namespace <pyVHDLModel.Namespace.Namespace>` 

545 """ 

546 

547 _declaredItems: List #: List of all declared items in this protected type declaration. 

548 _namespace: Namespace #: The namespace of this protected type declaration. 

549 

550 # FIXME: overloads are only collected into a list, not matched/resolved by signature. 

551 _functions: Dict[str, List['Function']] #: All declared functions, indexed by name; each is a list of overloads. 

552 _procedures: Dict[str, List['Procedure']] #: All declared procedures by name; each is a list of overloads. 

553 

554 def __init__(self, namespaceName: Nullable[str] = None, declaredItems: Nullable[Iterable] = None) -> None: 

555 """ 

556 Initialize a protected type declaration region. 

557 

558 :param namespaceName: Name of this region's namespace, usually the protected type's identifier. 

559 :param declaredItems: The items declared in this region. 

560 """ 

561 self._namespace = Namespace(namespaceName) 

562 

563 self._declaredItems = [] # TODO: convert to dict 

564 if declaredItems is not None: 

565 for item in declaredItems: 

566 self._declaredItems.append(item) 

567 item.Parent = self 

568 

569 self._functions = {} 

570 self._procedures = {} 

571 

572 @readonly 

573 def DeclaredItems(self) -> List: 

574 """ 

575 Read-only property to access the declared items (:attr:`_declaredItems`). 

576 

577 :returns: List of all declared items. 

578 """ 

579 return self._declaredItems 

580 

581 @readonly 

582 def Functions(self) -> Dict[str, List['Function']]: 

583 """ 

584 Read-only property to access the declared functions (:attr:`_functions`). 

585 

586 :returns: Dictionary of all functions, indexed by name; each entry is a list of overloads. 

587 """ 

588 return self._functions 

589 

590 @readonly 

591 def Procedures(self) -> Dict[str, List['Procedure']]: 

592 """ 

593 Read-only property to access the declared procedures (:attr:`_procedures`). 

594 

595 :returns: Dictionary of all procedures, indexed by name; each entry is a list of overloads. 

596 """ 

597 return self._procedures 

598 

599 def IndexDeclaredItems(self) -> None: 

600 """ 

601 Index declared items listed in the protected type declaration. 

602 

603 Only subprogram declarations are legal here, so anything else is passed to 

604 :meth:`_IndexOtherDeclaredItem`. 

605 

606 .. seealso:: 

607 

608 :meth:`SequentialDeclarationRegionMixin.IndexDeclaredItems` 

609 The same algorithm for the protected type's body. 

610 """ 

611 from pyVHDLModel.Subprogram import Function, Procedure 

612 from pyVHDLModel.Type import Subtype, FullType 

613 

614 for item in self._declaredItems: 

615 if isinstance(item, Function): 615 ↛ 618line 615 didn't jump to line 618 because the condition on line 615 was never true

616 # FIXME: overloads are only appended to a list, not matched/resolved by signature (no 

617 # real overload resolution yet). 

618 self._functions.setdefault(item._normalizedIdentifier, []).append(item) 

619 self._namespace.AddElement(item._normalizedIdentifier, item, overloadable=True) 

620 elif isinstance(item, Procedure): 620 ↛ 626line 620 didn't jump to line 626 because the condition on line 620 was always true

621 # FIXME: overloads are only appended to a list, not matched/resolved by signature (no 

622 # real overload resolution yet). 

623 self._procedures.setdefault(item._normalizedIdentifier, []).append(item) 

624 self._namespace.AddElement(item._normalizedIdentifier, item, overloadable=True) 

625 else: 

626 self._IndexOtherDeclaredItem(item)