예제 #1
0
 def __init__(self, source_filenames: list):
     self.source_filenames = source_filenames
     self.program = get_program(self.source_filenames)
예제 #2
0
    def do_refactor(self):
        program = utils2.get_program(self.source_filenames, print_status=True)
        superclass: utils_listener_fast.Class = program.packages[
            self.package_name].classes[self.superclass_name]

        if not self.pre_condition_check(program, superclass):
            print("Can't refactor")
            return False

        # all_derived_classes = [] # Not needed
        other_derived_classes = []
        classes_to_add_to = []
        for pn in program.packages:
            p: utils_listener_fast.Package = program.packages[pn]
            for cn in p.classes:
                c: utils_listener_fast.Class = p.classes[cn]
                if ((c.superclass_name == self.superclass_name and c.file_info.has_imported_class(self.package_name,
                                                                                                  self.superclass_name)) \
                        or (self.package_name is not None and c.superclass_name == self.package_name + '.' + self.superclass_name)):
                    # all_derived_classes.append(c)

                    if len(self.class_names) == 0 or cn in self.class_names:
                        if self.field_name in c.fields:
                            print("some classes have same variable")
                            return False
                        else:
                            classes_to_add_to.append(c)
                    else:
                        other_derived_classes.append(c)

        # Check if the field is used from the superclass or other derived classes
        for pn in program.packages:
            p: utils_listener_fast.Package = program.packages[pn]
            for cn in p.classes:
                c: utils_listener_fast.Class = p.classes[cn]
                has_imported_superclass = c.file_info.has_imported_class(
                    self.package_name, self.superclass_name)
                fields_of_superclass_type_or_others = []
                for fn in c.fields:
                    f: utils_listener_fast.Field = c.fields[fn]
                    if (f.name == self.field_name and has_imported_superclass) \
                            or (self.package_name is not None and f.name == (
                            self.package_name + '.' + self.superclass_name)):
                        fields_of_superclass_type_or_others.append(f.name)
                    if any((c.file_info.has_imported_class(
                            o.package_name, o.name) and f.datatype == o.name)
                           or f.datatype == (o.package_name + '.' + o.name)
                           for o in other_derived_classes):
                        fields_of_superclass_type_or_others.append(f.name)
                for mk in c.methods:
                    m: utils_listener_fast.Method = c.methods[mk]
                    local_vars_of_superclass_type_or_others = []
                    for item in m.body_local_vars_and_expr_names:
                        if isinstance(item, utils_listener_fast.LocalVariable):
                            if (item.datatype == self.superclass_name and has_imported_superclass) \
                                    or item.datatype == (self.package_name + '.' + self.superclass_name):
                                local_vars_of_superclass_type_or_others.append(
                                    item.identifier)
                            if any((c.file_info.has_imported_class(
                                    o.package_name, o.name) and item.datatype
                                    == o.name) or item.datatype == (
                                        o.package_name + '.' + o.name)
                                   for o in other_derived_classes):
                                local_vars_of_superclass_type_or_others.append(
                                    item.identifier)
                        elif isinstance(item,
                                        utils_listener_fast.ExpressionName):
                            if item.dot_separated_identifiers[-1] == self.field_name \
                                    and (
                                    (len(item.dot_separated_identifiers) == 2)
                                    or (len(item.dot_separated_identifiers) == 3 and item.dot_separated_identifiers[
                                0] == "this")
                            ) and (
                                    (item.dot_separated_identifiers[
                                         -2] in local_vars_of_superclass_type_or_others and len(
                                        item.dot_separated_identifiers) == 2)
                                    or item.dot_separated_identifiers[-2] in fields_of_superclass_type_or_others
                            ):
                                return False

        rewriter = utils2.Rewriter(program, self.filename_mapping)

        field = superclass.fields[self.field_name]
        if len(field.neighbor_names) == 0:
            rewriter.replace(field.get_tokens_info(), "")
            # Have to remove the modifiers too, because of the new grammar.
            for mod_ctx in field.modifiers_parser_contexts:
                rewriter.replace(utils_listener_fast.TokensInfo(mod_ctx), "")
        else:
            i = field.index_in_variable_declarators
            var_ctxs = field.all_variable_declarator_contexts
            if i == 0:
                to_remove = utils_listener_fast.TokensInfo(var_ctxs[i])
                to_remove.stop = utils_listener_fast.TokensInfo(
                    var_ctxs[i + 1]).start - 1  # Include the ',' after it
                rewriter.replace(to_remove, "")
            else:
                to_remove = utils_listener_fast.TokensInfo(var_ctxs[i])
                to_remove.start = utils_listener_fast.TokensInfo(
                    var_ctxs[i - 1]).stop + 1  # Include the ',' before it
                rewriter.replace(to_remove, "")

        is_public = "public" in field.modifiers
        is_protected = "protected" in field.modifiers
        modifier = ("public " if is_public else
                    ("protected " if is_protected else ""))
        for c in classes_to_add_to:
            c_body_start = utils_listener_fast.TokensInfo(
                c.parser_context.classBody())
            c_body_start.stop = c_body_start.start  # Start and stop both point to the '{'
            rewriter.insert_after(c_body_start, "\n    " + modifier + field.datatype + " " + self.field_name \
                                  + ((" = " + field.initializer) if field.initializer is not None else "")
                                  + ";")

        rewriter.apply()
        return True
