Coverage for pyVHDLModel/__init__.py: 76%

1110 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-07 22:12 +0000

1# ==================================================================================================================== # 

2# __ ___ _ ____ _ __ __ _ _ # 

3# _ __ _ \ \ / / | | | _ \| | | \/ | ___ __| | ___| | # 

4# | '_ \| | | \ \ / /| |_| | | | | | | |\/| |/ _ \ / _` |/ _ \ | # 

5# | |_) | |_| |\ V / | _ | |_| | |___| | | | (_) | (_| | __/ | # 

6# | .__/ \__, | \_/ |_| |_|____/|_____|_| |_|\___/ \__,_|\___|_| # 

7# |_| |___/ # 

8# ==================================================================================================================== # 

9# Authors: # 

10# Patrick Lehmann # 

11# # 

12# License: # 

13# ==================================================================================================================== # 

14# Copyright 2017-2025 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""" 

33**An abstract VHDL language model.** 

34 

35This package provides a unified abstract language model for VHDL. Projects reading from source files can derive own 

36classes and implement additional logic to create a concrete language model for their tools. 

37 

38Projects consuming pre-processed VHDL data (parsed, analyzed or elaborated) can build higher level features and services 

39on such a model, while supporting multiple frontends. 

40 

41.. admonition:: Copyright Information 

42 

43 :copyright: Copyright 2017-2025 Patrick Lehmann - Bötzingen, Germany 

44 :copyright: Copyright 2016-2017 Patrick Lehmann - Dresden, Germany 

45 :license: Apache License, Version 2.0 

46""" 

47__author__ = "Patrick Lehmann" 

48__email__ = "Paebbels@gmail.com" 

49__copyright__ = "2016-2025, Patrick Lehmann" 

50__license__ = "Apache License, Version 2.0" 

51__version__ = "0.31.0" 

52 

53 

54from enum import unique, Enum, Flag, auto 

55from pathlib import Path 

56from sys import version_info 

57 

58from typing import Union, Dict, cast, List, Generator, Optional as Nullable 

59 

60from pyTooling.Common import getFullyQualifiedName 

61from pyTooling.Decorators import export, readonly 

62from pyTooling.Graph import Graph, Vertex, Edge 

63 

64from pyVHDLModel.Exception import VHDLModelException 

65from pyVHDLModel.Exception import LibraryExistsInDesignError, LibraryRegisteredToForeignDesignError, LibraryNotRegisteredError, EntityExistsInLibraryError 

66from pyVHDLModel.Exception import ArchitectureExistsInLibraryError, PackageExistsInLibraryError, PackageBodyExistsError, ConfigurationExistsInLibraryError 

67from pyVHDLModel.Exception import ContextExistsInLibraryError, ReferencedLibraryNotExistingError 

68from pyVHDLModel.Base import ModelEntity, NamedEntityMixin, MultipleNamedEntityMixin, DocumentedEntityMixin 

69from pyVHDLModel.Expression import UnaryExpression, BinaryExpression, TernaryExpression 

70from pyVHDLModel.Namespace import Namespace 

71from pyVHDLModel.Object import Obj, Signal, Constant, DeferredConstant 

72from pyVHDLModel.Symbol import PackageReferenceSymbol, AllPackageMembersReferenceSymbol, PackageMemberReferenceSymbol, SimpleObjectOrFunctionCallSymbol 

73from pyVHDLModel.Concurrent import EntityInstantiation, ComponentInstantiation, ConfigurationInstantiation 

74from pyVHDLModel.DesignUnit import DesignUnit, PrimaryUnit, Architecture, PackageBody, Context, Entity, Configuration, Package 

75from pyVHDLModel.PSLModel import VerificationUnit, VerificationProperty, VerificationMode 

76from pyVHDLModel.Instantiation import PackageInstantiation 

77from pyVHDLModel.Type import IntegerType, PhysicalType, ArrayType, RecordType 

78 

79 

80@export 

81@unique 

82class VHDLVersion(Enum): 

83 """ 

84 An enumeration for all possible version numbers for VHDL and VHDL-AMS. 

85 

86 A version can be given as integer or string and is represented as a unified 

87 enumeration value. 

88 

89 This enumeration supports compare operators. 

90 """ 

91 

92 Any = -1 #: Any 

93 VHDL87 = 87 #: VHDL-1987 

94 VHDL93 = 93 #: VHDL-1993 

95 AMS93 = 1993 #: VHDL-AMS-1993 

96 AMS99 = 1999 #: VHDL-AMS-1999 

97 VHDL2000 = 2000 #: VHDL-2000 

98 VHDL2002 = 2002 #: VHDL-2002 

99 VHDL2008 = 2008 #: VHDL-2008 

100 AMS2017 = 2017 #: VHDL-AMS-2017 

101 VHDL2019 = 2019 #: VHDL-2019 

102 Latest = 10000 #: Latest VHDL (2019) 

103 

104 __VERSION_MAPPINGS__: Dict[Union[int, str], Enum] = { 

105 -1: Any, 

106 87: VHDL87, 

107 93: VHDL93, 

108 # 93: AMS93, 

109 99: AMS99, 

110 0: VHDL2000, 

111 2: VHDL2002, 

112 8: VHDL2008, 

113 17: AMS2017, 

114 19: VHDL2019, 

115 1987: VHDL87, 

116 # 1993: VHDL93, 

117 1993: AMS93, 

118 1999: AMS99, 

119 2000: VHDL2000, 

120 2002: VHDL2002, 

121 2008: VHDL2008, 

122 2017: AMS2017, 

123 2019: VHDL2019, 

124 10000: Latest, 

125 "Any": Any, 

126 "87": VHDL87, 

127 "93": VHDL93, 

128 # "93": AMS93, 

129 "99": AMS99, 

130 "00": VHDL2000, 

131 "02": VHDL2002, 

132 "08": VHDL2008, 

133 "17": AMS2017, 

134 "19": VHDL2019, 

135 "1987": VHDL87, 

136 # "1993": VHDL93, 

137 "1993": AMS93, 

138 "1999": AMS99, 

139 "2000": VHDL2000, 

140 "2002": VHDL2002, 

141 "2008": VHDL2008, 

142 "2017": AMS2017, 

143 "2019": VHDL2019, 

144 "Latest": Latest, 

145 } #: Dictionary of VHDL and VHDL-AMS year codes variants as integer and strings for mapping to unique enum values. 

146 

147 def __init__(self, *_) -> None: 

148 """Patch the embedded MAP dictionary""" 

149 for k, v in self.__class__.__VERSION_MAPPINGS__.items(): 

150 if (not isinstance(v, self.__class__)) and (v == self.value): 

151 self.__class__.__VERSION_MAPPINGS__[k] = self 

152 

153 @classmethod 

154 def Parse(cls, value: Union[int, str]) -> "VHDLVersion": 

155 """ 

156 Parses a VHDL or VHDL-AMS year code as integer or string to an enum value. 

157 

158 :param value: VHDL/VHDL-AMS year code. 

159 :returns: Enumeration value. 

160 :raises ValueError: If the year code is not recognized. 

161 """ 

162 try: 

163 return cls.__VERSION_MAPPINGS__[value] 

164 except KeyError: 

165 raise ValueError(f"Value '{value!s}' cannot be parsed to member of {cls.__name__}.") 

166 

167 def __lt__(self, other: Any) -> bool: 

168 """ 

169 Compare two VHDL/VHDL-AMS versions if the version is less than the second operand. 

170 

171 :param other: Parameter to compare against. 

172 :returns: True if version is less than the second operand. 

173 :raises TypeError: If parameter ``other`` is not of type :class:`VHDLVersion`. 

174 """ 

175 if isinstance(other, VHDLVersion): 

176 return self.value < other.value 

177 else: 

178 raise TypeError("Second operand is not of type 'VHDLVersion'.") 

179 

180 def __le__(self, other: Any) -> bool: 

181 """ 

182 Compare two VHDL/VHDL-AMS versions if the version is less or equal than the second operand. 

183 

184 :param other: Parameter to compare against. 

185 :returns: True if version is less or equal than the second operand. 

186 :raises TypeError: If parameter ``other`` is not of type :class:`VHDLVersion`. 

187 """ 

188 if isinstance(other, VHDLVersion): 

189 return self.value <= other.value 

190 else: 

191 raise TypeError("Second operand is not of type 'VHDLVersion'.") 

192 

193 def __gt__(self, other: Any) -> bool: 

194 """ 

195 Compare two VHDL/VHDL-AMS versions if the version is greater than the second operand. 

196 

197 :param other: Parameter to compare against. 

198 :returns: True if version is greater than the second operand. 

199 :raises TypeError: If parameter ``other`` is not of type :class:`VHDLVersion`. 

200 """ 

201 if isinstance(other, VHDLVersion): 

202 return self.value > other.value 

203 else: 

204 raise TypeError("Second operand is not of type 'VHDLVersion'.") 

205 

206 def __ge__(self, other: Any) -> bool: 

207 """ 

208 Compare two VHDL/VHDL-AMS versions if the version is greater or equal than the second operand. 

209 

210 :param other: Parameter to compare against. 

211 :returns: True if version is greater or equal than the second operand. 

212 :raises TypeError: If parameter ``other`` is not of type :class:`VHDLVersion`. 

213 """ 

214 if isinstance(other, VHDLVersion): 

215 return self.value >= other.value 

216 else: 

217 raise TypeError("Second operand is not of type 'VHDLVersion'.") 

218 

219 def __ne__(self, other: Any) -> bool: 

220 """ 

221 Compare two VHDL/VHDL-AMS versions if the version is unequal to the second operand. 

222 

223 :param other: Parameter to compare against. 

224 :returns: True if version is unequal to the second operand. 

225 :raises TypeError: If parameter ``other`` is not of type :class:`VHDLVersion`. 

226 """ 

227 if isinstance(other, VHDLVersion): 

228 return self.value != other.value 

229 else: 

230 raise TypeError("Second operand is not of type 'VHDLVersion'.") 

231 

232 def __eq__(self, other: Any) -> bool: 

233 """ 

234 Compare two VHDL/VHDL-AMS versions if the version is equal to the second operand. 

235 

236 :param other: Parameter to compare against. 

237 :returns: True if version is equal to the second operand. 

238 :raises TypeError: If parameter ``other`` is not of type :class:`VHDLVersion`. 

239 """ 

240 if isinstance(other, VHDLVersion): 

241 if (self is self.__class__.Any) or (other is self.__class__.Any): 

242 return True 

243 else: 

244 return self.value == other.value 

245 else: 

246 raise TypeError("Second operand is not of type 'VHDLVersion'.") 

247 

248 @readonly 

249 def IsVHDL(self) -> bool: 

250 """ 

251 Checks if the version is a VHDL (not VHDL-AMS) version. 

252 

253 :returns: True if version is a VHDL version. 

254 """ 

255 return self in (self.VHDL87, self.VHDL93, self.VHDL2002, self.VHDL2008, self.VHDL2019) 

256 

257 @readonly 

258 def IsAMS(self) -> bool: 

259 """ 

260 Checks if the version is a VHDL-AMS (not VHDL) version. 

261 

262 :returns: True if version is a VHDL-AMS version. 

263 """ 

264 return self in (self.AMS93, self.AMS99, self.AMS2017) 

265 

266 def __str__(self) -> str: 

267 """ 

268 Formats the VHDL version to pattern ``VHDL'xx`` or in case of VHDL-AMS to ``VHDL-AMS'xx``. 

269 

270 :return: Formatted VHDL/VHDL-AMS version. 

271 """ 

272 if self.value == self.Any.value: 

273 return "VHDL'Any" 

274 elif self.value == self.Latest.value: 

275 return "VHDL'Latest" 

276 

277 year = str(self.value)[-2:] 

278 if self.IsVHDL: 

279 return f"VHDL'{year}" 

280 else: 

281 return f"VHDL-AMS'{year}" 

282 

283 def __repr__(self) -> str: 

284 """ 

285 Formats the VHDL/VHDL-AMS version to pattern ``xxxx``. 

286 

287 :return: Formatted VHDL/VHDL-AMS version. 

288 """ 

289 if self.value == self.Any.value: 

290 return "Any" 

291 elif self.value == self.Latest.value: 

292 return "Latest" 

293 else: 

294 return str(self.value) 

295 

296 

297@export 

298class IEEEFlavor(Enum): 

299 IEEE = 0 

300 Synopsys = 1 

301 MentorGraphics = 2 

302 

303 

304@export 

305@unique 

306class ObjectClass(Enum): 

307 """ 

308 An ``ObjectClass`` is an enumeration and represents an object's class (``constant``, ``signal``, ...). 

309 

310 In case no *object class* is defined, ``Default`` is used, so the *object class* is inferred from context. 

311 """ 

312 

313 Default = 0 #: Object class not defined, thus it's context dependent. 

314 Constant = 1 #: Constant 

315 Variable = 2 #: Variable 

316 Signal = 3 #: Signal 

317 File = 4 #: File 

318 Type = 5 #: Type 

319 # FIXME: Package? 

320 Procedure = 6 #: Procedure 

321 Function = 7 #: Function 

322 

323 def __str__(self) -> str: 

324 """ 

325 Formats the object class. 

326 

327 :return: Formatted object class. 

328 """ 

329 return ("", "constant", "variable", "signal", "file", "type", "procedure", "function")[cast(int, self.value)] # TODO: check performance 

330 

331 

332@export 

333@unique 

334class DesignUnitKind(Flag): 

335 """ 

336 A ``DesignUnitKind`` is an enumeration and represents the kind of design unit (``Entity``, ``Architecture``, ...). 

337 

338 """ 

339 Context = auto() #: Context 

340 Package = auto() #: Package 

341 PackageBody = auto() #: Package Body 

342 Entity = auto() #: Entity 

343 Architecture = auto() #: Architecture 

344 Configuration = auto() #: Configuration 

345 

346 Primary = Context | Configuration | Entity | Package #: List of primary design units. 

347 Secondary = PackageBody | Architecture #: List of secondary design units. 

348 WithContext = Configuration | Package | Entity | PackageBody | Architecture #: List of design units with a context. 

349 WithDeclaredItems = Package | Entity | PackageBody | Architecture #: List of design units having a declaration region. 

350 

351 All = Primary | Secondary #: List of all design units. 

352 

353 

354@export 

355@unique 

356class DependencyGraphVertexKind(Flag): 

357 """ 

358 A ``DependencyGraphVertexKind`` is an enumeration and represents the kind of vertex in the dependency graph. 

359 """ 

360 Document = auto() #: A document (VHDL source file). 

361 Library = auto() #: A VHDL library. 

362 

363 Context = auto() #: A context design unit. 

364 Package = auto() #: A package design unit. 

365 PackageBody = auto() #: A package body design unit. 

366 Entity = auto() #: A entity design unit. 

367 Architecture = auto() #: A architecture design unit. 

368 Component = auto() #: A VHDL component. 

369 Configuration = auto() #: A configuration design unit. 

370 

371 

372@export 

373@unique 

374class DependencyGraphEdgeKind(Flag): 

375 """ 

376 A ``DependencyGraphEdgeKind`` is an enumeration and represents the kind of edge in the dependency graph. 

