Beispiel #1
0
 def _get_lambda_try_nodes(self, ast: AST,
                           lambda_node: ASTNode) -> List[int]:
     assert lambda_node.node_type == ASTNodeType.LAMBDA_EXPRESSION
     return [
         try_node.line for try_node in ast.get_subtree(
             lambda_node).get_proxy_nodes(ASTNodeType.TRY_STATEMENT)
     ]
Beispiel #2
0
    def _calculate_class_RFC(self, java_class: AST) -> int:
        class_declaration = java_class.get_root()
        assert class_declaration.node_type == ASTNodeType.CLASS_DECLARATION

        rfc = 0
        invoked_methods: Set[_MethodInvocationParams] = set()
        local_methods_names: Set[str] = set()
        for class_item in class_declaration.body:
            if class_item.node_type == ASTNodeType.METHOD_DECLARATION:
                local_methods_names.add(class_item.name)
                if "public" in class_item.modifiers:
                    rfc += 1
                    invoked_methods |= self._get_all_method_invocation_params(
                        java_class.get_subtree(class_item)
                    )

        # filter out inherited methods
        # consider local methods with name not found
        # among methods names of current class as inherited
        invoked_methods = {
            invoked_method
            for invoked_method in invoked_methods
            if not invoked_method.isLocal or invoked_method.name in local_methods_names
        }

        rfc += len(invoked_methods)
        return rfc
Beispiel #3
0
    def value(self, ast: AST) -> int:
        rfc = 0
        for class_declaration in ast.get_proxy_nodes(
                ASTNodeType.CLASS_DECLARATION):
            rfc += self._calculate_class_RFC(
                ast.get_subtree(class_declaration))

        return rfc
Beispiel #4
0
def _filter_class_methods_and_fields(class_ast: AST,
                                     allowed_fields_names: Set[str],
                                     allowed_methods_names: Set[str]) -> AST:
    class_declaration = class_ast.get_root()
    allowed_nodes = {class_declaration.node_index}

    for field_declaration in class_declaration.fields:
        if len(allowed_fields_names & set(field_declaration.names)) != 0:
            field_ast = class_ast.get_subtree(field_declaration)
            allowed_nodes.update(node.node_index for node in field_ast)

    for method_declaration in class_declaration.methods:
        if method_declaration.name in allowed_methods_names:
            method_ast = class_ast.get_subtree(method_declaration)
            allowed_nodes.update(node.node_index for node in method_ast)

    return AST(class_ast.tree.subgraph(allowed_nodes),
               class_declaration.node_index)
Beispiel #5
0
 def _check_this_statements(self, ast: AST, node: ASTNode) -> bool:
     for child_this in ast.get_subtree(node).get_proxy_nodes(
             ASTNodeType.THIS):
         child_membref = child_this.selectors
         if len(child_membref):
             mem_referenced_name = child_membref[0].member
             if node.name.lower() == 'set' + mem_referenced_name.lower():
                 return True
     return False
Beispiel #6
0
 def _process_catch(self, ast: AST, catch_clauses: List[ASTNode]):
     lines: List[int] = []
     for catch_clause in catch_clauses:
         throw_statements = ast.get_subtree(catch_clause).get_proxy_nodes(
             ASTNodeType.THROW_STATEMENT)
         for throw_stat in throw_statements:
             if throw_stat.expression.node_type == ASTNodeType.MEMBER_REFERENCE \
                and throw_stat.expression.member == catch_clause.parameter.name:
                 lines.append(throw_stat.line)
     return lines
 def __check_primary(self, ast: AST, node: Union[ASTNode,
                                                 List[ASTNode]]) -> bool:
     if isinstance(
             node, ASTNode
     ) and node.node_type == ASTNodeType.CONSTRUCTOR_DECLARATION:
         for assignment in ast.get_subtree(node).get_proxy_nodes(
                 ASTNodeType.ASSIGNMENT):
             if assignment.expressionl.node_type == ASTNodeType.THIS:
                 return True
     return False
Beispiel #8
0
 def value(self, ast: AST) -> List[int]:
     lines: List[int] = list()
     for method_declaration in ast.get_proxy_nodes(
             ASTNodeType.METHOD_DECLARATION):
         for bin_operation in ast.get_subtree(
                 method_declaration).get_proxy_nodes(
                     ASTNodeType.BINARY_OPERATION):
             if self._check_null(bin_operation):
                 lines.append(bin_operation.operandr.line)
     return lines
 def value(self, ast: AST) -> List[int]:
     total_code_lines: List[int] = []
     for method_declaration in ast.get_proxy_nodes(
             ASTNodeType.METHOD_DECLARATION):
         try_nodes = list(
             ast.get_subtree(method_declaration).get_proxy_nodes(
                 ASTNodeType.TRY_STATEMENT))
         if len(try_nodes) > 1:
             total_code_lines.append(method_declaration.line)
     return total_code_lines
Beispiel #10
0
def _extract_synchronized_block_semantic(
        statement: ASTNode,
        method_ast: AST) -> Dict[ASTNode, StatementSemantic]:
    lock_subtree = method_ast.get_subtree(statement.lock)
    statements_semantic: Dict[ASTNode, StatementSemantic] = OrderedDict([
        (statement, _extract_semantic_from_ast(lock_subtree))
    ])

    for inner_statement in statement.block:
        statements_semantic.update(
            _extract_statement_semantic(inner_statement, method_ast))
    return statements_semantic
