Exemplo n.º 1
0
    def NOP_class_level(self, class_entity: und.Ent):
        """
        NOP - Class Level Number of Polymorphic Methods
        Any method that can be used by a class and its descendants.
       :param class_entity: The class entity
        :return: Counts of the number of methods in a class excluding private, static and final ones.
        """
        if "Final" in class_entity.kindname():
            return 0

        all_methods = class_entity.metric(['CountDeclMethodAll'
                                           ]).get('CountDeclMethodAll', 0)
        # private_methods = class_entity.metric(['CountDeclMethodPrivate']).get('CountDeclMethodPrivate', 0)
        # static_methods = class_entity.metric(['CountDeclClassMethod']).get('CountDeclClassMethod', 0)
        # final_methods = 0
        if "Interface" in class_entity.kindname():
            return all_methods

        private_or_static_or_final = 0
        kind_filter = 'Java Method ~Jar ~Library ~Constructor ~Implicit ~Lambda ~External'
        for ref in class_entity.refs('Define', kind_filter):
            if "Final" in ref.ent().kindname() or "Private" in ref.ent(
            ).kindname() or "Static" in ref.ent().kindname():
                private_or_static_or_final += 1
        number_of_polymorphic_methods = all_methods - private_or_static_or_final
        # print(class_entity.longname(), number_of_polymorphic_methods)
        return number_of_polymorphic_methods if number_of_polymorphic_methods >= 0 else 0
Exemplo n.º 2
0
    def DCC_class_level(self, class_entity: und.Ent):
        """
        DCC - Class Level Direct Class Coupling
        :param class_entity: The class entity
        :return: Number of other classes a class relates to, either through a shared attribute or
        a parameter in a method.
        """
        others = list()
        if "Interface" in class_entity.kindname():
            return 0

        for ref in class_entity.refs("Define", "Variable"):
            if ref.ent().type() in self.all_classes:
                others.append(ref.ent().type())

        kind_filter = "Method ~Unknown ~Jar ~Library ~Constructor ~Implicit ~Lambda ~External"
        for ref in class_entity.refs("Define", kind_filter):
            for ref2 in ref.ent().refs("Java Define", "Java Parameter"):
                if ref2.ent().type() in self.all_classes:
                    others.append(ref2.ent().type())

        for ref in class_entity.refs("Define", kind_filter):
            for ref2 in ref.ent().refs("Java Use Return"):
                if ref2.ent().type() in self.all_classes:
                    others.append(ref2.ent().type())

        return len(set(others))
Exemplo n.º 3
0
    def MFA_class_level(self, class_entity: und.Ent):
        """
        MFA - Class Level Measure of Functional Abstraction
        :param class_entity: The class entity
        :return: Ratio of the number of inherited methods per the total number of methods within a class.
        """
        metrics = class_entity.metric(
            ['CountDeclMethod', 'CountDeclMethodAll'])
        local_methods = metrics.get('CountDeclMethod')
        all_methods = metrics.get('CountDeclMethodAll')
        # print(class_entity.longname(), metrics)

        if "Interface" in class_entity.kindname():
            return 2.
        else:
            implemented_interfaces = class_entity.ents('Java Implement Couple',
                                                       '~Unknown')
            if len(implemented_interfaces) == 0:
                if all_methods == 0:
                    mfa = 0
                else:
                    mfa = round((all_methods - local_methods) / all_methods, 5)
            else:
                implemented_methods = 0
                for interface_entity in implemented_interfaces:
                    implemented_methods += interface_entity.metric(
                        ['CountDeclMethodAll']).get('CountDeclMethodAll', 0)
                if all_methods == 0:
                    mfa = 0
                else:
                    mfa = round(
                        (all_methods - implemented_methods) / all_methods, 5)
        # print(class_entity.longname(), mfa)
        return 1. + mfa if mfa >= 0 else 1
Exemplo n.º 4
0
    def DAM_class_level(self, class_entity: und.Ent):
        """
        DAM - Class Level Direct Access Metric
        :param class_entity: The class entity.
        :return: Ratio of the number of private and protected attributes to the total number of attributes in a class.
        """
        if "Interface" in class_entity.kindname():
            return 2.0

        private_variables = len(
            class_entity.ents("Define", "Java Variable Private Member"))
        protected_variables = len(
            class_entity.ents("Define", "Java Variable Protected Member"))
        default_variables = len(
            class_entity.ents("Define", "Java Variable Default Member"))
        public_variables = len(
            class_entity.ents("Define", "Java Variable Public Member"))

        try:
            enum_ = private_variables + protected_variables
            denum_ = private_variables + protected_variables + default_variables + public_variables
            ratio = enum_ / denum_
        except ZeroDivisionError:
            # logger.error('ZeroDivisionError in computing QMOOD DAM metric.')
            ratio = 2.0
        return 1. + ratio
