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.

Interface._add_member()   F
last analyzed

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, comments=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 1
        self.comments = comments if comments else OrderedDict()
36
37 1
        for item in self.interfaces.values():
38 1
            item.package = self
39 1
        for item in self.typecollections.values():
40 1
            item.package = self
41
42 1
    def __contains__(self, namespace):
43 1
        if not isinstance(namespace, str):
44
            raise TypeError
45 1
        res = namespace in self.typecollections or namespace in self.interfaces
46 1
        return res
47
48 1
    def __getitem__(self, namespace):
49 1
        if not isinstance(namespace, str):
50
            raise TypeError
51 1
        elif namespace in self.typecollections:
52 1
            return self.typecollections[namespace]
53 1
        elif namespace in self.interfaces:
54 1
            return self.interfaces[namespace]
55
        else:
56
            raise KeyError
57
58 1
    def __iadd__(self, package):
59 1
        if not isinstance(package, Package):
60
            raise TypeError
61
        # Ignore the name
62 1
        self.files += package.files
63 1
        for item in package.imports:
64 1
            self.imports.append(item)
65 1
        for item in package.interfaces.values():
66 1
            if item.name in self:
67
                raise ASTException("Interface member defined more than"
68
                                   " once '{}'.".format(item.name))
69 1
            self.interfaces[item.name] = item
70 1
            item.package = self
71 1
        for item in package.typecollections.values():
72 1
            if item.name in self:
73
                raise ASTException("Type collection member defined more than"
74
                                   " once '{}'.".format(item.name))
75 1
            self.typecollections[item.name] = item
76 1
            item.package = self
77 1
        return self
78
79
80 1
class Import(object):
81
82 1
    def __init__(self, file_name, namespace=None):
83 1
        self.file = file_name
84 1
        self.namespace = namespace          # None for "import model"
85 1
        self.package_reference = None
86 1
        self.namespace_reference = None
87
88
89 1
class Namespace(object):
90
91 1
    __metaclass__ = ABCMeta
92
93 1
    def __init__(self, name, flags=None, members=None, comments=None):
94 1
        self.package = None
95 1
        self.name = name
96 1
        self.flags = flags if flags else []         # Unused
97 1
        self.version = None
98 1
        self.typedefs = OrderedDict()
99 1
        self.enumerations = OrderedDict()
100 1
        self.structs = OrderedDict()
101 1
        self.arrays = OrderedDict()
102 1
        self.maps = OrderedDict()
103 1
        self.constants = OrderedDict()
104 1
        self.comments = comments if comments else OrderedDict()
105 1
        if members:
106 1
            for member in members:
107 1
                self._add_member(member)
108
109 1
    def __contains__(self, name):
110 1
        if not isinstance(name, str):
111
            raise TypeError
112 1
        res = name in self.typedefs or \
113
            name in self.enumerations or \
114
            name in self.structs or \
115
            name in self.arrays or \
116
            name in self.maps or \
117
            name in self.constants
118 1
        return res
119
120 1
    def __getitem__(self, name):
121 1
        if not isinstance(name, str):
122
            raise TypeError
123 1
        elif name in self.typedefs:
124 1
            return self.typedefs[name]
125 1
        elif name in self.enumerations:
126 1
            return self.enumerations[name]
127 1
        elif name in self.structs:
128 1
            return self.structs[name]
129
        elif name in self.arrays:
130
            return self.arrays[name]
131
        elif name in self.maps:
132
            return self.maps[name]
133
        elif name in self.constants[name]:
134
            return self.constants[name]
135
        else:
136
            raise KeyError
137
138 1
    def _add_member(self, member):
139 1
        if isinstance(member, Version):
140 1
            if not self.version:
141 1
                self.version = member
142
            else:
143 1
                raise ASTException("Multiple version definitions.")
144 1
        elif isinstance(member, Type):
145 1
            if member.name in self:
146 1
                raise ASTException(
147
                    "Duplicate namespace member '{}'.".format(member.name))
148 1
            if isinstance(member, Typedef):
