• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

aas-core-works / aas-core-codegen / 25098769931

29 Apr 2026 08:30AM UTC coverage: 83.966% (-0.02%) from 83.987%
25098769931

Pull #615

github

web-flow
Merge 1321aff3e into c752b149a
Pull Request #615: Discontinue RDF+SHACL and JSON-LD generators

30593 of 36435 relevant lines covered (83.97%)

3.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.79
/aas_core_codegen/intermediate/doc.py
1
"""Provide types for the references in the docstrings."""
2

3
# pylint: disable=keyword-arg-before-vararg
4
import abc
4✔
5
from typing import Union, Tuple, Optional, TypeVar, Generic, List
4✔
6

7
import docutils
4✔
8
import docutils.nodes
4✔
9
from icontract import require, ensure, DBC
4✔
10

11
from aas_core_codegen.intermediate._types import (
4✔
12
    OurType,
13
    Property,
14
    Enumeration,
15
    EnumerationLiteral,
16
    ClassUnion,
17
    ConstantUnion,
18
)
19

20

21
class ReferenceToOurType(
4✔
22
    docutils.nodes.Inline, docutils.nodes.TextElement  # type: ignore
23
):
24
    """Represent a reference in the documentation to our type."""
25

26
    def __init__(  # type: ignore
4✔
27
        self,
28
        our_type: OurType,
29
        rawsource="",
30
        text="",
31
        *children,
32
        **attributes,
33
    ) -> None:
34
        """Initialize with the given our type and propagate the rest to the parent."""
35
        self.our_type = our_type
4✔
36
        docutils.nodes.TextElement.__init__(
4✔
37
            self, rawsource, text, *children, **attributes
38
        )
39

40

41
class ReferenceToProperty:
4✔
42
    """Model a reference to a property, usually used in the docstrings."""
43

44
    @require(lambda cls, prop: id(prop) in cls.property_id_set)
4✔
45
    def __init__(self, cls: ClassUnion, prop: Property) -> None:
4✔
46
        self.cls = cls
4✔
47
        self.prop = prop
4✔
48

49

50
class ReferenceToEnumerationLiteral:
4✔
51
    """Model a reference to an enumeration literal, usually used in the docstrings."""
52

53
    @require(lambda enumeration, literal: id(literal) in enumeration.literal_id_set)
4✔
54
    def __init__(self, enumeration: Enumeration, literal: EnumerationLiteral) -> None:
4✔
55
        self.enumeration = enumeration
4✔
56
        self.literal = literal
4✔
57

58

59
class ReferenceToAttribute(
4✔
60
    docutils.nodes.Inline, docutils.nodes.TextElement  # type: ignore
61
):
62
    """
63
    Represent a reference in the documentation to an "attribute".
64

65
    The attribute, in this context, refers to the role ``:attr:``. The references
66
    imply either a reference to a property of a class or a literal of an enumeration.
67
    """
68

69
    def __init__(  # type: ignore
4✔
70
        self,
71
        reference: Union[ReferenceToProperty, ReferenceToEnumerationLiteral],
72
        rawsource="",
73
        text="",
74
        *children,
75
        **attributes,
76
    ) -> None:
77
        """Initialize with ``property_name`` and propagate the rest to the parent."""
78
        self.reference = reference
4✔
79
        docutils.nodes.TextElement.__init__(
4✔
80
            self, rawsource, text, *children, **attributes
81
        )
82

83

84
class ReferenceToArgument(
4✔
85
    docutils.nodes.Inline, docutils.nodes.TextElement  # type: ignore
86
):
87
    """
88
    Represent a reference in the documentation to a method argument ("parameter").
89

90
    The argument, in this context, refers to the role ``:paramref:``.
91
    """
92

93
    def __init__(  # type: ignore
4✔
94
        self,
95
        reference: str,
96
        rawsource="",
97
        text="",
98
        *children,
99
        **attributes,
100
    ) -> None:
101
        """Initialize with ``reference`` and propagate the rest to the parent."""
102
        self.reference = reference
4✔
103
        docutils.nodes.TextElement.__init__(
4✔
104
            self, rawsource, text, *children, **attributes
105
        )
106

107

108
class ReferenceToConstraint(
4✔
109
    docutils.nodes.Inline, docutils.nodes.TextElement  # type: ignore
110
):
111
    """Represent a reference in the documentation to a constraint."""
