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)
Example #2
0
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)
Example #4
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)
Example #5
0
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
Example #6
0
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)