149 1
                self.typedefs[member.name] = member
150
                # Handle anonymous array special case.
151 1
                if isinstance(member.type, Array):
152 1
                    member.type.namespace = self
153 1
            elif isinstance(member, Enumeration):
154 1
                self.enumerations[member.name] = member
155 1
            elif isinstance(member, Struct):
156 1
                self.structs[member.name] = member
157
                # Handle anonymous array special case.
158 1
                for field in member.fields.values():
159 1
                    if isinstance(field.type, Array):
160 1
                        field.type.namespace = self
161 1
            elif isinstance(member, Array):
162 1
                self.arrays[member.name] = member
163
                # Handle anonymous array special case.
164 1
                if isinstance(member.type, Array):
165 1
                    member.type.namespace = self
166 1
            elif isinstance(member, Map):
167 1
                self.maps[member.name] = member
168
                # Handle anonymous array special case.
169 1
                if isinstance(member.key_type, Array):
170 1
                    member.key_type.namespace = self
171 1
                if isinstance(member.value_type, Array):
172 1
                    member.value_type.namespace = self
173 1
            elif isinstance(member, Constant):
174 1
                self.constants[member.name] = member
175
            else:
176
                raise ASTException("Unexpected namespace member type.")
177 1
            member.namespace = self
178
        else:
179
            raise ValueError("Unexpected namespace member type.")
180
181
182 1
class TypeCollection(Namespace):
183
184 1
    def __init__(self, name, flags=None, members=None, comments=None):
185 1
        super(TypeCollection, self).__init__(name, flags=flags,
186
                                             members=members, comments=comments)
187
188
189 1
class Type(object):
190
191 1
    __metaclass__ = ABCMeta
192
193 1
    def __init__(self, name=None, comments=None):
194 1
        self.namespace = None
195 1
        self.name = name if name else self.__class__.__name__
196 1
        self.comments = comments if comments else OrderedDict()
197
198
199 1
class Typedef(Type):
200
201 1
    def __init__(self, name, base_type, comments=None):
202 1
        super(Typedef, self).__init__(name, comments)
203 1
        self.type = base_type
204
205
206 1
class PrimitiveType(Type):
207
208 1
    __metaclass__ = ABCMeta
209
210 1
    def __init__(self):
211 1
        super(PrimitiveType, self).__init__()
212
213
214 1
class Int8(PrimitiveType):
215
216 1
    def __init__(self):
217 1
        super(Int8, self).__init__()
218
219
220 1
class Int16(PrimitiveType):
221
222 1
    def __init__(self):
223 1
        super(Int16, self).__init__()
224
225
226 1
class Int32(PrimitiveType):
227
228 1
    def __init__(self):
229 1
        super(Int32, self).__init__()
230
231
232 1
class Int64(PrimitiveType):
233
234 1
    def __init__(self):
235 1
        super(Int64, self).__init__()
236
237
238 1
class UInt8(PrimitiveType):
239
240 1
    def __init__(self):
241 1
        super(UInt8, self).__init__()
242
243
244 1
class UInt16(PrimitiveType):
245
246 1
    def __init__(self):
247 1
        super(UInt16, self).__init__()
248
249
250 1
class UInt32(PrimitiveType):
251
252 1
    def __init__(self):
253 1
        super(UInt32, self).__init__()
254
255
256 1
class UInt64(PrimitiveType):
257
258 1
    def __init__(self):
259 1
        super(UInt64, self).__init__()
260
261
262 1
class Boolean(PrimitiveType):
263
264 1
    def __init__(self):
265 1
        super(Boolean, self).__init__()
266
267
268 1
class Float(PrimitiveType):
269
270 1
    def __init__(self):
271 1
        super(Float, self).__init__()
272
273
274 1
class Double(PrimitiveType):
275
276 1
    def __init__(self):
277 1
        super(Double, self).__init__()
278
279
280 1
class String(PrimitiveType):
281
282 1
    def __init__(self):
283 1
        super(String, self).__init__()