112

113
    def __init__(  # type: ignore
4✔
114
        self,
115
        reference: str,
116
        rawsource="",
117
        text="",
118
        *children,
119
        **attributes,
120
    ) -> None:
121
        """Initialize with ``reference`` and propagate the rest to the parent."""
122
        self.reference = reference
4✔
123
        docutils.nodes.TextElement.__init__(
4✔
124
            self, rawsource, text, *children, **attributes
125
        )
126

127

128
class ReferenceToConstant(
4✔
129
    docutils.nodes.Inline, docutils.nodes.TextElement  # type: ignore
130
):
131
    """Represent a reference in the documentation to a constant of the meta-model."""
132

133
    def __init__(  # type: ignore
4✔
134
        self,
135
        constant: ConstantUnion,
136
        rawsource="",
137
        text="",
138
        *children,
139
        **attributes,
140
    ) -> None:
141
        """Initialize with the given constant and propagate the rest to the parent."""
142
        self.constant = constant
4✔
143
        docutils.nodes.TextElement.__init__(
4✔
144
            self, rawsource, text, *children, **attributes
145
        )
146

147

148
T = TypeVar("T")
4✔
149

150

151
class DocutilsElementTransformer(Generic[T], DBC):
4✔
152
    """
153
    Transform a pre-defined subset of the docutils elements.
154

155
    The subset is limited to the elements which we expect in the docstrings of
156
    our meta-model. Following YAGNI ("you ain't gonna need it"), we do not visit
157
    all the possible elements as our docstrings are indeed limited in style.
158

159
    Following a common pattern throughout this code base, all the transforming functions
160
    return either a result or an error.
161
    """
162

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

172
        if isinstance(element, docutils.nodes.Text):
4✔
173
            return self.transform_text(element)
4✔
174

175
        elif isinstance(element, ReferenceToOurType):
4✔
176
            return self.transform_reference_to_our_type_in_doc(element)
4✔
177

178
        elif isinstance(element, ReferenceToAttribute):
4✔
179
            return self.transform_reference_to_attribute_in_doc(element)
4✔
180

181
        elif isinstance(element, ReferenceToArgument):
4✔
182
            return self.transform_reference_to_argument_in_doc(element)
4✔
183

184
        elif isinstance(element, ReferenceToConstraint):
4✔
185
            return self.transform_reference_to_constraint_in_doc(element)
4✔
186

187
        elif isinstance(element, ReferenceToConstant):
4✔
188
            return self.transform_reference_to_constant_in_doc(element)
4✔
189

190
        elif isinstance(element, docutils.nodes.literal):
4✔
191
            return self.transform_literal(element)
4✔
192

193
        elif isinstance(element, docutils.nodes.paragraph):
4✔
194
            return self.transform_paragraph(element)
4✔
195

196
        elif isinstance(element, docutils.nodes.emphasis):
4✔
197
            return self.transform_emphasis(element)
4✔
198

199
        elif isinstance(element, docutils.nodes.list_item):
4✔
200
            return self.transform_list_item(element)
4✔
201

202
        elif isinstance(element, docutils.nodes.bullet_list):
4✔
203
            return self.transform_bullet_list(element)
4✔
204

205
        elif isinstance(element, docutils.nodes.note):
4✔
206
            return self.transform_note(element)
4✔
207

208
        elif isinstance(element, docutils.nodes.reference):
4✔
209
            return self.transform_reference(element)
4✔
210

211
        elif isinstance(element, docutils.nodes.field_body):
4✔
212
            return self.transform_field_body(element)
4✔
213

214
        elif isinstance(element, docutils.nodes.document):
4✔
215
            return self.transform_document(element)
×
216

217
        else:
218
            return None, [
4✔
219
                (
220
                    f"Handling of the element of a description "
221
                    f"with type {type(element)} "
222
                    f"has not been implemented: {element}"
223
                )
224
            ]
225

226
    @abc.abstractmethod
4✔
227
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
228
    def transform_text(
4✔
229
        self, element: docutils.nodes.Text
230
    ) -> Tuple[Optional[T], Optional[List[str]]]:
231
        """Transform a text element into something."""
232
        raise NotImplementedError()
×
233

234
    @abc.abstractmethod
