class ControlStructureComplexityMeasurer: code = "" # W_IF = 2 # W_FOR_WHILE = 3 # W_SWITCH = 2 # W_CASE = 1 w = wt() W_IF = w.get_control_structures()[0] W_FOR_WHILE = w.get_control_structures()[1] W_SWITCH = w.get_control_structures()[2] W_CASE = w.get_control_structures()[3] w_type = [] w_nest = [] n_conditions = [] method_lines = [] class_lines = [] control_structure_lines = [] loop_count = [] not_possible_lines = [] def __init__(self, code): self.clear_all() self.code = code self.remove_comments() self.run() def clear_all(self): self.w_type.clear() self.w_nest.clear() self.n_conditions.clear() self.method_lines.clear() self.class_lines.clear() self.control_structure_lines.clear() self.loop_count.clear() self.not_possible_lines.clear() def get_weight_due_to_type(self): return self.w_type def get_weight_due_to_nest(self): return self.w_nest def get_number_of_conditions(self): return self.n_conditions def get_control_structure_complexity(self): result = [] for t, c, n in zip(self.w_type, self.n_conditions, self.w_nest): if c == 0: c = 1 total = (t * c) + n result.append(total) return result def remove_comments(self): count = re.findall("/*", self.code) for i in count: # Remove multi line comments start = re.search("/\\*", self.code) end = re.search('\\*/', self.code) if start: a = self.code[0:start.span()[0]] b = self.code[end.span()[1]:len(self.code)] self.code = a + b # Remove Single line comments s = "" for i in self.code.split('\n'): start = re.search("//", i) if start: if i.strip(): if i[0:start.span()[0]].strip(): s += i[0:start.span()[0]] s += "\n" else: if i.strip(): s += i s += "\n" if s.strip(): self.code = s def run(self): self.find_line_types() saved_ccs = 0 for r, n_loops in zip(self.code.split('\n'), self.loop_count): w = 0 w_in = 0 conditions = 0 if r in self.control_structure_lines and r not in self.not_possible_lines: if "if" in r or "else" in r: conditions += 1 weight = self.W_IF if "&&" in r or "||" in r: n = ((len(re.findall("[|&]", r))) / 2) conditions += n if n_loops > 1: w_in += (weight * (n_loops - 1)) w += weight if "for" in r or "while" in r or "do" in r: conditions += 1 if n_loops > 1: w_in += (self.W_FOR_WHILE * (n_loops - 1)) w += self.W_FOR_WHILE if "switch" in r: conditions += 1 if n_loops > 1: w_in += (self.W_SWITCH * (n_loops - 1)) w += self.W_SWITCH if "case" in r: conditions += 1 if n_loops > 1: w_in += (self.W_CASE * (n_loops - 1)) w += self.W_CASE total = (w * conditions) + saved_ccs self.w_type.append(w) self.w_nest.append(w_in) self.n_conditions.append(conditions) print(total) saved_ccs = total def find_line_types(self): # cs - class stack, ms - method stack, css - control structure stack (including loops) cs = [] ms = [] css = [] types = [ "boolean", "byte", "char", "double", "float", "int", "long", "short", "string", "void", "String", "ArrayList", "List", "HashMap" ] loops = ["for", "while", "class", "do", "foreach"] control_structures = ["if", "switch", "else", "case", "IOException"] for r in self.code.split('\n'): frag = r.split(' ') if 'class' in frag: cs.append(1) self.not_possible_lines.append(r) else: # can be method, loop or control structure if '(' in r and ')' in r and "new" not in r: for f in frag: fl = f.strip() # Method if f in types or re.findall( "^[A-Z].*", f) and not re.findall("[.]", r): if f not in loops and f not in control_structures: cs.append(1) ms.append(1) self.not_possible_lines.append(r) # Loops elif fl in loops or fl in control_structures: cs.append(1) ms.append(1) css.append(1) else: print(fl) # Remove { from stacks if '}' in r: if len(cs) > 0: cs.pop() if len(ms) > 0: ms.pop() if len(css) > 0: css.pop() if len(cs) > 0: self.class_lines.append(r) if len(ms) > 0: self.method_lines.append(r) count = 0 if len(css) > 0: self.control_structure_lines.append(r) for i in css: count += i self.loop_count.append(count) print(self.control_structure_lines)
class MethodComplexityMeasurer: code = "" # W_PRIMITIVE = 1 # W_COMPOSITE = 2 # W_VOID = 0 # M_W_PRIMITIVE_R = 1 # M_W_COMPOSITE_R = 2 w = wt() W_PRIMITIVE = w.get_method()[0] W_COMPOSITE = w.get_method()[1] W_VOID = w.get_method()[2] M_W_PRIMITIVE_R = w.get_method()[3] M_W_COMPOSITE_R = w.get_method()[4] w_return_types = [] n_primitive_params = [] n_composite_params = [] complexity = [] method_lines = [] def __init__(self, code): self.clear_all() self.code = code self.remove_comments() self.run() def clear_all(self): self.code = "" self.w_return_types.clear() self.n_primitive_params.clear() self.n_composite_params.clear() self.complexity.clear() self.method_lines.clear() def remove_comments(self): count = re.findall("/*", self.code) for i in count: # Remove multi line comments start = re.search("/\\*", self.code) end = re.search('\\*/', self.code) if start: a = self.code[0:start.span()[0]] b = self.code[end.span()[1]:len(self.code)] self.code = a + b # Remove Single line comments s = "" for i in self.code.split('\n'): start = re.search("//", i) if start: if i.strip(): if i[0:start.span()[0]].strip(): s += i[0:start.span()[0]] s += "\n" else: if i.strip(): s += i s += "\n" if s.strip(): self.code = s def get_weight_return_type(self): return self.w_return_types def get_number_of_primitive_params(self): return self.n_primitive_params def get_number_of_composite_params(self): return self.n_composite_params def get_method_complexity(self): return self.complexity def run(self): self.find_method_lines() types = [ "boolean", "byte", "char", "double", "float", "int", "long", "short", "string" ] loops = ["for", "if", "while", "switch", "class", "do", "foreach"] for r in self.code.split('\n'): prim = 0 comp = 0 p_prim = 0 p_comp = 0 frag = r.split(' ') # Identify method declaration line if r in self.method_lines: sub_end = re.search("\\(", r).span()[0] next_end = re.search("\\)", r).span()[0] # get composite return type n_frag = r[0:sub_end].split(' ') comp_type = None for f in n_frag: comp_type = re.findall("^[A-Z].*", f) if comp_type: break # Identify Return type if comp_type: comp += 1 elif re.findall("void", r): pass else: for f in frag: if f in types: prim += 1 break # Parameters n_frag = r[sub_end + 1:next_end].split(' ') for f in n_frag: comp_type = re.findall("^[A-Z].*", f) if comp_type: p_comp += 1 elif re.findall("void", f): pass else: if f in types: p_prim += 1 r_complexity = (prim * self.W_PRIMITIVE) + (comp * self.W_COMPOSITE) self.w_return_types.append(r_complexity) self.n_primitive_params.append(p_prim) self.n_composite_params.append(p_comp) self.complexity.append(r_complexity + (p_prim * self.W_PRIMITIVE) + (p_comp * self.W_COMPOSITE)) def find_method_lines(self): types = [ "boolean", "byte", "char", "double", "float", "int", "long", "short", "string", "void", "String", "ArrayList", "List", "HashMap" ] loops = ["for", "while", "class", "do", "foreach"] control_structures = ["if", "switch", "else", "case", "IOException"] for r in self.code.split('\n'): frag = r.split(' ') if 'class' in frag: pass else: # can be method, loop or control structure if '(' in r and ')' in r and not re.findall( "[.]", r) and "new" not in r: for f in frag: # Method if f in types or re.findall("^[A-Z].*", f): if f not in loops and f not in control_structures: self.method_lines.append(r)
class InheritanceComplexityMeasurer: code = "" # C_W_0_INHERITANCE = 0 # C_W_1_INHERITANCE = 1 # C_W_2_INHERITANCE = 2 # C_W_3_INHERITANCE = 3 # C_W_MORE_INHERITANCE = 4 w = wt() C_W_0_INHERITANCE = w.get_inheritance()[0] C_W_1_INHERITANCE = w.get_inheritance()[1] C_W_2_INHERITANCE = w.get_inheritance()[2] C_W_3_INHERITANCE = w.get_inheritance()[3] C_W_MORE_INHERITANCE = w.get_inheritance()[4] final_result = [] ndi = [] nidi = [] ti = [] cname = "" CLASS_NAMES = [] LINES_WITH_INHERITANCE = [] class_name = " " class_info = {} directly_inherited = [] indirectly_inherited = [] def __init__(self, code): self.clear_all() self.code = code self.remove_comments() self.run() def clear_all(self): self.code = "" self.final_result.clear() self.ndi.clear() self.nidi.clear() self.ti.clear() def remove_comments(self): count = re.findall("/*", self.code) for i in count: # Remove multi line comments start = re.search("/\\*", self.code) end = re.search('\\*/', self.code) if start: a = self.code[0:start.span()[0]] b = self.code[end.span()[1]:len(self.code)] self.code = a + b # Remove Single line comments s = "" for i in self.code.split('\n'): start = re.search("//", i) if start: if i.strip(): if i[0:start.span()[0]].strip(): s += i[0:start.span()[0]] s += "\n" else: if i.strip(): s += i s += "\n" if s.strip(): self.code = s def get_complexity(self): return self.final_result def get_ndi(self): return self.ndi def get_nidi(self): return self.nidi def get_ti(self): return self.ti def run(self): # class inheritance details self.LINES_WITH_INHERITANCE = re.findall("class \\w+ : public \\w+", self.code) for line in (re.findall("class \\w+", self.code)): self.CLASS_NAMES.append(line.split(" ")[1].strip()) for class_name in self.CLASS_NAMES: # lists to store direct / indirect classes directly_inherited = [] indirectly_inherited = [] # Go through children using the recursion def find_children(cname): for line in self.LINES_WITH_INHERITANCE: if ":public " + cname in line: child_name = line.split(" ")[1] if cname == class_name: directly_inherited.append(child_name) find_children(child_name) else: indirectly_inherited.append(child_name) find_children(child_name) find_children(class_name) self.class_info[class_name] = [ directly_inherited, indirectly_inherited ] # starting to read a heavily code file line by line for r in self.code.split('\n'): frag = r.split(' ') if 'class' in frag: class_name = "" results = re.findall("class \\w+", r) class_name = results[0].split(" ")[1].strip() if class_name == "": continue dir_inh = 0 indir_inh = 0 for key, value in self.class_info.items(): if class_name in value[0]: dir_inh += 1 if class_name in value[1]: indir_inh += 1 self.ndi.append(dir_inh) self.nidi.append(indir_inh) tivalue = dir_inh + indir_inh self.ti.append(tivalue) if tivalue == self.C_W_0_INHERITANCE: self.final_result.append(self.C_W_0_INHERITANCE) elif tivalue == self.C_W_1_INHERITANCE: self.final_result.append(self.C_W_1_INHERITANCE) elif tivalue == self.C_W_2_INHERITANCE: self.final_result.append(self.C_W_2_INHERITANCE) elif tivalue == self.C_W_3_INHERITANCE: self.final_result.append(self.C_W_3_INHERITANCE) elif tivalue >= self.C_W_MORE_INHERITANCE: self.final_result.append(self.C_W_MORE_INHERITANCE) else: self.final_result.append(0) else: self.final_result.append(0) self.ndi.append(0) self.nidi.append(0) self.ti.append(0)
class VariableComplexityMeasurer: w = wt() # W_GLOBAL_SCOPE = 2 # W_LOCAL_SCOPE = 1 # W_PRIMITIVE = 1 # W_COMPOSITE = 2 W_GLOBAL_SCOPE = w.get_variable()[0] W_LOCAL_SCOPE = w.get_variable()[1] W_PRIMITIVE = w.get_variable()[2] W_COMPOSITE = w.get_variable()[3] code = "" lines = [] final_complexity = [] n_primitive = [] n_composite = [] inside_lines = [] method_lines = [] class_lines = [] control_structure_lines = [] not_possible_lines = [] def __init__(self, code): self.clear_all() self.code = code self.remove_comments() self.run() def clear_all(self): self.code = "" self.lines.clear() self.final_complexity.clear() self.n_primitive.clear() self.n_composite.clear() self.inside_lines.clear() self.method_lines.clear() self.class_lines.clear() self.control_structure_lines.clear() self.not_possible_lines.clear() def remove_comments(self): count = re.findall("/*", self.code) for i in count: # Remove multi line comments start = re.search("/\\*", self.code) end = re.search('\\*/', self.code) if start: a = self.code[0:start.span()[0]] b = self.code[end.span()[1]:len(self.code)] self.code = a + b # Remove Single line comments s = "" for i in self.code.split('\n'): start = re.search("//", i) if start: if i.strip(): if i[0:start.span()[0]].strip(): s += i[0:start.span()[0]] s += "\n" else: if i.strip(): s += i s += "\n" if s.strip(): self.code = s def get_variable_scope_weight(self): return self.lines def get_variable_complexity(self): return self.final_complexity def get_number_of_primitive_data(self): return self.n_primitive def get_number_of_composite_data(self): return self.n_composite def run(self): self.find_line_types() result = [] lines = [] p_types = [ "boolean", "byte", "char", "double", "float", "int", "long", "short", "string" ] c_structures = [ "class", "if", "else", "switch", "for", "while", "class", "do", "foreach", "switch", "case" ] for r in self.code.split('\n'): frag = r.strip().split(' ') if r in self.method_lines: lines.append(self.W_LOCAL_SCOPE) elif r in self.class_lines: lines.append(self.W_GLOBAL_SCOPE) else: lines.append(0) p_total = 0 # Primitive p = 0 for t in p_types: # in primitive data types if t in frag: if r not in self.not_possible_lines and r not in self.control_structure_lines: if r in self.method_lines: # Local p_total += (self.W_LOCAL_SCOPE * self.W_PRIMITIVE) p += 1 elif r in self.class_lines: # Global p_total += (self.W_GLOBAL_SCOPE * self.W_PRIMITIVE) p += 1 if "," in r: p *= 2 p_total *= 2 self.n_primitive.append(p) # Composite c = 0 c_total = 0 for f in frag: # f = f.strip() if re.findall("^[A-Z].*", f) \ and (not re.findall("[.]", r) or ".getInstance()" in r) \ and f not in c_structures \ and r not in self.not_possible_lines \ and r not in self.control_structure_lines: # Local if r in self.method_lines: c_total += (self.W_LOCAL_SCOPE * self.W_COMPOSITE) c += 1 # Global elif r in self.class_lines: c_total += (self.W_GLOBAL_SCOPE * self.W_COMPOSITE) c += 1 total = 0 if '"' in r: c = 0 if " new " in r or "getInstance()" in r: self.n_composite.append(int(c / 2)) total = p_total + (c_total / 2) else: self.n_composite.append(c) total = p_total + c_total if '"' in r: total = 0 result.append(total) self.final_complexity = result self.lines = lines def find_line_types(self): # cs - class stack, ms - method stack, css - control structure stack (including loops) cs = [] ms = [] css = [] types = [ "boolean", "byte", "char", "double", "float", "int", "long", "short", "string", "void", "String", "ArrayList", "List", "HashMap" ] loops = ["for", "while", "class", "do", "foreach"] control_structures = ["if", "switch", "else", "case", "IOException"] for r in self.code.split('\n'): frag = r.split(' ') if 'class' in frag: cs.append(1) self.not_possible_lines.append(r) else: # can be method, loop or control structure if '(' in r and ')' in r and not re.findall( "[.]", r) and "new" not in r: for f in frag: # Method if f in types or re.findall("^[A-Z].*", f): if f not in loops and f not in control_structures: cs.append(1) ms.append(1) self.not_possible_lines.append(r) # Loops elif f in loops or f in control_structures: cs.append(1) ms.append(1) css.append(1) self.not_possible_lines.append(r) # Remove { from stacks if '}' in r: if len(cs) > 0: cs.pop() if len(ms) > 0: ms.pop() if len(css) > 0: css.pop() if len(cs) > 0: self.class_lines.append(r) if len(ms) > 0: self.method_lines.append(r) if len(css) > 0: self.control_structure_lines.append(r)
class SizeComplexityMeasurer(object): w = wt() code = '' # W_KEYWORD = 1 # W_IDENTIFIER = 1 # W_OPERATOR = 1 # W_NUMERICAL_VAL = 1 # W_STRING_LIT = 1 W_KEYWORD = w.get_size()[0] W_IDENTIFIER = w.get_size()[1] W_OPERATOR = w.get_size()[2] W_NUMERICAL_VAL = w.get_size()[3] W_STRING_LIT = w.get_size()[4] def __init__(self, code): self.code = '' self.code = code self.remove_comments() def get_code_lines(self): code_lines = [] for i in self.code.split('\n'): code_lines.append(i) return code_lines def remove_comments(self): count = re.findall("/*", self.code) for i in count: # Remove multi line comments start = re.search("/\\*", self.code) end = re.search('\\*/', self.code) if start: a = self.code[0:start.span()[0]] b = self.code[end.span()[1]:len(self.code)] self.code = a + b # Remove Single line comments s = "" for i in self.code.split('\n'): start = re.search("//", i) if start: if i.strip(): if i[0:start.span()[0]].strip(): s += i[0:start.span()[0]] s += "\n" else: if i.strip(): s += i s += "\n" if s.strip(): self.code = s # def get_operators(self): # operators_list = ["+", "-", "*", "/", "%", "++", "--", "==", "!=", ">", "<", ">=", "<=", "&&", # "||", "!", "|", "^", "~", ",", # ".", "::", "+=", "-=", "*=", "/=", "=", # "|=", "&=", "%="] # operators = [] # y = [] # for i in self.code.split('\n'): # # y = re.findall("[=<>+/!&|:%\-*~]{1,2}", i.strip()) # # x = 0 # for w in i.split(' '): # if w in operators_list: # y.append(w) # if x == 0: # n = len(re.findall("[=<>+/!&|:%\-*~]{1,2}", i.strip())) # x += n # x = len(y) # y.clear() # # if "import " in i: # x = 0 # operators.append(x * self.W_OPERATOR) # return operators def get_operators(self): operators = [] for i in self.code.split('\n'): y = re.findall("[=<>+/!&|%\-*~.,]{1,2}", i.strip()) x = len(y) if "import " in i: x = 0 operators.append(x * self.W_OPERATOR) return operators def get_keywords(self): keyword_list = [ "abstract", "assert", "break", "catch", "class", "continue", "default", "enum", "exports", "extends", "final", "finally", "implements", "import", "instanceof", "module", "native", "new", "package", "private", "protected", "public", "requires", "return", "static", "strictfp", "super", "synchronized", "this", "throw", "throws", "transient", "try", "var", "void", "volatile", "true", "else", "null", "this" ] keyword = [] for i in self.code.split('\n'): count = 0 for word in i.split(' '): w = word.strip() if w in keyword_list: count += 1 if "import " in i: count = 0 keyword.append(count * self.W_KEYWORD) return keyword def get_numerical_values(self): num_values = [] for i in self.code.split('\n'): x = len(re.findall('[0-9]+', i)) num_values.append(x * self.W_NUMERICAL_VAL) return num_values def get_string_literals(self): string_literals = [] for i in self.code.split('\n'): count = 0 x = len(re.findall('"', i)) if x % 2 == 0: x = x / 2 count = int(x) * self.W_STRING_LIT string_literals.append(count) return string_literals def get_identifiers(self): identifier_list = [ "boolean", "byte", "char", "class", "double", "float", "int", "long", "short", "string", "String", "ArrayList", "List", "HashMap", "void" ] identifiers = [] for i in self.code.split('\n'): count = 0 for w in i.split(' '): if w in identifier_list: count += 1 if count == 0: x = len(re.findall('\\((int|bool)', i)) count = x for w in i.split(' '): j = len(re.findall("(?<=.)\w+(?=\.)", w)) count += j # Static identifiers for w in i.split(' '): c = len(re.findall('^[A-Z][\w]{1,20}[.]', w)) count += c # Commons for w in i.split(' '): if '"' not in w: c = len(re.findall('^[A-Z][\w]{1,20}', w)) count += c if "import " in i: count = 0 identifiers.append(count * self.W_IDENTIFIER) return identifiers
class CouplingComplexityMeasurer: # W_RM_TO_RM_INSIDE = 2 # W_RM_TO_RM_OUTSIDE = 3 # W_RM_TO_RCM_INSIDE = 3 # W_RM_TO_RCM_OUTSIDE = 4 # W_RCM_TO_RM_INSIDE = 3 # W_RCM_TO_RM_OUTSIDE = 4 # W_RCM_RCM_INSIDE = 4 # W_RCM_TO_RCM_OUTSIDE = 5 # W_RM_TO_GLOBAL_INSIDE = 1 # W_RCM_TO_GLOBAL_INSIDE = 1 # W_RM_TO_GLOBAL_OUTSIDE = 2 # W_RCM_TO_GLOBAL_OUTSIDE = 2 # RCM_CALL = 2 w = wt() W_RM_TO_RM_INSIDE = w.get_coupling()[0] W_RM_TO_RM_OUTSIDE = w.get_coupling()[1] W_RM_TO_RCM_INSIDE = w.get_coupling()[2] W_RM_TO_RCM_OUTSIDE = w.get_coupling()[3] W_RCM_TO_RM_INSIDE = w.get_coupling()[4] W_RCM_TO_RM_OUTSIDE = w.get_coupling()[5] W_RCM_RCM_INSIDE = w.get_coupling()[6] W_RCM_TO_RCM_OUTSIDE = w.get_coupling()[7] W_RM_TO_GLOBAL_INSIDE = w.get_coupling()[8] W_RCM_TO_GLOBAL_INSIDE = w.get_coupling()[9] W_RM_TO_GLOBAL_OUTSIDE = w.get_coupling()[10] W_RCM_TO_GLOBAL_OUTSIDE = w.get_coupling()[11] RCM_CALL = w.get_coupling()[12] code = "" declared_method_lines = [] declared_method_names = [] regular_method_calls_lines = [] recursive_method_calls_lines = [] regular_method_calls_names = [] recursive_method_calls_names = [] rm_to_rm_inside = [] rm_to_rm_outside = [] rm_to_rcm_inside = [] rm_to_rcm_outside = [] rcm_to_rm_inside = [] rcm_to_rm_outside = [] rcm_rcm_inside = [] rcm_to_rcm_outside = [] rm_to_global_inside = [] rcm_to_global_inside = [] rm_to_global_outside = [] rcm_to_global_outside = [] total = [] method_lines = [] class_lines = [] control_structure_lines = [] not_possible_lines = [] method_tracker = [] def __init__(self, code): self.clear_all() self.code = code self.remove_comments() self.run() def method_calls(self): types = [ "boolean", "byte", "char", "double", "float", "int", "long", "short", "string", "void", "String", "return", "int", "public" "ArrayList", "List", "HashMap", "return" ] loops = ["for", "while", "class", "do", "foreach"] control_structures = ["if", "switch", "else", "case", "IOException"] type_list = [] type_list.extend(types) type_list.extend(loops) type_list.extend(control_structures) global_variables = [] method_variable_list = [] main_index = 0 for line in self.code.split("\n"): if line not in self.method_lines: variable_list = re.findall(r'[ ]{0,20}[A-z]{1,20}[ =;]', line) for var in variable_list: variable = var.strip() if variable not in type_list: global_variables.append(variable.strip()) for line in self.code.split("\n"): new_list = [] if line in self.method_lines: if line not in self.declared_method_lines: variable_list_1 = re.findall(r' [A-z]{1,20} ', line) variable_list_2 = re.findall('[(][A-z]{1,20}[)]', line) for variable in variable_list_1: var = variable.strip() if var not in type_list: new_list.append(var) for variable in variable_list_2: var = re.findall('[A-z]{1,20}', variable) for v in var: if var not in type_list: new_list.append(v.strip()) method_variable_list.append(new_list) for line in self.code.split("\n"): rm_to_rm_inside = 0 rm_to_rm_outside = 0 rm_to_rcm_inside = 0 rm_to_rcm_outside = 0 rcm_to_rm_inside = 0 rcm_to_rm_outside = 0 rcm_rcm_inside = 0 rcm_to_rcm_outside = 0 rm_to_global_inside = 0 rcm_to_global_inside = 0 rm_to_global_outside = 0 rcm_to_global_outside = 0 if line not in self.not_possible_lines: # regular method parent if line in self.regular_method_calls_lines: # regular methods calls index = self.regular_method_calls_lines.index(line) name = self.regular_method_calls_names[index] # methods if name not in self.recursive_method_calls_names: if name in self.declared_method_names: rm_to_rm_inside += 1 else: rm_to_rm_outside += 1 # recursive method call else: if name in self.declared_method_names: rm_to_rcm_inside += 1 else: rm_to_rcm_outside += 1 for name in method_variable_list[main_index]: if name in global_variables: rm_to_global_inside += 1 break else: rm_to_global_outside += 1 break # rcm parent if line in self.recursive_method_calls_lines: index = self.recursive_method_calls_lines.index(line) name = self.recursive_method_calls_names[index] # regular methods calls if name not in self.recursive_method_calls_names: if name in self.declared_method_names: rcm_to_rm_inside += 1 else: rcm_to_rm_outside += 1 # recursive method call else: if name in self.declared_method_names: rcm_rcm_inside += 1 else: rcm_to_rcm_outside += 1 for name in method_variable_list[main_index]: if name in global_variables: rcm_to_global_inside += 1 break else: rcm_to_global_outside += 1 break self.rm_to_rm_inside.append(rm_to_rm_inside) self.rm_to_rm_outside.append(rm_to_rm_outside) self.rm_to_rcm_inside.append(rm_to_rcm_inside) self.rm_to_rcm_outside.append(rm_to_rcm_outside) self.rcm_to_rm_inside.append(rcm_to_rm_inside) self.rcm_to_rm_outside.append(rcm_to_rm_outside) self.rcm_rcm_inside.append(rcm_rcm_inside) self.rcm_to_rcm_outside.append(rcm_to_rcm_outside) self.rm_to_global_inside.append(rm_to_global_inside) self.rm_to_global_outside.append(rm_to_global_outside) self.rcm_to_global_inside.append(rcm_to_global_inside) self.rcm_to_global_outside.append(rcm_to_global_outside) main_index += 1 def clear_all(self): self.code = "" def remove_comments(self): count = re.findall("/*", self.code) for i in count: # Remove multi line comments start = re.search("/\\*", self.code) end = re.search('\\*/', self.code) if start: a = self.code[0:start.span()[0]] b = self.code[end.span()[1]:len(self.code)] self.code = a + b # Remove Single line comments s = "" for i in self.code.split('\n'): start = re.search("//", i) if start: if i.strip(): if i[0:start.span()[0]].strip(): s += i[0:start.span()[0]] s += "\n" else: if i.strip(): s += i s += "\n" if s.strip(): self.code = s def run(self): self.find_method_lines() self.find_line_types() self.find_method_line_types() self.method_calls() self.calculate_total() def find_method_lines(self): method_call_lines = [] types = [ "void", "boolean", "byte", "char", "double", "float", "int", "long", "short", "string", "String", "ArrayList", "List", "HashMap" ] loops = ["for", "while", "class", "do", "foreach"] control_structures = ["if", "switch", "else", "case", "IOException"] for r in self.code.split('\n'): frag = r.split(' ') if 'class' in frag: pass else: # can be method, loop or control structure if '(' in r and ')' in r and not re.findall( "[.]", r) and "new" not in r: for f in frag: # Method if f in types or re.findall("^[A-Z].*", f): if f not in loops and f not in control_structures: self.declared_method_lines.append(r) else: if f not in loops and f not in control_structures: if r not in method_call_lines: method_call_lines.append(r) for line in method_call_lines: if line in self.declared_method_lines: method_call_lines.remove(line) for declared in self.declared_method_lines: start = None for t in types: s = re.search(t, declared) if s: start = s.span()[1] break end = re.search("\\(", declared).span()[0] if start: name = str(declared[start:end]).strip() if name not in self.declared_method_names: self.declared_method_names.append(name) for call in method_call_lines: new_word = call.strip() end = re.search('\\(', new_word) if end: for f in new_word.split(' '): start = 0 self.regular_method_calls_lines.append(call) if 'return' in f: # self.recursive_method_calls_lines.append(call) s = re.search('return', new_word) if s: start = s.span()[1] # self.recursive_method_calls_names.append(new_word[start:end.span()[0]].strip()) # regular methods self.regular_method_calls_names.append( new_word[start:end.span()[0]].strip()) break else: # regular methods self.regular_method_calls_names.append( new_word[start:end.span()[0]].strip()) # def method_type_tracker(self): # method_types = [] # lines = self.code.split('\n') # start = 0 # while start < len(self.method_tracker): # method_type = False # if self.method_tracker[start] == 1: # count = 1 # next_start = start + 1 # while self.method_tracker[next_start] == 1: # for li in self.recursive_method_calls_lines: # if li in lines[next_start]: # method_type = True # count += 1 # next_start += 1 # for a in range(count): # method_types.append(method_type) # else: # method_types.append(method_type) # start += 1 # print(method_types) def find_method_line_types(self): inside_method = False last_saved_method = "" print(self.declared_method_lines) print(self.declared_method_names) for line in self.code.split("\n"): if line in self.method_lines: if line in self.declared_method_lines: try: last_saved_method = self.declared_method_names[ self.declared_method_lines.index(line)] except IndexError: last_saved_method = 'null' inside_method = True if inside_method and line not in self.declared_method_lines: s = re.search('return', line) end = re.search('\\(', line) if s and end: start = s.span()[1] name = line[start:end.span()[0]].strip() if last_saved_method == name: self.recursive_method_calls_lines.append(line) self.recursive_method_calls_names.append(name) else: inside_method = False for line in self.regular_method_calls_lines: if line in self.recursive_method_calls_lines: index = self.regular_method_calls_lines.index(line) self.regular_method_calls_lines.remove(line) self.regular_method_calls_names.remove( self.regular_method_calls_names[index]) def find_line_types(self): # cs - class stack, ms - method stack, css - control structure stack (including loops) cs = [] ms = [] css = [] types = [ "boolean", "byte", "char", "double", "float", "int", "long", "short", "string", "void", "String", "ArrayList", "List", "HashMap" ] loops = ["for", "while", "class", "do", "foreach"] control_structures = ["if", "switch", "else", "case", "IOException"] for r in self.code.split('\n'): bo = 0 frag = r.split(' ') if 'class' in frag: cs.append(1) self.not_possible_lines.append(r) else: # can be method, loop or control structure if '(' in r and ')' in r and not re.findall( "[.]", r) and "new" not in r: for f in frag: # Method if f in types or re.findall("^[A-Z].*", f): if f not in loops and f not in control_structures: cs.append(1) ms.append(1) bo = 1 self.not_possible_lines.append(r) # Loops elif f in loops or f in control_structures: cs.append(1) ms.append(1) css.append(1) self.not_possible_lines.append(r) # Remove { from stacks if '}' in r: if len(cs) > 0: cs.pop() if len(ms) > 0: ms.pop() if len(ms) == 0: bo = 1 if len(css) > 0: css.pop() if len(cs) > 0: self.class_lines.append(r) if len(ms) > 0: self.method_lines.append(r) if len(css) > 0: self.control_structure_lines.append(r) self.method_tracker.append(bo) def calculate_total(self): lines = self.code.split("\n") for i in range(0, len(lines)): total = self.rm_to_rm_inside[i] * self.W_RM_TO_RM_INSIDE + \ self.rm_to_rm_outside[i] * self.W_RM_TO_RM_OUTSIDE + \ self.rm_to_rcm_inside[i] * self.W_RM_TO_RCM_INSIDE + \ self.rm_to_rcm_outside[i] * self.W_RM_TO_RCM_OUTSIDE + \ self.rcm_to_rm_inside[i] * self.W_RCM_TO_RM_INSIDE + \ self.rcm_to_rm_outside[i] * self.W_RCM_TO_RM_OUTSIDE + \ self.rcm_rcm_inside[i] * self.W_RCM_RCM_INSIDE + \ self.rcm_to_rcm_outside[i] * self.W_RCM_TO_RCM_OUTSIDE + \ self.rm_to_global_inside[i] * self.W_RM_TO_GLOBAL_INSIDE + \ self.rcm_to_global_inside[i] * self.W_RCM_TO_GLOBAL_INSIDE + \ self.rm_to_global_outside[i] * self.W_RM_TO_GLOBAL_OUTSIDE + \ self.rcm_to_global_outside[i] * self.W_RCM_TO_GLOBAL_OUTSIDE self.total.append(total)