GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( e859f3...e9a5ca )
by Kaloyan
03:10
created

Interface._add_member()   F

Complexity

Conditions 13

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 13

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 13
c 1
b 0
f 0
dl 0
loc 30
ccs 24
cts 24
cp 1
crap 13
rs 2.7716

How to fix   Complexity   

Complexity

Complex classes like Interface._add_member() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
"""
2
Franca abstract syntax tree representation.
3
"""
4
5 1
from abc import ABCMeta
6 1
from collections import OrderedDict
7
8
9 1
class ASTException(Exception):
10
11 1
    def __init__(self, message):
12 1
        super(ASTException, self).__init__()
13 1
        self.message = message
14
15 1
    def __str__(self):
16
        return self.message
17
18
19 1
class Package(object):
20
    """
21
    AST representation of a Franca package.
22
    """
23
24 1
    def __init__(self, name, file_name=None, imports=None,
25
                 interfaces=None, typecollections=None):
26
        """
27
        Constructs a new Package.
28
        """
29 1
        self.name = name
30 1
        self.files = [file_name] if file_name else []
31 1
        self.imports = imports if imports else []
32 1
        self.interfaces = interfaces if interfaces else OrderedDict()
33 1
        self.typecollections = typecollections if typecollections else \
34
            OrderedDict()
35
36 1
        for item in self.interfaces.values():
37 1
            item.package = self
38 1
        for item in self.typecollections.values():
39 1
            item.package = self
40
41 1
    def __contains__(self, namespace):
42 1
        if not isinstance(namespace, str):
43
            raise TypeError
44 1
        res = namespace in self.typecollections or namespace in self.interfaces
45 1
        return res
46
47 1
    def __getitem__(self, namespace):
48 1
        if not isinstance(namespace, str):
49
            raise TypeError
50 1
        elif namespace in self.typecollections:
51 1
            return self.typecollections[namespace]
52 1
        elif namespace in self.interfaces:
53 1
            return self.interfaces[namespace]
54
        else:
55
            raise KeyError
56
57 1
    def __iadd__(self, package):
58 1
        if not isinstance(package, Package):
59
            raise TypeError
60
        # Ignore the name and imports
61 1
        self.files += package.files
62 1
        for item in package.interfaces.values():
63 1
            if item.name in self:
64
                raise ASTException("Interface member defined more than"
65
                                   " once '{}'.".format(item.name))
66 1
            self.interfaces[item.name] = item
67 1
            item.package = self
68 1
        for item in package.typecollections.values():
69
            if item.name in self:
70
                raise ASTException("Type collection member defined more than"
71
                                   " once '{}'.".format(item.name))
72
            self.typecollections[item.name] = item
73
            item.package = self
74 1
        return self
75
76
77 1
class Import(object):
78
79 1
    def __init__(self, file_name, namespace=None):
80 1
        self.file = file_name
81 1
        self.namespace = namespace          # None for "import model"
82 1
        self.package_reference = None
83 1
        self.namespace_reference = None
84
85
86 1
class Namespace(object):
87
88 1
    __metaclass__ = ABCMeta
89
90 1
    def __init__(self, name, flags=None, members=None):
91 1
        self.package = None
92 1
        self.name = name
93 1
        self.flags = flags if flags else []         # Unused
94 1
        self.version = None
95 1
        self.typedefs = OrderedDict()
96 1
        self.enumerations = OrderedDict()
97 1
        self.structs = OrderedDict()
98 1
        self.arrays = OrderedDict()
99 1
        self.maps = OrderedDict()
100 1
        if members:
101 1
            for member in members:
102 1
                self._add_member(member)
103
104 1
    def __contains__(self, name):
105 1
        if not isinstance(name, str):
106
            raise TypeError
107 1
        res = name in self.typedefs or \
108
            name in self.enumerations or \
109
            name in self.structs or \
110
            name in self.arrays or \
111
            name in self.maps
112 1
        return res
113
114 1
    def __getitem__(self, name):
115 1
        if not isinstance(name, str):
116
            raise TypeError
117 1
        elif name in self.typedefs:
118 1
            return self.typedefs[name]
119 1
        elif name in self.enumerations:
120 1
            return self.enumerations[name]
121 1
        elif name in self.structs:
122 1
            return self.structs[name]
123
        elif name in self.arrays:
124
            return self.arrays[name]
125
        elif name in self.maps:
126
            return self.maps[name]
127
        else:
128
            raise KeyError
129
130 1
    def _add_member(self, member):
131 1
        if isinstance(member, Version):
132 1
            if not self.version:
133 1
                self.version = member
134
            else:
135 1
                raise ASTException("Multiple version definitions.")
136 1
        elif isinstance(member, Type):
137 1
            if member.name in self:
138 1
                raise ASTException(
139
                    "Duplicate namespace member '{}'.".format(member.name))
140 1
            if isinstance(member, Typedef):
141 1
                self.typedefs[member.name] = member