377 """ 

378 Document = auto() 

379 Library = auto() 

380 Context = auto() 

381 Package = auto() 

382 Entity = auto() 

383 # Architecture = auto() 

384 Configuration = auto() 

385 Component = auto() 

386 

387 DeclaredIn = auto() 

388 Order = auto() 

389 Reference = auto() 

390 Implementation = auto() 

391 Instantiation = auto() 

392 

393 SourceFile = Document | DeclaredIn 

394 CompileOrder = Document | Order 

395 

396 LibraryClause = Library | Reference 

397 UseClause = Package | Reference 

398 ContextReference = Context | Reference 

399 

400 EntityImplementation = Entity | Implementation 

401 PackageImplementation = Package | Implementation 

402 

403 EntityInstantiation = Entity | Instantiation 

404 ComponentInstantiation = Component | Instantiation 

405 ConfigurationInstantiation = Configuration | Instantiation 

406 

407 

408@export 

409@unique 

410class ObjectGraphVertexKind(Flag): 

411 """ 

412 A ``ObjectGraphVertexKind`` is an enumeration and represents the kind of vertex in the object graph. 

413 """ 

414 Type = auto() 

415 Subtype = auto() 

416 

417 Constant = auto() 

418 DeferredConstant = auto() 

419 Variable = auto() 

420 Signal = auto() 

421 File = auto() 

422 

423 Alias = auto() 

424 

425 

426@export 

427@unique 

428class ObjectGraphEdgeKind(Flag): 

429 """ 

430 A ``ObjectGraphEdgeKind`` is an enumeration and represents the kind of edge in the object graph. 

431 """ 

432 BaseType = auto() 

433 Subtype = auto() 

434 

435 ReferenceInExpression = auto() 

436 

437 

438@export 

439class Design(ModelEntity): 

440 """ 

441 A ``Design`` represents set of VHDL libraries as well as all loaded and analysed source files (see :class:`~pyVHDLModel.Document`). 

442 

443 It's the root of this code document-object-model (CodeDOM). It contains at least one VHDL library (see :class:`~pyVHDLModel.Library`). When the design is 

444 analysed (see :meth:`Analyze`), multiple graph data structures will be created and populated with vertices and edges. As a first result, the design's compile 

445 order and hierarchy can be iterated. As a second result, the design's *top-level* is identified and referenced from the design (see :attr:`TopLevel`). 

446 

447 The *design* contains references to the following graphs: 

448 

449 * :attr:`DependencyGraph` 

450 * :attr:`CompileOrderGraph` 

451 * :attr:`HierarchyGraph` 

452 * :attr:`ObjectGraph` 

453 """ 

454 _name: Nullable[str] #: Name of the design. 

455 _allowBlackbox: bool #: Allow blackboxes after linking the design. 

456 _libraries: Dict[str, 'Library'] #: List of all libraries defined for a design. 

457 _documents: List['Document'] #: List of all documents loaded for a design. 

458 _dependencyGraph: Graph[None, None, None, None, None, None, None, None, str, DesignUnit, None, None, None, None, None, None, None, None, None, None, None, None, None] #: The graph of all dependencies in the designs. 

459 _compileOrderGraph: Graph[None, None, None, None, None, None, None, None, None, 'Document', None, None, None, None, None, None, None, None, None, None, None, None, None] #: A graph derived from dependency graph containing the order of documents for compilation. 

460 _hierarchyGraph: Graph[None, None, None, None, None, None, None, None, str, DesignUnit, None, None, None, None, None, None, None, None, None, None, None, None, None] #: A graph derived from dependency graph containing the design hierarchy. 

461 _objectGraph: Graph[None, None, None, None, None, None, None, None, str, Obj, None, None, None, None, None, None, None, None, None, None, None, None, None] #: The graph of all types and objects in the design. 

462 _toplevel: Union[Entity, Configuration] #: When computed, the toplevel design unit is cached in this field. 

463 

464 def __init__( 

465 self, 

466 name: Nullable[str] = None, 

467 allowBlackbox: bool = False 

468 ) -> None: 

469 """ 

470 Initialize a VHDL design. 

471 

472 :param allowBlackbox: Specify if blackboxes are allowed in this design. 

473 :param name: Name of the design. 

474 """ 

475 super().__init__() 

476 

477 self._name = name 

478 self._allowBlackbox = allowBlackbox 

479 

480 self._libraries = {} 

481 self._documents = [] 

482 

483 self._compileOrderGraph = Graph() 

484 self._dependencyGraph = Graph() 

485 self._hierarchyGraph = Graph() 

486 self._objectGraph = Graph() 

487 self._toplevel = None 

488 

489 @readonly 

490 def Name(self) -> Nullable[str]: 

491 """ 

492 Read-only property to access the design's name (:attr:`_name`). 

493 

494 :returns: The name of the design. 

495 """ 

496 return self._name 

497 

498 @property 

499 def AllowBlackbox(self) -> bool: 

500 """ 

501 Read-only property to check if a design supports blackboxes (:attr:`_allowBlackbox`). 

502 

503 :returns: If blackboxes are allowed. 

504 """ 

505 return self._allowBlackbox 

506 

507 @AllowBlackbox.setter 

508 def AllowBlackbox(self, value: Nullable[bool]) -> None: 

509 if value is None: 

510 raise ValueError(f"Property 'AllowBlackbox' doesn't accept value 'None'.") 

511 

512 self._allowBlackbox = value 

513 

514 @readonly 

515 def Libraries(self) -> Dict[str, 'Library']: 

516 """ 

517 Read-only property to access the dictionary of library names and VHDL libraries (:attr:`_libraries`). 

518 

519 :returns: A dictionary of library names and VHDL libraries. 

520 """ 

521 return self._libraries 

522 

523 @readonly 

524 def Documents(self) -> List['Document']: 

525 """ 

526 Read-only property to access the list of all documents (VHDL source files) loaded for this design (:attr:`_documents`). 

527 

528 :returns: A list of all documents. 

529 """ 

530 return self._documents 

531 

532 @readonly 

533 def CompileOrderGraph(self) -> Graph: 

534 """ 

535 Read-only property to access the compile-order graph (:attr:`_compileOrderGraph`). 

536 

537 :returns: Reference to the compile-order graph. 

538 """ 

539 return self._compileOrderGraph 

540 

541 @readonly 

542 def DependencyGraph(self) -> Graph: 

543 """ 

544 Read-only property to access the dependency graph (:attr:`_dependencyGraph`). 

545 

546 :returns: Reference to the dependency graph. 

547 """ 

548 return self._dependencyGraph 

549 

550 @readonly 

551 def HierarchyGraph(self) -> Graph: 

552 """ 

553 Read-only property to access the hierarchy graph (:attr:`_hierarchyGraph`). 

554 

555 :returns: Reference to the hierarchy graph. 

556 """ 

557 return self._hierarchyGraph 

558 

559 @readonly 

560 def ObjectGraph(self) -> Graph: 

561 """ 

562 Read-only property to access the object graph (:attr:`_objectGraph`). 

563 

564 :returns: Reference to the object graph. 

565 """ 

566 return self._objectGraph 

567 

568 @readonly 

569 def TopLevel(self) -> Union[Entity, Configuration]: 

570 """ 

571 Read-only property to access the design's *top-level* (:attr:`_toplevel`). 

572 

573 When called the first time, the hierarchy graph is checked for its root elements. When there is only one root element in the graph, a new field ``toplevel`` 

574 is added to :attr:`_hierarchyGraph` referencing that single element. In addition, the result is cached in :attr:`_toplevel`. 

575 

576 :returns: Reference to the design's *top-level*. 

577 :raises VHDLModelException: If the hierarchy graph is not yet computed from dependency graph. 

578 :raises VHDLModelException: If there is more than one *top-level*. 

579 """ 

580 # Check for cached result 

581 if self._toplevel is not None: 

582 return self._toplevel 

583 

584 if self._hierarchyGraph.EdgeCount == 0: 

585 raise VHDLModelException(f"Hierarchy is not yet computed from dependency graph.") 

586 

587 roots = tuple(self._hierarchyGraph.IterateRoots()) 

588 if len(roots) == 1: 

589 toplevel = roots[0] 

590 self._hierarchyGraph["toplevel"] = toplevel 

591 self._toplevel = toplevel.Value 

592 

593 return toplevel.Value 

594 else: 

595 raise VHDLModelException(f"Found more than one toplevel: {', '.join(roots)}") 

596 

597 def LoadStdLibrary(self) -> 'Library': 

598 """ 

599 Load the predefined VHDL library ``std`` into the design. 

600 

601 This will create a virtual source code file ``std.vhdl`` and register VHDL design units of library ``std`` to that file. 

602 

603 :returns: The library object of library ``std``. 

604 """ 

605 from pyVHDLModel.STD import Std 

606 

607 doc = Document(Path("std.vhdl"), parent=self) 

608 

609 library = Std() 

610 for designUnit in library.IterateDesignUnits(): 

611 doc._AddDesignUnit(designUnit) 

612 

613 self.AddLibrary(library) 

614 

615 return library 

616 

617 def LoadIEEELibrary(self, flavor: Nullable[IEEEFlavor] = None) -> 'Library': 

618 """ 

619 Load the predefined VHDL library ``ieee`` into the design. 

620 

621 This will create a virtual source code file ``ieee.vhdl`` and register VHDL design units of library ``ieee`` to that file. 

622 

623 :param flavor: Select the IEEE library flavor: IEEE, Synopsys, MentorGraphics. 

624 :returns: The library object of library ``ieee``. 

625 """ 

626 from pyVHDLModel.IEEE import Ieee 

627 

628 doc = Document(Path("ieee.vhdl"), parent=self) 

629 

630 library = Ieee(flavor) 

631 for designUnit in library.IterateDesignUnits(): 

632 doc._AddDesignUnit(designUnit) 

633 

634 self.AddLibrary(library) 

635 

636 return library 

637 

638 def AddLibrary(self, library: 'Library') -> None: 

639 """ 

640 Add a VHDL library to the design. 

641 

642 Ensure the libraries name doesn't collide with existing libraries in the design. |br| 

643 If ok, set the libraries parent reference to the design. 

644 

645 :param library: Library object to loaded. 

646 :raises LibraryExistsInDesignError: If the library already exists in the design. 

647 :raises LibraryRegisteredToForeignDesignError: If library is already used by a different design. 

648 """ 

649 libraryIdentifier = library.NormalizedIdentifier 

650 if libraryIdentifier in self._libraries: 

651 raise LibraryExistsInDesignError(library) 

652 

653 if library._parent is not None: 

654 raise LibraryRegisteredToForeignDesignError(library) 

655 

656 self._libraries[libraryIdentifier] = library 

657 library._parent = self 

658 

659 def GetLibrary(self, libraryName: str) -> 'Library': 

660 """ 

661 Return an (existing) VHDL library object of name ``libraryName``. 

662 

663 If the requested VHDL library doesn't exist, a new VHDL library with that name will be created. 

664 

665 :param libraryName: Name of the requested VHDL library. 

666 :returns: The VHDL library object. 

667 """ 

668 libraryIdentifier = libraryName.lower() 

669 try: 

670 return self._libraries[libraryIdentifier] 

671 except KeyError: 

672 lib = Library(libraryName, parent=self) 

673 self._libraries[libraryIdentifier] = lib 

674 lib._parent = self 

675 return lib 

676 

677 # TODO: allow overloaded parameter library to be str? 

678 def AddDocument(self, document: 'Document', library: 'Library') -> None: 

679 """ 

680 Add a document (VHDL source file) to the design and register all embedded design units to the given VHDL library. 

681 

682 .. rubric:: Algorithm 

683 

684 1. Iterate all entities in the document 

685 

686 1. Check if entity name might exist in target library. 

687 2. Add entity to library and update library membership. 

688 

689 2. Iterate all architectures in the document 

690 

691 1. Check if architecture name might exist in target library. 

692 2. Add architecture to library and update library membership. 

693 

694 3. Iterate all packages in the document 

695 

696 1. Check if package name might exist in target library. 

697 2. Add package to library and update library membership. 

698 

699 4. Iterate all package bodies in the document 

700 

701 1. Check if package body name might exist in target library. 

702 2. Add package body to library and update library membership. 

703 

704 5. Iterate all configurations in the document 

705 

706 1. Check if configuration name might exist in target library. 

707 2. Add configuration to library and update library membership. 

708 

709 6. Iterate all contexts in the document 

710 

711 1. Check if context name might exist in target library. 

712 2. Add context to library and update library membership. 

713 

714 :param document: The VHDL source code file. 

715 :param library: The VHDL library used to register the embedded design units to. 

716 :raises LibraryNotRegisteredError: If the given VHDL library is not a library in the design. 

717 :raises EntityExistsInLibraryError: If the processed entity's name is already existing in the VHDL library. 

718 :raises ArchitectureExistsInLibraryError: If the processed architecture's name is already existing in the VHDL library. 

719 :raises PackageExistsInLibraryError: If the processed package's name is already existing in the VHDL library. 

720 :raises PackageBodyExistsError: If the processed package body's name is already existing in the VHDL library. 

721 :raises ConfigurationExistsInLibraryError: If the processed configuration's name is already existing in the VHDL library. 

722 :raises ContextExistsInLibraryError: If the processed context's name is already existing in the VHDL library. 

723 """ 

724 # FIXME: this checks for the library name, but not the object 

725 # should the libraries parent be checked too? 

726 if library._normalizedIdentifier not in self._libraries: 726 ↛ 727line 726 didn't jump to line 727 because the condition on line 726 was never true

727 raise LibraryNotRegisteredError(library) 

728 

729 self._documents.append(document) 

730 document._parent = self 

731 

732 for entityIdentifier, entity in document._entities.items(): 

733 if entityIdentifier in library._entities: 733 ↛ 734line 733 didn't jump to line 734 because the condition on line 733 was never true

734 raise EntityExistsInLibraryError(entity, library) 

735 

736 library._entities[entityIdentifier] = entity 

737 entity.Library = library 

738 

739 for entityIdentifier, architectures in document._architectures.items(): 

740 try: 

741 architecturesPerEntity = library._architectures[entityIdentifier] 

742 for architectureIdentifier, architecture in architectures.items(): 

743 if architectureIdentifier in architecturesPerEntity: 

744 raise ArchitectureExistsInLibraryError(architecture, library._entities[entityIdentifier], library) 

745 

746 architecturesPerEntity[architectureIdentifier] = architecture 

747 architecture.Library = library 

748 except KeyError: 

749 architecturesPerEntity = document._architectures[entityIdentifier].copy() 

750 library._architectures[entityIdentifier] = architecturesPerEntity 

751 

752 for architecture in architecturesPerEntity.values(): 

753 architecture.Library = library 

754 

755 for packageIdentifier, package in document._packages.items(): 

756 if packageIdentifier in library._packages: 756 ↛ 757line 756 didn't jump to line 757 because the condition on line 756 was never true

757 raise PackageExistsInLibraryError(package, library) 

758 

759 library._packages[packageIdentifier] = package 

760 package.Library = library 

761 

762 for packageBodyIdentifier, packageBody in document._packageBodies.items(): 

763 if packageBodyIdentifier in library._packageBodies: 763 ↛ 764line 763 didn't jump to line 764 because the condition on line 763 was never true

764 raise PackageBodyExistsError(packageBody, library) 

765 

766 library._packageBodies[packageBodyIdentifier] = packageBody 

767 packageBody.Library = library 

768 

769 for configurationIdentifier, configuration in document._configurations.items(): 

770 if configurationIdentifier in library._configurations: 770 ↛ 771line 770 didn't jump to line 771 because the condition on line 770 was never true

771 raise ConfigurationExistsInLibraryError(configuration, library) 

772 

773 library._configurations[configurationIdentifier] = configuration 

774 configuration.Library = library 

775 

776 for contextIdentifier, context in document._contexts.items(): 

777 if contextIdentifier in library._contexts: 777 ↛ 778line 777 didn't jump to line 778 because the condition on line 777 was never true

778 raise ContextExistsInLibraryError(context, library) 

779 

780 library._contexts[contextIdentifier] = context 

781 context.Library = library 

782 

783 def IterateDesignUnits(self, filter: DesignUnitKind = DesignUnitKind.All) -> Generator[DesignUnit, None, None]: 

784 """ 