Beispiel #11
0
def _extract_for_cycle_semantic(
        statement: ASTNode,
        method_ast: AST) -> Dict[ASTNode, StatementSemantic]:
    control_subtree = method_ast.get_subtree(statement.control)
    statements_semantic: Dict[ASTNode, StatementSemantic] = OrderedDict([
        (statement, _extract_semantic_from_ast(control_subtree))
    ])

    statements_semantic.update(
        _extract_statement_semantic(statement.body, method_ast))

    return statements_semantic
Beispiel #12
0
    def value(self, ast: AST) -> List[int]:
        lines: List[int] = []
        excluded_nodes: List[int] = []

        for method_declaration in ast.get_proxy_nodes(
                ASTNodeType.METHOD_DECLARATION,
                ASTNodeType.CONSTRUCTOR_DECLARATION):
            method_throw_names = method_declaration.throws
            for try_node in ast.get_subtree(
                    method_declaration).get_proxy_nodes(
                        ASTNodeType.TRY_STATEMENT):
                if method_throw_names is not None and \
                        try_node.catches is not None and \
                        self._is_redundant(method_throw_names, try_node):
                    lines.append(try_node.line)

            for lambda_node in ast.get_subtree(
                    method_declaration).get_proxy_nodes(
                        ASTNodeType.LAMBDA_EXPRESSION):
                excluded_nodes.extend(
                    self._get_lambda_try_nodes(ast, lambda_node))
        return sorted(list(set(lines).difference(set(excluded_nodes))))
Beispiel #13
0
def _extract_switch_branching_semantic(
        statement: ASTNode,
        method_ast: AST) -> Dict[ASTNode, StatementSemantic]:
    expression_subtree = method_ast.get_subtree(statement.expression)
    statements_semantic: Dict[ASTNode, StatementSemantic] = OrderedDict([
        (statement, _extract_semantic_from_ast(expression_subtree))
    ])

    for case in statement.cases:
        for inner_statement in case.statements:
            statements_semantic.update(
                _extract_statement_semantic(inner_statement, method_ast))

    return statements_semantic
Beispiel #14
0
def _extract_if_branching_sematic(
        statement: ASTNode,
        method_ast: AST) -> Dict[ASTNode, StatementSemantic]:
    condition_subtree = method_ast.get_subtree(statement.condition)
    statements_semantic: Dict[ASTNode, StatementSemantic] = OrderedDict([
        (statement, _extract_semantic_from_ast(condition_subtree))
    ])

    statements_semantic.update(
        _extract_statement_semantic(statement.then_statement, method_ast))

    if statement.else_statement is not None:
        statements_semantic.update(
            _extract_statement_semantic(statement.else_statement, method_ast))

    return statements_semantic
Beispiel #15
0
def find_patterns(tree: AST, patterns: List[Any]) -> Set[str]:
    """
    Searches all setters in a component
    :param patterns: list of patterns to check
    :param tree: ast tree
    :return: list of method name which are setters
    """

    patterns_method_names: Set[str] = set()
    for method_declaration in tree.get_root().methods:
        method_ast = tree.get_subtree(method_declaration)
        for pattern in patterns:
            if is_ast_pattern(method_ast, pattern):
                patterns_method_names.add(method_declaration.name)

    return patterns_method_names
Beispiel #16
0
def _create_usage_graph(class_ast: AST) -> DiGraph:
    usage_graph = DiGraph()
    fields_ids: Dict[str, int] = {}
    methods_ids: Dict[str, int] = {}

    class_declaration = class_ast.get_root()

    for field_declaration in class_declaration.fields:
        # several fields can be declared at one line
        for field_name in field_declaration.names:
            fields_ids[field_name] = len(fields_ids)
            usage_graph.add_node(fields_ids[field_name],
                                 type="field",
                                 name=field_name)

    for method_declaration in class_declaration.methods:
        method_name = method_declaration.name

        # overloaded methods considered as single node in usage_graph
        if method_name not in methods_ids:
            methods_ids[method_name] = len(fields_ids) + 1 + len(methods_ids)
            usage_graph.add_node(methods_ids[method_name],
                                 type="method",
                                 name=method_name)

    for method_declaration in class_declaration.methods:
        method_ast = class_ast.get_subtree(method_declaration)

        for invoked_method_name in _find_local_method_invocations(method_ast):
            if invoked_method_name in methods_ids:
                usage_graph.add_edge(
                    methods_ids[method_declaration.name],
                    methods_ids[invoked_method_name],
                )

        for used_field_name in _find_fields_usage(method_ast):
            if used_field_name in fields_ids:
                usage_graph.add_edge(methods_ids[method_declaration.name],
                                     fields_ids[used_field_name])

    return usage_graph
Beispiel #17
0
def _extract_try_block_semantic(
        statement: ASTNode,
        method_ast: AST) -> Dict[ASTNode, StatementSemantic]:
    statements_semantic: Dict[ASTNode, StatementSemantic] = OrderedDict()

    for resource in statement.resources or []:
        resource_ast = method_ast.get_subtree(resource)
        statements_semantic[resource] = _extract_semantic_from_ast(
            resource_ast)

    for node in statement.block:
        statements_semantic.update(
            _extract_statement_semantic(node, method_ast))

    for catch_clause in statement.catches or []:
        for inner_statement in catch_clause.block:
            statements_semantic.update(
                _extract_statement_semantic(inner_statement, method_ast))

    for node in statement.finally_block or []:
        statements_semantic.update(
            _extract_statement_semantic(node, method_ast))

    return statements_semantic
Beispiel #18
0
def _extract_plain_statement_semantic(
        statement: ASTNode,
        method_ast: AST) -> Dict[ASTNode, StatementSemantic]:
    statement_ast = method_ast.get_subtree(statement)
    return OrderedDict([(statement, _extract_semantic_from_ast(statement_ast))
                        ])