Exemplo n.º 5
0
    def set_metrics(self, udb_ent: u.Ent):
        # lookup udb metrics
        metrics = udb_ent.metric(list(self.metrics.keys()))
        metrics = dict((k, v) for k, v in metrics.items() if v is not None)
        for k, v in metrics.items():
            if type(v) == str:
                self.metrics[k]['val'] = float(v)
            else:
                self.metrics[k]['val'] = v

        # set badFix
        if 'MaxCyclomaticStrict' in self.metrics.keys() and self.metrics['MaxCyclomaticStrict']['val'] not in [None, 0]:
            self.metrics['badFix']['val'] = self.metrics['MaxCyclomaticStrict']['val']

        # remove unnecessary metrics
        remove_set = set()
        if self.metrics['CountStmt']['val'] == 0:
            remove_set.add('RatioCommentToCode')

        ls = ['CountStmt']
        remove_set = remove_set.union(k for k, v in self.metrics.items() if v['val'] == 0 and k not in ls)
        remove_set = remove_set.union(set(k for (k, v) in self.metrics.items() if v['val'] is None))
        for m in remove_set:
            del self.metrics[m]

        # score the remaining metrics
        converters.score_metrics(self.metrics)
Exemplo n.º 6
0
    def CIS_class_level(self, class_entity: und.Ent):
        """
        CIS - Class Level Class Interface Size
        :param class_entity: The class entity
        :return: Number of public methods in class
        """
        if "Interface" in class_entity.kindname():
            value = class_entity.metric(['CountDeclMethodAll'
                                         ]).get('CountDeclMethodAll', 0)
        else:
            value = class_entity.metric(['CountDeclMethodPublic'
                                         ]).get('CountDeclMethodPublic', 0)
            # public_methods = len(class_entity.ents("Define", "Java Method Public Member"))

        if value is None:
            value = 0.
        # print(class_entity.longname(), value)
        return value
Exemplo n.º 7
0
    def CAMC_class_level(self, class_entity: und.Ent):
        """
        CAMC - Class Level Cohesion Among Methods of class
        Measures of how related methods are in a class in terms of used parameters.
        It can also be computed by: 1 - LackOfCohesionOfMethods()
        :param class_entity: The class entity.
        :return:  A float number between 0 (1) and 1 (2).
        """
        if "Interface" in class_entity.kindname():
            return 2.

        percentage = class_entity.metric(['PercentLackOfCohesion'
                                          ]).get('PercentLackOfCohesion', 0)

        if percentage is None:
            percentage = 0
        cohesion_ = 1. - (percentage / 100.)
        # print(class_entity.longname(), cohesion_)
        return 1. + round(cohesion_, 5)
Exemplo n.º 8
0
    def MOA_class_level(self, class_entity: und.Ent):
        """
        MOA - Class Level Measure of Aggregation
        :param class_entity: The class entity.
        :return: Count of number of attributes whose type is user defined class(es).
        """
        counter = 0
        for ref in class_entity.refs("Define, Typed, Set, Create",
                                     "Java Variable, Parameter"):
            if ref.ent().type() in self.user_defined_classes:
                counter += 1
        filter_ = "Method ~Unknown ~Jar ~Library ~Constructor ~Implicit ~Lambda ~External"
        for ref in class_entity.refs("Define, Typed, Set, Create", filter_):
            for ref2 in ref.ent().refs(
                    "Define, Typed, Set, Create",
                    "Java Variable ~Unknown, Java Parameter"):
                if ref2.ent().type() in self.user_defined_classes:
                    counter += 1

        return counter
Exemplo n.º 9
0
 def NOM_class_level(self, class_entity: und.Ent):
     """
     NOM - Class Level Number of Methods (WMC)
     :param class_entity: The class entity
     :return: Number of methods declared in a class.
     """
     if class_entity is not None:
         # print(class_entity.metric(['CountDeclMethod']).get('CountDeclMethod', 0))
         # kind_filter = 'Java Method ~Unknown ~Unresolved ~Jar ~Library ~Constructor ~Implicit ~Lambda ~External'
         # method_list = class_entity.ents('Define', kind_filter)
         # counter = 0
         # for method_ in method_list:
         #     if method_.metric(['Cyclomatic']).get('Cyclomatic', 0) > 1:
         #         counter += 1
         # return counter
         if "Interface" in class_entity.kindname():
             return 0
         # wmc = class_entity.metric(['SumCyclomatic']).get('SumCyclomatic', 0)
         wmc2 = class_entity.metric(['SumCyclomaticModified'
                                     ]).get('SumCyclomaticModified', 0)
         # print(class_entity.longname(), wmc, wmc2)
         return wmc2
     return 0
Exemplo n.º 10
0
 def __init__(self, udb_ent: u.Ent, parent_path: str):
     self.uid: int = udb_ent.id()
     self.name: str = udb_ent.name()
     self.long_name: str = udb_ent.longname()
     self.kind: str = udb_ent.kind().name()
     self.kind_long_name: str = udb_ent.kind().longname()
     self.language: str = udb_ent.language()
     self.path: str = '{}/{}'.format(parent_path, self.name)
     self.metrics: Dict = converters.get_empty_metrics_dict()
     self.set_metrics(udb_ent)
     if self.kind not in ['File', 'Module File']:
         sys.exit('entity is not a file kind {}'.format(self.name))
     self.deps = {}
     for k, vs in udb_ent.depends().items():
         self.deps[k.id()] = len(vs)
     self.metrics_ribbon = []