Failed Conditions
Pull Request — master (#1139)
by Mischa
01:51
created

coalib.bearlib.languages.documentation.DocstyleDefinition   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 138
Duplicated Lines 0 %
Metric Value
dl 0
loc 138
rs 10
wmc 12

5 Methods

Rating   Name   Duplication   Size   Complexity  
A docstyle() 0 9 1
B __init__() 0 23 4
A language() 0 9 1
B markers() 0 38 1
B load() 0 46 5
1
import os.path
2
3
from coalib.misc.Compatability import FileNotFoundError
4
from coalib.misc.Decorators import generate_eq, generate_repr
5
from coalib.parsing.ConfParser import ConfParser
6
7
8
@generate_repr()
9
@generate_eq("language", "docstyle", "markers")
10
class DocstyleDefinition:
11
    """
12
    The DocstyleDefinition class holds values that identify a certain type of
13
    documentation comment (for which language, documentation style/tool used
14
    etc.).
15
    """
16
17
    def __init__(self, language, docstyle, markers):
18
        """
19
        Instantiates a new DocstyleDefinition.
20
21
        :param language: The case insensitive programming language of the
22
                         documentation comment, e.g. `"CPP"` for C++ or
23
                         `"PYTHON3"`.
24
        :param docstyle: The case insensitive documentation style/tool used
25
                         to document code, e.g. `"default"` or `"doxygen"`.
26
        :param markers:  An iterable of marker/delimiter string iterables that
27
                         identify a documentation comment. See `markers`
28
                         property for more details on markers.
29
        """
30
        self._language = language.lower()
31
        self._docstyle = docstyle.lower()
32
        self._markers = tuple(tuple(marker_set) for marker_set in markers)
33
34
        # Check marker set dimensions.
35
        for marker_set in self._markers:
36
            length = len(marker_set)
37
            if length != 3:
38
                raise ValueError("Length of a given marker set was not 3 (was "
39
                                 "actually {}).".format(length))
40
41
    @property
42
    def language(self):
43
        """
44
        The programming language.
45
46
        :return: A lower-case string defining the programming language (i.e.
47
                 "cpp" or "python").
48
        """
49
        return self._language
50
51
    @property
52
    def docstyle(self):
53
        """
54
        The documentation style/tool used to document code.
55
56
        :return: A lower-case string defining the docstyle (i.e. "default" or
57
                 "doxygen").
58
        """
59
        return self._docstyle
60
61
    @property
62
    def markers(self):
63
        """
64
        A tuple of marker sets that identify a documentation comment.
65
66
        Marker sets consist of 3 entries where the first is the start-marker,
67
        the second one the each-line marker and the last one the end-marker.
68
        For example a marker tuple with a single marker set
69
        `(("/**", "*", "*/"),)` would match following documentation comment:
70
71
        ```
72
        /**
73
         * This is documentation.
74
         */
75
        ```
76
77
        It's also possible to supply an empty each-line marker
78
        (`("/**", "", "*/")`):
79
80
        ```
81
        /**
82
         This is more documentation.
83
         */
84
        ```
85
86
        Markers are matched "greedy", that means it will match as many
87
        each-line markers as possible. I.e. for `("///", "///", "///")`):
88
89
        ```
90
        /// Brief documentation.
91
        ///
92
        /// Detailed documentation.
93
        ```
94
95
        :return: A tuple of marker/delimiter string tuples that identify a
96
                 documentation comment.
97
        """
98
        return self._markers
99
100
    @classmethod
101
    def load(cls, language, docstyle):
102
        """
103
        Loads a `DocstyleDefinition` from the coala docstyle definition files.
104
105
        This function considers all settings inside the according coalang-files
106
        as markers.
107
108
        :param language:           The case insensitive programming language of
109
                                   the documentation comment as a string.
110
        :param docstyle:           The case insensitive documentation
111
                                   style/tool used to document code, e.g.
112
                                   `"default"` or `"doxygen"`.
113
        :raises FileNotFoundError: Raised when the given docstyle was not
114
                                   found. This is a compatability exception
115
                                   from `coalib.misc.Compatability` module.
116
        :raises KeyError:          Raised when the given language is not
117
                                   defined for given docstyle.
118
        :return:                   The `DocstyleDefinition` for given language
119
                                   and docstyle.
120
        """
121
122
        docstyle = docstyle.lower()
123
124
        language_config_parser = ConfParser(remove_empty_iter_elements=False)
125
        try:
126
            docstyle_settings = language_config_parser.parse(
127
                os.path.dirname(__file__) + "/" + docstyle + ".coalang")
128
        except FileNotFoundError as ex:
129
            raise type(ex)("Docstyle definition " + repr(docstyle) + " not "
130
                           "found.")
131
132
        language = language.lower()
133
134
        try:
135
            docstyle_settings = docstyle_settings[language]
136
        except KeyError:
137
            raise KeyError("Language {} is not defined for docstyle {}."
138
                           .format(repr(language), repr(docstyle)))
139
140
        marker_sets = (tuple(value)
141
                       for key, value in
142
                           filter(lambda kv: not kv[0].startswith("comment"),
143
                                  docstyle_settings.contents.items()))
144
145
        return cls(language, docstyle, marker_sets)
146