785 Iterate all design units in the design. 

786 

787 A union of :class:`DesignUnitKind` values can be given to filter the returned result for suitable design units. 

788 

789 .. rubric:: Algorithm 

790 

791 1. Iterate all VHDL libraries. 

792 

793 1. Iterate all contexts in that library. 

794 2. Iterate all packages in that library. 

795 3. Iterate all package bodies in that library. 

796 4. Iterate all entites in that library. 

797 5. Iterate all architectures in that library. 

798 6. Iterate all configurations in that library. 

799 

800 :param filter: An enumeration with possibly multiple flags to filter the returned design units. 

801 :returns: A generator to iterate all matched design units in the design. 

802 

803 .. seealso:: 

804 

805 :meth:`pyVHDLModel.Library.IterateDesignUnits` 

806 Iterate all design units in the library. 

807 :meth:`pyVHDLModel.Document.IterateDesignUnits` 

808 Iterate all design units in the document. 

809 """ 

810 for library in self._libraries.values(): 

811 yield from library.IterateDesignUnits(filter) 

812 

813 def Analyze(self) -> None: 

814 """ 

815 Analyze the whole design. 

816 

817 .. rubric:: Algorithm 

818 

819 1. Analyze dependencies of design units. |br| 

820 This will also yield the design hierarchy and the compiler order. 

821 2. Analyze dependencies of types and objects. 

822 

823 .. seealso:: 

824 

825 :meth:`AnalyzeDependencies` 

826 Analyze the dependencies of design units. 

827 

828 :meth:`AnalyzeObjects` 

829 Analyze the dependencies of types and objects. 

830 """ 

831 self.AnalyzeDependencies() 

832 self.AnalyzeObjects() 

833 

834 def AnalyzeDependencies(self) -> None: 

835 """ 

836 Analyze the dependencies of design units. 

837 

838 .. rubric:: Algorithm 

839 

840 1. Create all vertices of the dependency graph by iterating all design units in all libraries. |br| 

841 |rarr| :meth:`CreateDependencyGraph` 

842 2. Create the compile order graph. |br| 

843 |rarr| :meth:`CreateCompileOrderGraph` 

844 3. Index all packages. |br| 

845 |rarr| :meth:`IndexPackages` 

846 4. Index all architectures. |br| 

847 |rarr| :meth:`IndexArchitectures` 

848 5. Link all contexts |br| 

849 |rarr| :meth:`LinkContexts` 

850 6. Link all architectures. |br| 

851 |rarr| :meth:`LinkArchitectures` 

852 7. Link all package bodies. |br| 

853 |rarr| :meth:`LinkPackageBodies` 

854 8. Link all library references. |br| 

855 |rarr| :meth:`LinkLibraryReferences` 

856 9. Link all package references. |br| 

857 |rarr| :meth:`LinkPackageReferences` 

858 10. Link all context references. |br| 

859 |rarr| :meth:`LinkContextReferences` 

860 11. Link all components. |br| 

861 |rarr| :meth:`LinkComponents` 

862 12. Link all instantiations. |br| 

863 |rarr| :meth:`LinkInstantiations` 

864 13. Create the hierarchy graph. |br| 

865 |rarr| :meth:`CreateHierarchyGraph` 

866 14. Compute the compile order. |br| 

867 |rarr| :meth:`ComputeCompileOrder` 

868 """ 

869 self.CreateDependencyGraph() 

870 self.CreateCompileOrderGraph() 

871 

872 self.IndexPackages() 

873 self.IndexArchitectures() 

874 

875 self.LinkContexts() 

876 self.LinkArchitectures() 

877 self.LinkPackageBodies() 

878 self.LinkLibraryReferences() 

879 self.LinkPackageReferences() 

880 self.LinkContextReferences() 

881 

882 self.LinkComponents() 

883 self.LinkInstantiations() 

884 self.CreateHierarchyGraph() 

885 self.ComputeCompileOrder() 

886 

887 def AnalyzeObjects(self) -> None: 

888 """ 

889 Analyze the dependencies of types and objects. 

890 

891 .. rubric:: Algorithm 

892 

893 1. Index all entities. |br| 

894 |rarr| :meth:`IndexEntities` 

895 2. Index all package bodies. |br| 

896 |rarr| :meth:`IndexPackageBodies` 

897 3. Import objects. |br| 

898 |rarr| :meth:`ImportObjects` 

899 4. Create the type and object graph. |br| 

900 |rarr| :meth:`CreateTypeAndObjectGraph` 

901 """ 

902 self.IndexEntities() 

903 self.IndexPackageBodies() 

904 

905 self.ImportObjects() 

906 self.CreateTypeAndObjectGraph() 

907 

908 def CreateDependencyGraph(self) -> None: 

909 """ 

910 Create all vertices of the dependency graph by iterating all design units in all libraries. 

911 

912 This method will purely create a sea of vertices without any linking between vertices. The edges will be created later by other methods. |br| 

913 See :meth:`AnalyzeDependencies` for these methods and their algorithmic order. 

914 

915 Each vertex has the following properties: 

916 

917 * The vertex' ID is the design unit's identifier. 

918 * The vertex' value references the design unit. 

919 * A key-value-pair called ``kind`` denotes the vertex's kind as an enumeration value of type :class:`DependencyGraphVertexKind`. 

920 * A key-value-pair called ``predefined`` denotes if the referenced design unit is a predefined language entity. 

921 

922 .. rubric:: Algorithm 

923 

924 1. Iterate all libraries in the design. 

925 

926 * Create a vertex for that library and reference the library by the vertex' value field. |br| 

927 In return, set the library's :attr:`~pyVHDLModel.Library._dependencyVertex` field to reference the created vertex. 

928 

929 1. Iterate all contexts in that library. 

930 

931 * Create a vertex for that context and reference the context by the vertex' value field. |br| 

932 In return, set the context's :attr:`~pyVHDLModel.DesignUnit.Context._dependencyVertex` field to reference the created vertex. 

933 

934 2. Iterate all packages in that library. 

935 

936 * Create a vertex for that package and reference the package by the vertex' value field. |br| 

937 In return, set the package's :attr:`~pyVHDLModel.DesignUnit.Package._dependencyVertex` field to reference the created vertex. 

938 

939 3. Iterate all package bodies in that library. 

940 

941 * Create a vertex for that package body and reference the package body by the vertex' value field. |br| 

942 In return, set the package body's :attr:`~pyVHDLModel.DesignUnit.PackageBody._dependencyVertex` field to reference the created vertex. 

943 

944 4. Iterate all entities in that library. 

945 

946 * Create a vertex for that entity and reference the entity by the vertex' value field. |br| 

947 In return, set the entity's :attr:`~pyVHDLModel.DesignUnit.Entity._dependencyVertex` field to reference the created vertex. 

948 

949 5. Iterate all architectures in that library. 

950 

951 * Create a vertex for that architecture and reference the architecture by the vertex' value field. |br| 

952 In return, set the architecture's :attr:`~pyVHDLModel.DesignUnit.Architecture._dependencyVertex` field to reference the created vertex. 

953 

954 6. Iterate all configurations in that library. 

955 

956 * Create a vertex for that configuration and reference the configuration by the vertex' value field. |br| 

957 In return, set the configuration's :attr:`~pyVHDLModel.DesignUnit.Configuration._dependencyVertex` field to reference the created vertex. 

958 """ 

959 predefinedLibraries = ("std", "ieee") 

960 

961 for libraryIdentifier, library in self._libraries.items(): 

962 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}", value=library, graph=self._dependencyGraph) 

963 dependencyVertex["kind"] = DependencyGraphVertexKind.Library 

964 dependencyVertex["predefined"] = libraryIdentifier in predefinedLibraries 

965 library._dependencyVertex = dependencyVertex 

966 

967 for contextIdentifier, context in library._contexts.items(): 

968 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}.{contextIdentifier}", value=context, graph=self._dependencyGraph) 

969 dependencyVertex["kind"] = DependencyGraphVertexKind.Context 

970 dependencyVertex["predefined"] = context._parent._normalizedIdentifier in predefinedLibraries 

971 context._dependencyVertex = dependencyVertex 

972 

973 for packageIdentifier, package in library._packages.items(): 

974 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}.{packageIdentifier}", value=package, graph=self._dependencyGraph) 

975 dependencyVertex["kind"] = DependencyGraphVertexKind.Package 

976 dependencyVertex["predefined"] = package._parent._normalizedIdentifier in predefinedLibraries 

977 package._dependencyVertex = dependencyVertex 

978 

979 for packageBodyIdentifier, packageBody in library._packageBodies.items(): 

980 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}.{packageBodyIdentifier}(body)", value=packageBody, graph=self._dependencyGraph) 

981 dependencyVertex["kind"] = DependencyGraphVertexKind.PackageBody 

982 dependencyVertex["predefined"] = packageBody._parent._normalizedIdentifier in predefinedLibraries 

983 packageBody._dependencyVertex = dependencyVertex 

984 

985 for entityIdentifier, entity in library._entities.items(): 

986 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}.{entityIdentifier}", value=entity, graph=self._dependencyGraph) 

987 dependencyVertex["kind"] = DependencyGraphVertexKind.Entity 

988 dependencyVertex["predefined"] = entity._parent._normalizedIdentifier in predefinedLibraries 

989 entity._dependencyVertex = dependencyVertex 

990 

991 for entityIdentifier, architectures in library._architectures.items(): 

992 for architectureIdentifier, architecture in architectures.items(): 

993 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}.{entityIdentifier}({architectureIdentifier})", value=architecture, graph=self._dependencyGraph) 

994 dependencyVertex["kind"] = DependencyGraphVertexKind.Architecture 

995 dependencyVertex["predefined"] = architecture._parent._normalizedIdentifier in predefinedLibraries 

996 architecture._dependencyVertex = dependencyVertex 

997 

998 for configurationIdentifier, configuration in library._configurations.items(): 

999 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}.{configurationIdentifier}", value=configuration, graph=self._dependencyGraph) 

1000 dependencyVertex["kind"] = DependencyGraphVertexKind.Configuration 

1001 dependencyVertex["predefined"] = configuration._parent._normalizedIdentifier in predefinedLibraries 

1002 configuration._dependencyVertex = dependencyVertex 

1003 

1004 def CreateCompileOrderGraph(self) -> None: 

1005 """ 

1006 Create a compile-order graph with bidirectional references to the dependency graph. 

1007 

1008 Add vertices representing a document (VHDL source file) to the dependency graph. Each "document" vertex in dependency graph is copied into the compile-order 

1009 graph and bidirectionally referenced. 

1010 

1011 In addition, each vertex of a corresponding design unit in a document is linked to the vertex representing that document to express the design unit in 

1012 document relationship. 

1013 

1014 Each added vertex has the following properties: 

1015 

1016 * The vertex' ID is the document's filename. 

1017 * The vertex' value references the document. 

1018 * A key-value-pair called ``kind`` denotes the vertex's kind as an enumeration value of type :class:`DependencyGraphVertexKind`. 

1019 * A key-value-pair called ``predefined`` does not exist. 

1020 

1021 .. rubric:: Algorithm 

1022 

1023 1. Iterate all documents in the design. 

1024 

1025 * Create a vertex for that document and reference the document by the vertex' value field. |br| 

1026 In return, set the documents's :attr:`~pyVHDLModel.Document._dependencyVertex` field to reference the created vertex. 

1027 * Copy the vertex from dependency graph to compile-order graph and link both vertices bidirectionally. |br| 

1028 In addition, set the documents's :attr:`~pyVHDLModel.Document._dependencyVertex` field to reference the copied vertex. 

1029 

1030 * Add a key-value-pair called ``compileOrderVertex`` to the dependency graph's vertex. 

1031 * Add a key-value-pair called ``dependencyVertex`` to the compiler-order graph's vertex. 

1032 

1033 1. Iterate the documents design units and create an edge from the design unit's corresponding dependency vertex to the documents corresponding 

1034 dependency vertex. This expresses a "design unit is located in document" relation. 

1035 