예제 #3
0
    def do_refactor(self):
        program = utils2.get_program(self.source_filenames, print_status=True)
        # print(program.packages)
        if self.package_name not in program.packages \
                or self.class_name not in program.packages[self.package_name].classes \
                or self.field_name not in program.packages[self.package_name].classes[self.class_name].fields:
            return False

        _class: utils_listener_fast.Class = program.packages[
            self.package_name].classes[self.class_name]
        if _class.superclass_name is None:
            return False

        superclass_name = _class.superclass_name

        superclass: utils_listener_fast.Class = program.packages[
            self.package_name].classes[superclass_name]
        superclass_body_start = utils_listener_fast.TokensInfo(
            superclass.parser_context.classBody())
        superclass_body_start.stop = superclass_body_start.start  # Start and stop both point to the '{'

        if self.field_name in superclass.fields:
            return False

        datatype = _class.fields[self.field_name].datatype

        fields_to_remove = []
        for pn in program.packages:
            p: utils_listener_fast.Package = program.packages[pn]
            for cn in p.classes:
                c: utils_listener_fast.Class = p.classes[cn]
                if ((c.superclass_name == superclass_name and c.file_info.has_imported_class(self.package_name,
                                                                                             superclass_name))
                    or (
                            self.package_name is not None and c.superclass_name == self.package_name + '.' + superclass_name)) \
                        and self.field_name in c.fields \
                        and c.fields[self.field_name].datatype == datatype:
                    fields_to_remove.append(c.fields[self.field_name])

        if len(fields_to_remove) == 0:
            return False

        is_public = False
        is_protected = True
        for field in fields_to_remove:
            field: utils_listener_fast.Field = field
            is_public = is_public or "public" in field.modifiers
            is_protected = is_protected and ("protected" in field.modifiers
                                             or "private" in field.modifiers)

        rewriter = utils2.Rewriter(program, self.filename_mapping)

        rewriter.insert_after(
            superclass_body_start,
            "\n    " + ("public " if is_public else
                        ("protected " if is_protected else "")) + datatype +
            " " + self.field_name + ";")

        for field in fields_to_remove:
            if len(field.neighbor_names) == 0:
                rewriter.replace(field.get_tokens_info(), "")
                # Have to remove the modifiers too, because of the new grammar.
                for mod_ctx in field.modifiers_parser_contexts:
                    rewriter.replace(utils_listener_fast.TokensInfo(mod_ctx),
                                     "")
            else:
                i = field.index_in_variable_declarators
                var_ctxs = field.all_variable_declarator_contexts
                if i == 0:
                    to_remove = utils_listener_fast.TokensInfo(var_ctxs[i])
                    to_remove.stop = utils_listener_fast.TokensInfo(
                        var_ctxs[i + 1]).start - 1  # Include the ',' after it
                    rewriter.replace(to_remove, "")
                else:
                    to_remove = utils_listener_fast.TokensInfo(var_ctxs[i])
                    to_remove.start = utils_listener_fast.TokensInfo(
                        var_ctxs[i - 1]).stop + 1  # Include the ',' before it
                    rewriter.replace(to_remove, "")

            # Add initializer to class constructor if initializer exists in field declaration
            if field.initializer is not None:
                _class: utils_listener_fast.Class = program.packages[
                    field.package_name].classes[field.class_name]
                initializer_statement = (
                    field.name + " = " +
                    ("new " + field.datatype +
                     " " if field.initializer.startswith('{') else "") +
                    field.initializer + ";")
                has_contructor = False
                for class_body_decl in _class.parser_context.classBody(
                ).getChildren():
                    if class_body_decl.getText() in ['{', '}']:
                        continue
                    member_decl = class_body_decl.memberDeclaration()
                    if member_decl is not None:
                        constructor = member_decl.constructorDeclaration()
                        if constructor is not None:
                            body = constructor.constructorBody  # Start token = '{'
                            body_start = utils_listener_fast.TokensInfo(body)
                            body_start.stop = body_start.start  # Start and stop both point to the '{'
                            rewriter.insert_after(
                                body_start,
                                "\n        " + initializer_statement)
                            has_contructor = True
                if not has_contructor:
                    body = _class.parser_context.classBody()
                    body_start = utils_listener_fast.TokensInfo(body)
                    body_start.stop = body_start.start  # Start and stop both point to the '{'
                    rewriter.insert_after(
                        body_start, "\n    " + _class.modifiers[0] + " " +
                        _class.name + "() { " + initializer_statement + " }")

        rewriter.apply()

        # check for multilevel inheritance recursively.

        if _class.superclass_name is not None:
            PullUpFieldRefactoring(self.source_filenames, self.package_name,
                                   _class.superclass_name, "id").do_refactor()
        return True
