예제 #1
0
 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))
예제 #2
0
 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())
예제 #3
0
 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())
예제 #4
0
 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())
예제 #5
0
    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())
예제 #6
0
 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')
예제 #7
0
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
예제 #8
0
 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()
예제 #9
0
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