sdoc.sdoc1.data_type.ArrayDataType   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 187
Duplicated Lines 95.72 %

Test Coverage

Coverage 83.58%

Importance

Changes 0
Metric Value
wmc 27
eloc 67
dl 179
loc 187
ccs 56
cts 67
cp 0.8358
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A ArrayDataType.is_scalar() 5 5 1
A ArrayDataType.add_element() 15 15 2
A ArrayDataType.__init__() 9 9 2
A ArrayDataType.get_array() 20 20 3
A ArrayDataType.has_element() 7 7 1
A ArrayDataType.is_defined() 5 5 1
A ArrayDataType.get_reference() 12 12 2
A ArrayDataType.is_constant() 5 5 1
A ArrayDataType.get_value() 5 5 1
C ArrayDataType.debug() 45 45 10
A ArrayDataType.is_true() 5 5 1
A ArrayDataType.get_type_id() 5 5 1
A ArrayDataType.dereference() 7 7 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1 1
import copy
2 1
from typing import Any, Dict, Optional, Union
3
4 1
from sdoc.sdoc1.data_type.DataType import DataType
5 1
from sdoc.sdoc1.error import DataTypeError
6
7
8 1 View Code Duplication
class ArrayDataType(DataType):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
9
    """
10
    Class for array data types.
11
    """
12
13
    # ------------------------------------------------------------------------------------------------------------------
14 1
    def __init__(self, elements: Optional[Dict[Any, DataType]] = None):
15
        """
16
        Object constructor.
17
18
        :param dict[any,DataType]|None: The elements of this array.
19
        """
20
21 1
        self._elements = copy.deepcopy(elements) if elements else {}
22 1
        """
23
        The elements in this array.
24
25
        :type: dict[any,DataType]|None
26
        """
27
28
    # ------------------------------------------------------------------------------------------------------------------
29 1
    def debug(self, indent: int = 0) -> str:
30
        """
31
        Returns a string for debugging.
32
33
        :param int indent: The indentation level.
34
        """
35 1
        ret = '[\n'
36 1
        sep = " => "
37 1
        longest = 0
38 1
        brace_indent = indent
39 1
        first = True
40
41
        # Find the length of the longest key.
42 1
        for key in self._elements:
43 1
            if len("{0!s}".format(key)) >= longest:
44 1
                longest = len("{0!s}".format(key))
45 1
                if isinstance(key, str):
46
                    # The longest key is a string. Add 2 positions for quotes.
47 1
                    longest += 2
48
49 1
        for key in sorted(self._elements, key=lambda x: str(x)):
50
            # Checking the key type, and setting quotes.
51 1
            if isinstance(key, int):
52 1
                str1 = " " + " " * indent + "{}".format(key).ljust(longest, " ")
53 1
            elif isinstance(key, str):
54 1
                str1 = " " + " " * indent + "'{}'".format(key).ljust(longest, " ")
55
            else:
56
                raise ValueError()
57
58
            # Creating indentation level.
59 1
            if isinstance(self._elements[key], ArrayDataType):
60
                # Need this check if we have many nested nodes.
61 1
                if first:
62
                    indent += len(str1 + sep)
63
                else:
64 1
                    indent = len(str1 + sep)
65 1
                str2 = "{}".format(self._elements[key].debug(indent)).ljust(longest, " ")
66 1
                ret += str1 + sep + str2
67
            else:
68 1
                str2 = "{}".format(self._elements[key].debug()).strip()
69 1
                ret += str1 + sep + str2 + "\n"
70
71 1
            first = False
72
73 1
        return ret + brace_indent * " " + "]\n"
74
75
    # ------------------------------------------------------------------------------------------------------------------
76 1
    def dereference(self):
77
        """
78
        Returns a clone of this array.
79
80
        :rtype: sdoc.sdoc1.data_type.ArrayDataType.ArrayDataType
81
        """
82 1
        return ArrayDataType(self._elements)
83
84
    # ------------------------------------------------------------------------------------------------------------------
85 1
    def get_array(self, key: Union[int, str]):
86
        """
87
        Adds a new elements to this array. If the key holds an element already the element will be replaced.
88
89
        :param int|str key: The key of the new element. Must be a scalar data type.
90
91
        :rtype: sdoc.sdoc1.data_type.ArrayDataType.ArrayDataType
92
        """
93 1
        if key not in self._elements:
94
            # Variable is not defined: create a new array.
95 1
            self._elements[key] = ArrayDataType()
96
97
        else:
98
            # Variable is defined.
99 1
            element = self._elements[key]
100 1
            if not isinstance(element, ArrayDataType):
101
                # Variable is defined but not an array: replace the element.
102
                self._elements[key] = ArrayDataType()
103
104 1
        return self._elements[key]
105
106
    # ------------------------------------------------------------------------------------------------------------------
107 1
    def add_element(self, key, value):
108
        """
109
        Adds a new elements to this array. If the key holds an element already the element will be replaced.
110
111
        :param sdoc.sdoc1.data_type.DataType.DataType key: The key of the new element. Must be a scalar data type.
112
        :param sdoc.sdoc1.data_type.DataType.DataType value: The value of the new element.
113
114
        :rtype: sdoc.sdoc1.data_type.DataType.DataType
115
        """
116 1
        if not key.is_scalar():
117
            raise DataTypeError("Key '{0!s}' is not a scalar.".format(str(key)))
118
119 1
        self._elements[key.get_value()] = value.dereference()
120
121 1
        return self._elements[key.get_value()]
122
123
    # ------------------------------------------------------------------------------------------------------------------
124 1
    def get_reference(self, name: Union[int, str]):
125
        """
126
        Returns a reference to an element in this array.
127
128
        :param int|str name: The name of the elements
129
130
        :rtype: sdoc.sdoc1.data_type.DataType.DataType
131
        """
132 1
        if name not in self._elements:
133
            raise DataTypeError("Identifier '{0!s}' does not have a value.".format(name))
134
135 1
        return self._elements[name]
136
137
    # ------------------------------------------------------------------------------------------------------------------
138 1
    def get_value(self):
139
        """
140
        Not implemented.
141
        """
142
        raise RuntimeError()
143
144
    # ------------------------------------------------------------------------------------------------------------------
145 1
    def get_type_id(self) -> int:
146
        """
147
        Returns the ID of this data type.
148
        """
149
        return DataType.ARRAY
150
151
    # ------------------------------------------------------------------------------------------------------------------
152 1
    def has_element(self, name: Union[int, str]) -> bool:
153
        """
154
        Returns True if this array has a specified element.
155
156
        :param int|str name: The name of the element.
157
        """
158 1
        return name in self._elements
159
160
    # ------------------------------------------------------------------------------------------------------------------
161 1
    def is_constant(self) -> bool:
162
        """
163
        Returns False always.
164
        """
165
        return False
166
167
    # ------------------------------------------------------------------------------------------------------------------
168 1
    def is_defined(self) -> bool:
169
        """
170
        Returns True always.
171
        """
172
        return True
173
174
    # ------------------------------------------------------------------------------------------------------------------
175 1
    def is_scalar(self) -> bool:
176
        """
177
        Returns False always.
178
        """
179
        return False
180
181
    # ------------------------------------------------------------------------------------------------------------------
182 1
    def is_true(self) -> bool:
183
        """
184
        Returns True if this array holds 1 or more elements. Returns False otherwise.
185
        """
186
        return len(self._elements) > 0
187
188
# ----------------------------------------------------------------------------------------------------------------------
189