diff options
Diffstat (limited to 'pyGHDL/dom')
-rw-r--r-- | pyGHDL/dom/Attribute.py | 17 | ||||
-rw-r--r-- | pyGHDL/dom/DesignUnit.py | 109 | ||||
-rw-r--r-- | pyGHDL/dom/InterfaceItem.py | 168 | ||||
-rw-r--r-- | pyGHDL/dom/Misc.py | 16 | ||||
-rw-r--r-- | pyGHDL/dom/NonStandard.py | 37 | ||||
-rw-r--r-- | pyGHDL/dom/Object.py | 124 | ||||
-rw-r--r-- | pyGHDL/dom/Subprogram.py | 16 | ||||
-rw-r--r-- | pyGHDL/dom/Symbol.py | 24 | ||||
-rw-r--r-- | pyGHDL/dom/Type.py | 25 | ||||
-rw-r--r-- | pyGHDL/dom/_Translate.py | 55 | ||||
-rw-r--r-- | pyGHDL/dom/_Utils.py | 16 | ||||
-rw-r--r-- | pyGHDL/dom/__init__.py | 2 | ||||
-rw-r--r-- | pyGHDL/dom/formatting/prettyprint.py | 6 | ||||
-rw-r--r-- | pyGHDL/dom/requirements.txt | 2 |
14 files changed, 319 insertions, 298 deletions
diff --git a/pyGHDL/dom/Attribute.py b/pyGHDL/dom/Attribute.py index 86be400ac..ccd3ecf47 100644 --- a/pyGHDL/dom/Attribute.py +++ b/pyGHDL/dom/Attribute.py @@ -13,7 +13,7 @@ # # License: # ============================================================================ -# Copyright (C) 2019-2021 Tristan Gingold +# Copyright (C) 2019-2022 Tristan Gingold # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -46,7 +46,7 @@ from pyGHDL.libghdl._types import Iir from pyGHDL.libghdl.vhdl import nodes from pyGHDL.libghdl.vhdl.tokens import Tok from pyGHDL.dom import DOMMixin, Position, DOMException, Expression -from pyGHDL.dom._Utils import GetNameOfNode, GetIirKindOfNode +from pyGHDL.dom._Utils import GetNameOfNode, GetIirKindOfNode, GetDocumentationOfNode from pyGHDL.dom._Translate import GetNameFromNode, GetExpressionFromNode from pyGHDL.dom.Names import SimpleName from pyGHDL.dom.Symbol import SimpleSubtypeSymbol @@ -54,18 +54,19 @@ from pyGHDL.dom.Symbol import SimpleSubtypeSymbol @export class Attribute(VHDLModel_Attribute, DOMMixin): - def __init__(self, node: Iir, identifier: str, subtype: SubtypeOrSymbol): - super().__init__(identifier, subtype) + def __init__(self, node: Iir, identifier: str, subtype: SubtypeOrSymbol, documentation: str = None): + super().__init__(identifier, subtype, documentation) DOMMixin.__init__(self, node) @classmethod def parse(cls, attributeNode: Iir) -> "Attribute": name = GetNameOfNode(attributeNode) + documentation = GetDocumentationOfNode(attributeNode) subtypeMark = nodes.Get_Type_Mark(attributeNode) subtypeName = GetNameOfNode(subtypeMark) subtype = SimpleSubtypeSymbol(subtypeMark, subtypeName) - return cls(attributeNode, name, subtype) + return cls(attributeNode, name, subtype, documentation) _TOKEN_TRANSLATION = { @@ -102,14 +103,16 @@ class AttributeSpecification(VHDLModel_AttributeSpecification, DOMMixin): attribute: Name, entityClass: EntityClass, expression: Expression, + documentation: str = None, ): - super().__init__(identifiers, attribute, entityClass, expression) + super().__init__(identifiers, attribute, entityClass, expression, documentation) DOMMixin.__init__(self, node) @classmethod def parse(cls, attributeNode: Iir) -> "AttributeSpecification": attributeDesignator = nodes.Get_Attribute_Designator(attributeNode) attributeName = GetNameFromNode(attributeDesignator) + documentation = GetDocumentationOfNode(attributeNode) names = [] entityNameList = nodes.Get_Entity_Name_List(attributeNode) @@ -136,4 +139,4 @@ class AttributeSpecification(VHDLModel_AttributeSpecification, DOMMixin): expression = GetExpressionFromNode(nodes.Get_Expression(attributeNode)) - return cls(attributeNode, names, attributeName, entityClass, expression) + return cls(attributeNode, names, attributeName, entityClass, expression, documentation) diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py index f45cb8340..eebf888bc 100644 --- a/pyGHDL/dom/DesignUnit.py +++ b/pyGHDL/dom/DesignUnit.py @@ -13,7 +13,7 @@ # # License: # ============================================================================ -# Copyright (C) 2019-2021 Tristan Gingold +# Copyright (C) 2019-2022 Tristan Gingold # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -43,11 +43,15 @@ from typing import Iterable from pyTooling.Decorators import export -from pyVHDLModel import ContextUnion, EntityOrSymbol -from pyVHDLModel.SyntaxModel import ( +from pyVHDLModel import ( + ContextUnion as VHDLModel_ContextUnion, + EntityOrSymbol as VHDLModel_EntityOrSymbol, LibraryClause as VHDLModel_LibraryClause, UseClause as VHDLModel_UseClause, ContextReference as VHDLModel_ContextReference, + Name, +) +from pyVHDLModel.SyntaxModel import ( Entity as VHDLModel_Entity, Architecture as VHDLModel_Architecture, Package as VHDLModel_Package, @@ -58,15 +62,16 @@ from pyVHDLModel.SyntaxModel import ( Component as VHDLModel_Component, GenericInterfaceItem, PortInterfaceItem, - Name, ConcurrentStatement, + PackageReferenceSymbol, + ContextReferenceSymbol, ) from pyGHDL.libghdl import utils from pyGHDL.libghdl._types import Iir from pyGHDL.libghdl.vhdl import nodes from pyGHDL.dom import DOMMixin, Position, DOMException -from pyGHDL.dom._Utils import GetNameOfNode +from pyGHDL.dom._Utils import GetNameOfNode, GetDocumentationOfNode from pyGHDL.dom._Translate import ( GetGenericsFromChainedNodes, GetPortsFromChainedNodes, @@ -82,41 +87,41 @@ __all__ = [] @export class LibraryClause(VHDLModel_LibraryClause, DOMMixin): - def __init__(self, libraryNode: Iir, names: Iterable[Name]): - super().__init__(names) + def __init__(self, libraryNode: Iir, symbols: Iterable[Name]): + super().__init__(symbols) DOMMixin.__init__(self, libraryNode) @export class UseClause(VHDLModel_UseClause, DOMMixin): - def __init__(self, useNode: Iir, names: Iterable[Name]): - super().__init__(names) + def __init__(self, useNode: Iir, symbols: Iterable[Name]): + super().__init__(symbols) DOMMixin.__init__(self, useNode) @classmethod def parse(cls, useNode: Iir): from pyGHDL.dom._Translate import GetNameFromNode - uses = [GetNameFromNode(nodes.Get_Selected_Name(useNode))] + uses = [PackageReferenceSymbol(GetNameFromNode(nodes.Get_Selected_Name(useNode)))] for use in utils.chain_iter(nodes.Get_Use_Clause_Chain(useNode)): - uses.append(GetNameFromNode(nodes.Get_Selected_Name(use))) + uses.append(PackageReferenceSymbol(GetNameFromNode(nodes.Get_Selected_Name(use)))) return cls(useNode, uses) @export class ContextReference(VHDLModel_ContextReference, DOMMixin): - def __init__(self, contextNode: Iir, names: Iterable[Name]): - super().__init__(names) + def __init__(self, contextNode: Iir, symbols: Iterable[Name]): + super().__init__(symbols) DOMMixin.__init__(self, contextNode) @classmethod def parse(cls, contextNode: Iir): from pyGHDL.dom._Translate import GetNameFromNode - contexts = [GetNameFromNode(nodes.Get_Selected_Name(contextNode))] + contexts = [ContextReferenceSymbol(GetNameFromNode(nodes.Get_Selected_Name(contextNode)))] for context in utils.chain_iter(nodes.Get_Context_Reference_Chain(contextNode)): - contexts.append(GetNameFromNode(nodes.Get_Selected_Name(context))) + contexts.append(ContextReferenceSymbol(GetNameFromNode(nodes.Get_Selected_Name(context)))) return cls(contextNode, contexts) @@ -127,18 +132,20 @@ class Entity(VHDLModel_Entity, DOMMixin): self, node: Iir, identifier: str, - contextItems: Iterable[ContextUnion] = None, + contextItems: Iterable[VHDLModel_ContextUnion] = None, genericItems: Iterable[GenericInterfaceItem] = None, portItems: Iterable[PortInterfaceItem] = None, declaredItems: Iterable = None, statements: Iterable["ConcurrentStatement"] = None, + documentation: str = None, ): - super().__init__(identifier, contextItems, genericItems, portItems, declaredItems, statements) + super().__init__(identifier, contextItems, genericItems, portItems, declaredItems, statements, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, entityNode: Iir, contextItems: Iterable[ContextUnion]): + def parse(cls, entityNode: Iir, contextItems: Iterable[VHDLModel_ContextUnion]): name = GetNameOfNode(entityNode) + documentation = GetDocumentationOfNode(entityNode) generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(entityNode)) ports = GetPortsFromChainedNodes(nodes.Get_Port_Chain(entityNode)) declaredItems = GetDeclaredItemsFromChainedNodes(nodes.Get_Declaration_Chain(entityNode), "entity", name) @@ -148,7 +155,7 @@ class Entity(VHDLModel_Entity, DOMMixin): # FIXME: read use clauses - return cls(entityNode, name, contextItems, generics, ports, declaredItems, statements) + return cls(entityNode, name, contextItems, generics, ports, declaredItems, statements, documentation) @export @@ -157,20 +164,22 @@ class Architecture(VHDLModel_Architecture, DOMMixin): self, node: Iir, identifier: str, - entity: EntityOrSymbol, - contextItems: Iterable[ContextUnion] = None, + entity: VHDLModel_EntityOrSymbol, + contextItems: Iterable[VHDLModel_ContextUnion] = None, declaredItems: Iterable = None, statements: Iterable["ConcurrentStatement"] = None, + documentation: str = None, ): - super().__init__(identifier, entity, contextItems, declaredItems, statements) + super().__init__(identifier, entity, contextItems, declaredItems, statements, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, architectureNode: Iir, contextItems: Iterable[ContextUnion]): + def parse(cls, architectureNode: Iir, contextItems: Iterable[VHDLModel_ContextUnion]): name = GetNameOfNode(architectureNode) + documentation = GetDocumentationOfNode(architectureNode) entityNameNode = nodes.Get_Entity_Name(architectureNode) entityName = GetNameOfNode(entityNameNode) - entity = EntitySymbol(entityNameNode, SimpleName(entityNameNode, entityName)) + entitySymbol = EntitySymbol(entityNameNode, SimpleName(entityNameNode, entityName)) declaredItems = GetDeclaredItemsFromChainedNodes( nodes.Get_Declaration_Chain(architectureNode), "architecture", name ) @@ -180,7 +189,7 @@ class Architecture(VHDLModel_Architecture, DOMMixin): # FIXME: read use clauses - return cls(architectureNode, name, entity, contextItems, declaredItems, statements) + return cls(architectureNode, name, entitySymbol, contextItems, declaredItems, statements, documentation) @export @@ -191,17 +200,19 @@ class Component(VHDLModel_Component, DOMMixin): identifier: str, genericItems: Iterable[GenericInterfaceItem] = None, portItems: Iterable[PortInterfaceItem] = None, + documentation: str = None, ): - super().__init__(identifier, genericItems, portItems) + super().__init__(identifier, genericItems, portItems, documentation) DOMMixin.__init__(self, node) @classmethod def parse(cls, componentNode: Iir): name = GetNameOfNode(componentNode) + documentation = GetDocumentationOfNode(componentNode) generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(componentNode)) ports = GetPortsFromChainedNodes(nodes.Get_Port_Chain(componentNode)) - return cls(componentNode, name, generics, ports) + return cls(componentNode, name, generics, ports, documentation) @export @@ -210,16 +221,18 @@ class Package(VHDLModel_Package, DOMMixin): self, node: Iir, identifier: str, - contextItems: Iterable[ContextUnion] = None, + contextItems: Iterable[VHDLModel_ContextUnion] = None, genericItems: Iterable[GenericInterfaceItem] = None, declaredItems: Iterable = None, + documentation: str = None, ): - super().__init__(identifier, contextItems, genericItems, declaredItems) + super().__init__(identifier, contextItems, genericItems, declaredItems, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, packageNode: Iir, contextItems: Iterable[ContextUnion]): + def parse(cls, packageNode: Iir, contextItems: Iterable[VHDLModel_ContextUnion]): name = GetNameOfNode(packageNode) + documentation = GetDocumentationOfNode(packageNode) packageHeader = nodes.Get_Package_Header(packageNode) if packageHeader is not nodes.Null_Iir: @@ -231,7 +244,7 @@ class Package(VHDLModel_Package, DOMMixin): # FIXME: read use clauses - return cls(packageNode, name, contextItems, generics, declaredItems) + return cls(packageNode, name, contextItems, generics, declaredItems, documentation) @export @@ -240,20 +253,22 @@ class PackageBody(VHDLModel_PackageBody, DOMMixin): self, node: Iir, identifier: str, - contextItems: Iterable[ContextUnion] = None, + contextItems: Iterable[VHDLModel_ContextUnion] = None, declaredItems: Iterable = None, + documentation: str = None, ): - super().__init__(identifier, contextItems, declaredItems) + super().__init__(identifier, contextItems, declaredItems, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, packageBodyNode: Iir, contextItems: Iterable[ContextUnion]): + def parse(cls, packageBodyNode: Iir, contextItems: Iterable[VHDLModel_ContextUnion]): name = GetNameOfNode(packageBodyNode) + documentation = GetDocumentationOfNode(packageBodyNode) declaredItems = GetDeclaredItemsFromChainedNodes(nodes.Get_Declaration_Chain(packageBodyNode), "package", name) # FIXME: read use clauses - return cls(packageBodyNode, name, contextItems, declaredItems) + return cls(packageBodyNode, name, contextItems, declaredItems, documentation) @export @@ -264,13 +279,15 @@ class PackageInstantiation(VHDLModel_PackageInstantiation, DOMMixin): identifier: str, uninstantiatedPackageName: Name, # genericItems: List[GenericInterfaceItem] = None, + documentation: str = None, ): - super().__init__(identifier, uninstantiatedPackageName) + super().__init__(identifier, uninstantiatedPackageName, documentation) DOMMixin.__init__(self, node) @classmethod def parse(cls, packageNode: Iir): name = GetNameOfNode(packageNode) + documentation = GetDocumentationOfNode(packageNode) uninstantiatedPackageName = nodes.Get_Uninstantiated_Package_Name(packageNode) # FIXME: read use clauses (does it apply here too?) @@ -278,7 +295,7 @@ class PackageInstantiation(VHDLModel_PackageInstantiation, DOMMixin): # FIXME: read generic map # genericAssociations = GetGenericMapAspect(nodes.Get_Generic_Map_Aspect_Chain(instantiationNode)) - return cls(packageNode, name, uninstantiatedPackageName) + return cls(packageNode, name, uninstantiatedPackageName, documentation) @export @@ -289,8 +306,9 @@ class Context(VHDLModel_Context, DOMMixin): identifier: str, libraryReferences: Iterable[LibraryClause] = None, packageReferences: Iterable[UseClause] = None, + documentation: str = None, ): - super().__init__(identifier, libraryReferences, packageReferences) + super().__init__(identifier, libraryReferences, packageReferences, documentation) DOMMixin.__init__(self, node) @classmethod @@ -298,6 +316,7 @@ class Context(VHDLModel_Context, DOMMixin): from pyGHDL.dom._Utils import GetIirKindOfNode name = GetNameOfNode(contextNode) + documentation = GetDocumentationOfNode(contextNode) items = [] names = [] @@ -316,25 +335,21 @@ class Context(VHDLModel_Context, DOMMixin): pos = Position.parse(item) raise DOMException(f"Unknown context item kind '{kind.name}' in context at line {pos.Line}.") - return cls(contextNode, name, items) + return cls(contextNode, name, items, documentation) @export class Configuration(VHDLModel_Configuration, DOMMixin): - def __init__( - self, - node: Iir, - identifier: str, - contextItems: Iterable[Context] = None, - ): - super().__init__(identifier, contextItems) + def __init__(self, node: Iir, identifier: str, contextItems: Iterable[Context] = None, documentation: str = None): + super().__init__(identifier, contextItems, documentation) DOMMixin.__init__(self, node) @classmethod def parse(cls, configurationNode: Iir, contextItems: Iterable[Context]): name = GetNameOfNode(configurationNode) + documentation = GetDocumentationOfNode(configurationNode) # FIXME: read use clauses # FIXME: read specifications - return cls(configurationNode, name, contextItems) + return cls(configurationNode, name, contextItems, documentation) diff --git a/pyGHDL/dom/InterfaceItem.py b/pyGHDL/dom/InterfaceItem.py index 66a8fe37b..aa63f3094 100644 --- a/pyGHDL/dom/InterfaceItem.py +++ b/pyGHDL/dom/InterfaceItem.py @@ -13,7 +13,7 @@ # # License: # ============================================================================ -# Copyright (C) 2019-2021 Tristan Gingold +# Copyright (C) 2019-2022 Tristan Gingold # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -30,7 +30,7 @@ # # SPDX-License-Identifier: GPL-2.0-or-later # ============================================================================ -from typing import List +from typing import List, Iterable from pyTooling.Decorators import export @@ -53,7 +53,7 @@ from pyVHDLModel.SyntaxModel import ( from pyGHDL.libghdl._types import Iir from pyGHDL.libghdl.vhdl import nodes from pyGHDL.dom import DOMMixin -from pyGHDL.dom._Utils import GetNameOfNode, GetModeOfNode +from pyGHDL.dom._Utils import GetNameOfNode, GetModeOfNode, GetDocumentationOfNode from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode, GetExpressionFromNode @@ -69,95 +69,80 @@ class GenericConstantInterfaceItem(VHDLModel_GenericConstantInterfaceItem, DOMMi mode: Mode, subtype: SubtypeOrSymbol, defaultExpression: ExpressionUnion, + documentation: str = None, ): - super().__init__(identifiers, mode, subtype, defaultExpression) + super().__init__(identifiers, mode, subtype, defaultExpression, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, genericNode: Iir) -> "GenericConstantInterfaceItem": + def parse(cls, genericNode: Iir, furtherIdentifiers: Iterable[str] = None) -> "GenericConstantInterfaceItem": name = GetNameOfNode(genericNode) + documentation = GetDocumentationOfNode(genericNode) + identifiers = [name] + if furtherIdentifiers is not None: + identifiers.extend(furtherIdentifiers) mode = GetModeOfNode(genericNode) subtypeIndication = GetSubtypeIndicationFromNode(genericNode, "generic", name) default = nodes.Get_Default_Value(genericNode) value = GetExpressionFromNode(default) if default else None - return cls( - genericNode, - [ - name, - ], - mode, - subtypeIndication, - value, - ) + return cls(genericNode, identifiers, mode, subtypeIndication, value, documentation) @export class GenericTypeInterfaceItem(VHDLModel_GenericTypeInterfaceItem, DOMMixin): - def __init__( - self, - node: Iir, - identifier: str, - ): - super().__init__(identifier) + def __init__(self, node: Iir, identifier: str, documentation: str = None): + super().__init__(identifier, documentation) DOMMixin.__init__(self, node) @classmethod def parse(cls, genericNode: Iir) -> "GenericTypeInterfaceItem": name = GetNameOfNode(genericNode) + documentation = GetDocumentationOfNode(genericNode) - return cls(genericNode, name) + return cls(genericNode, name, documentation) @export class GenericPackageInterfaceItem(VHDLModel_GenericPackageInterfaceItem, DOMMixin): - def __init__( - self, - node: Iir, - name: str, - ): - super().__init__(name) + def __init__(self, node: Iir, name: str, documentation: str = None): + super().__init__(name, documentation) DOMMixin.__init__(self, node) @classmethod def parse(cls, genericNode: Iir) -> "GenericPackageInterfaceItem": name = GetNameOfNode(genericNode) + documentation = GetDocumentationOfNode(genericNode) - return cls(genericNode, name) + return cls(genericNode, name, documentation) @export class GenericProcedureInterfaceItem(VHDLModel_GenericProcedureInterfaceItem, DOMMixin): - def __init__( - self, - node: Iir, - identifier: str, - ): - super().__init__(identifier) + def __init__(self, node: Iir, identifier: str, documentation: str = None): + super().__init__(identifier, documentation) DOMMixin.__init__(self, node) @classmethod def parse(cls, genericNode: Iir) -> "GenericProcedureInterfaceItem": name = GetNameOfNode(genericNode) + documentation = GetDocumentationOfNode(genericNode) - return cls(genericNode, name) + return cls(genericNode, name, documentation) @export class GenericFunctionInterfaceItem(VHDLModel_GenericFunctionInterfaceItem, DOMMixin): - def __init__( - self, - node: Iir, - identifier: str, - ): - super().__init__(identifier) + def __init__(self, node: Iir, identifier: str, documentation: str = None): + super().__init__(identifier, documentation) DOMMixin.__init__(self, node) @classmethod def parse(cls, genericNode: Iir) -> "GenericFunctionInterfaceItem": name = GetNameOfNode(genericNode) + documentation = GetDocumentationOfNode(genericNode) - return cls(genericNode, name) + return cls(genericNode, name, documentation) @export @@ -169,28 +154,25 @@ class PortSignalInterfaceItem(VHDLModel_PortSignalInterfaceItem, DOMMixin): mode: Mode, subtype: SubtypeOrSymbol, defaultExpression: ExpressionUnion = None, + documentation: str = None, ): - super().__init__(identifiers, mode, subtype, defaultExpression) + super().__init__(identifiers, mode, subtype, defaultExpression, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, portNode: Iir) -> "PortSignalInterfaceItem": + def parse(cls, portNode: Iir, furtherIdentifiers: Iterable[str] = None) -> "PortSignalInterfaceItem": name = GetNameOfNode(portNode) + documentation = GetDocumentationOfNode(portNode) + identifiers = [name] + if furtherIdentifiers is not None: + identifiers.extend(furtherIdentifiers) mode = GetModeOfNode(portNode) subtypeIndication = GetSubtypeIndicationFromNode(portNode, "port", name) defaultValue = nodes.Get_Default_Value(portNode) value = GetExpressionFromNode(defaultValue) if defaultValue != nodes.Null_Iir else None - return cls( - portNode, - [ - name, - ], - mode, - subtypeIndication, - value, - ) + return cls(portNode, identifiers, mode, subtypeIndication, value, documentation) @export @@ -202,28 +184,25 @@ class ParameterConstantInterfaceItem(VHDLModel_ParameterConstantInterfaceItem, D mode: Mode, subtype: SubtypeOrSymbol, defaultExpression: ExpressionUnion = None, + documentation: str = None, ): - super().__init__(identifiers, mode, subtype, defaultExpression) + super().__init__(identifiers, mode, subtype, defaultExpression, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, parameterNode: Iir) -> "ParameterConstantInterfaceItem": + def parse(cls, parameterNode: Iir, furtherIdentifiers: Iterable[str] = None) -> "ParameterConstantInterfaceItem": name = GetNameOfNode(parameterNode) + documentation = GetDocumentationOfNode(parameterNode) + identifiers = [name] + if furtherIdentifiers is not None: + identifiers.extend(furtherIdentifiers) mode = GetModeOfNode(parameterNode) subtypeIndication = GetSubtypeIndicationFromNode(parameterNode, "parameter", name) defaultValue = nodes.Get_Default_Value(parameterNode) value = GetExpressionFromNode(defaultValue) if defaultValue != nodes.Null_Iir else None - return cls( - parameterNode, - [ - name, - ], - mode, - subtypeIndication, - value, - ) + return cls(parameterNode, identifiers, mode, subtypeIndication, value, documentation) @export @@ -235,28 +214,25 @@ class ParameterVariableInterfaceItem(VHDLModel_ParameterVariableInterfaceItem, D mode: Mode, subtype: SubtypeOrSymbol, defaultExpression: ExpressionUnion = None, + documentation: str = None, ): - super().__init__(identifiers, mode, subtype, defaultExpression) + super().__init__(identifiers, mode, subtype, defaultExpression, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, parameterNode: Iir) -> "ParameterVariableInterfaceItem": + def parse(cls, parameterNode: Iir, furtherIdentifiers: Iterable[str] = None) -> "ParameterVariableInterfaceItem": name = GetNameOfNode(parameterNode) + documentation = GetDocumentationOfNode(parameterNode) + identifiers = [name] + if furtherIdentifiers is not None: + identifiers.extend(furtherIdentifiers) mode = GetModeOfNode(parameterNode) subtypeIndication = GetSubtypeIndicationFromNode(parameterNode, "parameter", name) defaultValue = nodes.Get_Default_Value(parameterNode) value = GetExpressionFromNode(defaultValue) if defaultValue != nodes.Null_Iir else None - return cls( - parameterNode, - [ - name, - ], - mode, - subtypeIndication, - value, - ) + return cls(parameterNode, identifiers, mode, subtypeIndication, value, documentation) @export @@ -268,50 +244,40 @@ class ParameterSignalInterfaceItem(VHDLModel_ParameterSignalInterfaceItem, DOMMi mode: Mode, subtype: SubtypeOrSymbol, defaultExpression: ExpressionUnion = None, + documentation: str = None, ): - super().__init__(identifiers, mode, subtype, defaultExpression) + super().__init__(identifiers, mode, subtype, defaultExpression, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, parameterNode: Iir) -> "ParameterSignalInterfaceItem": + def parse(cls, parameterNode: Iir, furtherIdentifiers: Iterable[str] = None) -> "ParameterSignalInterfaceItem": name = GetNameOfNode(parameterNode) + documentation = GetDocumentationOfNode(parameterNode) + identifiers = [name] + if furtherIdentifiers is not None: + identifiers.extend(furtherIdentifiers) mode = GetModeOfNode(parameterNode) subtypeIndication = GetSubtypeIndicationFromNode(parameterNode, "parameter", name) defaultValue = nodes.Get_Default_Value(parameterNode) value = GetExpressionFromNode(defaultValue) if defaultValue != nodes.Null_Iir else None - return cls( - parameterNode, - [ - name, - ], - mode, - subtypeIndication, - value, - ) + return cls(parameterNode, identifiers, mode, subtypeIndication, value, documentation) @export class ParameterFileInterfaceItem(VHDLModel_ParameterFileInterfaceItem, DOMMixin): - def __init__( - self, - node: Iir, - identifiers: List[str], - subtype: SubtypeOrSymbol, - ): - super().__init__(identifiers, subtype) + def __init__(self, node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol, documentation: str = None): + super().__init__(identifiers, subtype, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, parameterNode: Iir) -> "ParameterFileInterfaceItem": + def parse(cls, parameterNode: Iir, furtherIdentifiers: Iterable[str] = None) -> "ParameterFileInterfaceItem": name = GetNameOfNode(parameterNode) + documentation = GetDocumentationOfNode(parameterNode) + identifiers = [name] + if furtherIdentifiers is not None: + identifiers.extend(furtherIdentifiers) subtypeIndication = GetSubtypeIndicationFromNode(parameterNode, "parameter", name) - return cls( - parameterNode, - [ - name, - ], - subtypeIndication, - ) + return cls(parameterNode, identifiers, subtypeIndication, documentation) diff --git a/pyGHDL/dom/Misc.py b/pyGHDL/dom/Misc.py index d6fc08524..8f85db222 100644 --- a/pyGHDL/dom/Misc.py +++ b/pyGHDL/dom/Misc.py @@ -13,7 +13,7 @@ # # License: # ============================================================================ -# Copyright (C) 2019-2021 Tristan Gingold +# Copyright (C) 2019-2022 Tristan Gingold # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -42,22 +42,22 @@ from pyVHDLModel.SyntaxModel import ( ) from pyGHDL.libghdl._types import Iir from pyGHDL.dom import DOMMixin -from pyGHDL.dom._Utils import GetNameOfNode - +from pyGHDL.dom._Utils import GetNameOfNode, GetDocumentationOfNode __all__ = [] @export class Alias(VHDLModel_Alias, DOMMixin): - def __init__(self, node: Iir, aliasName: str): - super().__init__(aliasName) + def __init__(self, node: Iir, aliasName: str, documentation: str = None): + super().__init__(aliasName, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, node: Iir): - aliasName = GetNameOfNode(node) + def parse(cls, aliasNode: Iir): + aliasName = GetNameOfNode(aliasNode) + documentation = GetDocumentationOfNode(aliasNode) # FIXME: add an implementation - return cls(node, aliasName) + return cls(aliasNode, aliasName) diff --git a/pyGHDL/dom/NonStandard.py b/pyGHDL/dom/NonStandard.py index c55786d54..14f5e1eac 100644 --- a/pyGHDL/dom/NonStandard.py +++ b/pyGHDL/dom/NonStandard.py @@ -13,7 +13,7 @@ # # License: # ============================================================================ -# Copyright (C) 2019-2021 Tristan Gingold +# Copyright (C) 2019-2022 Tristan Gingold # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -42,11 +42,11 @@ from typing import Any from pyTooling.Decorators import export -from pyGHDL.dom.Names import SimpleName from pyVHDLModel.SyntaxModel import ( Design as VHDLModel_Design, Library as VHDLModel_Library, Document as VHDLModel_Document, + LibraryReferenceSymbol, ) from pyGHDL.libghdl import ( @@ -61,9 +61,12 @@ from pyGHDL.libghdl import ( utils, files_map_editor, ) -from pyGHDL.libghdl.vhdl import nodes, sem_lib, parse +from pyGHDL.libghdl.flags import Flag_Gather_Comments +from pyGHDL.libghdl.vhdl import nodes, sem_lib +from pyGHDL.libghdl.vhdl.parse import Flag_Parse_Parenthesis from pyGHDL.dom import DOMException, Position -from pyGHDL.dom._Utils import GetIirKindOfNode, CheckForErrors, GetNameOfNode +from pyGHDL.dom._Utils import GetIirKindOfNode, CheckForErrors, GetNameOfNode, GetDocumentationOfNode +from pyGHDL.dom.Names import SimpleName from pyGHDL.dom.DesignUnit import ( Entity, Architecture, @@ -100,7 +103,8 @@ class Design(VHDLModel_Design): libghdl_set_option("--std=08") libghdl_set_option("--ams") - parse.Flag_Parse_Parenthesis.value = True + Flag_Gather_Comments.value = True + Flag_Parse_Parenthesis.value = True # Finish initialization. This will load the standard package. if libghdl_analyze_init_status() != 0: @@ -167,6 +171,7 @@ class Document(VHDLModel_Document): def translate(self): firstUnit = nodes.Get_First_Design_Unit(self.__ghdlFile) + self._documentation = GetDocumentationOfNode(firstUnit) for unit in utils.chain_iter(firstUnit): libraryUnit = nodes.Get_Library_Unit(unit) @@ -179,7 +184,7 @@ class Document(VHDLModel_Document): for item in utils.chain_iter(context): itemKind = GetIirKindOfNode(item) if itemKind is nodes.Iir_Kind.Library_Clause: - contextNames.append(SimpleName(item, GetNameOfNode(item))) + contextNames.append(LibraryReferenceSymbol(SimpleName(item, GetNameOfNode(item)))) if nodes.Get_Has_Identifier_List(item): continue @@ -197,43 +202,43 @@ class Document(VHDLModel_Document): if nodeKind == nodes.Iir_Kind.Entity_Declaration: entity = Entity.parse(libraryUnit, contextItems) - self.Entities.append(entity) + self._AddEntity(entity) elif nodeKind == nodes.Iir_Kind.Architecture_Body: architecture = Architecture.parse(libraryUnit, contextItems) - self.Architectures.append(architecture) + self._AddArchitecture(architecture) elif nodeKind == nodes.Iir_Kind.Package_Declaration: package = Package.parse(libraryUnit, contextItems) - self.Packages.append(package) + self._AddPackage(package) elif nodeKind == nodes.Iir_Kind.Package_Body: packageBody = PackageBody.parse(libraryUnit, contextItems) - self.PackageBodies.append(packageBody) + self._AddPackageBody(packageBody) elif nodeKind == nodes.Iir_Kind.Package_Instantiation_Declaration: package = PackageInstantiation.parse(libraryUnit) - self.Packages.append(package) + self._AddPackage(package) elif nodeKind == nodes.Iir_Kind.Context_Declaration: context = Context.parse(libraryUnit) - self.Contexts.append(context) + self._AddContext(context) elif nodeKind == nodes.Iir_Kind.Configuration_Declaration: configuration = Configuration.parse(libraryUnit, contextItems) - self.Configurations.append(configuration) + self._AddConfiguration(configuration) elif nodeKind == nodes.Iir_Kind.Vunit_Declaration: vunit = VerificationUnit.parse(libraryUnit) - self.VerificationUnits.append(vunit) + self._AddVerificationUnit(vunit) elif nodeKind == nodes.Iir_Kind.Vprop_Declaration: vprop = VerificationProperty.parse(libraryUnit) - self.VerificationProperties.append(vprop) + self._AddVerificationProperty(vprop) elif nodeKind == nodes.Iir_Kind.Vmode_Declaration: vmod = VerificationMode.parse(libraryUnit) - self.VerificationModes.append(vmod) + self._AddVerificationMode(vmod) else: raise DOMException(f"Unknown design unit kind '{nodeKind.name}'.") diff --git a/pyGHDL/dom/Object.py b/pyGHDL/dom/Object.py index 6d3472a6f..1079eae4a 100644 --- a/pyGHDL/dom/Object.py +++ b/pyGHDL/dom/Object.py @@ -13,7 +13,7 @@ # # License: # ============================================================================ -# Copyright (C) 2019-2021 Tristan Gingold +# Copyright (C) 2019-2022 Tristan Gingold # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -30,7 +30,7 @@ # # SPDX-License-Identifier: GPL-2.0-or-later # ============================================================================ -from typing import Union, List +from typing import Union, List, Iterable from pyTooling.Decorators import export @@ -48,7 +48,7 @@ from pyVHDLModel.SyntaxModel import ( from pyGHDL.libghdl._types import Iir from pyGHDL.libghdl.vhdl import nodes from pyGHDL.dom import DOMMixin -from pyGHDL.dom._Utils import GetNameOfNode +from pyGHDL.dom._Utils import GetNameOfNode, GetDocumentationOfNode __all__ = [] @@ -61,61 +61,53 @@ class Constant(VHDLModel_Constant, DOMMixin): identifiers: List[str], subtype: SubtypeOrSymbol, defaultExpression: ExpressionUnion, + documentation: str = None, ): - super().__init__(identifiers, subtype, defaultExpression) + super().__init__(identifiers, subtype, defaultExpression, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, constantNode: Iir) -> Union["Constant", "DeferredConstant"]: + def parse( + cls, constantNode: Iir, furtherIdentifiers: Iterable[str] = None + ) -> Union["Constant", "DeferredConstant"]: from pyGHDL.dom._Translate import ( GetSubtypeIndicationFromNode, GetExpressionFromNode, ) name = GetNameOfNode(constantNode) + documentation = GetDocumentationOfNode(constantNode) + identifiers = [name] + if furtherIdentifiers is not None: + identifiers.extend(furtherIdentifiers) subtypeIndication = GetSubtypeIndicationFromNode(constantNode, "constant", name) defaultValue = nodes.Get_Default_Value(constantNode) if defaultValue != nodes.Null_Iir: defaultExpression = GetExpressionFromNode(defaultValue) - return cls( - constantNode, - [ - name, - ], - subtypeIndication, - defaultExpression, - ) + return cls(constantNode, identifiers, subtypeIndication, defaultExpression, documentation) else: - return DeferredConstant( - constantNode, - [ - name, - ], - subtypeIndication, - ) + return DeferredConstant(constantNode, identifiers, subtypeIndication, documentation) @export class DeferredConstant(VHDLModel_DeferredConstant, DOMMixin): - def __init__(self, node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol): - super().__init__(identifiers, subtype) + def __init__(self, node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol, documentation: str = None): + super().__init__(identifiers, subtype, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, constantNode: Iir) -> "DeferredConstant": + def parse(cls, constantNode: Iir, furtherIdentifiers: Iterable[str] = None) -> "DeferredConstant": from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode name = GetNameOfNode(constantNode) + documentation = GetDocumentationOfNode(constantNode) + identifiers = [name] + if furtherIdentifiers is not None: + identifiers.extend(furtherIdentifiers) subtypeIndication = GetSubtypeIndicationFromNode(constantNode, "deferred constant", name) - return cls( - constantNode, - [ - name, - ], - subtypeIndication, - ) + return cls(constantNode, identifiers, subtypeIndication, documentation) @export @@ -126,54 +118,50 @@ class Variable(VHDLModel_Variable, DOMMixin): identifiers: List[str], subtype: SubtypeOrSymbol, defaultExpression: ExpressionUnion, + documentation: str = None, ): - super().__init__(identifiers, subtype, defaultExpression) + super().__init__(identifiers, subtype, defaultExpression, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, variableNode: Iir) -> "Variable": + def parse(cls, variableNode: Iir, furtherIdentifiers: Iterable[str] = None) -> "Variable": from pyGHDL.dom._Translate import ( GetSubtypeIndicationFromNode, GetExpressionFromNode, ) name = GetNameOfNode(variableNode) + documentation = GetDocumentationOfNode(variableNode) + identifiers = [name] + if furtherIdentifiers is not None: + identifiers.extend(furtherIdentifiers) subtypeIndication = GetSubtypeIndicationFromNode(variableNode, "variable", name) defaultValue = nodes.Get_Default_Value(variableNode) defaultExpression = None if defaultValue != nodes.Null_Iir: defaultExpression = GetExpressionFromNode(defaultValue) - return cls( - variableNode, - [ - name, - ], - subtypeIndication, - defaultExpression, - ) + return cls(variableNode, identifiers, subtypeIndication, defaultExpression, documentation) @export class SharedVariable(VHDLModel_SharedVariable, DOMMixin): - def __init__(self, node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol): - super().__init__(identifiers, subtype) + def __init__(self, node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol, documentation: str = None): + super().__init__(identifiers, subtype, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, variableNode: Iir) -> "SharedVariable": + def parse(cls, variableNode: Iir, furtherIdentifiers: Iterable[str] = None) -> "SharedVariable": from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode name = GetNameOfNode(variableNode) + documentation = GetDocumentationOfNode(variableNode) + identifiers = [name] + if furtherIdentifiers is not None: + identifiers.extend(furtherIdentifiers) subtypeIndication = GetSubtypeIndicationFromNode(variableNode, "variable", name) - return cls( - variableNode, - [ - name, - ], - subtypeIndication, - ) + return cls(variableNode, identifiers, subtypeIndication, documentation) @export @@ -184,51 +172,47 @@ class Signal(VHDLModel_Signal, DOMMixin): identifiers: List[str], subtype: SubtypeOrSymbol, defaultExpression: ExpressionUnion, + documentation: str = None, ): - super().__init__(identifiers, subtype, defaultExpression) + super().__init__(identifiers, subtype, defaultExpression, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, signalNode: Iir) -> "Signal": + def parse(cls, signalNode: Iir, furtherIdentifiers: Iterable[str] = None) -> "Signal": from pyGHDL.dom._Translate import ( GetSubtypeIndicationFromNode, GetExpressionFromNode, ) name = GetNameOfNode(signalNode) + documentation = GetDocumentationOfNode(signalNode) + identifiers = [name] + if furtherIdentifiers is not None: + identifiers.extend(furtherIdentifiers) subtypeIndication = GetSubtypeIndicationFromNode(signalNode, "signal", name) default = nodes.Get_Default_Value(signalNode) defaultExpression = GetExpressionFromNode(default) if default else None - return cls( - signalNode, - [ - name, - ], - subtypeIndication, - defaultExpression, - ) + return cls(signalNode, identifiers, subtypeIndication, defaultExpression, documentation) @export class File(VHDLModel_File, DOMMixin): - def __init__(self, node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol): - super().__init__(identifiers, subtype) + def __init__(self, node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol, documentation: str = None): + super().__init__(identifiers, subtype, documentation) DOMMixin.__init__(self, node) @classmethod - def parse(cls, fileNode: Iir) -> "File": + def parse(cls, fileNode: Iir, furtherIdentifiers: Iterable[str] = None) -> "File": from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode name = GetNameOfNode(fileNode) + documentation = GetDocumentationOfNode(fileNode) + identifiers = [name] + if furtherIdentifiers is not None: + identifiers.extend(furtherIdentifiers) subtypeIndication = GetSubtypeIndicationFromNode(fileNode, "file", name) # FIXME: handle file open stuff - return cls( - fileNode, - [ - name, - ], - subtypeIndication, - ) + return cls(fileNode, identifiers, subtypeIndication, documentation) diff --git a/pyGHDL/dom/Subprogram.py b/pyGHDL/dom/Subprogram.py index 2e9c0116f..46ce92707 100644 --- a/pyGHDL/dom/Subprogram.py +++ b/pyGHDL/dom/Subprogram.py @@ -13,7 +13,7 @@ # # License: # ============================================================================ -# Copyright (C) 2019-2021 Tristan Gingold +# Copyright (C) 2019-2022 Tristan Gingold # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ from pyVHDLModel.SyntaxModel import ( from pyGHDL.libghdl._types import Iir from pyGHDL.libghdl.vhdl import nodes from pyGHDL.dom import DOMMixin -from pyGHDL.dom._Utils import GetNameOfNode +from pyGHDL.dom._Utils import GetNameOfNode, GetDocumentationOfNode from pyGHDL.dom.Symbol import SimpleSubtypeSymbol @@ -57,8 +57,9 @@ class Function(VHDLModel_Function, DOMMixin): returnType: SubtypeOrSymbol, genericItems: List[GenericInterfaceItem] = None, parameterItems: List[ParameterInterfaceItem] = None, + documentation: str = None, ): - super().__init__(functionName) + super().__init__(functionName, documentation) DOMMixin.__init__(self, node) # TODO: move to model @@ -74,6 +75,7 @@ class Function(VHDLModel_Function, DOMMixin): ) functionName = GetNameOfNode(functionNode) + documentation = GetDocumentationOfNode(functionNode) generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(functionNode)) parameters = GetParameterFromChainedNodes(nodes.Get_Interface_Declaration_Chain(functionNode)) @@ -82,7 +84,7 @@ class Function(VHDLModel_Function, DOMMixin): returnTypeName = GetNameOfNode(returnType) returnTypeSymbol = SimpleSubtypeSymbol(returnType, returnTypeName) - return cls(functionNode, functionName, returnTypeSymbol, generics, parameters) + return cls(functionNode, functionName, returnTypeSymbol, generics, parameters, documentation) @export @@ -93,8 +95,9 @@ class Procedure(VHDLModel_Procedure, DOMMixin): procedureName: str, genericItems: List[GenericInterfaceItem] = None, parameterItems: List[ParameterInterfaceItem] = None, + documentation: str = None, ): - super().__init__(procedureName) + super().__init__(procedureName, documentation) DOMMixin.__init__(self, node) # TODO: move to model @@ -109,8 +112,9 @@ class Procedure(VHDLModel_Procedure, DOMMixin): ) procedureName = GetNameOfNode(procedureNode) + documentation = GetDocumentationOfNode(procedureNode) generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(procedureNode)) parameters = GetParameterFromChainedNodes(nodes.Get_Interface_Declaration_Chain(procedureNode)) - return cls(procedureNode, procedureName, generics, parameters) + return cls(procedureNode, procedureName, generics, parameters, documentation) diff --git a/pyGHDL/dom/Symbol.py b/pyGHDL/dom/Symbol.py index c5ed39ba3..0dd0fefa9 100644 --- a/pyGHDL/dom/Symbol.py +++ b/pyGHDL/dom/Symbol.py @@ -32,10 +32,13 @@ # ============================================================================ from typing import List, Iterator -from pyTooling.Decorators import export +from pyTooling.Decorators import export, InheritDocString +from pyGHDL.dom.Names import SimpleName from pyVHDLModel.SyntaxModel import ( EntitySymbol as VHDLModel_EntitySymbol, + ArchitectureSymbol as VHDLModel_ArchitectureSymbol, + PackageSymbol as VHDLModel_PackageSymbol, SimpleSubtypeSymbol as VHDLModel_SimpleSubtypeSymbol, ConstrainedScalarSubtypeSymbol as VHDLModel_ConstrainedScalarSubtypeSymbol, ConstrainedCompositeSubtypeSymbol as VHDLModel_ConstrainedCompositeSubtypeSymbol, @@ -54,12 +57,29 @@ __all__ = [] @export class EntitySymbol(VHDLModel_EntitySymbol, DOMMixin): - def __init__(self, node: Iir, entityName: Name): + @InheritDocString(VHDLModel_EntitySymbol) + def __init__(self, node: Iir, entityName: SimpleName): super().__init__(entityName) DOMMixin.__init__(self, node) @export +class ArchitectureSymbol(VHDLModel_ArchitectureSymbol, DOMMixin): + @InheritDocString(VHDLModel_ArchitectureSymbol) + def __init__(self, node: Iir, architectureName: SimpleName): + super().__init__(architectureName) + DOMMixin.__init__(self, node) + + +@export +class PackageSymbol(VHDLModel_PackageSymbol, DOMMixin): + @InheritDocString(VHDLModel_PackageSymbol) + def __init__(self, node: Iir, packageName: SimpleName): + super().__init__(packageName) + DOMMixin.__init__(self, node) + + +@export class SimpleSubtypeSymbol(VHDLModel_SimpleSubtypeSymbol, DOMMixin): def __init__(self, node: Iir, subtypeName: Name): if isinstance(subtypeName, (List, Iterator)): diff --git a/pyGHDL/dom/Type.py b/pyGHDL/dom/Type.py index b0f2d1311..2b71ccc3c 100644 --- a/pyGHDL/dom/Type.py +++ b/pyGHDL/dom/Type.py @@ -13,7 +13,7 @@ # # License: # ============================================================================ -# Copyright (C) 2019-2021 Tristan Gingold +# Copyright (C) 2019-2022 Tristan Gingold # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -30,7 +30,7 @@ # # SPDX-License-Identifier: GPL-2.0-or-later # ============================================================================ -from typing import List, Union, Iterator, Tuple +from typing import List, Union, Iterator, Tuple, Iterable from pyTooling.Decorators import export @@ -185,20 +185,18 @@ class RecordTypeElement(VHDLModel_RecordTypeElement, DOMMixin): DOMMixin.__init__(self, node) @classmethod - def parse(cls, elementDeclarationNode: Iir) -> "RecordTypeElement": + def parse(cls, elementDeclarationNode: Iir, furtherIdentifiers: Iterable[str] = None) -> "RecordTypeElement": from pyGHDL.dom._Utils import GetNameOfNode from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode elementName = GetNameOfNode(elementDeclarationNode) elementType = GetSubtypeIndicationFromNode(elementDeclarationNode, "record element", elementName) - return cls( - elementDeclarationNode, - [ - elementName, - ], - elementType, - ) + identifiers = [elementName] + if furtherIdentifiers is not None: + identifiers.extend(furtherIdentifiers) + + return cls(elementDeclarationNode, identifiers, elementType) @export @@ -214,13 +212,12 @@ class RecordType(VHDLModel_RecordType, DOMMixin): elements = [] elementDeclarations = nodes.Get_Elements_Declaration_List(typeDefinitionNode) + furtherIdentifiers = [] elementCount = flists.Flast(elementDeclarations) + 1 index = 0 while index < elementCount: elementDeclaration = flists.Get_Nth_Element(elementDeclarations, index) - element = RecordTypeElement.parse(elementDeclaration) - # Lookahead for elements with multiple identifiers at once if nodes.Get_Has_Identifier_List(elementDeclaration): index += 1 @@ -228,7 +225,7 @@ class RecordType(VHDLModel_RecordType, DOMMixin): nextNode: Iir = flists.Get_Nth_Element(elementDeclarations, index) # Consecutive identifiers are found, if the subtype indication is Null if nodes.Get_Subtype_Indication(nextNode) == nodes.Null_Iir: - element.Identifiers.append(GetNameOfNode(nextNode)) + furtherIdentifiers.append(GetNameOfNode(nextNode)) else: break index += 1 @@ -239,7 +236,9 @@ class RecordType(VHDLModel_RecordType, DOMMixin): else: index += 1 + element = RecordTypeElement.parse(elementDeclaration, furtherIdentifiers) elements.append(element) + furtherIdentifiers.clear() return cls(typeDefinitionNode, typeName, elements) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index a125abfe5..b3a48769b 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -464,13 +464,14 @@ def GetGenericsFromChainedNodes( GenericFunctionInterfaceItem, ) + furtherIdentifiers = [] generic = nodeChain while generic != nodes.Null_Iir: kind = GetIirKindOfNode(generic) if kind == nodes.Iir_Kind.Interface_Constant_Declaration: from pyGHDL.dom.InterfaceItem import GenericConstantInterfaceItem - genericConstant = GenericConstantInterfaceItem.parse(generic) + parseNode = generic # Lookahead for generics with multiple identifiers at once if nodes.Get_Has_Identifier_List(generic): @@ -478,7 +479,7 @@ def GetGenericsFromChainedNodes( for nextGeneric in utils.chain_iter(nextNode): # Consecutive identifiers are found, if the subtype indication is Null if nodes.Get_Subtype_Indication(nextGeneric) == nodes.Null_Iir: - genericConstant.Identifiers.append(GetNameOfNode(nextGeneric)) + furtherIdentifiers.append(GetNameOfNode(nextGeneric)) else: generic = nextGeneric break @@ -492,7 +493,8 @@ def GetGenericsFromChainedNodes( else: generic = nodes.Get_Chain(generic) - yield genericConstant + yield GenericConstantInterfaceItem.parse(parseNode, furtherIdentifiers) + furtherIdentifiers.clear() continue else: if kind == nodes.Iir_Kind.Interface_Type_Declaration: @@ -517,13 +519,14 @@ def GetPortsFromChainedNodes( nodeChain: Iir, ) -> Generator[PortInterfaceItem, None, None]: + furtherIdentifiers = [] port = nodeChain while port != nodes.Null_Iir: kind = GetIirKindOfNode(port) if kind == nodes.Iir_Kind.Interface_Signal_Declaration: from pyGHDL.dom.InterfaceItem import PortSignalInterfaceItem - portSignal = PortSignalInterfaceItem.parse(port) + portToParse = port # Lookahead for ports with multiple identifiers at once if nodes.Get_Has_Identifier_List(port): @@ -531,7 +534,7 @@ def GetPortsFromChainedNodes( for nextPort in utils.chain_iter(nextNode): # Consecutive identifiers are found, if the subtype indication is Null if nodes.Get_Subtype_Indication(nextPort) == nodes.Null_Iir: - portSignal.Identifiers.append(GetNameOfNode(nextPort)) + furtherIdentifiers.append(GetNameOfNode(nextPort)) else: port = nextPort break @@ -545,7 +548,8 @@ def GetPortsFromChainedNodes( else: port = nodes.Get_Chain(port) - yield portSignal + yield PortSignalInterfaceItem.parse(portToParse, furtherIdentifiers) + furtherIdentifiers.clear() continue else: position = Position.parse(port) @@ -559,25 +563,30 @@ def GetParameterFromChainedNodes( nodeChain: Iir, ) -> Generator[ParameterInterfaceItem, None, None]: + identifiers = [] parameter = nodeChain while parameter != nodes.Null_Iir: kind = GetIirKindOfNode(parameter) if kind == nodes.Iir_Kind.Interface_Constant_Declaration: from pyGHDL.dom.InterfaceItem import ParameterConstantInterfaceItem - param = ParameterConstantInterfaceItem.parse(parameter) + parseMethod = ParameterConstantInterfaceItem.parse + parseNode = parameter elif kind == nodes.Iir_Kind.Interface_Variable_Declaration: from pyGHDL.dom.InterfaceItem import ParameterVariableInterfaceItem - param = ParameterVariableInterfaceItem.parse(parameter) + parseMethod = ParameterVariableInterfaceItem.parse + parseNode = parameter elif kind == nodes.Iir_Kind.Interface_Signal_Declaration: from pyGHDL.dom.InterfaceItem import ParameterSignalInterfaceItem - param = ParameterSignalInterfaceItem.parse(parameter) + parseMethod = ParameterSignalInterfaceItem.parse + parseNode = parameter elif kind == nodes.Iir_Kind.Interface_File_Declaration: from pyGHDL.dom.InterfaceItem import ParameterFileInterfaceItem - param = ParameterFileInterfaceItem.parse(parameter) + parseMethod = ParameterFileInterfaceItem.parse + parseNode = parameter else: position = Position.parse(parameter) raise DOMException( @@ -590,7 +599,7 @@ def GetParameterFromChainedNodes( for nextParameter in utils.chain_iter(nextNode): # Consecutive identifiers are found, if the subtype indication is Null if nodes.Get_Subtype_Indication(nextParameter) == nodes.Null_Iir: - param.Identifiers.append(GetNameOfNode(nextParameter)) + identifiers.append(GetNameOfNode(nextParameter)) else: parameter = nextParameter break @@ -604,7 +613,7 @@ def GetParameterFromChainedNodes( else: parameter = nodes.Get_Chain(parameter) - yield param + yield parseMethod(parseNode, identifiers) def GetMapAspect(mapAspect: Iir, cls: Type, entity: str) -> Generator[AssociationItem, None, None]: @@ -650,6 +659,7 @@ def GetParameterMapAspect( def GetDeclaredItemsFromChainedNodes(nodeChain: Iir, entity: str, name: str) -> Generator[ModelEntity, None, None]: + furtherIdentifiers = [] item = nodeChain lastKind = None while item != nodes.Null_Iir: @@ -657,23 +667,27 @@ def GetDeclaredItemsFromChainedNodes(nodeChain: Iir, entity: str, name: str) -> if kind == nodes.Iir_Kind.Constant_Declaration: from pyGHDL.dom.Object import Constant - obj = Constant.parse(item) - + objectParseMethod = Constant.parse + objectItem = item elif kind == nodes.Iir_Kind.Variable_Declaration: from pyGHDL.dom.Object import SharedVariable if nodes.Get_Shared_Flag(item): - obj = SharedVariable.parse(item) + objectParseMethod = SharedVariable.parse + objectItem = item else: - obj = Variable.parse(item) + objectParseMethod = Variable.parse + objectItem = item elif kind == nodes.Iir_Kind.Signal_Declaration: from pyGHDL.dom.Object import Signal - obj = Signal.parse(item) + objectParseMethod = Signal.parse + objectItem = item elif kind == nodes.Iir_Kind.File_Declaration: from pyGHDL.dom.Object import File - obj = File.parse(item) + objectParseMethod = File.parse + objectItem = item else: if kind == nodes.Iir_Kind.Type_Declaration: yield GetTypeFromNode(item) @@ -782,7 +796,7 @@ def GetDeclaredItemsFromChainedNodes(nodeChain: Iir, entity: str, name: str) -> for nextItem in utils.chain_iter(nextNode): # Consecutive identifiers are found, if the subtype indication is Null if nodes.Get_Subtype_Indication(nextItem) == nodes.Null_Iir: - obj.Identifiers.append(GetNameOfNode(nextItem)) + furtherIdentifiers.append(GetNameOfNode(nextItem)) else: item = nextItem break @@ -796,7 +810,8 @@ def GetDeclaredItemsFromChainedNodes(nodeChain: Iir, entity: str, name: str) -> else: item = nodes.Get_Chain(item) - yield obj + yield objectParseMethod(objectItem, furtherIdentifiers) + furtherIdentifiers.clear() def GetConcurrentStatementsFromChainedNodes( diff --git a/pyGHDL/dom/_Utils.py b/pyGHDL/dom/_Utils.py index 0349a11ef..10053db6e 100644 --- a/pyGHDL/dom/_Utils.py +++ b/pyGHDL/dom/_Utils.py @@ -13,7 +13,7 @@ # # License: # ============================================================================ -# Copyright (C) 2019-2021 Tristan Gingold +# Copyright (C) 2019-2022 Tristan Gingold # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -34,7 +34,7 @@ from pyTooling.Decorators import export from pyVHDLModel.SyntaxModel import Mode -from pyGHDL.libghdl import LibGHDLException, name_table, errorout_memory +from pyGHDL.libghdl import LibGHDLException, name_table, errorout_memory, files_map, file_comments from pyGHDL.libghdl._types import Iir from pyGHDL.libghdl.vhdl import nodes, utils from pyGHDL.libghdl.vhdl.nodes import Null_Iir @@ -88,6 +88,18 @@ def GetNameOfNode(node: Iir) -> str: @export +def GetDocumentationOfNode(node: Iir) -> str: + file = files_map.Location_To_File(nodes.Get_Location(node)) + idx = file_comments.Find_First_Comment(file, node) + documentation = [] + while idx != file_comments.No_Comment_Index: + documentation.append(file_comments.Get_Comment(file, idx)) + idx = file_comments.Get_Next_Comment(file, idx) + + return "\n".join(documentation) + + +@export def GetModeOfNode(node: Iir) -> Mode: """Return the mode of a :obj:`node`.""" if node == Null_Iir: diff --git a/pyGHDL/dom/__init__.py b/pyGHDL/dom/__init__.py index e9eb89240..12caccc1b 100644 --- a/pyGHDL/dom/__init__.py +++ b/pyGHDL/dom/__init__.py @@ -39,8 +39,6 @@ from pyGHDL.libghdl import files_map, name_table from pyGHDL.libghdl._types import Iir from pyGHDL.libghdl.vhdl import nodes -__all__ = [] - @export class Position: diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index aa9c90c34..b5397610a 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -47,7 +47,7 @@ from pyGHDL.dom.Concurrent import ( ) from pyVHDLModel.SyntaxModel import ( GenericInterfaceItem, - NamedEntity, + NamedEntityMixin, PortInterfaceItem, WithDefaultExpressionMixin, Function, @@ -301,7 +301,7 @@ class PrettyPrint: return buffer - def formatGeneric(self, generic: Union[NamedEntity, GenericInterfaceItem], level: int = 0) -> StringBuffer: + def formatGeneric(self, generic: Union[NamedEntityMixin, GenericInterfaceItem], level: int = 0) -> StringBuffer: if isinstance(generic, GenericConstantInterfaceItem): return self.formatGenericConstant(generic, level) elif isinstance(generic, GenericTypeInterfaceItem): @@ -311,7 +311,7 @@ class PrettyPrint: f"Unhandled generic kind '{generic.__class__.__name__}' for generic '{generic.Identifiers[0]}'." ) - def formatPort(self, port: Union[NamedEntity, PortInterfaceItem], level: int = 0) -> StringBuffer: + def formatPort(self, port: Union[NamedEntityMixin, PortInterfaceItem], level: int = 0) -> StringBuffer: if isinstance(port, PortSignalInterfaceItem): return self.formatPortSignal(port, level) else: diff --git a/pyGHDL/dom/requirements.txt b/pyGHDL/dom/requirements.txt index 943757e92..6b540d7b7 100644 --- a/pyGHDL/dom/requirements.txt +++ b/pyGHDL/dom/requirements.txt @@ -1,4 +1,4 @@ -r ../libghdl/requirements.txt -pyVHDLModel==0.14.4 +pyVHDLModel==0.18.0 #https://github.com/VHDL/pyVHDLModel/archive/dev.zip#pyVHDLModel |