Completed
Push — master ( 57e7bf...8a74a7 )
by P.R.
01:36
created

ArrayDataType   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 192
Duplicated Lines 0 %
Metric Value
wmc 26
dl 0
loc 192
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A has_element() 0 9 1
A is_scalar() 0 7 1
A dereference() 0 10 1
A get_reference() 0 12 2
F debug() 0 45 10
A add_element() 0 17 2
A is_defined() 0 7 1
A get_value() 0 5 1
A get_type_id() 0 7 1
A is_true() 0 7 1
A get_array() 0 22 3
A __init__() 0 7 1
A is_constant() 0 7 1
1
"""
2
SDoc
3
4
Copyright 2016 Set Based IT Consultancy
5
6
Licence MIT
7
"""
8
# ----------------------------------------------------------------------------------------------------------------------
9
import copy
10
from sdoc.sdoc1.data_type.DataType import DataType
11
12
13
class ArrayDataType(DataType):
0 ignored issues
show
Unused Code introduced by
This abstract class does not seem to be used anywhere.
Loading history...
14
    """
15
    Class for array data types.
16
    """
17
18
    # ------------------------------------------------------------------------------------------------------------------
19
    def __init__(self):
20
        self._elements = {}
21
        """
22
        The elements in this array.
23
24
        :type: dict[mixed, sdoc.sdoc1.data_type.DataType.DataType]
25
        """
26
27
    # ------------------------------------------------------------------------------------------------------------------
28
    def debug(self, indent=0):
29
        """
30
        Returns a string for debugging.
31
32
        :param int indent: The indentation level.
33
34
        :rtype: str
35
        """
36
        ret = '[\n'
37
        sep = " => "
38
        longest = 0
39
        brace_indent = indent
40
        first = True
41
42
        # Find the length of the longest key.
43
        for key in self._elements:
44
            if len("{0!s}".format(key)) >= longest:
45
                longest = len("{0!s}".format(key))
46
                if isinstance(key, str):
47
                    # The longest key is a string. Add 2 positions for quotes.
48
                    longest += 2
49
50
        for key in sorted(self._elements, key=lambda x: str(x)):
0 ignored issues
show
Unused Code introduced by
This lambda might be unnecessary.
Loading history...
51
            # Checking the key type, and setting quotes.
52
            if isinstance(key, int):
53
                str1 = " " + " " * indent + "{}".format(key).ljust(longest, " ")
54
            elif isinstance(key, str):
55
                str1 = " " + " " * indent + "'{}'".format(key).ljust(longest, " ")
56
57
            # Creating indentation level.
58
            if isinstance(self._elements[key], ArrayDataType):
59
                # Need this check if we have many nested nodes.
60
                if first:
61
                    indent += len(str1 + sep)
62
                else:
63
                    indent = len(str1 + sep)
64
                str2 = "{}".format(self._elements[key].debug(indent)).ljust(longest, " ")
65
                ret += str1 + sep + str2
66
            else:
67
                str2 = "{}".format(self._elements[key].debug()).strip()
68
                ret += str1 + sep + str2 + "\n"
69
70
            first = False
71
72
        return ret + brace_indent * " " + "]\n"
73
74
    # ------------------------------------------------------------------------------------------------------------------
75
    def dereference(self):
76
        """
77
        Returns a clone of this array.
78
79
        :rtype: ArrayDataType
80
        """
81
        tmp = ArrayDataType()
82
        tmp._elements = copy.deepcopy(self._elements)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _elements was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
83
84
        return tmp
85
86
    # ------------------------------------------------------------------------------------------------------------------
87
    def get_array(self, key):
88
        """
89
        Adds a new elements to this array. If the key holds an element already the element will be replaced.
90
91
        :param int_str key: The key of the new element. Must be a scalar data type.
92
93
        :rtype: sdoc.sdoc1.data_type.DataType.ArrayDataType
94
95
        @todo consider key must be int or str
96
        """
97
        if key not in self._elements:
98
            # Variable is not defined: create a new array.
99
            self._elements[key] = ArrayDataType()
100
101
        else:
102
            # Variable is defined.
103
            element = self._elements[key]
104
            if not isinstance(element, ArrayDataType):
105
                # Variable is defined but not an array: replace the element.
106
                self._elements[key] = ArrayDataType()
107
108
        return self._elements[key]
109
110
    # ------------------------------------------------------------------------------------------------------------------
111
    def add_element(self, key, value):
112
        """
113
        Adds a new elements to this array. If the key holds an element already the element will be replaced.
114
115
        :param sdoc.sdoc1.data_type.DataType.DataType key: The key of the new element. Must be a scalar data type.
116
        :param sdoc.sdoc1.data_type.DataType.DataType value: The value of the new element.
117
118
        :rtype: sdoc.sdoc1.data_type.DataType.DataType
119
120
        @todo consider key must be int or str
121
        """
122
        if not key.is_scalar():
123
            raise RuntimeError("Key '{0!s}' is not a scalar.".format(str(key)))
124
125
        self._elements[key.get_value()] = value.dereference()
126
127
        return self._elements[key.get_value()]
128
129
    # ------------------------------------------------------------------------------------------------------------------
130
    def get_reference(self, name):
131
        """
132
        Returns a reference to an element in this array.
133
134
        :param int|str name: The name of the elements
135
136
        :rtype: sdoc.sdoc1.data_type.DataType.DataType
137
        """
138
        if name not in self._elements:
139
            raise RuntimeError("Identifier '{0!s}' does not have a value.".format(name))
140
141
        return self._elements[name]
142
143
    # ------------------------------------------------------------------------------------------------------------------
144
    def get_value(self):
145
        """
146
        Not implemented.
147
        """
148
        raise NotImplementedError
149
150
    # ------------------------------------------------------------------------------------------------------------------
151
    def get_type_id(self):
152
        """
153
        Returns the ID of this data type.
154
155
        :rtype: int
156
        """
157
        return DataType.ARRAY
158
159
    # ------------------------------------------------------------------------------------------------------------------
160
    def has_element(self, name):
161
        """
162
        Returns True if this array has a specified element.
163
164
        :param int|str name: The name of the element.
165
166
        :rtype: bool
167
        """
168
        return name in self._elements
169
170
    # ------------------------------------------------------------------------------------------------------------------
171
    def is_constant(self):
172
        """
173
        Returns False always.
174
175
        :rtype: bool
176
        """
177
        return False
178
179
    # ------------------------------------------------------------------------------------------------------------------
180
    def is_defined(self):
181
        """
182
        Returns True always.
183
184
        :rtype: bool
185
        """
186
        return True
187
188
    # ------------------------------------------------------------------------------------------------------------------
189
    def is_scalar(self):
190
        """
191
        Returns False always.
192
193
        :rtype: bool
194
        """
195
        return False
196
197
    # ------------------------------------------------------------------------------------------------------------------
198
    def is_true(self):
199
        """
200
        Returns True if this array holds 1 or more elements. Returns False otherwise.
201
202
        :rtype: bool
203
        """
204
        return len(self._elements) > 0
205
206
# ----------------------------------------------------------------------------------------------------------------------
207