Skip to content

Make method non-static

Introduction

The module implements make method non-static refactoring operation

Pre and post-conditions

Pre-conditions:

Todo: Add pre-conditions

Post-conditions:

Todo: Add post-conditions

MakeMethodNonStaticRefactoringListener (JavaParserLabeledListener)

To implement Make Method None-Static refactoring based on its actors.

Source code in codart\refactorings\make_method_non_static.py
class MakeMethodNonStaticRefactoringListener(JavaParserLabeledListener):
    """

    To implement Make Method None-Static refactoring based on its actors.

    """

    def __init__(
            self, common_token_stream: CommonTokenStream = None,
            target_class: str = None, target_methods: list = None):
        """


        """

        if common_token_stream is None:
            raise ValueError('common_token_stream is None')
        else:
            self.token_stream_rewriter = TokenStreamRewriter(common_token_stream)

        if target_class is None:
            raise ValueError("source_class is None")
        else:
            self.target_class = target_class
        if target_methods is None or len(target_methods) == 0:
            raise ValueError("target method must have one method name")
        else:
            self.target_methods = target_methods

        self.target_class_data = None
        self.is_target_class = False
        self.detected_field = None
        self.detected_method = None
        self.TAB = "\t"
        self.NEW_LINE = "\n"
        self.code = ""

    def enterClassDeclaration(self, ctx: JavaParserLabeled.ClassDeclarationContext):
        class_identifier = ctx.IDENTIFIER().getText()
        if class_identifier == self.target_class:
            self.is_target_class = True
            self.target_class_data = {'constructors': []}
        else:
            self.is_target_class = False

    def exitClassDeclaration(self, ctx: JavaParserLabeled.ClassDeclarationContext):
        if self.is_target_class:
            have_default_constructor = False
            for constructor in self.target_class_data['constructor']:
                if len(constructor.parameters) == 0:
                    have_default_constructor = True
                    break
            if not have_default_constructor:
                self.token_stream_rewriter.insertBeforeIndex(
                    index=ctx.stop.tokenIndex - 1,
                    text=f'\n\t public {self.target_class_data["constructors"][0]} ()\n\t{{}}\n'
                )
            self.is_target_class = False

    def enterMethodDeclaration(self, ctx: JavaParserLabeled.MethodDeclarationContext):
        if self.is_target_class:
            if ctx.IDENTIFIER().getText() in self.target_methods:
                grand_parent_ctx = ctx.parentCtx.parentCtx
                if grand_parent_ctx.modifier():
                    if len(grand_parent_ctx.modifier()) == 2:
                        self.token_stream_rewriter.delete(
                            program_name=self.token_stream_rewriter.DEFAULT_PROGRAM_NAME,
                            from_idx=grand_parent_ctx.modifier(1).start.tokenIndex - 1,
                            to_idx=grand_parent_ctx.modifier(1).stop.tokenIndex
                        )
                    else:
                        if grand_parent_ctx.modifier(0).getText() == 'static':
                            self.token_stream_rewriter.delete(
                                program_name=self.token_stream_rewriter.DEFAULT_PROGRAM_NAME,
                                from_idx=grand_parent_ctx.modifier(0).start.tokenIndex - 1,
                                to_idx=grand_parent_ctx.modifier(0).stop.tokenIndex
                            )
                else:
                    return None

    def enterConstructorDeclaration(self, ctx: JavaParserLabeled.ConstructorDeclarationContext):
        if self.is_target_class:
            if ctx.formalParameters().formalParameterList():
                constructor_parameters = [ctx.formalParameters().formalParameterList().children[i] for i in
                                          range(len(ctx.formalParameters().formalParameterList().children)) if
                                          i % 2 == 0]
            else:
                constructor_parameters = []
            constructor_text = ''
            for modifier in ctx.parentCtx.parentCtx.modifier():
                constructor_text += modifier.getText() + ' '
                constructor_text += ctx.IDENTIFIER().getText()
            constructor_text += ' ( '
            for parameter in constructor_parameters:
                constructor_text += parameter.typeType().getText() + ' '
                constructor_text += parameter.variableDeclaratorId().getText() + ', '
            if constructor_parameters:
                constructor_text = constructor_text[:len(constructor_text) - 2]
            constructor_text += ')\n\t{'
            constructor_text += self.token_stream_rewriter.getText(
                program_name=self.token_stream_rewriter.DEFAULT_PROGRAM_NAME,
                start=ctx.block().start.tokenIndex + 1,
                stop=ctx.block().stop.tokenIndex - 1
            )
            constructor_text += '}\n'
            self.target_class_data['constructors'].append(ConstructorOrMethod(
                name=self.target_class,
                parameters=[
                    Parameter(parameterType=p.typeType().getText(),
                              name=p.variableDeclaratorId().IDENTIFIER().getText()) for p in constructor_parameters
                ],
                text=constructor_text))

__init__(self, common_token_stream=None, target_class=None, target_methods=None) special

Source code in codart\refactorings\make_method_non_static.py
def __init__(
        self, common_token_stream: CommonTokenStream = None,
        target_class: str = None, target_methods: list = None):
    """


    """

    if common_token_stream is None:
        raise ValueError('common_token_stream is None')
    else:
        self.token_stream_rewriter = TokenStreamRewriter(common_token_stream)

    if target_class is None:
        raise ValueError("source_class is None")
    else:
        self.target_class = target_class
    if target_methods is None or len(target_methods) == 0:
        raise ValueError("target method must have one method name")
    else:
        self.target_methods = target_methods

    self.target_class_data = None
    self.is_target_class = False
    self.detected_field = None
    self.detected_method = None
    self.TAB = "\t"
    self.NEW_LINE = "\n"
    self.code = ""

main(udb_path, target_class, target_methods)

Source code in codart\refactorings\make_method_non_static.py
def main(udb_path, target_class, target_methods):
    """


    """

    main_file = None
    db = understand.open(udb_path)
    classes = db.ents("Class")
    for cls in classes:
        if cls.simplename() == target_class:
            if cls.parent() is not None:
                temp_file = str(cls.parent().longname(True))
                if os.path.isfile(temp_file):
                    main_file = temp_file
                    break

    if main_file is None:
        db.close()
        return False

    db.close()
    stream = FileStream(main_file, encoding='utf8', errors='ignore')
    lexer = JavaLexer(stream)
    token_stream = CommonTokenStream(lexer)
    parser = JavaParserLabeled(token_stream)
    parser.getTokenStream()
    parse_tree = parser.compilationUnit()
    my_listener = MakeMethodNonStaticRefactoringListener(common_token_stream=token_stream, target_class=target_class,
                                                         target_methods=target_methods)
    walker = ParseTreeWalker()
    walker.walk(t=parse_tree, listener=my_listener)

    with open(main_file, mode='w', encoding='utf8', errors='ignore', newline='') as f:
        f.write(my_listener.token_stream_rewriter.getDefaultText())

    return True

Introduction

The module implements a light-weight version of make method non-static refactoring operation described in make_method_non_static.

Pre and post-conditions

Pre-conditions:

Todo: Add pre-conditions

Post-conditions:

Todo: Add post-conditions

MakeMethodNonStaticRefactoringListener (JavaParserLabeledListener)

To implement Make Method Non-Static refactoring based on its actors (version 2).

Source code in codart\refactorings\make_method_non_static2.py
class MakeMethodNonStaticRefactoringListener(JavaParserLabeledListener):
    """

    To implement Make Method Non-Static refactoring based on its actors (version 2).

    """

    def __init__(self, common_token_stream: CommonTokenStream = None, source_class=None, method_name: str = None):
        """


        """

        if method_name is None:
            self.method_name = ""
        else:
            self.method_name = method_name

        if source_class is None:
            self.source_class = ""
        else:
            self.source_class = source_class
        if common_token_stream is None:
            raise ValueError('common_token_stream is None')
        else:
            self.token_stream_rewriter = TokenStreamRewriter(common_token_stream)

        self.is_source_class = False
        self.is_static = False

    def enterClassDeclaration(self, ctx: JavaParserLabeled.ClassDeclarationContext):

        class_identifier = ctx.IDENTIFIER().getText()
        if class_identifier == self.source_class:
            self.is_source_class = True
        else:
            self.is_source_class = False

    def exitMethodDeclaration(self, ctx: JavaParserLabeled.MethodDeclarationContext):
        if not self.is_source_class:
            return
        grand_parent_ctx = ctx.parentCtx.parentCtx
        method_identifier = ctx.IDENTIFIER().getText()
        if self.method_name in method_identifier:
            if not hasattr(grand_parent_ctx, "modifier"):
                return
            if not (grand_parent_ctx.modifier() == []):
                i = 0
                for i in range(0, len(grand_parent_ctx.modifier())):
                    if grand_parent_ctx.modifier(i).getText() == "static":
                        self.is_static = True
                        break
                if self.is_static:
                    self.token_stream_rewriter.replaceRange(
                        from_idx=grand_parent_ctx.modifier(i).start.tokenIndex,
                        to_idx=grand_parent_ctx.modifier(i).stop.tokenIndex,
                        text=''
                    )

__init__(self, common_token_stream=None, source_class=None, method_name=None) special

Source code in codart\refactorings\make_method_non_static2.py
def __init__(self, common_token_stream: CommonTokenStream = None, source_class=None, method_name: str = None):
    """


    """

    if method_name is None:
        self.method_name = ""
    else:
        self.method_name = method_name

    if source_class is None:
        self.source_class = ""
    else:
        self.source_class = source_class
    if common_token_stream is None:
        raise ValueError('common_token_stream is None')
    else:
        self.token_stream_rewriter = TokenStreamRewriter(common_token_stream)

    self.is_source_class = False
    self.is_static = False

main(udb_path=None, source_class=None, method_name=None, *args, **kwargs)

Source code in codart\refactorings\make_method_non_static2.py
def main(udb_path=None, source_class=None, method_name=None, *args, **kwargs):
    """

    """

    main_file = None
    db = und.open(udb_path)
    classes = db.ents("Class")
    for cls in classes:
        if cls.parent() is not None:
            if cls.simplename() == source_class:
                temp_file = str(cls.parent().longname(True))
                if os.path.isfile(temp_file):
                    main_file = temp_file
                    break

    if main_file is None:
        db.close()
        return False

    db.close()

    stream = FileStream(main_file, encoding='utf8', errors='ignore')
    lexer = JavaLexer(stream)
    token_stream = CommonTokenStream(lexer)
    parser = JavaParserLabeled(token_stream)
    parser.getTokenStream()
    parse_tree = parser.compilationUnit()
    my_listener = MakeMethodNonStaticRefactoringListener(
        common_token_stream=token_stream,
        source_class=source_class,
        method_name=method_name
    )
    walker = ParseTreeWalker()
    walker.walk(t=parse_tree, listener=my_listener)

    with open(main_file, mode='w', encoding='utf8', errors='ignore', newline='') as f:
        f.write(my_listener.token_stream_rewriter.getDefaultText())

    return True