Skip to content

Commit

Permalink
Move intermediate.rendering to doc (#418)
Browse files Browse the repository at this point in the history
We merge the module `intermediate.rendering` into `intermediate.doc` as
it is directly related to it, and no other functionalities emerged in
`intermediate.rendering`.

Originally, we thought that `intermediate.rendering` would span more
functionalities, which did not materialize.
  • Loading branch information
mristin authored Nov 7, 2023
1 parent def1900 commit 39980e5
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 221 deletions.
3 changes: 1 addition & 2 deletions aas_core_codegen/csharp/description.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
)
from aas_core_codegen.intermediate import (
doc as intermediate_doc,
rendering as intermediate_rendering,
_translate as intermediate_translate,
)

Expand Down Expand Up @@ -153,7 +152,7 @@ def visit_element(self, node: _Element) -> None:
self.visit(node.children)


class _ElementRenderer(intermediate_rendering.DocutilsElementTransformer[_NodeUnion]):
class _ElementRenderer(intermediate_doc.DocutilsElementTransformer[_NodeUnion]):
"""Render descriptions as C# docstring XML."""

def transform_text(
Expand Down
3 changes: 1 addition & 2 deletions aas_core_codegen/golang/description.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
)
from aas_core_codegen.intermediate import (
doc as intermediate_doc,
rendering as intermediate_rendering,
)


Expand Down Expand Up @@ -56,7 +55,7 @@ def __init__(
self.cls_or_enum = cls_or_enum


class _ElementRenderer(intermediate_rendering.DocutilsElementTransformer[str]):
class _ElementRenderer(intermediate_doc.DocutilsElementTransformer[str]):
"""Render descriptions as a content of a docstring."""

def __init__(self, context: Context) -> None:
Expand Down
3 changes: 1 addition & 2 deletions aas_core_codegen/intermediate/_translate.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
construction,
doc,
pattern_verification,
rendering,
)
from aas_core_codegen.intermediate._types import (
SymbolTable,
Expand Down Expand Up @@ -4195,7 +4194,7 @@ def check_and_report_duplicate(
def _verify_description_rendering_with_smoke(symbol_table: SymbolTable) -> List[Error]:
"""Check that we can smoke-render all the descriptions."""

class DummyRenderer(rendering.DocutilsElementTransformer[bool]):
class DummyRenderer(doc.DocutilsElementTransformer[bool]):
"""Perform a smoke rendering to test that all the elements have been covered."""

def transform_text(
Expand Down
205 changes: 202 additions & 3 deletions aas_core_codegen/intermediate/doc.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""Provide types for the references in the docstrings."""

# pylint: disable=keyword-arg-before-vararg

from typing import Union
import abc
from typing import Union, Tuple, Optional, TypeVar, Generic, List

import docutils
import docutils.nodes
from icontract import require
from icontract import require, ensure, DBC

from aas_core_codegen.intermediate._types import (
OurType,
Expand Down Expand Up @@ -143,3 +143,202 @@ def __init__( # type: ignore
docutils.nodes.TextElement.__init__(
self, rawsource, text, *children, **attributes
)


T = TypeVar("T")


class DocutilsElementTransformer(Generic[T], DBC):
"""
Transform a pre-defined subset of the docutils elements.
The subset is limited to the elements which we expect in the docstrings of
our meta-model. Following YAGNI ("you ain't gonna need it"), we do not visit
all the possible elements as our docstrings are indeed limited in style.
Following a common pattern throughout this code base, all the transforming functions
return either a result or an error.
"""

@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform(
self, element: docutils.nodes.Element
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Dispatch the transformation to the appropriate ``transform_*``."""
# NOTE (mristin, 2021-12-26):
# Please keep the dispatching order. We have to implement a chain-of-command,
# not an efficient dispatch as classes inherit from each other.

if isinstance(element, docutils.nodes.Text):
return self.transform_text(element)

elif isinstance(element, ReferenceToOurType):
return self.transform_reference_to_our_type_in_doc(element)

elif isinstance(element, ReferenceToAttribute):
return self.transform_reference_to_attribute_in_doc(element)

elif isinstance(element, ReferenceToArgument):
return self.transform_reference_to_argument_in_doc(element)

elif isinstance(element, ReferenceToConstraint):
return self.transform_reference_to_constraint_in_doc(element)

elif isinstance(element, ReferenceToConstant):
return self.transform_reference_to_constant_in_doc(element)

elif isinstance(element, docutils.nodes.literal):
return self.transform_literal(element)

elif isinstance(element, docutils.nodes.paragraph):
return self.transform_paragraph(element)

elif isinstance(element, docutils.nodes.emphasis):
return self.transform_emphasis(element)

elif isinstance(element, docutils.nodes.list_item):
return self.transform_list_item(element)

elif isinstance(element, docutils.nodes.bullet_list):
return self.transform_bullet_list(element)

elif isinstance(element, docutils.nodes.note):
return self.transform_note(element)

elif isinstance(element, docutils.nodes.reference):
return self.transform_reference(element)

elif isinstance(element, docutils.nodes.field_body):
return self.transform_field_body(element)

elif isinstance(element, docutils.nodes.document):
return self.transform_document(element)

else:
return None, [
(
f"Handling of the element of a description "
f"with type {type(element)} "
f"has not been implemented: {element}"
)
]

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_text(
self, element: docutils.nodes.Text
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a text element into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_reference_to_our_type_in_doc(
self, element: ReferenceToOurType
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a reference to our type into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_reference_to_attribute_in_doc(
self, element: ReferenceToAttribute
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a reference to an attribute into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_reference_to_argument_in_doc(
self, element: ReferenceToArgument
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a reference to an argument into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_reference_to_constraint_in_doc(
self, element: ReferenceToConstraint
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a reference to a constraint into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_reference_to_constant_in_doc(
self, element: ReferenceToConstant
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a reference to a constant into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_literal(
self, element: docutils.nodes.literal
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a code literal into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_paragraph(
self, element: docutils.nodes.paragraph
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a paragraph element into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_emphasis(
self, element: docutils.nodes.emphasis
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform an emphasis element into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_list_item(
self, element: docutils.nodes.list_item
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a list item element into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_bullet_list(
self, element: docutils.nodes.bullet_list
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a bullet list element into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_note(
self, element: docutils.nodes.note
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a note element into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_reference(
self, element: docutils.nodes.reference
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a general reference element into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_field_body(
self, element: docutils.nodes.field_body
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a field body into something."""
raise NotImplementedError()

@abc.abstractmethod
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_document(
self, element: docutils.nodes.document
) -> Tuple[Optional[T], Optional[List[str]]]:
"""Transform a document into something."""
raise NotImplementedError()
Loading

0 comments on commit 39980e5

Please sign in to comment.