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