284
285
286 1
class ByteBuffer(PrimitiveType):
287
288 1
    def __init__(self):
289 1
        super(ByteBuffer, self).__init__()
290
291
292 1
class ComplexType(Type):
293
294 1
    __metaclass__ = ABCMeta
295
296 1
    def __init__(self, comments=None):
297 1
        super(ComplexType, self).__init__(comments=comments)
298
299
300 1
class Value(Type):
301
302 1
    _metaclass__ = ABCMeta
303
304 1
    def __init__(self, value, value_type=None):
305 1
        super(Value, self).__init__(value_type if value_type else self.__class__.__name__)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (90/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
306 1
        self.value = value
307
308
309 1
class IntegerValue(Value):
310
311 1
    BINARY = 2
312 1
    DECIMAL = 10
313 1
    HEXADECIMAL = 16
314
315 1
    def __init__(self, value, base=DECIMAL):
316 1
        super(IntegerValue, self).__init__(value)
317 1
        self.base = base
318
319
320 1
class BooleanValue(Value):
321
322 1
    def __init__(self, value):
323 1
        super(BooleanValue, self).__init__(value)
324
325
326 1
class FloatValue(Value):
327
328 1
    def __init__(self, value):
329 1
        super(FloatValue, self).__init__(value)
330
331
332 1
class DoubleValue(Value):
333
334 1
    def __init__(self, value):
335 1
        super(DoubleValue, self).__init__(value)
336
337
338 1
class StringValue(Value):
339
340 1
    def __init__(self, value):
341 1
        super(StringValue, self).__init__(value)
342
343
344 1
class Enumeration(ComplexType):
345
346 1
    def __init__(self, name, enumerators=None, extends=None, flags=None, comments=None):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (88/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
347 1
        super(Enumeration, self).__init__(comments=comments)
348 1
        self.name = name
349 1
        self.enumerators = enumerators if enumerators else OrderedDict()
350 1
        self.extends = extends
351 1
        self.reference = None
352 1
        self.flags = flags if flags else []         # Unused
353
354
355 1
class Enumerator(object):
356
357 1
    def __init__(self, name, value=None, comments=None):
358 1
        self.name = name
359 1
        self.value = value
360 1
        self.comments = comments if comments else OrderedDict()
361
362
363 1
class Struct(ComplexType):
364
365 1
    def __init__(self, name, fields=None, extends=None, flags=None, comments=None):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (83/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
366 1
        super(Struct, self).__init__(comments=comments)
367 1
        self.name = name
368 1
        self.fields = fields if fields else OrderedDict()
369 1
        self.extends = extends
370 1
        self.reference = None
371 1
        self.flags = flags if flags else []
372
373
374 1
class StructField(object):
375
376 1
    def __init__(self, name, field_type, comments=None):
377 1
        self.name = name
378 1
        self.type = field_type
379 1
        self.comments = comments if comments else OrderedDict()
380
381
382 1
class Array(ComplexType):
383
384 1
    def __init__(self, name, element_type, comments=None):
385 1
        super(Array, self).__init__(comments=comments)
386 1
        self.name = name            # None for implicit arrays.
387 1
        self.type = element_type
388
389
390 1
class Map(ComplexType):
391
392 1
    def __init__(self, name, key_type, value_type, comments=None):
393 1
        super(Map, self).__init__(comments=comments)
394 1
        self.name = name
395 1
        self.key_type = key_type
396 1
        self.value_type = value_type
397
398
399 1
class Constant(ComplexType):
400
401 1
    def __init__(self, name, element_type, element_value, comments=None):
402 1
        super(Constant, self).__init__(comments=comments)
403 1
        self.name = name
404 1
        self.type = element_type
405 1
        self.value = element_value
406
407
408 1
class Reference(Type):
409
410 1
    def __init__(self, name):
411 1
        super(Reference, self).__init__()
412 1
        self.name = name
413 1
        self.reference = None
414
415
416 1
class Interface(Namespace):
417
418 1
    def __init__(self, name, flags=None, members=None, extends=None, comments=None):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (84/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
419 1
        super(Interface, self).__init__(name=name, flags=flags, members=None, comments=comments)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (96/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
420 1
        self.attributes = OrderedDict()
421 1
        self.methods = OrderedDict()
422 1
        self.broadcasts = OrderedDict()
423 1
        self.extends = extends
424 1
        self.reference = None
425 1
        if members:
426 1
            for member in members:
427 1
                self._add_member(member)
428
429 1
    def __contains__(self, name):
430 1
        if not isinstance(name, str):
431
            raise TypeError
432 1
        res = super(Interface, self).__contains__(name) or \
433
            name in self.attributes or \
434
            name in self.methods or \
435
            name in self.broadcasts
436 1
        return res
437
438 1
    def __getitem__(self, name):
439 1
        if not isinstance(name, str):
440
            raise TypeError
441 1
        elif name in self.attributes:
442
            return self.attributes[name]
443 1
        elif name in self.methods:
444
            return self.methods[name]
445 1
        elif name in self.broadcasts:
446
            return self.broadcasts[name]
447
        else:
448 1
            return super(Interface, self).__getitem__(name)
449
450 1
    def _add_member(self, member):
451 1
        if isinstance(member, Type):
452 1
            if member.name in self:
453 1
                raise ASTException(
454
                    "Duplicate namespace member '{}'.".format(member.name))
455 1
            if isinstance(member, Attribute):
456 1
                self.attributes[member.name] = member
457
                # Handle anonymous array special case.
458 1
                if isinstance(member.type, Array):
459 1
                    member.type.namespace = self
460 1
            elif isinstance(member, Method):
461 1
                self.methods[member.name] = member
462
                # Handle anonymous array special case.
463 1
                for arg in member.in_args.values():
464 1
                    if isinstance(arg.type, Array):
465 1
                        arg.type.namespace = self
466 1
                for arg in member.out_args.values():
467 1
                    if isinstance(arg.type, Array):
468 1
                        arg.type.namespace = self
469 1
            elif isinstance(member, Broadcast):
470 1
                self.broadcasts[member.name] = member
471
                # Handle anonymous array special case.
472 1
                for arg in member.out_args.values():
473 1
                    if isinstance(arg.type, Array):
474 1
                        arg.type.namespace = self
475
            else:
476 1
                super(Interface, self)._add_member(member)
477 1
            member.namespace = self
478
        else:
479 1
            super(Interface, self)._add_member(member)
480
481
482 1
class Version(object):
483
484 1
    def __init__(self, major, minor):
485 1
        self.major = major
486 1
        self.minor = minor
487
488 1
    def __str__(self):
489 1
        return "{}.{}".format(self.major, self.minor)
490
491
492 1
class Attribute(Type):
493
494 1
    def __init__(self, name, attr_type, flags=None, comments=None):
495 1
        super(Attribute, self).__init__(name, comments)
496 1
        self.type = attr_type
497 1
        self.flags = flags if flags else []
498
499
500 1
class Method(Type):
501
502 1
    def __init__(self, name, flags=None,
503
                 in_args=None, out_args=None, errors=None, comments=None):
504 1
        super(Method, self).__init__(name, comments)
505 1
        self.flags = flags if flags else []
506 1
        self.in_args = in_args if in_args else OrderedDict()
507 1
        self.out_args = out_args if out_args else OrderedDict()
508
        # Errors can be an OrderedDict() or a Reference to an enumeration.
509 1
        self.errors = errors if errors else OrderedDict()
510
511
512 1
class Broadcast(Type):
513
514 1
    def __init__(self, name, flags=None, out_args=None, comments=None):
515 1
        super(Broadcast, self).__init__(name, comments)
516 1
        self.flags = flags if flags else []
517 1
        self.out_args = out_args if out_args else OrderedDict()
518
519
520 1
class Argument(object):
521
522 1
    def __init__(self, name, arg_type, comments=None):
523 1
        self.name = name
524 1
        self.type = arg_type
525
        self.comments = comments if comments else OrderedDict()
526