1036 * Add a key-value-pair called `kind`` denoting the edge's kind as an enumeration value of type :class:`DependencyGraphEdgeKind`. 

1037 """ 

1038 for document in self._documents: 

1039 dependencyVertex = Vertex(vertexID=document.Path.name, value=document, graph=self._dependencyGraph) 

1040 dependencyVertex["kind"] = DependencyGraphVertexKind.Document 

1041 document._dependencyVertex = dependencyVertex 

1042 

1043 compilerOrderVertex = dependencyVertex.Copy( 

1044 self._compileOrderGraph, 

1045 copyDict=True, 

1046 linkingKeyToOriginalVertex="dependencyVertex", 

1047 linkingKeyFromOriginalVertex="compileOrderVertex" 

1048 ) 

1049 document._compileOrderVertex = compilerOrderVertex 

1050 

1051 for designUnit in document._designUnits: 

1052 edge = dependencyVertex.EdgeFromVertex(designUnit._dependencyVertex) 

1053 edge["kind"] = DependencyGraphEdgeKind.SourceFile 

1054 

1055 def ImportObjects(self) -> None: 

1056 def _ImportObjects(package: Package) -> None: 

1057 for referencedLibrary in package._referencedPackages.values(): 

1058 for referencedPackage in referencedLibrary.values(): 

1059 for declaredItem in referencedPackage._declaredItems: 

1060 if isinstance(declaredItem, MultipleNamedEntityMixin): 1060 ↛ 1061line 1060 didn't jump to line 1061 because the condition on line 1060 was never true

1061 for normalizedIdentifier in declaredItem._normalizedIdentifiers: 

1062 package._namespace._elements[normalizedIdentifier] = declaredItem 

1063 elif isinstance(declaredItem, NamedEntityMixin): 1063 ↛ 1066line 1063 didn't jump to line 1066 because the condition on line 1063 was always true

1064 package._namespace._elements[declaredItem._normalizedIdentifier] = declaredItem 

1065 else: 

1066 raise VHDLModelException(f"Unexpected declared item.") 

1067 

1068 for libraryName in ("std", "ieee"): 

1069 for package in self.GetLibrary(libraryName).IterateDesignUnits(filter=DesignUnitKind.Package): # type: Package 

1070 _ImportObjects(package) 

1071 

1072 for document in self.IterateDocumentsInCompileOrder(): 

1073 for package in document.IterateDesignUnits(filter=DesignUnitKind.Package): # type: Package 

1074 _ImportObjects(package) 

1075 

1076 def CreateTypeAndObjectGraph(self) -> None: 

1077 def _HandlePackage(package) -> None: 

1078 packagePrefix = f"{package.Library.NormalizedIdentifier}.{package.NormalizedIdentifier}" 

1079 

1080 for deferredConstant in package._deferredConstants.values(): 1080 ↛ 1081line 1080 didn't jump to line 1081 because the loop on line 1080 never started

1081 print(f"Deferred Constant: {deferredConstant}") 

1082 deferredConstantVertex = Vertex( 

1083 vertexID=f"{packagePrefix}.{deferredConstant.NormalizedIdentifiers[0]}", 

1084 value=deferredConstant, 

1085 graph=self._objectGraph 

1086 ) 

1087 deferredConstantVertex["kind"] = ObjectGraphVertexKind.DeferredConstant 

1088 deferredConstant._objectVertex = deferredConstantVertex 

1089 

1090 for constant in package._constants.values(): 1090 ↛ 1091line 1090 didn't jump to line 1091 because the loop on line 1090 never started

1091 print(f"Constant: {constant}") 

1092 constantVertex = Vertex( 

1093 vertexID=f"{packagePrefix}.{constant.NormalizedIdentifiers[0]}", 

1094 value=constant, 

1095 graph=self._objectGraph 

1096 ) 

1097 constantVertex["kind"] = ObjectGraphVertexKind.Constant 

1098 constant._objectVertex = constantVertex 

1099 

1100 for type in package._types.values(): 

1101 print(f"Type: {type}") 

1102 typeVertex = Vertex( 

1103 vertexID=f"{packagePrefix}.{type.NormalizedIdentifier}", 

1104 value=type, 

1105 graph=self._objectGraph 

1106 ) 

1107 typeVertex["kind"] = ObjectGraphVertexKind.Type 

1108 type._objectVertex = typeVertex 

1109 

1110 for subtype in package._subtypes.values(): 

1111 print(f"Subtype: {subtype}") 

1112 subtypeVertex = Vertex( 

1113 vertexID=f"{packagePrefix}.{subtype.NormalizedIdentifier}", 

1114 value=subtype, 

1115 graph=self._objectGraph 

1116 ) 

1117 subtypeVertex["kind"] = ObjectGraphVertexKind.Subtype 

1118 subtype._objectVertex = subtypeVertex 

1119 

1120 for function in package._functions.values(): 1120 ↛ 1121line 1120 didn't jump to line 1121 because the loop on line 1120 never started

1121 print(f"Function: {function}") 

1122 functionVertex = Vertex( 

1123 vertexID=f"{packagePrefix}.{function.NormalizedIdentifier}", 

1124 value=function, 

1125 graph=self._objectGraph 

1126 ) 

1127 functionVertex["kind"] = ObjectGraphVertexKind.Function 

1128 function._objectVertex = functionVertex 

1129 

1130 for procedure in package._procedures.values(): 1130 ↛ 1131line 1130 didn't jump to line 1131 because the loop on line 1130 never started

1131 print(f"Procedure: {procedure}") 

1132 procedureVertex = Vertex( 

1133 vertexID=f"{packagePrefix}.{procedure.NormalizedIdentifier}", 

1134 value=procedure, 

1135 graph=self._objectGraph 

1136 ) 

1137 procedureVertex["kind"] = ObjectGraphVertexKind.Function 

1138 procedure._objectVertex = procedureVertex 

1139 

1140 for signal in package._signals.values(): 1140 ↛ 1141line 1140 didn't jump to line 1141 because the loop on line 1140 never started

1141 print(f"Signal: {signal}") 

1142 signalVertex = Vertex( 

1143 vertexID=f"{packagePrefix}.{signal.NormalizedIdentifiers[0]}", 

1144 value=signal, 

1145 graph=self._objectGraph 

1146 ) 

1147 signalVertex["kind"] = ObjectGraphVertexKind.Signal 

1148 signal._objectVertex = signalVertex 

1149 

1150 def _LinkSymbolsInExpression(expression, namespace: Namespace, typeVertex: Vertex): 

1151 if isinstance(expression, UnaryExpression): 1151 ↛ 1152line 1151 didn't jump to line 1152 because the condition on line 1151 was never true

1152 _LinkSymbolsInExpression(expression.Operand, namespace, typeVertex) 

1153 elif isinstance(expression, BinaryExpression): 1153 ↛ 1154line 1153 didn't jump to line 1154 because the condition on line 1153 was never true

1154 _LinkSymbolsInExpression(expression.LeftOperand, namespace, typeVertex) 

1155 _LinkSymbolsInExpression(expression.RightOperand, namespace, typeVertex) 

1156 elif isinstance(expression, TernaryExpression): 1156 ↛ 1157line 1156 didn't jump to line 1157 because the condition on line 1156 was never true

1157 pass 

1158 elif isinstance(expression, SimpleObjectOrFunctionCallSymbol): 1158 ↛ 1159line 1158 didn't jump to line 1159 because the condition on line 1158 was never true

1159 obj = namespace.FindObject(expression) 

1160 expression._reference = obj 

1161 

1162 edge = obj._objectVertex.EdgeToVertex(typeVertex) 

1163 edge["kind"] = ObjectGraphEdgeKind.ReferenceInExpression 

1164 else: 

1165 pass 

1166 

1167 def _LinkItems(package: Package): 

1168 for item in package._declaredItems: 

1169 if isinstance(item, Constant): 1169 ↛ 1170line 1169 didn't jump to line 1170 because the condition on line 1169 was never true

1170 print(f"constant: {item}") 

1171 elif isinstance(item, DeferredConstant): 1171 ↛ 1172line 1171 didn't jump to line 1172 because the condition on line 1171 was never true

1172 print(f"deferred constant: {item}") 

1173 elif isinstance(item, Signal): 1173 ↛ 1174line 1173 didn't jump to line 1174 because the condition on line 1173 was never true

1174 print(f"signal: {item}") 

1175 elif isinstance(item, IntegerType): 

1176 typeNode = item._objectVertex 

1177 

1178 _LinkSymbolsInExpression(item.Range.LeftBound, package._namespace, typeNode) 

1179 _LinkSymbolsInExpression(item.Range.RightBound, package._namespace, typeNode) 

1180 # elif isinstance(item, FloatingType): 

1181 # print(f"signal: {item}") 

1182 elif isinstance(item, PhysicalType): 

1183 typeNode = item._objectVertex 

1184 

1185 _LinkSymbolsInExpression(item.Range.LeftBound, package._namespace, typeNode) 

1186 _LinkSymbolsInExpression(item.Range.RightBound, package._namespace, typeNode) 

1187 elif isinstance(item, ArrayType): 

1188 # Resolve dimensions 

1189 for dimension in item._dimensions: 

1190 subtype = package._namespace.FindSubtype(dimension) 

1191 dimension._reference = subtype 

1192 

1193 edge = item._objectVertex.EdgeToVertex(subtype._objectVertex) 

1194 edge["kind"] = ObjectGraphEdgeKind.Subtype 

1195 

1196 # Resolve element subtype 

1197 subtype = package._namespace.FindSubtype(item._elementType) 

1198 item._elementType._reference = subtype 

1199 

1200 edge = item._objectVertex.EdgeToVertex(subtype._objectVertex) 

1201 edge["kind"] = ObjectGraphEdgeKind.Subtype 

1202 elif isinstance(item, RecordType): 1202 ↛ 1204line 1202 didn't jump to line 1204 because the condition on line 1202 was never true

1203 # Resolve each elements subtype 

1204 for element in item._elements: 

1205 subtype = package._namespace.FindSubtype(element._subtype) 

1206 element._subtype._reference = subtype 

1207 

1208 edge = item._objectVertex.EdgeToVertex(subtype._objectVertex) 

1209 edge["kind"] = ObjectGraphEdgeKind.Subtype 

1210 else: 

1211 print(f"not handled: {item}") 

1212 

1213 for libraryName in ("std", "ieee"): 

1214 for package in self.GetLibrary(libraryName).IterateDesignUnits(filter=DesignUnitKind.Package): # type: Package 

1215 _HandlePackage(package) 

1216 _LinkItems(package) 

1217 

1218 for document in self.IterateDocumentsInCompileOrder(): 

1219 for package in document.IterateDesignUnits(filter=DesignUnitKind.Package): # type: Package 

1220 _HandlePackage(package) 

1221 _LinkItems(package) 

1222 

1223 def LinkContexts(self) -> None: 

1224 """ 

1225 Resolves and links all items (library clauses, use clauses and nested context references) in contexts. 

1226 

1227 It iterates all contexts in the design. Therefore, the library of the context is used as the working library. By 

1228 default, the working library is implicitly referenced in :data:`_referencedLibraries`. In addition, a new empty 

1229 dictionary is created in :data:`_referencedPackages` and :data:`_referencedContexts` for that working library. 

1230 

1231 At first, all library clauses are resolved (a library clause my have multiple library reference symbols). For each 

1232 referenced library an entry in :data:`_referencedLibraries` is generated and new empty dictionaries in 

1233 :data:`_referencedPackages` and :data:`_referencedContexts` for that working library. In addition, a vertex in the 

1234 dependency graph is added for that relationship. 

1235 

1236 At second, all use clauses are resolved (a use clause my have multiple package member reference symbols). For each 

1237 referenced package, 

1238 """ 

1239 for context in self.IterateDesignUnits(DesignUnitKind.Context): # type: Context 

1240 # Create entries in _referenced*** for the current working library under its real name. 

1241 workingLibrary: Library = context.Library 

1242 libraryNormalizedIdentifier = workingLibrary._normalizedIdentifier 

1243 

1244 context._referencedLibraries[libraryNormalizedIdentifier] = self._libraries[libraryNormalizedIdentifier] 

1245 context._referencedPackages[libraryNormalizedIdentifier] = {} 

1246 context._referencedContexts[libraryNormalizedIdentifier] = {} 

1247 

1248 # Process all library clauses 

1249 for libraryReference in context._libraryReferences: 

1250 # A library clause can have multiple comma-separated references 

1251 for libraryName in libraryReference.Symbols: 

1252 libraryNormalizedIdentifier = libraryName.Name._normalizedIdentifier 

1253 try: 

1254 library = self._libraries[libraryNormalizedIdentifier] 

1255 except KeyError: 

1256 raise ReferencedLibraryNotExistingError(context, libraryName) 

1257 # TODO: add position to these messages 

1258 

1259 libraryName.Library = library 

1260 

1261 context._referencedLibraries[libraryNormalizedIdentifier] = library 

1262 context._referencedPackages[libraryNormalizedIdentifier] = {} 

1263 context._referencedContexts[libraryNormalizedIdentifier] = {} 

1264 # TODO: warn duplicate library reference 

1265 

1266 dependency = context._dependencyVertex.EdgeToVertex(library._dependencyVertex, edgeValue=libraryReference) 

1267 dependency["kind"] = DependencyGraphEdgeKind.LibraryClause 

1268 

1269 # Process all use clauses 

1270 for packageReference in context.PackageReferences: 

1271 # A use clause can have multiple comma-separated references 

1272 for symbol in packageReference.Symbols: # type: PackageReferenceSymbol 

1273 packageName = symbol.Name.Prefix 

1274 libraryName = packageName.Prefix 

1275 

1276 libraryNormalizedIdentifier = libraryName._normalizedIdentifier 

1277 packageNormalizedIdentifier = packageName._normalizedIdentifier 

1278 

1279 # In case work is used, resolve to the real library name. 

1280 if libraryNormalizedIdentifier == "work": 1280 ↛ 1281line 1280 didn't jump to line 1281 because the condition on line 1280 was never true

1281 library: Library = context._parent 

1282 libraryNormalizedIdentifier = library._normalizedIdentifier 

1283 elif libraryNormalizedIdentifier not in context._referencedLibraries: 1283 ↛ 1285line 1283 didn't jump to line 1285 because the condition on line 1283 was never true

1284 # TODO: This check doesn't trigger if it's the working library. 

1285 raise VHDLModelException(f"Use clause references library '{libraryName._identifier}', which was not referenced by a library clause.") 

1286 else: 

1287 library = self._libraries[libraryNormalizedIdentifier] 

1288 

1289 try: 

1290 package = library._packages[packageNormalizedIdentifier] 

1291 except KeyError: 

1292 raise VHDLModelException(f"Package '{packageName._identifier}' not found in {'working ' if libraryName._normalizedIdentifier == 'work' else ''}library '{library._identifier}'.") 

1293 

1294 symbol.Package = package 

1295 

1296 # TODO: warn duplicate package reference 

1297 context._referencedPackages[libraryNormalizedIdentifier][packageNormalizedIdentifier] = package 

1298 

1299 dependency = context._dependencyVertex.EdgeToVertex(package._dependencyVertex, edgeValue=packageReference) 

1300 dependency["kind"] = DependencyGraphEdgeKind.UseClause 

1301 

1302 # TODO: update the namespace with visible members 

1303 if isinstance(symbol, AllPackageMembersReferenceSymbol): 1303 ↛ 1306line 1303 didn't jump to line 1306 because the condition on line 1303 was always true

1304 pass 

1305 

1306 elif isinstance(symbol, PackageMemberReferenceSymbol): 

1307 raise NotImplementedError() 

1308 else: 

1309 raise VHDLModelException() 

1310 

1311 def LinkArchitectures(self) -> None: 

1312 """ 

1313 Link all architectures to corresponding entities in all libraries. 

1314 

1315 .. rubric:: Algorithm 

1316 

1317 1. Iterate all libraries: 

1318 

1319 1. Iterate all architecture groups (grouped per entity symbol's name). 

1320 |rarr| :meth:`pyVHDLModel.Library.LinkArchitectures` 

1321 

1322 * Check if entity symbol's name exists as an entity in this library. 

1323 

1324 1. For each architecture in the same architecture group: 

1325 

1326 * Add architecture to entities architecture dictionary :attr:`pyVHDLModel.DesignUnit.Entity._architectures`. 

1327 * Assign found entity to architecture's entity symbol :attr:`pyVHDLModel.DesignUnit.Architecture._entity` 

1328 * Set parent namespace of architecture's namespace to the entitie's namespace. 

1329 * Add an edge in the dependency graph from the architecture's corresponding dependency vertex to the entity's corresponding dependency vertex. 

1330 

1331 .. seealso:: 

1332 

1333 :meth:`LinkPackageBodies` 

1334 Link all package bodies to corresponding packages in all libraries. 

1335 """ 

1336 for library in self._libraries.values(): 

1337 library.LinkArchitectures() 

1338 

1339 def LinkPackageBodies(self) -> None: 

1340 """ 

1341 Link all package bodies to corresponding packages in all libraries. 

1342 

1343 .. rubric:: Algorithm 

1344 

1345 1. Iterate all libraries: 

1346 

1347 1. Iterate all package bodies. 

1348 |rarr| :meth:`pyVHDLModel.Library.LinkPackageBodies` 

1349 

1350 * Check if package body symbol's name exists as a package in this library. 

1351 * Add package body to package :attr:`pyVHDLModel.DesignUnit.Package._packageBody`. 

1352 * Assign found package to package body's package symbol :attr:`pyVHDLModel.DesignUnit.PackageBody._package` 

1353 * Set parent namespace of package body's namespace to the package's namespace. 

1354 * Add an edge in the dependency graph from the package body's corresponding dependency vertex to the package's corresponding dependency vertex. 

1355 

1356 .. seealso:: 

1357 

1358 :meth:`LinkArchitectures` 

1359 Link all architectures to corresponding entities in all libraries. 

1360 """ 

1361 for library in self._libraries.values(): 

1362 library.LinkPackageBodies() 

1363 

1364 def LinkLibraryReferences(self) -> None: 

1365 DEFAULT_LIBRARIES = ("std",) 

1366 

1367 for designUnit in self.IterateDesignUnits(DesignUnitKind.WithContext): 

1368 # All primary units supporting a context, have at least one library implicitly referenced 

1369 if isinstance(designUnit, PrimaryUnit): 

1370 for libraryIdentifier in DEFAULT_LIBRARIES: 

1371 referencedLibrary = self._libraries[libraryIdentifier] 

1372 designUnit._referencedLibraries[libraryIdentifier] = referencedLibrary 

1373 designUnit._referencedPackages[libraryIdentifier] = {} 

1374 designUnit._referencedContexts[libraryIdentifier] = {} 

1375 # TODO: catch KeyError on self._libraries[libName] 

1376 # TODO: warn duplicate library reference 

1377 

1378 dependency = designUnit._dependencyVertex.EdgeToVertex(referencedLibrary._dependencyVertex) 

1379 dependency["kind"] = DependencyGraphEdgeKind.LibraryClause 

1380 

1381 workingLibrary: Library = designUnit.Library 

1382 libraryIdentifier = workingLibrary.NormalizedIdentifier 

1383 referencedLibrary = self._libraries[libraryIdentifier] 

1384 

1385 

1386 designUnit._referencedLibraries[libraryIdentifier] = referencedLibrary 

1387 designUnit._referencedPackages[libraryIdentifier] = {} 

1388 designUnit._referencedContexts[libraryIdentifier] = {} 

1389 

1390 dependency = designUnit._dependencyVertex.EdgeToVertex(referencedLibrary._dependencyVertex) 

1391 dependency["kind"] = DependencyGraphEdgeKind.LibraryClause 

1392 

1393 # All secondary units inherit referenced libraries from their primary units. 

1394 else: 

1395 if isinstance(designUnit, Architecture): 

1396 referencedLibraries = designUnit.Entity.Entity._referencedLibraries 

1397 elif isinstance(designUnit, PackageBody): 1397 ↛ 1400line 1397 didn't jump to line 1400 because the condition on line 1397 was always true

1398 referencedLibraries = designUnit.Package.Package._referencedLibraries 

1399 else: 

1400 raise VHDLModelException() 

1401 

1402 for libraryIdentifier, library in referencedLibraries.items(): 

1403 designUnit._referencedLibraries[libraryIdentifier] = library 

1404 

1405 for libraryReference in designUnit._libraryReferences: 

1406 # A library clause can have multiple comma-separated references 

1407 for librarySymbol in libraryReference.Symbols: 

1408 libraryIdentifier = librarySymbol.Name.NormalizedIdentifier 

1409 if libraryIdentifier == "work": 1409 ↛ 1410line 1409 didn't jump to line 1410 because the condition on line 1409 was never true

1410 continue 

1411 

1412 try: 

1413 library = self._libraries[libraryIdentifier] 

1414 except KeyError: 

1415 ex = VHDLModelException(f"Library '{librarySymbol.Name.Identifier}' referenced by library clause of design unit '{designUnit.Identifier}' doesn't exist in design.") 

1416 ex.add_note(f"""Known libraries: '{"', '".join(library for library in self._libraries)}'""") 

1417 raise ex 

1418 

1419 librarySymbol.Library = library 

1420 designUnit._referencedLibraries[libraryIdentifier] = library 

1421 designUnit._referencedPackages[libraryIdentifier] = {} 

1422 designUnit._referencedContexts[libraryIdentifier] = {} 

1423 # TODO: warn duplicate library reference 

1424 

1425 dependency = designUnit._dependencyVertex.EdgeToVertex(library._dependencyVertex, edgeValue=libraryReference) 

1426 dependency["kind"] = DependencyGraphEdgeKind.LibraryClause 

1427 

1428 def LinkPackageReferences(self) -> None: 

1429 DEFAULT_PACKAGES = ( 

1430 ("std", ("standard",)), 

1431 ) 

1432 

1433 for designUnit in self.IterateDesignUnits(DesignUnitKind.WithContext): 

1434 # All primary units supporting a context, have at least one package implicitly referenced 

1435 if isinstance(designUnit, PrimaryUnit): 

1436 if designUnit.Library.NormalizedIdentifier != "std" and \ 

1437 designUnit.NormalizedIdentifier != "standard": 

1438 for lib in DEFAULT_PACKAGES: 

1439 if lib[0] not in designUnit._referencedLibraries: 1439 ↛ 1440line 1439 didn't jump to line 1440 because the condition on line 1439 was never true

1440 raise VHDLModelException() 

1441 for pack in lib[1]: 

1442 referencedPackage = self._libraries[lib[0]]._packages[pack] 

1443 designUnit._referencedPackages[lib[0]][pack] = referencedPackage 

1444 # TODO: catch KeyError on self._libraries[lib[0]]._packages[pack] 

1445 # TODO: warn duplicate package reference 

1446 

1447 dependency = designUnit._dependencyVertex.EdgeToVertex(referencedPackage._dependencyVertex) 

1448 dependency["kind"] = DependencyGraphEdgeKind.UseClause 

1449 

1450 # All secondary units inherit referenced packages from their primary units. 

1451 else: 

1452 if isinstance(designUnit, Architecture): 

1453 referencedPackages = designUnit.Entity.Entity._referencedPackages 

1454 elif isinstance(designUnit, PackageBody): 1454 ↛ 1457line 1454 didn't jump to line 1457 because the condition on line 1454 was always true

1455 referencedPackages = designUnit.Package.Package._referencedPackages 

1456 else: 

1457 raise VHDLModelException() 

1458 

1459 for packageIdentifier, package in referencedPackages.items(): 

1460 designUnit._referencedPackages[packageIdentifier] = package 

1461 

1462 for packageReference in designUnit.PackageReferences: 

1463 # A use clause can have multiple comma-separated references 

1464 for packageMemberSymbol in packageReference.Symbols: 

1465 packageName = packageMemberSymbol.Name.Prefix 

1466 libraryName = packageName.Prefix 

1467 

1468 libraryIdentifier = libraryName.NormalizedIdentifier 

1469 packageIdentifier = packageName.NormalizedIdentifier 

1470 

1471 # In case work is used, resolve to the real library name. 

1472 if libraryIdentifier == "work": 

1473 library: Library = designUnit.Library 

1474 libraryIdentifier = library.NormalizedIdentifier 

1475 elif libraryIdentifier not in designUnit._referencedLibraries: 1475 ↛ 1477line 1475 didn't jump to line 1477 because the condition on line 1475 was never true

1476 # TODO: This check doesn't trigger if it's the working library. 

1477 raise VHDLModelException(f"Use clause references library '{libraryName.Identifier}', which was not referenced by a library clause.") 

1478 else: 

1479 library = self._libraries[libraryIdentifier] 

1480 

1481 try: 

1482 package = library._packages[packageIdentifier] 

1483 except KeyError: 

1484 ex = VHDLModelException(f"Package '{packageName.Identifier}' not found in {'working ' if libraryName.NormalizedIdentifier == 'work' else ''}library '{library.Identifier}'.") 

1485 ex.add_note(f"Caused in design unit '{designUnit}' in file '{designUnit.Document}'.") 

1486 raise ex 

1487 

1488 packageMemberSymbol.Package = package 

1489 

1490 # TODO: warn duplicate package reference 

1491 designUnit._referencedPackages[libraryIdentifier][packageIdentifier] = package 

1492 

1493 dependency = designUnit._dependencyVertex.EdgeToVertex(package._dependencyVertex, edgeValue=packageReference) 

1494 dependency["kind"] = DependencyGraphEdgeKind.UseClause 

1495 

1496 # TODO: update the namespace with visible members 

1497 if isinstance(packageMemberSymbol, AllPackageMembersReferenceSymbol): 1497 ↛ 1501line 1497 didn't jump to line 1501 because the condition on line 1497 was always true

1498 for componentIdentifier, component in package._components.items(): 1498 ↛ 1499line 1498 didn't jump to line 1499 because the loop on line 1498 never started

1499 designUnit._namespace._elements[componentIdentifier] = component 

1500 

1501 elif isinstance(packageMemberSymbol, PackageMemberReferenceSymbol): 

1502 raise NotImplementedError() 

1503 else: 

1504 raise VHDLModelException() 

1505 

1506 def LinkContextReferences(self) -> None: 

1507 for designUnit in self.IterateDesignUnits(): 

1508 for contextReference in designUnit._contextReferences: 

1509 # A context reference can have multiple comma-separated references 

1510 for contextSymbol in contextReference.Symbols: 

1511 libraryName = contextSymbol.Name.Prefix 

1512 

1513 libraryIdentifier = libraryName.NormalizedIdentifier 

1514 contextIdentifier = contextSymbol.Name.NormalizedIdentifier 

1515 

1516 # In case work is used, resolve to the real library name. 

1517 if libraryIdentifier == "work": 1517 ↛ 1520line 1517 didn't jump to line 1520 because the condition on line 1517 was always true

1518 referencedLibrary = designUnit.Library 

1519 libraryIdentifier = referencedLibrary.NormalizedIdentifier 

1520 elif libraryIdentifier not in designUnit._referencedLibraries: 

1521 # TODO: This check doesn't trigger if it's the working library. 

1522 raise VHDLModelException(f"Context reference references library '{libraryName.Identifier}', which was not referenced by a library clause.") 

1523 else: 

1524 referencedLibrary = self._libraries[libraryIdentifier] 

1525 

1526 try: 

1527 referencedContext = referencedLibrary._contexts[contextIdentifier] 

1528 except KeyError: 

1529 raise VHDLModelException(f"Context '{contextSymbol.Name.Identifier}' not found in {'working ' if libraryName.NormalizedIdentifier == 'work' else ''}library '{referencedLibrary.Identifier}'.") 

1530 

1531 contextSymbol.Package = referencedContext 

1532 

1533 # TODO: warn duplicate referencedContext reference 

1534 designUnit._referencedContexts[libraryIdentifier][contextIdentifier] = referencedContext 

1535 

1536 dependency = designUnit._dependencyVertex.EdgeToVertex(referencedContext._dependencyVertex, edgeValue=contextReference) 

1537 dependency["kind"] = DependencyGraphEdgeKind.ContextReference 

1538 

1539 for vertex in self._dependencyGraph.IterateTopologically(): 

1540 if vertex["kind"] is DependencyGraphVertexKind.Context: 

1541 context: Context = vertex.Value 

1542 for designUnitVertex in vertex.IteratePredecessorVertices(): 

1543 designUnit: DesignUnit = designUnitVertex.Value 

1544 for libraryIdentifier, library in context._referencedLibraries.items(): 

1545 # if libraryIdentifier in designUnit._referencedLibraries: 

1546 # raise VHDLModelException(f"Referenced library '{library.Identifier}' already exists in references for design unit '{designUnit.Identifier}'.") 

1547 

1548 designUnit._referencedLibraries[libraryIdentifier] = library 

1549 designUnit._referencedPackages[libraryIdentifier] = {} 

1550 

1551 for libraryIdentifier, packages in context._referencedPackages.items(): 

1552 for packageIdentifier, package in packages.items(): 

1553 if packageIdentifier in designUnit._referencedPackages: 1553 ↛ 1554line 1553 didn't jump to line 1554 because the condition on line 1553 was never true

1554 raise VHDLModelException(f"Referenced package '{package.Identifier}' already exists in references for design unit '{designUnit.Identifier}'.") 

1555 

1556 designUnit._referencedPackages[libraryIdentifier][packageIdentifier] = package 

1557 

1558 def LinkComponents(self) -> None: 

1559 for package in self.IterateDesignUnits(DesignUnitKind.Package): # type: Package 

1560 library = package._parent 

1561 for component in package._components.values(): 1561 ↛ 1562line 1561 didn't jump to line 1562 because the loop on line 1561 never started

1562 try: 

1563 entity = library._entities[component.NormalizedIdentifier] 

1564 except KeyError: 

1565 if not component.AllowBlackbox: 

1566 raise VHDLModelException(f"Entity '{component.Identifier}' not found for component '{component.Identifier}' in library '{library.Identifier}'.") 

1567 else: 

1568 component._isBlackBox = True 

1569 continue 

1570 

1571 component.Entity = entity 

1572 

1573 # QUESTION: Add link in dependency graph as dashed line from component to entity? 

1574 # Currently, component has no _dependencyVertex field 

1575 

1576 # FIXME: also link components in architectures (and nested structures like generate statements and block statements 

1577 # for architecture in self.IterateDesignUnits(DesignUnitKind.Architecture): 

1578 # library = architecture._parent 

1579 # for component in architecture._components.values(): 

1580 # pass 

1581 

1582 def LinkInstantiations(self) -> None: 

1583 for architecture in self.IterateDesignUnits(DesignUnitKind.Architecture): # type: Architecture 

1584 for instance in architecture.IterateInstantiations(): 

1585 if isinstance(instance, EntityInstantiation): 1585 ↛ 1618line 1585 didn't jump to line 1618 because the condition on line 1585 was always true

1586 libraryName = instance.Entity.Name.Prefix 

1587 libraryIdentifier = libraryName.Identifier 

1588 normalizedLibraryIdentifier = libraryName.NormalizedIdentifier 

1589 if normalizedLibraryIdentifier == "work": 

1590 libraryIdentifier = architecture.Library.Identifier 

1591 normalizedLibraryIdentifier = architecture.Library.NormalizedIdentifier 

1592 elif normalizedLibraryIdentifier not in architecture._referencedLibraries: 1592 ↛ 1593line 1592 didn't jump to line 1593 because the condition on line 1592 was never true

1593 ex = VHDLModelException(f"Referenced library '{libraryIdentifier}' in direct entity instantiation '{instance.Label}: entity {instance.Entity.Prefix.Identifier}.{instance.Entity.Identifier}' not found in architecture '{architecture!r}'.") 

1594 ex.add_note(f"Add a library reference to the architecture or entity using a library clause like: 'library {libraryIdentifier};'.") 

1595 raise ex 

1596 

1597 try: 

1598 library = self._libraries[normalizedLibraryIdentifier] 

1599 except KeyError: 

1600 ex = VHDLModelException(f"Referenced library '{libraryIdentifier}' in direct entity instantiation '{instance.Label}: entity {instance.Entity.Prefix.Identifier}.{instance.Entity.Identifier}' not found in design.") 

1601 ex.add_note(f"No design units were parsed into library '{libraryIdentifier}'. Thus it doesn't exist in design.") 

1602 raise ex 

1603 

1604 try: 

1605 entity = library._entities[instance.Entity.Name.NormalizedIdentifier] 

1606 except KeyError: 

1607 ex = VHDLModelException(f"Referenced entity '{instance.Entity.Name.Identifier}' in direct entity instantiation '{instance.Label}: entity {instance.Entity.Name.Prefix.Identifier}.{instance.Entity.Name.Identifier}' not found in {'working ' if instance.Entity.Name.Prefix.NormalizedIdentifier == 'work' else ''}library '{libraryIdentifier}'.") 

1608 libs = [library.Identifier for library in self._libraries.values() for entityIdentifier in library._entities.keys() if entityIdentifier == instance.Entity.Name.NormalizedIdentifier] 

1609 if libs: 

1610 ex.add_note(f"Found entity '{instance.Entity!s}' in other libraries: {', '.join(libs)}") 

1611 raise ex 

1612 

1613 instance.Entity.Entity = entity 

1614 

1615 dependency = architecture._dependencyVertex.EdgeToVertex(entity._dependencyVertex, edgeValue=instance) 

1616 dependency["kind"] = DependencyGraphEdgeKind.EntityInstantiation 

1617 

1618 elif isinstance(instance, ComponentInstantiation): 

1619 component = architecture._namespace.FindComponent(instance.Component) 

1620 

1621 instance.Component.Component = component 

1622 

1623 if not component.IsBlackbox: 

1624 dependency = architecture._dependencyVertex.EdgeToVertex(component.Entity._dependencyVertex, edgeValue=instance) 

1625 dependency["kind"] = DependencyGraphEdgeKind.ComponentInstantiation 

1626 else: 

1627 print(f"Found a blackbox for '{instance.Label}: {instance.Component.Name}'.") 

1628 

1629 elif isinstance(instance, ConfigurationInstantiation): 

1630 # pass 

1631 print(instance.Label, instance.Configuration) 

1632 

1633 def IndexPackages(self) -> None: 

1634 """ 

1635 Index all declared items in all packages in all libraries. 

1636 

1637 .. rubric:: Algorithm 

1638 

1639 1. Iterate all libraries: 

1640 

1641 1. Iterate all packages |br| 

1642 |rarr| :meth:`pyVHDLModel.Library.IndexPackages` 

1643 

1644 * Index all declared items in that package. |br| 

1645 |rarr| :meth:`pyVHDLModel.DesignUnit.Package.IndexDeclaredItems` 

1646 

1647 .. seealso:: 

1648 

1649 :meth:`IndexPackageBodies` 

1650 Index all declared items in all package bodies in all libraries. 

1651 :meth:`IndexEntities` 

1652 Index all declared items in all entities in all libraries. 

1653 :meth:`IndexArchitectures` 

1654 Index all declared items in all architectures in all libraries. 

1655 """ 

1656 for library in self._libraries.values(): 

1657 library.IndexPackages() 

1658 

1659 def IndexPackageBodies(self) -> None: 

1660 """ 

1661 Index all declared items in all packages in all libraries. 

1662 

1663 .. rubric:: Algorithm 

1664 

1665 1. Iterate all libraries: 

1666 

1667 1. Iterate all packages |br| 

1668 |rarr| :meth:`pyVHDLModel.Library.IndexPackageBodies` 

1669 

1670 * Index all declared items in that package body. |br| 

1671 |rarr| :meth:`pyVHDLModel.DesignUnit.PackageBody.IndexDeclaredItems` 

1672 

1673 .. seealso:: 

1674 

1675 :meth:`IndexPackages` 

1676 Index all declared items in all packages in all libraries. 

1677 :meth:`IndexEntities` 

1678 Index all declared items in all entities in all libraries. 

1679 :meth:`IndexArchitectures` 

1680 Index all declared items in all architectures in all libraries. 

1681 """ 

1682 for library in self._libraries.values(): 

1683 library.IndexPackageBodies() 

1684 

1685 def IndexEntities(self) -> None: 

1686 """ 

1687 Index all declared items in all packages in all libraries. 

1688 

1689 .. rubric:: Algorithm 

1690 

1691 1. Iterate all libraries: 

1692 

1693 1. Iterate all packages |br| 

1694 |rarr| :meth:`pyVHDLModel.Library.IndexEntities` 

1695 

1696 * Index all declared items in that entity. |br| 

1697 |rarr| :meth:`pyVHDLModel.DesignUnit.Entity.IndexDeclaredItems` 

1698 

1699 .. seealso:: 

1700 

1701 :meth:`IndexPackages` 

1702 Index all declared items in all packages in all libraries. 

1703 :meth:`IndexPackageBodies` 

1704 Index all declared items in all package bodies in all libraries. 

1705 :meth:`IndexArchitectures` 

1706 Index all declared items in all architectures in all libraries. 

1707 """ 

1708 for library in self._libraries.values(): 

1709 library.IndexEntities() 

1710 

1711 def IndexArchitectures(self) -> None: 

1712 """ 

1713 Index all declared items in all packages in all libraries. 

1714 

1715 .. rubric:: Algorithm 

1716 

1717 1. Iterate all libraries: 

1718 

1719 1. Iterate all packages |br| 

1720 |rarr| :meth:`pyVHDLModel.Library.IndexArchitectures` 

1721 

1722 * Index all declared items in that architecture. |br| 

1723 |rarr| :meth:`pyVHDLModel.DesignUnit.Architecture.IndexDeclaredItems` 

1724 

1725 .. seealso:: 

1726 

1727 :meth:`IndexPackages` 

1728 Index all declared items in all packages in all libraries. 

1729 :meth:`IndexPackageBodies` 

1730 Index all declared items in all package bodies in all libraries. 

1731 :meth:`IndexEntities` 

1732 Index all declared items in all entities in all libraries. 

1733 """ 

1734 for library in self._libraries.values(): 

1735 library.IndexArchitectures() 

1736 

1737 def CreateHierarchyGraph(self) -> None: 

1738 """ 

1739 Create the hierarchy graph from dependency graph. 

1740 

1741 .. rubric:: Algorithm 

1742 

1743 1. Iterate all vertices corresponding to entities and architectures in the dependency graph: 

1744 

1745 * Copy these vertices to the hierarchy graph and create a bidirectional linking. |br| 

1746 In addition, set the referenced design unit's :attr:`~pyVHDLModel.Document._hierarchyVertex` field to reference the copied vertex. 

1747 

1748 * Add a key-value-pair called ``hierarchyVertex`` to the dependency graph's vertex. 

1749 * Add a key-value-pair called ``dependencyVertex`` to the hierarchy graph's vertex. 

1750 

1751 2. Iterate all architectures ... 

1752 

1753 .. todo:: Design::CreateHierarchyGraph describe algorithm 

1754 

1755 1. Iterate all outbound edges 

1756 

1757 .. todo:: Design::CreateHierarchyGraph describe algorithm 

1758 """ 

1759 # Copy all entity and architecture vertices from dependency graph to hierarchy graph and double-link them 

1760 entityArchitectureFilter = lambda v: v["kind"] in DependencyGraphVertexKind.Entity | DependencyGraphVertexKind.Architecture 

1761 for vertex in self._dependencyGraph.IterateVertices(predicate=entityArchitectureFilter): 

1762 hierarchyVertex = vertex.Copy(self._hierarchyGraph, copyDict=True, linkingKeyToOriginalVertex="dependencyVertex", linkingKeyFromOriginalVertex="hierarchyVertex") 

1763 vertex.Value._hierarchyVertex = hierarchyVertex 

1764 

1765 # Copy implementation edges from 

1766 for hierarchyArchitectureVertex in self._hierarchyGraph.IterateVertices(predicate=lambda v: v["kind"] is DependencyGraphVertexKind.Architecture): 

1767 for dependencyEdge in hierarchyArchitectureVertex["dependencyVertex"].IterateOutboundEdges(): 

1768 kind: DependencyGraphEdgeKind = dependencyEdge["kind"] 

1769 if DependencyGraphEdgeKind.Implementation in kind: 

1770 hierarchyDestinationVertex = dependencyEdge.Destination["hierarchyVertex"] 

1771 newEdge = hierarchyArchitectureVertex.EdgeFromVertex(hierarchyDestinationVertex) 

1772 elif DependencyGraphEdgeKind.Instantiation in kind: 

1773 hierarchyDestinationVertex = dependencyEdge.Destination["hierarchyVertex"] 

1774 

1775 # FIXME: avoid parallel edges, to graph can be converted to a tree until "real" hierarchy is computed (unrole generics and blocks) 

1776 if hierarchyArchitectureVertex.HasEdgeToDestination(hierarchyDestinationVertex): 

1777 continue 

1778 

1779 newEdge = hierarchyArchitectureVertex.EdgeToVertex(hierarchyDestinationVertex) 

1780 else: 

1781 continue 

1782 

1783 newEdge["kind"] = kind 

1784 

1785 def ComputeCompileOrder(self) -> None: 

1786 def predicate(edge: Edge) -> bool: 

1787 return ( 

1788 DependencyGraphEdgeKind.Implementation in edge["kind"] or 

1789 DependencyGraphEdgeKind.Instantiation in edge["kind"] or 

1790 DependencyGraphEdgeKind.UseClause in edge["kind"] or 

1791 DependencyGraphEdgeKind.ContextReference in edge["kind"] 

1792 ) and edge.Destination["predefined"] is False 

1793 

1794 for edge in self._dependencyGraph.IterateEdges(predicate=predicate): 

1795 sourceDocument: Document = edge.Source.Value.Document 

1796 destinationDocument: Document = edge.Destination.Value.Document 

1797 

1798 sourceVertex = sourceDocument._compileOrderVertex 

1799 destinationVertex = destinationDocument._compileOrderVertex 

1800 

1801 # Don't add self-edges 

1802 if sourceVertex is destinationVertex: 1802 ↛ 1805line 1802 didn't jump to line 1805 because the condition on line 1802 was always true

1803 continue 

1804 # Don't add parallel edges 

1805 elif sourceVertex.HasEdgeToDestination(destinationVertex): 

1806 continue 

1807 

1808 e = sourceVertex.EdgeToVertex(destinationVertex) 

1809 e["kind"] = DependencyGraphEdgeKind.CompileOrder 

1810 

1811 e = sourceVertex["dependencyVertex"].EdgeToVertex(destinationVertex["dependencyVertex"]) 

1812 e["kind"] = DependencyGraphEdgeKind.CompileOrder 

1813 

1814 def IterateDocumentsInCompileOrder(self) -> Generator['Document', None, None]: 

1815 """ 

1816 Iterate all document in compile-order. 

1817 

1818 .. rubric:: Algorithm 

1819 

1820 * Check if compile-order graph was populated with vertices and its vertices are linked by edges. 

1821 

1822 1. Iterate compile-order graph in topological order. |br| 

1823 :meth:`pyTooling.Graph.Graph.IterateTopologically` 

1824 

1825 * yield the compiler-order vertex' referenced document. 

1826 

1827 :returns: A generator to iterate all documents in compile-order in the design. 

1828 :raises VHDLModelException: If compile-order was not computed. 

1829 

1830 .. seealso:: 

1831 

1832 .. todo:: missing text 

1833 

1834 :meth:`pyVHDLModel.Design.ComputeCompileOrder` 

1835 

1836 """ 

1837 if self._compileOrderGraph.EdgeCount < self._compileOrderGraph.VertexCount - 1: 1837 ↛ 1838line 1837 didn't jump to line 1838 because the condition on line 1837 was never true

1838 raise VHDLModelException(f"Compile order is not yet computed from dependency graph.") 

1839 

1840 for compileOrderNode in self._compileOrderGraph.IterateTopologically(): 

1841 yield compileOrderNode.Value 

1842 

1843 def GetUnusedDesignUnits(self) -> List[DesignUnit]: 

1844 raise NotImplementedError() 

1845 

1846 def __repr__(self) -> str: 

1847 """ 

1848 Formats a representation of the design. 

1849 

1850 **Format:** ``Document: 'my_design'`` 

1851 

1852 :returns: String representation of the design. 

1853 """ 

1854 return f"Design: {self._name}" 

1855 

1856 __str__ = __repr__ 

1857 

1858 

1859@export 

1860class Library(ModelEntity, NamedEntityMixin): 

1861 """A ``Library`` represents a VHDL library. It contains all *primary* and *secondary* design units.""" 

1862 

1863 _allowBlackbox: Nullable[bool] #: Allow blackboxes for components in this library. 

1864 _contexts: Dict[str, Context] #: Dictionary of all contexts defined in a library. 

1865 _configurations: Dict[str, Configuration] #: Dictionary of all configurations defined in a library. 

1866 _entities: Dict[str, Entity] #: Dictionary of all entities defined in a library. 

1867 _architectures: Dict[str, Dict[str, Architecture]] #: Dictionary of all architectures defined in a library. 

1868 _packages: Dict[str, Package] #: Dictionary of all packages defined in a library. 

1869 _packageBodies: Dict[str, PackageBody] #: Dictionary of all package bodies defined in a library. 

1870 

1871 _dependencyVertex: Vertex[None, None, str, Union['Library', DesignUnit], None, None, None, None, None, None, None, None, None, None, None, None, None] #: Reference to the vertex in the dependency graph representing the library. |br| This reference is set by :meth:`~pyVHDLModel.Design.CreateDependencyGraph`. 

1872 

1873 def __init__( 

1874 self, 

1875 identifier: str, 

1876 allowBlackbox: Nullable[bool] = None, 

1877 parent: ModelEntity = None 

1878 ) -> None: 

1879 """ 

1880 Initialize a VHDL library. 

1881 

1882 :param identifier: Name of the VHDL library. 

1883 :param allowBlackbox: Specify if blackboxes are allowed in this design. 

1884 :param parent: The parent model entity (design) of this VHDL library. 

1885 """ 

1886 super().__init__(parent) 

1887 NamedEntityMixin.__init__(self, identifier) 

1888 

1889 self._allowBlackbox = allowBlackbox 

1890 

1891 self._contexts = {} 

1892 self._configurations = {} 

1893 self._entities = {} 

1894 self._architectures = {} 

1895 self._packages = {} 

1896 self._packageBodies = {} 

1897 

1898 self._dependencyVertex = None 

1899 

1900 @property 

1901 def AllowBlackbox(self) -> bool: 

1902 """ 

1903 Read-only property to check if a design supports blackboxes (:attr:`_allowBlackbox`). 

1904 

1905 :returns: If blackboxes are allowed. 

1906 """ 

1907 if self._allowBlackbox is None: 

1908 return self._parent.AllowBlackbox 

1909 else: 

1910 return self._allowBlackbox 

1911 

1912 @AllowBlackbox.setter 

1913 def AllowBlackbox(self, value: Nullable[bool]) -> None: 

1914 self._allowBlackbox = value 

1915 

1916 @readonly 

1917 def Contexts(self) -> Dict[str, Context]: 

1918 """Returns a list of all context declarations declared in this library.""" 

1919 return self._contexts 

1920 

1921 @readonly 

1922 def Configurations(self) -> Dict[str, Configuration]: 

1923 """Returns a list of all configuration declarations declared in this library.""" 

1924 return self._configurations 

1925 

1926 @readonly 

1927 def Entities(self) -> Dict[str, Entity]: 

1928 """Returns a list of all entity declarations declared in this library.""" 

1929 return self._entities 

1930 

1931 @readonly 

1932 def Architectures(self) -> Dict[str, Dict[str, Architecture]]: 

1933 """Returns a list of all architectures declarations declared in this library.""" 

1934 return self._architectures 

1935 

1936 @readonly 

1937 def Packages(self) -> Dict[str, Package]: 

1938 """Returns a list of all package declarations declared in this library.""" 

1939 return self._packages 

1940 

1941 @readonly 

1942 def PackageBodies(self) -> Dict[str, PackageBody]: 

1943 """Returns a list of all package body declarations declared in this library.""" 

1944 return self._packageBodies 

1945 

1946 @readonly 

1947 def DependencyVertex(self) -> Vertex: 

1948 """ 

1949 Read-only property to access the corresponding dependency vertex (:attr:`_dependencyVertex`). 

1950 

1951 The dependency vertex references this library by its value field. 

1952 

1953 :returns: The corresponding dependency vertex. 

1954 """ 

1955 return self._dependencyVertex 

1956 

1957 def IterateDesignUnits(self, filter: DesignUnitKind = DesignUnitKind.All) -> Generator[DesignUnit, None, None]: 

1958 """ 

1959 Iterate all design units in the library. 

1960 

1961 A union of :class:`DesignUnitKind` values can be given to filter the returned result for suitable design units. 

1962 

1963 .. rubric:: Algorithm 

1964 

1965 1. Iterate all contexts in that library. 

1966 2. Iterate all packages in that library. 

1967 3. Iterate all package bodies in that library. 

1968 4. Iterate all entities in that library. 

1969 5. Iterate all architectures in that library. 

1970 6. Iterate all configurations in that library. 

1971 

1972 :param filter: An enumeration with possibly multiple flags to filter the returned design units. 

1973 :returns: A generator to iterate all matched design units in the library. 

1974 

1975 .. seealso:: 

1976 

1977 :meth:`pyVHDLModel.Design.IterateDesignUnits` 

1978 Iterate all design units in the design. 

1979 :meth:`pyVHDLModel.Document.IterateDesignUnits` 

1980 Iterate all design units in the document. 

1981 """ 

1982 if DesignUnitKind.Context in filter: 

1983 for context in self._contexts.values(): 

1984 yield context 

1985 

1986 if DesignUnitKind.Package in filter: 

1987 for package in self._packages.values(): 

1988 yield package 

1989 

1990 if DesignUnitKind.PackageBody in filter: 

1991 for packageBody in self._packageBodies.values(): 

1992 yield packageBody 

1993 

1994 if DesignUnitKind.Entity in filter: 

1995 for entity in self._entities.values(): 

1996 yield entity 

1997 

1998 if DesignUnitKind.Architecture in filter: 

1999 for architectures in self._architectures.values(): 

2000 for architecture in architectures.values(): 

2001 yield architecture 

2002 

2003 if DesignUnitKind.Configuration in filter: 

2004 for configuration in self._configurations.values(): 

2005 yield configuration 

2006 

2007 # for verificationProperty in self._verificationUnits.values(): 

2008 # yield verificationProperty 

2009 # for verificationUnit in self._verificationProperties.values(): 

2010 # yield entity 

2011 # for verificationMode in self._verificationModes.values(): 

2012 # yield verificationMode 

2013 

2014 def LinkArchitectures(self) -> None: 

2015 """ 

2016 Link all architectures to corresponding entities. 

2017 

2018 .. rubric:: Algorithm 

2019 

2020 1. Iterate all architecture groups (grouped per entity symbol's name). 

2021 

2022 * Check if entity symbol's name exists as an entity in this library. 

2023 

2024 1. For each architecture in the same architecture group: 

2025 

2026 * Add architecture to entities architecture dictionary :attr:`pyVHDLModel.DesignUnit.Entity._architectures`. 

2027 * Assign found entity to architecture's entity symbol :attr:`pyVHDLModel.DesignUnit.Architecture._entity` 

2028 * Set parent namespace of architecture's namespace to the entitie's namespace. 

2029 * Add an edge in the dependency graph from the architecture's corresponding dependency vertex to the entity's corresponding dependency vertex. 

2030 

2031 :raises VHDLModelException: If entity name doesn't exist. 

2032 :raises VHDLModelException: If architecture name already exists for entity. 

2033 

2034 .. seealso:: 

2035 

2036 :meth:`LinkPackageBodies` 

2037 Link all package bodies to corresponding packages. 

2038 """ 

2039 for entityName, architecturesPerEntity in self._architectures.items(): 

2040 if entityName not in self._entities: 2040 ↛ 2041line 2040 didn't jump to line 2041 because the condition on line 2040 was never true

2041 architectureNames = "', '".join(architecturesPerEntity.keys()) 

2042 raise VHDLModelException(f"Entity '{entityName}' referenced by architecture(s) '{architectureNames}' doesn't exist in library '{self._identifier}'.") 

2043 # TODO: search in other libraries to find that entity. 

2044 # TODO: add code position 

2045 

2046 entity = self._entities[entityName] 

2047 for architecture in architecturesPerEntity.values(): 

2048 if architecture._normalizedIdentifier in entity._architectures: 2048 ↛ 2049line 2048 didn't jump to line 2049 because the condition on line 2048 was never true

2049 raise VHDLModelException(f"Architecture '{architecture._identifier}' already exists for entity '{entity._identifier}'.") 

2050 # TODO: add code position of existing and current 

2051 

2052 entity._architectures[architecture._normalizedIdentifier] = architecture 

2053 architecture._entity.Entity = entity 

2054 architecture._namespace._parentNamespace = entity._namespace 

2055 

2056 # add "architecture -> entity" relation in dependency graph 

2057 dependency = architecture._dependencyVertex.EdgeToVertex(entity._dependencyVertex) 

2058 dependency["kind"] = DependencyGraphEdgeKind.EntityImplementation 

2059 

2060 def LinkPackageBodies(self) -> None: 

2061 """ 

2062 Link all package bodies to corresponding packages. 

2063 

2064 .. rubric:: Algorithm 

2065 

2066 1. Iterate all package bodies. 

2067 

2068 * Check if package body symbol's name exists as a package in this library. 

2069 * Add package body to package :attr:`pyVHDLModel.DesignUnit.Package._packageBody`. 

2070 * Assign found package to package body's package symbol :attr:`pyVHDLModel.DesignUnit.PackageBody._package` 

2071 * Set parent namespace of package body's namespace to the package's namespace. 

2072 * Add an edge in the dependency graph from the package body's corresponding dependency vertex to the package's corresponding dependency vertex. 

2073 

2074 :raises VHDLModelException: If package name doesn't exist. 

2075 

2076 .. seealso:: 

2077 

2078 :meth:`LinkArchitectures` 

2079 Link all architectures to corresponding entities. 

2080 """ 

2081 for packageBodyName, packageBody in self._packageBodies.items(): 

2082 if packageBodyName not in self._packages: 2082 ↛ 2083line 2082 didn't jump to line 2083 because the condition on line 2082 was never true

2083 raise VHDLModelException(f"Package '{packageBodyName}' referenced by package body '{packageBodyName}' doesn't exist in library '{self._identifier}'.") 

2084 

2085 package = self._packages[packageBodyName] 

2086 package._packageBody = packageBody # TODO: add warning if package had already a body, which is now replaced 

2087 packageBody._package.Package = package 

2088 packageBody._namespace._parentNamespace = package._namespace 

2089 

2090 # add "package body -> package" relation in dependency graph 

2091 dependency = packageBody._dependencyVertex.EdgeToVertex(package._dependencyVertex) 

2092 dependency["kind"] = DependencyGraphEdgeKind.PackageImplementation 

2093 

2094 def IndexPackages(self) -> None: 

2095 """ 

2096 Index declared items in all packages. 

2097 

2098 .. rubric:: Algorithm 

2099 

2100 1. Iterate all packages: 

2101 

2102 * Index all declared items. |br| 

2103 |rarr| :meth:`pyVHDLModel.DesignUnit.Package.IndexDeclaredItems` 

2104 

2105 .. seealso:: 

2106 

2107 :meth:`IndexPackageBodies` 

2108 Index all declared items in a package body. 

2109 :meth:`IndexEntities` 

2110 Index all declared items in an entity. 

2111 :meth:`IndexArchitectures` 

2112 Index all declared items in an architecture. 

2113 """ 

2114 for package in self._packages.values(): 

2115 if isinstance(package, Package): 2115 ↛ 2114line 2115 didn't jump to line 2114 because the condition on line 2115 was always true

2116 package.IndexDeclaredItems() 

2117 

2118 def IndexPackageBodies(self) -> None: 

2119 """ 

2120 Index declared items in all package bodies. 

2121 

2122 .. rubric:: Algorithm 

2123 

2124 1. Iterate all package bodies: 

2125 

2126 * Index all declared items. |br| 

2127 |rarr| :meth:`pyVHDLModel.DesignUnit.PackageBody.IndexDeclaredItems` 

2128 

2129 .. seealso:: 

2130 

2131 :meth:`IndexPackages` 

2132 Index all declared items in a package. 

2133 :meth:`IndexEntities` 

2134 Index all declared items in an entity. 

2135 :meth:`IndexArchitectures` 

2136 Index all declared items in an architecture. 

2137 """ 

2138 for packageBody in self._packageBodies.values(): 

2139 packageBody.IndexDeclaredItems() 

2140 

2141 def IndexEntities(self) -> None: 

2142 """ 

2143 Index declared items in all entities. 

2144 

2145 .. rubric:: Algorithm 

2146 

2147 1. Iterate all entities: 

2148 

2149 * Index all declared items. |br| 

2150 |rarr| :meth:`pyVHDLModel.DesignUnit.Entity.IndexDeclaredItems` 

2151 

2152 .. seealso:: 

2153 

2154 :meth:`IndexPackages` 

2155 Index all declared items in a package. 

2156 :meth:`IndexPackageBodies` 

2157 Index all declared items in a package body. 

2158 :meth:`IndexArchitectures` 

2159 Index all declared items in an architecture. 

2160 """ 

2161 for entity in self._entities.values(): 

2162 entity.IndexDeclaredItems() 

2163 

2164 def IndexArchitectures(self) -> None: 

2165 """ 

2166 Index declared items in all architectures. 

2167 

2168 .. rubric:: Algorithm 

2169 

2170 1. Iterate all architectures: 

2171 

2172 * Index all declared items. |br| 

2173 |rarr| :meth:`pyVHDLModel.DesignUnit.Architecture.IndexDeclaredItems` 

2174 

2175 .. seealso:: 

2176 

2177 :meth:`IndexPackages` 

2178 Index all declared items in a package. 

2179 :meth:`IndexPackageBodies` 

2180 Index all declared items in a package body. 

2181 :meth:`IndexEntities` 

2182 Index all declared items in an entity. 

2183 """ 

2184 for architectures in self._architectures.values(): 

2185 for architecture in architectures.values(): 

2186 architecture.IndexDeclaredItems() 

2187 architecture.IndexStatements() 

2188 

2189 def __repr__(self) -> str: 

2190 """ 

2191 Formats a representation of the library. 

2192 

2193 **Format:** ``Library: 'my_library'`` 

2194 

2195 :returns: String representation of the library. 

2196 """ 

2197 return f"Library: '{self._identifier}'" 

2198 

2199 __str__ = __repr__ 

2200 

2201 

2202@export 

2203class Document(ModelEntity, DocumentedEntityMixin): 

2204 """A ``Document`` represents a sourcefile. It contains *primary* and *secondary* design units.""" 

2205 

2206 _path: Path #: path to the document. ``None`` if virtual document. 

2207 _designUnits: List[DesignUnit] #: List of all design units defined in a document. 

2208 _contexts: Dict[str, Context] #: Dictionary of all contexts defined in a document. 

2209 _configurations: Dict[str, Configuration] #: Dictionary of all configurations defined in a document. 

2210 _entities: Dict[str, Entity] #: Dictionary of all entities defined in a document. 

2211 _architectures: Dict[str, Dict[str, Architecture]] #: Dictionary of all architectures defined in a document. 

2212 _packages: Dict[str, Package] #: Dictionary of all packages defined in a document. 

2213 _packageBodies: Dict[str, PackageBody] #: Dictionary of all package bodies defined in a document. 

2214 _verificationUnits: Dict[str, VerificationUnit] #: Dictionary of all PSL verification units defined in a document. 

2215 _verificationProperties: Dict[str, VerificationProperty] #: Dictionary of all PSL verification properties defined in a document. 

2216 _verificationModes: Dict[str, VerificationMode] #: Dictionary of all PSL verification modes defined in a document. 

2217 

2218 _dependencyVertex: Vertex[None, None, None, 'Document', None, None, None, None, None, None, None, None, None, None, None, None, None] #: Reference to the vertex in the dependency graph representing the document. |br| This reference is set by :meth:`~pyVHDLModel.Design.CreateCompileOrderGraph`. 

2219 _compileOrderVertex: Vertex[None, None, None, 'Document', None, None, None, None, None, None, None, None, None, None, None, None, None] #: Reference to the vertex in the compile-order graph representing the document. |br| This reference is set by :meth:`~pyVHDLModel.Design.CreateCompileOrderGraph`. 

2220 

2221 def __init__(self, path: Path, documentation: Nullable[str] = None, parent: ModelEntity = None) -> None: 

2222 super().__init__(parent) 

2223 DocumentedEntityMixin.__init__(self, documentation) 

2224 

2225 self._path = path 

2226 self._designUnits = [] 

2227 self._contexts = {} 

2228 self._configurations = {} 

2229 self._entities = {} 

2230 self._architectures = {} 

2231 self._packages = {} 

2232 self._packageBodies = {} 

2233 self._verificationUnits = {} 

2234 self._verificationProperties = {} 

2235 self._verificationModes = {} 

2236 

2237 self._dependencyVertex = None 

2238 self._compileOrderVertex = None 

2239 

2240 def _AddEntity(self, item: Entity) -> None: 

2241 """ 

2242 Add an entity to the document's lists of design units. 

2243 

2244 :param item: Entity object to be added to the document. 

2245 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.Entity`. 