예제 #4
0
    def do_refactor(self):
        program = get_program(self.source_filenames)
        static = 0

        if self.class_name not in program.packages[self.package_name].classes or self.target_class_name not in \
                program.packages[
                    self.target_package_name].classes or self.method_key not in \
                program.packages[self.package_name].classes[
                    self.class_name].methods:
            return False

        _sourceclass = program.packages[self.package_name].classes[
            self.class_name]
        _targetclass = program.packages[self.target_package_name].classes[
            self.target_class_name]
        _method = program.packages[self.package_name].classes[
            self.class_name].methods[self.method_key]

        if _method.is_constructor:
            return False

        Rewriter_ = Rewriter(program, lambda x: x)
        tokens_info = TokensInfo(
            _method.parser_context)  # tokens of ctx method
        param_tokens_info = TokensInfo(_method.formalparam_context)
        method_declaration_info = TokensInfo(
            _method.method_declaration_context)
        exp = [
        ]  # برای نگه داری متغیرهایی که داخل کلاس تعریف شدند و در بدنه متد استفاده شدند
        exps = tokens_info.get_token_index(tokens_info.token_stream.tokens,
                                           tokens_info.start, tokens_info.stop)

        # check that method is static or not
        for modifier in _method.modifiers:
            if modifier == "static":
                static = 1

        for token in exps:
            if token.text in _sourceclass.fields:
                exp.append(token.tokenIndex)
            # check that where this method is call
        for package_names in program.packages:
            package = program.packages[package_names]
            for class_ in package.classes:
                _class = package.classes[class_]
                for method_ in _class.methods:
                    __method = _class.methods[method_]
                    for inv in __method.body_method_invocations:
                        invc = __method.body_method_invocations[inv]
                        method_name = self.method_key[:self.method_key.find('('
                                                                            )]
                        if invc[0] == method_name:
                            inv_tokens_info = TokensInfo(inv)
                            if static == 0:
                                class_token_info = TokensInfo(
                                    _class.body_context)
                                Rewriter_.insert_after_start(
                                    class_token_info,
                                    self.target_class_name + " " +
                                    str.lower(self.target_class_name) + "=" +
                                    "new " + self.target_class_name + "();")
                                Rewriter_.apply()
                            Rewriter_.insert_before_start(
                                class_token_info,
                                "import " + self.target_package_name + "." +
                                self.target_class_name + ";")
                            Rewriter_.replace(inv_tokens_info,
                                              self.target_class_name)
                        Rewriter_.apply()

        class_tokens_info = TokensInfo(_targetclass.parser_context)
        package_tokens_info = TokensInfo(
            program.packages[self.target_package_name].package_ctx)
        singlefileelement = SingleFileElement(_method.parser_context,
                                              _method.filename)
        token_stream_rewriter = TokenStreamRewriter(
            singlefileelement.get_token_stream())

        # insert name of source.java class befor param that define in body of classe (that use in method)
        for index in exp:
            token_stream_rewriter.insertBeforeIndex(
                index=index, text=str.lower(self.class_name) + ".")

        for inv in _method.body_method_invocations:
            if inv.getText() == self.target_class_name:
                inv_tokens_info_target = TokensInfo(inv)
                token_stream_rewriter.replaceRange(
                    from_idx=inv_tokens_info_target.start,
                    to_idx=inv_tokens_info_target.stop + 1,
                    text=" ")

            # insert source.java class befor methods of sourcr class that used in method
        for i in _method.body_method_invocations_without_typename:
            if i.getText() == self.class_name:
                ii = _method.body_method_invocations_without_typename[i]
                i_tokens = TokensInfo(ii[0])
                token_stream_rewriter.insertBeforeIndex(
                    index=i_tokens.start,
                    text=str.lower(self.class_name) + ".")

        # pass object of source.java class to method
        if param_tokens_info.start is not None:
            token_stream_rewriter.insertBeforeIndex(
                param_tokens_info.start,
                text=self.class_name + " " + str.lower(self.class_name) + ",")
        else:
            token_stream_rewriter.insertBeforeIndex(
                method_declaration_info.stop,
                text=self.class_name + " " + str.lower(self.class_name))

        strofmethod = token_stream_rewriter.getText(
            program_name=token_stream_rewriter.DEFAULT_PROGRAM_NAME,
            start=tokens_info.start,
            stop=tokens_info.stop)

        Rewriter_.insert_before(tokens_info=class_tokens_info,
                                text=strofmethod)
        Rewriter_.insert_after(
            package_tokens_info, "import " + self.target_package_name + "." +
            self.target_class_name + ";")
        Rewriter_.replace(tokens_info, "")
        Rewriter_.apply()
        return True
예제 #5
0
    def do_refactor(self):
        program = get_program(
            self.source_filenames)  # getting the program packages
        _sourceclass = program.packages[self.package_name].classes[
            self.class_name]
        target_class_name = _sourceclass.superclass_name
        removemethod, removemethod1 = get_cons(
            program, self.package_name, target_class_name,
            self.class_name)  # Similar cons in other classes
        _targetclass = program.packages[
            self.package_name].classes[target_class_name]
        mets = program.packages[self.package_name].classes[
            self.class_name].methods
        _method_name = []
        for methodName, method in mets.items():
            if method.is_constructor:
                _method_name = method
                break
        tokens_info = TokensInfo(_method_name.parser_context)

        if not _method_name.is_constructor:
            return False
        param_dict = {}
        len_params = {}

        Rewriter_ = Rewriter(program, self.filename_mapping)
        for remove in removemethod:
            flag2 = False
            _methodd = removemethod[remove]
            len_params[remove] = len(_methodd[0].split(","))
            not_present = removemethod1
            if _methodd is not None:
                _methodds = _methodd[0]
                _method = program.packages[
                    self.package_name].classes[remove].methods[str(_methodds)]
                params = ""
                params2 = ""
                for param in _method.parameters:
                    flag = False
                    for x in not_present:
                        for y in x:
                            if param[1] in y:
                                flag = True
                                flag2 = True
                    if not flag:
                        params += param[1] + ","
                    params2 += param[0] + " " + param[1] + ","
                    flag = False
                param_dict[remove] = params2[:-1]
                _method_token_info = TokensInfo(_method.parser_context)
                if flag2:
                    str1 = ""
                    for x in not_present:
                        for y in x:
                            str1 += y + ";" + "\n\t"
                    Rewriter_.replace(
                        _method_token_info, "public " + remove + "(" +
                        params2[:-1] + ")" + "{\n\t" + "super(" + params[:-1] +
                        ");" + "\n\t " + str1 + "}")
                else:
                    Rewriter_.replace(
                        _method_token_info,
                        "public " + remove + "(" + params2[:-1] + ")" +
                        "{\n\t" + "super(" + params[:-1] + ");" + "\n\t}")

        class_tokens_info = TokensInfo(_targetclass.parser_context.classBody())
        class_tokens_info.stop = class_tokens_info.start
        key = min(len_params, key=len_params.get)
        _method_name1 = program.packages[
            self.package_name].classes[key].methods[removemethod[key][0]]
        tokens_info = TokensInfo(_method_name1.parser_context)
        singlefileelement = SingleFileElement(_method_name1.parser_context,
                                              _method_name1.filename)
        token_stream_rewriter = TokenStreamRewriter(
            singlefileelement.get_token_stream())
        strofmethod = token_stream_rewriter.getText(
            program_name=token_stream_rewriter.DEFAULT_PROGRAM_NAME,
            start=tokens_info.start,
            stop=tokens_info.stop)
        strofmethod = strofmethod.replace(_method_name1.class_name,
                                          target_class_name)

        Rewriter_.insert_after(tokens_info=class_tokens_info, text=strofmethod)
        Rewriter_.apply()

        return True
예제 #6
0
    def do_refactor(self):
        program = get_program(
            self.source_filenames)  # getting the program packages
        _sourceclass = program.packages[self.package_name].classes[
            self.class_name]
        target_class_name = _sourceclass.superclass_name
        static = 0
        removemethod = get_removemethods(
            program, self.package_name, target_class_name, self.method_key,
            self.class_name)  # Similar methods in other classes
        _targetclass = program.packages[
            self.package_name].classes[target_class_name]
        _method_name = program.packages[self.package_name].classes[
            self.class_name].methods[self.method_key]
        tokens_info = TokensInfo(_method_name.parser_context)
        exps = tokens_info.get_token_index(
            tokens_info.token_stream.tokens, tokens_info.start, tokens_info.
            stop)  # list of class variables that are used in the method
        if _method_name.is_constructor:
            return False
        # if method use param of class body return false
        for token in exps:
            if token.text in _sourceclass.fields:
                return False

        if bool(_method_name.body_method_invocations_without_typename):
            return False

        Rewriter_ = Rewriter(program, self.filename_mapping)
        for remove in removemethod:
            _methodd = removemethod[remove]
            if _methodd is not None:
                _methodds = _methodd[0]
                _method = program.packages[
                    self.package_name].classes[remove].methods[str(_methodds)]
                _method_token_info = TokensInfo(_method.parser_context)
                Rewriter_.replace(_method_token_info, " ")

        class_tokens_info = TokensInfo(_targetclass.parser_context)
        singlefileelement = SingleFileElement(_method_name.parser_context,
                                              _method_name.filename)
        token_stream_rewriter = TokenStreamRewriter(
            singlefileelement.get_token_stream())
        strofmethod = token_stream_rewriter.getText(
            program_name=token_stream_rewriter.DEFAULT_PROGRAM_NAME,
            start=tokens_info.start,
            stop=tokens_info.stop)
        Rewriter_.insert_before(tokens_info=class_tokens_info,
                                text=strofmethod)
        Rewriter_.apply()
        # The Method has to be updated anywhere else that it's used
        for package_names in program.packages:
            package = program.packages[package_names]
            for class_ in package.classes:
                _class = package.classes[class_]
                for method_ in _class.methods:
                    __method = _class.methods[method_]
                    for inv in __method.body_method_invocations:
                        invc = __method.body_method_invocations[inv]
                        method_name = self.method_key[:self.method_key.find('('
                                                                            )]
                        if invc[0] == method_name & package_names == self.package_name:
                            inv_tokens_info = TokensInfo(inv)
                            if static == 0:
                                class_token_info = TokensInfo(
                                    _class.body_context)
                                Rewriter_.insert_after_start(
                                    class_token_info, target_class_name + " " +
                                    str.lower(target_class_name) + "=" +
                                    "new " + target_class_name + "();")
                                Rewriter_.apply()
                            Rewriter_.replace(inv_tokens_info,
                                              target_class_name)
                            Rewriter_.apply()
        return True
예제 #7
0
    def do_refactor(self):
        program = utils2.get_program(self.source_filenames, print_status=True)
        if self.package_name not in program.packages \
                or any(
            class_name not in program.packages[self.package_name].classes
            for class_name in self.class_names
        ) \
                or any(
            method_key not in program.packages[self.package_name].classes[class_name].methods
            for class_name in self.class_names for method_key in self.method_keys
        ):
            return False

        method_returntypes = {}
        method_parameters = {}
        method_names = []
        for method_key in self.method_keys:
            method_names.append(method_key[:method_key.find('(')])

        rewriter = utils2.Rewriter(program, self.filename_mapping)

        for class_name in self.class_names:
            c: utils_listener_fast.Class = program.packages[
                self.package_name].classes[class_name]
            # Add implements to the class
            has_superinterface = False
            if c.parser_context.IMPLEMENTS(
            ) is not None:  # old: c.parser_context.superinterfaces()
                t = utils_listener_fast.TokensInfo(c.parser_context.typeList(
                ))  # old: c.parser_context.superinterfaces()
                has_superinterface = True
            elif c.parser_context.EXTENDS(
            ) is not None:  # old: c.parser_context.superclass()
                t = utils_listener_fast.TokensInfo(c.parser_context.typeType(
                ))  # old: c.parser_context.superclass()
            elif c.parser_context.typeParameters() is not None:
                t = utils_listener_fast.TokensInfo(
                    c.parser_context.typeParameters())
            else:
                # old: TokensInfo(c.parser_context.identifier())
                t = utils_listener_fast.TokensInfo(c.parser_context)
                t.stop = c.parser_context.IDENTIFIER().getSymbol().tokenIndex
            rewriter.insert_after(
                t, (", " if has_superinterface else " implements ") +
                self.interface_name)
            for method_key in self.method_keys:
                m: utils_listener_fast.Method = c.methods[method_key]
                # Check if the return types / parameter types are the same
                # Or add to dictionary
                if method_key in method_returntypes:
                    if method_returntypes[method_key] != m.returntype:
                        return False
                    if len(method_parameters[method_key]) != len(m.parameters):
                        return False
                    for i in range(len(m.parameters)):
                        if method_parameters[method_key][i][0] != m.parameters[
                                i][0]:
                            return False
                else:
                    method_returntypes[method_key] = m.returntype
                    method_parameters[method_key] = m.parameters
                # Manage method modifiers
                if len(m.modifiers_parser_contexts) > 0:
                    t = utils_listener_fast.TokensInfo(
                        m.modifiers_parser_contexts[0])
                else:
                    t = m.get_tokens_info()
                rewriter.insert_before_start(
                    t,  # old: m.get_tokens_info() # without requiring t
                    ("" if "@Override" in m.modifiers else "@Override\n    ") +
                    ("" if "public" in m.modifiers else "public "))
                for i in range(len(m.modifiers)):
                    mm = m.modifiers[i]
                    if mm == "private" or mm == "protected":
                        t = utils_listener_fast.TokensInfo(
                            m.modifiers_parser_contexts[i]
                        )  # old: m.parser_context.methodModifier(i)
                        rewriter.replace(t, "")

        # Change variable types to the interface if only interface methods are used.
        for package_name in program.packages:
            p: utils_listener_fast.Package = program.packages[package_name]
            for class_name in p.classes:
                c: utils_listener_fast.Class = p.classes[class_name]
                fields_of_interest = {}
                for fn in c.fields:
                    f: utils_listener_fast.Field = c.fields[fn]
                    d = False
                    for cn in self.class_names:
                        if (f.datatype == cn and f.file_info.has_imported_class(package_name, cn)) \
                                or (package_name is not None and f.datatype == package_name + '.' + cn):
                            d = True
                            break
                    if d and "private" in f.modifiers:
                        fields_of_interest[f.name] = f
                for method_key in c.methods:
                    m: utils_listener_fast.Method = c.methods[method_key]
                    vars_of_interest = {}
                    for item in m.body_local_vars_and_expr_names:
                        if isinstance(item, utils_listener_fast.LocalVariable):
                            for cn in self.class_names:
                                if (item.datatype == cn and c.file_info.has_imported_class(package_name, cn)) \
                                        or (package_name is not None and item.datatype == package_name + '.' + cn):
                                    vars_of_interest[item.identifier] = item
                                    break
                        if isinstance(item,
                                      utils_listener_fast.MethodInvocation):
                            if len(item.dot_separated_identifiers) == 2 or \
                                    (len(item.dot_separated_identifiers) == 3 and item.dot_separated_identifiers[
                                        0] == "this"):
                                if item.dot_separated_identifiers[
                                        -2] in vars_of_interest:
                                    if item.dot_separated_identifiers[
                                            -1] not in method_names:
                                        vars_of_interest.pop(
                                            item.dot_separated_identifiers[-2])
                                elif item.dot_separated_identifiers[-2] in fields_of_interest \
                                        and item.dot_separated_identifiers[-1] not in method_names:
                                    fields_of_interest.pop(
                                        item.dot_separated_identifiers[-2])
                    for var_name in vars_of_interest:
                        var = vars_of_interest[var_name]
                        if m.file_info.has_imported_package(package_name):
                            # old: var.parser_context.unannType()
                            rewriter.replace(
                                utils_listener_fast.TokensInfo(
                                    var.parser_context.typeType()),
                                self.interface_name)
                        else:
                            if package_name is None:
                                break
                            # old: var.parser_context.unannType()
                            rewriter.replace(
                                utils_listener_fast.TokensInfo(
                                    var.parser_context.typeType()),
                                package_name + '.' + self.interface_name)
                for field_name in fields_of_interest:
                    f = fields_of_interest[field_name]
                    if c.file_info.has_imported_package(package_name):
                        typename = self.interface_name
                    else:
                        if package_name is None:
                            break
                        typename = package_name + '.' + self.interface_name
                    if len(f.neighbor_names) == 0:
                        rewriter.replace(
                            utils_listener_fast.TokensInfo(
                                f.parser_context.typeType()),
                            typename)  # old: f.parser_context.unannType()
                    else:
                        if not any(nn in fields_of_interest
                                   for nn in f.neighbor_names):
                            t = utils_listener_fast.TokensInfo(
                                f.all_variable_declarator_contexts[
                                    f.index_in_variable_declarators])
                            if f.index_in_variable_declarators == 0:
                                t.stop = utils_listener_fast.TokensInfo(
                                    f.all_variable_declarator_contexts[
                                        f.index_in_variable_declarators +
                                        1]).start - 1
                            else:
                                t.start = utils_listener_fast.TokensInfo(
                                    f.all_variable_declarator_contexts[
                                        f.index_in_variable_declarators -
                                        1]).start + 1
                            rewriter.replace(t, "")
                            rewriter.insert_after(
                                f.get_tokens_info(),
                                "\n    private " + typename + " " + f.name +
                                (" = " + f.initializer +
                                 ";" if f.initializer is not None else ";"))

        # Create the interface
        interface_file_content = ("package " + package_name + ";\n\n" +
                                  "public interface " + self.interface_name +
                                  "\n" + "{\n")
        for method_key in self.method_keys:
            method_name = method_key[:method_key.find('(')]
            interface_file_content += "    " + method_returntypes[
                method_key] + " " + method_name + "("
            if len(method_parameters[method_key]) > 0:
                interface_file_content += method_parameters[method_key][0][
                    0] + " " + method_parameters[method_key][0][1]
            for i in range(1, len(method_parameters[method_key])):
                param = method_parameters[method_key][i]
                interface_file_content += ", " + param[0] + " " + param[1]
            interface_file_content += ");\n"
        interface_file_content += "}\n"

        if not os.path.exists(
                self.interface_filename[:self.interface_filename.rfind('/')]):
            os.makedirs(
                self.interface_filename[:self.interface_filename.rfind('/')])
        file = open(self.interface_filename, "w+")
        file.write(interface_file_content)
        file.close()

        rewriter.apply()
        return True
예제 #8
0
    def do_refactor(self):
        program = get_program(
            self.source_filenames,
            print_status=True)  # getting the program packages
        superclass: utils_listener_fast.Class = program.packages[
            self.package_name].classes[self.superclass_name]
        if not self.pre_propagation_check(program, superclass):
            return False

        other_derived_classes = []
        classes_to_add_to = []
        for p in program.packages:
            package: utils_listener_fast.Package = program.packages[p]
            for cn in package.classes:
                c: utils_listener_fast.Class = package.classes[cn]
                if ((c.superclass_name == self.superclass_name
                     and c.file_info.has_imported_class(
                         self.package_name, self.superclass_name)) or
                    (self.package_name is not None and c.superclass_name
                     == self.package_name + '.' + self.superclass_name)):

                    # enable functionality of class name
                    if len(self.class_names) == 0 or cn in self.class_names:
                        # check for methods with same name (post-condition 1)
                        if self.method_key in c.methods:
                            print("some classes have same method")
                            return False
                        else:
                            for m in c.methods:
                                method: utils_listener_fast.Method = c.methods[
                                    m]
                                is_used = False
                                for item in method.body_local_vars_and_expr_names:
                                    if isinstance(item, utils_listener_fast.MethodInvocation) and \
                                            item.dot_separated_identifiers[0] + '()' == self.method_key:
                                        is_used = True
                                if is_used:
                                    classes_to_add_to.append(c)
                    else:
                        other_derived_classes.append(c)

        rewriter = utils2.Rewriter(program, self.filename_mapping)

        method = superclass.methods[self.method_key]

        is_public = "public" in method.modifiers
        is_protected = "protected" in method.modifiers
        is_private = "private" in method.modifiers

        for c in classes_to_add_to:
            c_body_start = utils_listener_fast.TokensInfo(
                c.parser_context.classBody())
            c_body_start.stop = c_body_start.start
            rewriter.insert_after(
                c_body_start, "\n\n    %s %s %s() {\n       %s\n    }\n" %
                (" ".join(method.modifiers), method.returntype, method.name,
                 method.body_text[1:-1]))

        method_token_info = utils_listener_fast.TokensInfo(
            method.parser_context)
        rewriter.replace(method_token_info, "")

        rewriter.apply()
        return True