142
                # Handle anonymous array special case.
143 1
                if isinstance(member.type, Array):
144 1
                    member.type.namespace = self
145 1
            elif isinstance(member, Enumeration):
146 1
                self.enumerations[member.name] = member
147 1
            elif isinstance(member, Struct):
148 1
                self.structs[member.name] = member
149
                # Handle anonymous array special case.
150 1
                for field in member.fields.values():
151 1
                    if isinstance(field.type, Array):
152 1
                        field.type.namespace = self
153 1
            elif isinstance(member, Array):
154 1
                self.arrays[member.name] = member
155
                # Handle anonymous array special case.
156 1
                if isinstance(member.type, Array):
157 1
                    member.type.namespace = self
158 1
            elif isinstance(member, Map):
159 1
                self.maps[member.name] = member
160
                # Handle anonymous array special case.
161 1
                if isinstance(member.key_type, Array):
162 1
                    member.key_type.namespace = self
163 1
                if isinstance(member.value_type, Array):
164 1
                    member.value_type.namespace = self
165
            else:
166
                raise ASTException("Unexpected namespace member type.")
167 1
            member.namespace = self
168
        else:
169
            raise ValueError("Unexpected namespace member type.")
170
171
172 1
class TypeCollection(Namespace):
173
174 1
    def __init__(self, name, flags=None, members=None):
175 1
        super(TypeCollection, self).__init__(name, flags=flags,
176
                                             members=members)
177
178
179 1
class Type(object):
180
181 1
    __metaclass__ = ABCMeta
182
183 1
    def __init__(self, name=None):
184 1
        self.namespace = None
185 1
        self.name = name if name else self.__class__.__name__
186
187
188 1
class Typedef(Type):
189
190 1
    def __init__(self, name, base_type):
191 1
        super(Typedef, self).__init__(name)
192 1
        self.type = base_type
193
194
195 1
class PrimitiveType(Type):
196
197 1
    __metaclass__ = ABCMeta
198
199 1
    def __init__(self):
200 1
        super(PrimitiveType, self).__init__()
201
202
203 1
class Int8(PrimitiveType):
204
205 1
    def __init__(self):
206 1
        super(Int8, self).__init__()
207
208
209 1
class Int16(PrimitiveType):
210
211 1
    def __init__(self):
212 1
        super(Int16, self).__init__()
213
214
215 1
class Int32(PrimitiveType):
216
217 1
    def __init__(self):
218 1
        super(Int32, self).__init__()
219
220
221 1
class Int64(PrimitiveType):
222
223 1
    def __init__(self):
224 1
        super(Int64, self).__init__()
225
226
227 1
class UInt8(PrimitiveType):
228
229 1
    def __init__(self):
230 1
        super(UInt8, self).__init__()
231
232
233 1
class UInt16(PrimitiveType):
234
235 1
    def __init__(self):
236 1
        super(UInt16, self).__init__()
237
238
239 1
class UInt32(PrimitiveType):
240
241 1
    def __init__(self):
242 1
        super(UInt32, self).__init__()
243
244
245 1
class UInt64(PrimitiveType):
246
247 1
    def __init__(self):
248 1
        super(UInt64, self).__init__()
249
250
251 1
class Boolean(PrimitiveType):
252
253 1
    def __init__(self):
254 1
        super(Boolean, self).__init__()
255
256
257 1
class Float(PrimitiveType):
258
259 1
    def __init__(self):
260 1
        super(Float, self).__init__()
261
262
263 1
class Double(PrimitiveType):
264
265 1
    def __init__(self):
266 1
        super(Double, self).__init__()
267
268
269 1
class String(PrimitiveType):
270
271 1
    def __init__(self):
272 1
        super(String, self).__init__()
273
274
275 1
class ByteBuffer(PrimitiveType):
276
277 1
    def __init__(self):
278 1
        super(ByteBuffer, self).__init__()
279
280
281 1
class ComplexType(Type):
282
283 1
    __metaclass__ = ABCMeta
284
285 1
    def __init__(self):
286 1
        super(ComplexType, self).__init__()
287
288
289 1
class Enumeration(ComplexType):
290
291 1
    def __init__(self, name, enumerators=None, extends=None, flags=None):
292 1
        super(Enumeration, self).__init__()
293 1
        self.name = name
294 1
        self.enumerators = enumerators if enumerators else OrderedDict()
295 1
        self.extends = extends
296 1
        self.reference = None
297 1
        self.flags = flags if flags else []         # Unused
298
299
300 1
class Enumerator(object):
301
302 1
    def __init__(self, name, value=None):
303 1
        self.name = name
304 1
        self.value = value
305
306
307 1
class Struct(ComplexType):
308
309 1
    def __init__(self, name, fields=None, extends=None, flags=None):
310 1
        super(Struct, self).__init__()
311 1
        self.name = name
312 1
        self.fields = fields if fields else OrderedDict()
