def test_start_end_inline_without_args(self): algorithm_type = InlineTypesAlgorithms.WITHOUT_RETURN_WITHOUT_ARGUMENTS algorithm_for_inlining = AlgorithmFactory().create_obj(algorithm_type) pred_inline_rel_bounds = algorithm_for_inlining().inline_function( self.filepath, 30, 21, 27, self.temp_filename) self.assertEqual( [30, 34], pred_inline_rel_bounds, msg='Wrong inline bounds: {}'.format(pred_inline_rel_bounds))
def test_inline_strange_body2(self): filepath = self.current_directory / 'InlineExamples' / 'cut.java' test_filepath = self.current_directory / 'InlineTestExamples' / 'cut.java' algorithm_type = InlineTypesAlgorithms.WITHOUT_RETURN_WITHOUT_ARGUMENTS algorithm_for_inlining = AlgorithmFactory().create_obj(algorithm_type) body_start_line, body_end_line = self._get_lines(filepath, 'copy') algorithm_for_inlining().inline_function(filepath, 8, body_start_line, body_end_line, self.temp_filename) with open(self.temp_filename, encoding='utf-8') as actual_file, \ open(test_filepath, encoding='utf-8') as test_ex: self.assertEqual(actual_file.read(), test_ex.read())
def test_inline_comments_at_the_end(self): filepath = self.current_directory / 'InlineExamples' / 'ObjectProperties_cut.java' test_filepath = self.current_directory / 'InlineTestExamples' / 'ObjectProperties_cut.java' algorithm_type = InlineTypesAlgorithms.WITHOUT_RETURN_WITHOUT_ARGUMENTS algorithm_for_inlining = AlgorithmFactory().create_obj(algorithm_type) body_start_line, body_end_line = self._get_lines( filepath, 'updateSashWidths') algorithm_for_inlining().inline_function(filepath, 43, body_start_line, body_end_line, self.temp_filename) with open(self.temp_filename, encoding='utf-8') as actual_file, \ open(test_filepath, encoding='utf-8') as test_ex: self.assertEqual(actual_file.read(), test_ex.read())
def test_inline_invocation_inside_var_declaration(self): filepath = self.current_directory / 'InlineExamples' / 'EntityResolver_cut.java' test_filepath = self.current_directory / 'InlineTestExamples' / 'EntityResolver_cut.java' algorithm_type = InlineTypesAlgorithms.WITH_RETURN_WITHOUT_ARGUMENTS algorithm_for_inlining = AlgorithmFactory().create_obj(algorithm_type) body_start_line, body_end_line = self._get_lines( filepath, 'createDocumentBuilderFactory') self.assertEqual(body_start_line == 33, body_end_line == 40) algorithm_for_inlining().inline_function(filepath, 22, body_start_line, body_end_line, self.temp_filename) with open(self.temp_filename, encoding='utf-8') as actual_file, \ open(test_filepath, encoding='utf-8') as test_ex: self.assertEqual(actual_file.read(), test_ex.read())
def test_inline_inside_invokation_several_lines(self): filepath = self.current_directory / 'InlineExamples' / 'AbstractMarshaller_cut.java' test_filepath = self.current_directory / 'InlineTestExamples' / 'AbstractMarshaller_cut.java' algorithm_type = InlineTypesAlgorithms.WITH_RETURN_WITHOUT_ARGUMENTS algorithm_for_inlining = AlgorithmFactory().create_obj(algorithm_type) body_start_line, body_end_line = self._get_lines( filepath, 'fireChildRemoved') self.assertEqual(body_start_line == 17, body_end_line == 20) algorithm_for_inlining().inline_function(filepath, 14, body_start_line, body_end_line, self.temp_filename) with open(self.temp_filename, encoding='utf-8') as actual_file, \ open(test_filepath, encoding='utf-8') as test_ex: self.assertEqual(actual_file.read(), test_ex.read())
def test_inline_with_return_with_assigning(self): filepath = self.current_directory / 'InlineExamples' / 'Parameters.java' test_filepath = self.current_directory / 'InlineTestExamples/Parameters_without_return_without_assigning.java' algorithm_type = InlineTypesAlgorithms.WITH_RETURN_WITHOUT_ARGUMENTS algorithm_for_inlining = AlgorithmFactory().create_obj(algorithm_type) body_start_line, body_end_line = self._get_lines( filepath, 'cboComponent') self.assertEqual(body_start_line == 40, body_end_line == 45) algorithm_for_inlining().inline_function(filepath, 113, body_start_line, body_end_line, self.temp_filename) with open(self.temp_filename, encoding='utf-8') as actual_file, \ open(test_filepath, encoding='utf-8') as test_ex: self.assertMultiLineEqual(actual_file.read(), test_ex.read(), 'File are not matched')
def insert_code_with_new_file_creation( class_name: str, ast: AST, method_node: ASTNode, invocation_node: ASTNode, file_path: Path, output_path: Path, dict_original_invocations: Dict[str, List[ASTNode]]) -> List[Any]: """ If invocations of class methods were found, we process through all of them and for each substitution opportunity by method's body, we create new file. """ file_name = file_path.stem if not os.path.exists(output_path): output_path.mkdir(parents=True) new_full_filename = Path( output_path, f'{file_name}_{method_node.name}_{invocation_node.line}.java') original_func = dict_original_invocations.get( invocation_node.member)[0] # type: ignore body_start_line, body_end_line = method_body_lines(original_func, file_path) text_lines = read_text_with_autodetected_encoding( str(file_path)).split('\n') line_to_csv = [] if body_start_line != body_end_line: algorithm_type = determine_algorithm_insertion_type( ast, method_node, invocation_node, dict_original_invocations) algorithm_for_inlining = AlgorithmFactory().create_obj(algorithm_type) if algorithm_type != InlineTypesAlgorithms.DO_NOTHING: line_to_csv = [ file_path, class_name, text_lines[invocation_node.line - 1].lstrip(), invocation_node.line, original_func.line, method_node.name, new_full_filename, body_start_line, body_end_line ] algorithm_for_inlining().inline_function( file_path, invocation_node.line, body_start_line, body_end_line, new_full_filename, ) return line_to_csv
def test_inline_strange_body2(self): filepath = self.current_directory / 'InlineExamples' / 'cut.java' test_filepath = self.current_directory / 'InlineTestExamples' / 'cut.java' temp_filename = self.current_directory / 'temp1.java' algorithm_type = InlineTypesAlgorithms.WITHOUT_RETURN_WITHOUT_ARGUMENTS algorithm_for_inlining = AlgorithmFactory().create_obj(algorithm_type) ast = AST.build_from_javalang(build_ast(filepath)) m_decl = [ x for x in ast.get_proxy_nodes(ASTNodeType.METHOD_DECLARATION) if x.name == 'copy' ][0] body_start_line, body_end_line = method_body_lines(m_decl, filepath) algorithm_for_inlining().inline_function(filepath, 8, body_start_line, body_end_line, temp_filename) with open(temp_filename, encoding='utf-8') as actual_file, \ open(test_filepath, encoding='utf-8') as test_ex: self.assertEqual(actual_file.read(), test_ex.read()) temp_filename.unlink()
def insert_code_with_new_file_creation( class_name: str, ast: AST, method_node: ASTNode, invocation_node: ASTNode, file_path: Path, output_path: Path, dict_original_invocations: Dict[str, List[ASTNode]]) -> Dict[str, Any]: """ If invocations of class methods were found, we process through all of them and for each substitution opportunity by method's body, we create new file. """ file_name = file_path.stem if not os.path.exists(output_path): output_path.mkdir(parents=True) new_full_filename = Path( output_path, f'{file_name}_{method_node.name}_{invocation_node.line}.java') original_func = dict_original_invocations.get( invocation_node.member)[0] # type: ignore ncss = NCSSMetric().value(ast.get_subtree(original_func)) line_to_csv = {} # @acheshkov asked to consider only methods with ncss > 3, that's all. if ncss > 3: body_start_line, body_end_line = method_body_lines( original_func, file_path) text_lines = read_text_with_autodetected_encoding( str(file_path)).split('\n') # we do not inline one-line methods like # public String getRemainingString() {return str.substring(index);} if body_start_line != body_end_line: algorithm_type = determine_algorithm_insertion_type( ast, method_node, invocation_node, dict_original_invocations) algorithm_for_inlining = AlgorithmFactory().create_obj( algorithm_type) if algorithm_type != InlineTypesAlgorithms.DO_NOTHING: line_to_csv = { 'input_filename': file_path, 'class_name': class_name, 'invocation_text_string': text_lines[invocation_node.line - 1].lstrip(), 'method_where_invocation_occurred': method_node.name, 'invocation_method_name': original_func.name, 'output_filename': new_full_filename } inline_method_bounds = algorithm_for_inlining( ).inline_function( file_path, invocation_node.line, body_start_line, body_end_line, new_full_filename, ) if inline_method_bounds is not None: line_to_csv[ 'inline_insertion_line_start'] = inline_method_bounds[ 0] line_to_csv[ 'inline_insertion_line_end'] = inline_method_bounds[1] if get_ast_if_possible(new_full_filename): rest_of_csv_row_for_changed_file = find_lines_in_changed_file( class_name=class_name, method_node=method_node, new_full_filename=new_full_filename, original_func=original_func) can_be_parsed = True line_to_csv.update(rest_of_csv_row_for_changed_file) else: can_be_parsed = False line_to_csv['can_be_parsed'] = can_be_parsed return line_to_csv