2246 :raises VHDLModelException: If entity name already exists in document. 

2247 """ 

2248 if not isinstance(item, Entity): 2248 ↛ 2249line 2248 didn't jump to line 2249 because the condition on line 2248 was never true

2249 ex = TypeError(f"Parameter 'item' is not of type 'Entity'.") 

2250 if version_info >= (3, 11): # pragma: no cover 

2251 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2252 raise ex 

2253 

2254 identifier = item._normalizedIdentifier 

2255 if identifier in self._entities: 2255 ↛ 2257line 2255 didn't jump to line 2257 because the condition on line 2255 was never true

2256 # TODO: use a more specific exception 

2257 raise VHDLModelException(f"An entity '{item._identifier}' already exists in this document.") 

2258 

2259 self._entities[identifier] = item 

2260 self._designUnits.append(item) 

2261 item._document = self 

2262 

2263 def _AddArchitecture(self, item: Architecture) -> None: 

2264 """ 

2265 Add an architecture to the document's lists of design units. 

2266 

2267 :param item: Architecture object to be added to the document. 

2268 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.Architecture`. 

2269 :raises VHDLModelException: If architecture name already exists for the referenced entity name in document. 

2270 """ 

2271 if not isinstance(item, Architecture): 2271 ↛ 2272line 2271 didn't jump to line 2272 because the condition on line 2271 was never true

2272 ex = TypeError(f"Parameter 'item' is not of type 'Architecture'.") 

2273 if version_info >= (3, 11): # pragma: no cover 

2274 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2275 raise ex 

2276 

2277 entity = item._entity.Name 

2278 entityIdentifier = entity._normalizedIdentifier 

2279 try: 

2280 architectures = self._architectures[entityIdentifier] 

2281 if item._normalizedIdentifier in architectures: 

2282 # TODO: use a more specific exception 

2283 # FIXME: this is allowed and should be a warning or a strict mode. 

2284 raise VHDLModelException(f"An architecture '{item._identifier}' for entity '{entity._identifier}' already exists in this document.") 

2285 

2286 architectures[item.Identifier] = item 

2287 except KeyError: 

2288 self._architectures[entityIdentifier] = {item._identifier: item} 

2289 

2290 self._designUnits.append(item) 

2291 item._document = self 

2292 

2293 def _AddPackage(self, item: Package) -> None: 

2294 """ 

2295 Add a package to the document's lists of design units. 

2296 

2297 :param item: Package object to be added to the document. 

2298 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.Package`. 

