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
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
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))
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
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
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)
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