313 1
        self.extends = extends
314 1
        self.reference = None
315 1
        self.flags = flags if flags else []
316
317
318 1
class StructField(object):
319
320 1
    def __init__(self, name, field_type):
321 1
        self.name = name
322 1
        self.type = field_type
323
324
325 1
class Array(ComplexType):
326
327 1
    def __init__(self, name, element_type):
328 1
        super(Array, self).__init__()
329 1
        self.name = name            # None for implicit arrays.
330 1
        self.type = element_type
331
332
333 1
class Map(ComplexType):
334
335 1
    def __init__(self, name, key_type, value_type):
336 1
        super(Map, self).__init__()
337 1
        self.name = name
338 1
        self.key_type = key_type
339 1
        self.value_type = value_type
340
341
342 1
class Reference(Type):
343
344 1
    def __init__(self, name):
345 1
        super(Reference, self).__init__()
346 1
        self.name = name
347 1
        self.reference = None
348
349
350 1
class Interface(Namespace):
351
352 1
    def __init__(self, name, flags=None, members=None, extends=None):
353 1
        super(Interface, self).__init__(name=name, flags=flags, members=None)
354 1
        self.attributes = OrderedDict()
355 1
        self.methods = OrderedDict()
356 1
        self.broadcasts = OrderedDict()
357 1
        self.extends = extends
358 1
        self.reference = None
359 1
        if members:
360 1
            for member in members:
361 1
                self._add_member(member)
362
363 1
    def __contains__(self, name):
364 1
        if not isinstance(name, str):
365
            raise TypeError
366 1
        res = super(Interface, self).__contains__(name) or \
367
            name in self.attributes or \
368
            name in self.methods or \
369
            name in self.broadcasts
370 1
        return res
371
372 1
    def __getitem__(self, name):
373 1
        if not isinstance(name, str):
374
            raise TypeError
375 1
        elif name in self.attributes:
376
            return self.attributes[name]
377 1
        elif name in self.methods:
378
            return self.methods[name]
379 1
        elif name in self.broadcasts:
380
            return self.broadcasts[name]
381
        else:
382 1
            return super(Interface, self).__getitem__(name)
383
384 1
    def _add_member(self, member):
385 1
        if isinstance(member, Type):
386 1
            if member.name in self:
387 1
                raise ASTException(
388
                    "Duplicate namespace member '{}'.".format(member.name))
389 1
            if isinstance(member, Attribute):
390 1
                self.attributes[member.name] = member
391
                # Handle anonymous array special case.
392 1
                if isinstance(member.type, Array):
393 1
                    member.type.namespace = self
394 1
            elif isinstance(member, Method):
395 1
                self.methods[member.name] = member
396
                # Handle anonymous array special case.
397 1
                for arg in member.in_args.values():
398 1
                    if isinstance(arg.type, Array):
399 1
                        arg.type.namespace = self
400 1
                for arg in member.out_args.values():
401 1
                    if isinstance(arg.type, Array):
402 1
                        arg.type.namespace = self
403 1
            elif isinstance(member, Broadcast):
404 1
                self.broadcasts[member.name] = member
405
                # Handle anonymous array special case.
406 1
                for arg in member.out_args.values():
407 1
                    if isinstance(arg.type, Array):
408 1
                        arg.type.namespace = self
409
            else:
410 1
                super(Interface, self)._add_member(member)
411 1
            member.namespace = self
412
        else:
413 1
            super(Interface, self)._add_member(member)
414
415
416 1
class Version(object):
417
418 1
    def __init__(self, major, minor):
419 1
        self.major = major
420 1
        self.minor = minor
421
422 1
    def __str__(self):
423 1
        return "{}.{}".format(self.major, self.minor)
424
425
426 1
class Attribute(Type):
427
428 1
    def __init__(self, name, attr_type, flags=None):
429 1
        super(Attribute, self).__init__(name)
430 1
        self.type = attr_type
431 1
        self.flags = flags if flags else []
432
433
434 1
class Method(Type):
435
436 1
    def __init__(self, name, flags=None,
437
                 in_args=None, out_args=None, errors=None):
438 1
        super(Method, self).__init__(name)
439 1
        self.flags = flags if flags else []
440 1
        self.in_args = in_args if in_args else OrderedDict()
441 1
        self.out_args = out_args if out_args else OrderedDict()
442
        # Errors can be an OrderedDict() or a Reference to an enumeration.
443 1
        self.errors = errors if errors else OrderedDict()
444
445
446 1
class Broadcast(Type):
447
448 1
    def __init__(self, name, flags=None, out_args=None):
449 1
        super(Broadcast, self).__init__(name)
450 1
        self.flags = flags if flags else []
451 1
        self.out_args = out_args if out_args else OrderedDict()
452
453
454 1
class Argument(object):
455
456 1
    def __init__(self, name, arg_type):
457 1
        self.name = name
458
        self.type = arg_type
459