2299 :raises VHDLModelException: If package name already exists in document. 

2300 """ 

2301 if not isinstance(item, (Package, PackageInstantiation)): 2301 ↛ 2302line 2301 didn't jump to line 2302 because the condition on line 2301 was never true

2302 ex = TypeError(f"Parameter 'item' is not of type 'Package' or 'PackageInstantiation'.") 

2303 if version_info >= (3, 11): # pragma: no cover 

2304 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2305 raise ex 

2306 

2307 identifier = item._normalizedIdentifier 

2308 if identifier in self._packages: 2308 ↛ 2310line 2308 didn't jump to line 2310 because the condition on line 2308 was never true

2309 # TODO: use a more specific exception 

2310 raise VHDLModelException(f"A package '{item._identifier}' already exists in this document.") 

2311 

2312 self._packages[identifier] = item 

2313 self._designUnits.append(item) 

2314 item._document = self 

2315 

2316 def _AddPackageBody(self, item: PackageBody) -> None: 

2317 """ 

2318 Add a package body to the document's lists of design units. 

2319 

2320 :param item: Package body object to be added to the document. 

2321 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.PackageBody`. 

2322 :raises VHDLModelException: If package body name already exists in document. 

2323 """ 

2324 if not isinstance(item, PackageBody): 2324 ↛ 2325line 2324 didn't jump to line 2325 because the condition on line 2324 was never true

2325 ex = TypeError(f"Parameter 'item' is not of type 'PackageBody'.") 

2326 if version_info >= (3, 11): # pragma: no cover 

2327 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2328 raise ex 

2329 

2330 identifier = item._normalizedIdentifier 

2331 if identifier in self._packageBodies: 2331 ↛ 2333line 2331 didn't jump to line 2333 because the condition on line 2331 was never true

2332 # TODO: use a more specific exception 

2333 raise VHDLModelException(f"A package body '{item._identifier}' already exists in this document.") 

2334 

2335 self._packageBodies[identifier] = item 

2336 self._designUnits.append(item) 

2337 item._document = self 

2338 

2339 def _AddContext(self, item: Context) -> None: 

2340 """ 

2341 Add a context to the document's lists of design units. 

2342 

2343 :param item: Context object to be added to the document. 

2344 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.Context`. 