4✔
235
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
236
    def transform_reference_to_our_type_in_doc(
4✔
237
        self, element: ReferenceToOurType
238
    ) -> Tuple[Optional[T], Optional[List[str]]]:
239
        """Transform a reference to our type into something."""
240
        raise NotImplementedError()
×
241

242
    @abc.abstractmethod
4✔
243
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
244
    def transform_reference_to_attribute_in_doc(
4✔
245
        self, element: ReferenceToAttribute
246
    ) -> Tuple[Optional[T], Optional[List[str]]]:
247
        """Transform a reference to an attribute into something."""
248
        raise NotImplementedError()
×
249

250
    @abc.abstractmethod
4✔
251
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
252
    def transform_reference_to_argument_in_doc(
4✔
253
        self, element: ReferenceToArgument
254
    ) -> Tuple[Optional[T], Optional[List[str]]]:
255
        """Transform a reference to an argument into something."""
256
        raise NotImplementedError()
×
257

258
    @abc.abstractmethod
4✔
259
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
260
    def transform_reference_to_constraint_in_doc(
4✔
261
        self, element: ReferenceToConstraint
262
    ) -> Tuple[Optional[T], Optional[List[str]]]:
263
        """Transform a reference to a constraint into something."""
264
        raise NotImplementedError()
×
265

266
    @abc.abstractmethod
4✔
267
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
268
    def transform_reference_to_constant_in_doc(
4✔
269
        self, element: ReferenceToConstant
270
    ) -> Tuple[Optional[T], Optional[List[str]]]:
271
        """Transform a reference to a constant into something."""
272
        raise NotImplementedError()
×
273

274
    @abc.abstractmethod
4✔
275
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
276
    def transform_literal(
4✔
277
        self, element: docutils.nodes.literal
278
    ) -> Tuple[Optional[T], Optional[List[str]]]:
279
        """Transform a code literal into something."""
280
        raise NotImplementedError()
×
281

282
    @abc.abstractmethod
4✔
283
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
284
    def transform_paragraph(
4✔
285
        self, element: docutils.nodes.paragraph
286
    ) -> Tuple[Optional[T], Optional[List[str]]]:
287
        """Transform a paragraph element into something."""
288
        raise NotImplementedError()
×
289

290
    @abc.abstractmethod
4✔
291
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
292
    def transform_emphasis(
4✔
293
        self, element: docutils.nodes.emphasis
294
    ) -> Tuple[Optional[T], Optional[List[str]]]:
295
        """Transform an emphasis element into something."""
296
        raise NotImplementedError()
×
297

298
    @abc.abstractmethod
4✔
299
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
300
    def transform_list_item(
4✔
301
        self, element: docutils.nodes.list_item
302
    ) -> Tuple[Optional[T], Optional[List[str]]]:
303
        """Transform a list item element into something."""
304
        raise NotImplementedError()
×
305

306
    @abc.abstractmethod
4✔
307
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
308
    def transform_bullet_list(
4✔
309
        self, element: docutils.nodes.bullet_list
310
    ) -> Tuple[Optional[T], Optional[List[str]]]:
311
        """Transform a bullet list element into something."""
312
        raise NotImplementedError()
×
313

314
    @abc.abstractmethod
4✔
315
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
316
    def transform_note(
4✔
317
        self, element: docutils.nodes.note
318
    ) -> Tuple[Optional[T], Optional[List[str]]]:
319
        """Transform a note element into something."""
320
        raise NotImplementedError()
×
321

322
    @abc.abstractmethod
4✔
323
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
324
    def transform_reference(
4✔
325
        self, element: docutils.nodes.reference
326
    ) -> Tuple[Optional[T], Optional[List[str]]]:
327
        """Transform a general reference element into something."""
328
        raise NotImplementedError()
×
329

330
    @abc.abstractmethod
4✔
331
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
332
    def transform_field_body(
4✔
333
        self, element: docutils.nodes.field_body
334
    ) -> Tuple[Optional[T], Optional[List[str]]]:
335
        """Transform a field body into something."""
336
        raise NotImplementedError()
×
337

338
    @abc.abstractmethod
4✔
339
    @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
4✔
340
    def transform_document(
4✔
341
        self, element: docutils.nodes.document
342
    ) -> Tuple[Optional[T], Optional[List[str]]]:
343
        """Transform a document into something."""
344
        raise NotImplementedError()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc