Skip to content

Make field final

Introduction

Add the "final" property / keyword to a field, so that it never changes once it is initialized.

Pre and post-conditions

Pre-conditions:

  1. User must enter the field's name and the name of the source class in order to make it final

  2. Check if the field exists, then make it final

Post-conditions:

  1. The value of this field should never be changed in the project

MakeFieldFinalRefactoringListener (JavaParserLabeledListener)

The Main listener which parses the file based on the provided information using ANTLR parser generator and tokenization methods.

Detects the desired field and changes its status to final.

Source code in codart\refactorings\make_field_final.py
class MakeFieldFinalRefactoringListener(JavaParserLabeledListener):
    """
    The Main listener which parses the file based on the provided information
    using ANTLR parser generator and tokenization methods.

    Detects the desired field and changes its status to final.

    """

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

        Args:

            common_token_stream (CommonTokenStream): A stream of tokens generated by parsing the main file using \
            the ANTLR parser generator.

            source_class (str): Name of the class in which the refactoring has to be done.

            field_name (str): Name of the field whose final status has to be changed.

        Returns:

            object (MakeFieldFinalRefactoringListener): An instance of MakeFieldFinalRefactoringListener.

        """

        if field_name is None:
            self.field_name = ""
        else:
            self.field_name = field_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_final = 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 exitFieldDeclaration(self, ctx: JavaParserLabeled.FieldDeclarationContext):
        if not self.is_source_class:
            return None
        grand_parent_ctx = ctx.parentCtx.parentCtx
        # field_identifier = ctx.variableDeclarators().getText().split(",")
        field_identifier = ctx.variableDeclarators().variableDeclarator(0).variableDeclaratorId().IDENTIFIER().getText()
        if self.field_name in field_identifier:
            if not grand_parent_ctx.modifier():
                self.token_stream_rewriter.replaceRange(
                    from_idx=ctx.typeType().start.tokenIndex,
                    to_idx=ctx.typeType().stop.tokenIndex,
                    text='final ' + ctx.typeType().getText()
                )
            else:
                for i in range(0, len(grand_parent_ctx.modifier())):
                    if grand_parent_ctx.modifier(i).getText() == "final":
                        self.is_final = True
                        break
                if not self.is_final:
                    self.token_stream_rewriter.replaceRange(
                        from_idx=grand_parent_ctx.modifier(0).start.tokenIndex,
                        to_idx=grand_parent_ctx.modifier(0).stop.tokenIndex,
                        text=grand_parent_ctx.modifier(0).getText() + ' final'
                    )

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

Parameters:

Name Type Description Default
common_token_stream CommonTokenStream

A stream of tokens generated by parsing the main file using the ANTLR parser generator.

None
source_class str

Name of the class in which the refactoring has to be done.

None
field_name str

Name of the field whose final status has to be changed.

None

Returns:

Type Description
object (MakeFieldFinalRefactoringListener)

An instance of MakeFieldFinalRefactoringListener.

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

    Args:

        common_token_stream (CommonTokenStream): A stream of tokens generated by parsing the main file using \
        the ANTLR parser generator.

        source_class (str): Name of the class in which the refactoring has to be done.

        field_name (str): Name of the field whose final status has to be changed.

    Returns:

        object (MakeFieldFinalRefactoringListener): An instance of MakeFieldFinalRefactoringListener.

    """

    if field_name is None:
        self.field_name = ""
    else:
        self.field_name = field_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_final = False