2345 :raises VHDLModelException: If context name already exists in document. 

2346 """ 

2347 if not isinstance(item, Context): 2347 ↛ 2348line 2347 didn't jump to line 2348 because the condition on line 2347 was never true

2348 ex = TypeError(f"Parameter 'item' is not of type 'Context'.") 

2349 if version_info >= (3, 11): # pragma: no cover 

2350 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2351 raise ex 

2352 

2353 identifier = item._normalizedIdentifier 

2354 if identifier in self._contexts: 2354 ↛ 2356line 2354 didn't jump to line 2356 because the condition on line 2354 was never true

2355 # TODO: use a more specific exception 

2356 raise VHDLModelException(f"A context '{item._identifier}' already exists in this document.") 

2357 

2358 self._contexts[identifier] = item 

2359 self._designUnits.append(item) 

2360 item._document = self 

2361 

2362 def _AddConfiguration(self, item: Configuration) -> None: 

2363 """ 

2364 Add a configuration to the document's lists of design units. 

2365 

2366 :param item: Configuration object to be added to the document. 

2367 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.Configuration`. 

2368 :raises VHDLModelException: If configuration name already exists in document. 

2369 """ 

2370 if not isinstance(item, Configuration): 2370 ↛ 2371line 2370 didn't jump to line 2371 because the condition on line 2370 was never true

2371 ex = TypeError(f"Parameter 'item' is not of type 'Configuration'.") 

2372 if version_info >= (3, 11): # pragma: no cover 

2373 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2374 raise ex 

2375 

2376 identifier = item._normalizedIdentifier 

2377 if identifier in self._configurations: 2377 ↛ 2379line 2377 didn't jump to line 2379 because the condition on line 2377 was never true

2378 # TODO: use a more specific exception 

2379 raise VHDLModelException(f"A configuration '{item._identifier}' already exists in this document.") 

2380 

2381 self._configurations[identifier] = item 

2382 self._designUnits.append(item) 

2383 item._document = self 

2384 

2385 def _AddVerificationUnit(self, item: VerificationUnit) -> None: 

2386 if not isinstance(item, VerificationUnit): 

2387 ex = TypeError(f"Parameter 'item' is not of type 'VerificationUnit'.") 

2388 if version_info >= (3, 11): # pragma: no cover 

2389 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2390 raise ex 

2391 

2392 identifier = item._normalizedIdentifier 

2393 if identifier in self._verificationUnits: 

2394 raise ValueError(f"A verification unit '{item._identifier}' already exists in this document.") 

2395 

2396 self._verificationUnits[identifier] = item 

2397 self._designUnits.append(item) 

2398 item._document = self 

2399 

2400 def _AddVerificationProperty(self, item: VerificationProperty) -> None: 

2401 if not isinstance(item, VerificationProperty): 

2402 ex = TypeError(f"Parameter 'item' is not of type 'VerificationProperty'.") 

2403 if version_info >= (3, 11): # pragma: no cover 

2404 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2405 raise ex 

2406 

2407 identifier = item.NormalizedIdentifier 

2408 if identifier in self._verificationProperties: 

2409 raise ValueError(f"A verification property '{item.Identifier}' already exists in this document.") 

2410 

2411 self._verificationProperties[identifier] = item 

2412 self._designUnits.append(item) 

2413 item._document = self 

2414 

2415 def _AddVerificationMode(self, item: VerificationMode) -> None: 

2416 if not isinstance(item, VerificationMode): 

2417 ex = TypeError(f"Parameter 'item' is not of type 'VerificationMode'.") 

2418 if version_info >= (3, 11): # pragma: no cover 

2419 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2420 raise ex 

2421 

2422 identifier = item.NormalizedIdentifier 

2423 if identifier in self._verificationModes: 

2424 raise ValueError(f"A verification mode '{item.Identifier}' already exists in this document.") 

2425 

2426 self._verificationModes[identifier] = item 

2427 self._designUnits.append(item) 

2428 item._document = self 

2429 

2430 def _AddDesignUnit(self, item: DesignUnit) -> None: 

2431 """ 

2432 Add a design unit to the document's lists of design units. 

2433 

2434 :param item: Configuration object to be added to the document. 

2435 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.DesignUnit`. 

2436 :raises ValueError: If parameter 'item' is an unknown :class:`~pyVHDLModel.DesignUnits.DesignUnit`. 

2437 :raises VHDLModelException: If configuration name already exists in document. 

2438 """ 

2439 if not isinstance(item, DesignUnit): 2439 ↛ 2440line 2439 didn't jump to line 2440 because the condition on line 2439 was never true

2440 ex = TypeError(f"Parameter 'item' is not of type 'DesignUnit'.") 

2441 if version_info >= (3, 11): # pragma: no cover 

2442 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2443 raise ex 

2444 

2445 if isinstance(item, Entity): 

2446 self._AddEntity(item) 

2447 elif isinstance(item, Architecture): 

2448 self._AddArchitecture(item) 

2449 elif isinstance(item, Package): 

2450 self._AddPackage(item) 

2451 elif isinstance(item, PackageBody): 

2452 self._AddPackageBody(item) 

2453 elif isinstance(item, Context): 

2454 self._AddContext(item) 

2455 elif isinstance(item, Configuration): 2455 ↛ 2457line 2455 didn't jump to line 2457 because the condition on line 2455 was always true

2456 self._AddConfiguration(item) 

2457 elif isinstance(item, VerificationUnit): 

2458 self._AddVerificationUnit(item) 

2459 elif isinstance(item, VerificationProperty): 

2460 self._AddVerificationProperty(item) 

2461 elif isinstance(item, VerificationMode): 

2462 self._AddVerificationMode(item) 

2463 else: 

2464 ex = ValueError(f"Parameter 'item' is an unknown 'DesignUnit'.") 

2465 if version_info >= (3, 11): # pragma: no cover 

2466 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2467 raise ex 

2468 

2469 @readonly 

2470 def Path(self) -> Path: 

2471 """ 

2472 Read-only property to access the document's path (:attr:`_path`). 

2473 

2474 :returns: The path of this document. 

2475 """ 

2476 return self._path 

2477 

2478 @readonly 

2479 def DesignUnits(self) -> List[DesignUnit]: 

2480 """ 

2481 Read-only property to access a list of all design units declarations found in this document (:attr:`_designUnits`). 

2482 

2483 :returns: List of all design units. 

2484 """ 

2485 return self._designUnits 

2486 

2487 @readonly 

2488 def Contexts(self) -> Dict[str, Context]: 

2489 """ 

2490 Read-only property to access a list of all context declarations found in this document (:attr:`_contexts`). 

2491 

2492 :returns: List of all contexts. 

2493 """ 

2494 return self._contexts 

2495 

2496 @readonly 

2497 def Configurations(self) -> Dict[str, Configuration]: 

2498 """ 

2499 Read-only property to access a list of all configuration declarations found in this document (:attr:`_configurations`). 

2500 

2501 :returns: List of all configurations. 

2502 """ 

2503 return self._configurations 

2504 

2505 @readonly 

2506 def Entities(self) -> Dict[str, Entity]: 

2507 """ 

2508 Read-only property to access a list of all entity declarations found in this document (:attr:`_entities`). 

2509 

2510 :returns: List of all entities. 

2511 """ 

2512 return self._entities 

2513 

2514 @readonly 

2515 def Architectures(self) -> Dict[str, Dict[str, Architecture]]: 

2516 """ 

2517 Read-only property to access a list of all architecture declarations found in this document (:attr:`_architectures`). 

2518 

2519 :returns: List of all architectures. 

2520 """ 

2521 return self._architectures 

2522 

2523 @readonly 

2524 def Packages(self) -> Dict[str, Package]: 

2525 """ 

2526 Read-only property to access a list of all package declarations found in this document (:attr:`_packages`). 

2527 

2528 :returns: List of all packages. 

2529 """ 

2530 return self._packages 

2531 

2532 @readonly 

2533 def PackageBodies(self) -> Dict[str, PackageBody]: 

2534 """ 

2535 Read-only property to access a list of all package body declarations found in this document (:attr:`_packageBodies`). 

2536 

2537 :returns: List of all package bodies. 

2538 """ 

2539 return self._packageBodies 

2540 

2541 @readonly 

2542 def VerificationUnits(self) -> Dict[str, VerificationUnit]: 

2543 """ 

2544 Read-only property to access a list of all verification unit declarations found in this document (:attr:`_verificationUnits`). 

2545 

2546 :returns: List of all verification units. 

2547 """ 

2548 return self._verificationUnits 

2549 

2550 @readonly 

2551 def VerificationProperties(self) -> Dict[str, VerificationProperty]: 

2552 """ 

2553 Read-only property to access a list of all verification properties declarations found in this document (:attr:`_verificationProperties`). 

2554 

2555 :returns: List of all verification properties. 

2556 """ 

2557 return self._verificationProperties 

2558 

2559 @readonly 

2560 def VerificationModes(self) -> Dict[str, VerificationMode]: 

2561 """ 

2562 Read-only property to access a list of all verification modes declarations found in this document (:attr:`_verificationModes`). 

2563 

2564 :returns: List of all verification modes. 

2565 """ 

2566 return self._verificationModes 

2567 

2568 @readonly 

2569 def CompileOrderVertex(self) -> Vertex[None, None, None, 'Document', None, None, None, None, None, None, None, None, None, None, None, None, None]: 

2570 """ 

2571 Read-only property to access the corresponding compile-order vertex (:attr:`_compileOrderVertex`). 

2572 

2573 The compile-order vertex references this document by its value field. 

2574 

2575 :returns: The corresponding compile-order vertex. 

2576 """ 

2577 return self._compileOrderVertex 

2578 

2579 def IterateDesignUnits(self, filter: DesignUnitKind = DesignUnitKind.All) -> Generator[DesignUnit, None, None]: 

2580 """ 

2581 Iterate all design units in the document. 

2582 

2583 A union of :class:`DesignUnitKind` values can be given to filter the returned result for suitable design units. 

2584 

2585 .. rubric:: Algorithm 

2586 

2587 * If contexts are selected in the filter: 

2588 

2589 1. Iterate all contexts in that library. 

2590 

2591 * If packages are selected in the filter: 

2592 

2593 1. Iterate all packages in that library. 

2594 

2595 * If package bodies are selected in the filter: 

2596 

2597 1. Iterate all package bodies in that library. 

2598 

2599 * If entites are selected in the filter: 

2600 

2601 1. Iterate all entites in that library. 

2602 

2603 * If architectures are selected in the filter: 

2604 

2605 1. Iterate all architectures in that library. 

2606 

2607 * If configurations are selected in the filter: 

2608 

2609 1. Iterate all configurations in that library. 

2610 

2611 :param filter: An enumeration with possibly multiple flags to filter the returned design units. 

2612 :returns: A generator to iterate all matched design units in the document. 

2613 

2614 .. seealso:: 

2615 

2616 :meth:`pyVHDLModel.Design.IterateDesignUnits` 

2617 Iterate all design units in the design. 

2618 :meth:`pyVHDLModel.Library.IterateDesignUnits` 

2619 Iterate all design units in the library. 

2620 """ 

2621 if DesignUnitKind.Context in filter: 

2622 for context in self._contexts.values(): 

2623 yield context 

2624 

2625 if DesignUnitKind.Package in filter: 2625 ↛ 2629line 2625 didn't jump to line 2629 because the condition on line 2625 was always true

2626 for package in self._packages.values(): 

2627 yield package 

2628 

2629 if DesignUnitKind.PackageBody in filter: 

2630 for packageBody in self._packageBodies.values(): 

2631 yield packageBody 

2632 

2633 if DesignUnitKind.Entity in filter: 

2634 for entity in self._entities.values(): 

2635 yield entity 

2636 

2637 if DesignUnitKind.Architecture in filter: 

2638 for architectures in self._architectures.values(): 

2639 for architecture in architectures.values(): 

2640 yield architecture 

2641 

2642 if DesignUnitKind.Configuration in filter: 

2643 for configuration in self._configurations.values(): 

2644 yield configuration 

2645 

2646 # for verificationProperty in self._verificationUnits.values(): 

2647 # yield verificationProperty 

2648 # for verificationUnit in self._verificationProperties.values(): 

2649 # yield entity 

2650 # for verificationMode in self._verificationModes.values(): 

2651 # yield verificationMode 

2652 

2653 def __repr__(self) -> str: 

2654 """ 

2655 Formats a representation of the document. 

2656 

2657 **Format:** ``Document: 'path/to/file.vhdl'`` 

2658 

2659 :returns: String representation of the document. 

2660 """ 

2661 return f"Document: '{self._path}'" 

2662 

2663 __str__ = __repr__