Search in sources :

Example 1 with BlockGraph

use of com.android.tools.idea.experimental.codeanalysis.datastructs.graph.BlockGraph in project android by JetBrains.

the class CFGBuilder method dfsPsiForeachStatementBuilder.

/**
   * Build nodes for "for each" loops
   * @param statement The foreach statement
   * @param label The label for this loop. In case of labeled break.
   */
public void dfsPsiForeachStatementBuilder(@NotNull PsiForeachStatement statement, @Nullable PsiIdentifier label) {
    PsiStatement loopBody = statement.getBody();
    int loopType;
    LoopBranchingNodeImpl loopNode;
    GraphNode conditionCheckEntry;
    ConditionCheckNode conditionCheckExit;
    GraphNode postLoopEntry;
    GraphNode postLoopExit;
    loopType = LoopBranchingNode.FOREACH_LOOP;
    //for (Type iter : val);
    //The iter is the iterParam here
    //The val is the iterValue here.
    PsiParameter iterParam = statement.getIterationParameter();
    PsiExpression iterValue = statement.getIteratedValue();
    if (iterParam == null) {
        //TODO: Log it and return
        return;
    }
    if (iterParam == null) {
        //TODO: Log it and return
        return;
    }
    Value iterV = dfsExpressionBuilder(iterValue);
    Param iterP = new ParamImpl(iterParam);
    loopNode = new LoopBranchingNodeImpl(this.mGraph, loopType);
    connectCurrentWorkingNode(loopNode);
    pushLoopNode(loopNode, label);
    BlockGraph loopBodyGraph = loopbodyBuilder(loopBody, statement, iterParam, iterP);
    loopNode.setLoopBody(loopBodyGraph);
    loopNode.setForeachIteratorParam(iterP);
    loopNode.setForeachIteratorValue(iterV);
    GraphNodeUtil.connectGraphNode(loopNode, loopBodyGraph.getEntryNode());
    GraphNodeUtil.connectGraphNode(loopNode, loopBodyGraph.getExitNode());
    GraphNodeUtil.connectGraphNode(loopBodyGraph.getExitNode(), loopNode);
    loopNode.connectSpecialNodes();
    curWorkingNodeList.clear();
    curWorkingNodeList.add(loopBodyGraph.getExitNode());
    popLoopNode();
}
Also used : BlockGraph(com.android.tools.idea.experimental.codeanalysis.datastructs.graph.BlockGraph)

Example 2 with BlockGraph

use of com.android.tools.idea.experimental.codeanalysis.datastructs.graph.BlockGraph in project android by JetBrains.

the class CFGBuilder method resolveParam.

/**
   * Resolve the parameter at the current context.
   * @param param The parameter
   * @return The PsiCFG wrapper for the parameter
   */
@Nullable
private Param resolveParam(@NotNull PsiParameter param) {
    Graph graph = this.mGraph;
    if (graph instanceof BlockGraph) {
        Param p = ((BlockGraph) graph).getParamFromPsiParameter(param);
        if (p == null) {
            if (graph instanceof MethodGraph) {
                MethodGraph methodGraph = (MethodGraph) graph;
                PsiCFGDebugUtil.LOG.warning("Parameter " + param.getName() + " does not exist in method " + methodGraph.getPsiCFGMethod().getName() + " in class " + this.containerClass.getQualifiedClassName());
            } else {
                PsiStatement psiStmt = ((BlockGraph) graph).getParentStmt();
                PsiCFGDebugUtil.LOG.warning("Parameter " + param.getName() + " does not exist in context " + psiStmt.getText() + " in class " + this.containerClass.getQualifiedClassName());
            }
        }
        return p;
    }
    PsiCFGDebugUtil.LOG.warning("Parameter " + param.getName() + " does not exist, the graph is not" + " a block graph");
    return null;
}
Also used : SwitchCaseGraph(com.android.tools.idea.experimental.codeanalysis.datastructs.graph.SwitchCaseGraph) MethodGraph(com.android.tools.idea.experimental.codeanalysis.datastructs.graph.MethodGraph) BlockGraph(com.android.tools.idea.experimental.codeanalysis.datastructs.graph.BlockGraph) Graph(com.android.tools.idea.experimental.codeanalysis.datastructs.graph.Graph) MethodGraph(com.android.tools.idea.experimental.codeanalysis.datastructs.graph.MethodGraph) BlockGraph(com.android.tools.idea.experimental.codeanalysis.datastructs.graph.BlockGraph) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with BlockGraph

use of com.android.tools.idea.experimental.codeanalysis.datastructs.graph.BlockGraph in project android by JetBrains.

the class CFGBuilder method dfsDeclarationStatementBuilder.

/**
   * Declaration Statement will not return a value, therefore always return null;
   *
   * @param resultArray
   * @param currentDeclStmt
   * @return
   */
public Value dfsDeclarationStatementBuilder(PsiDeclarationStatement currentDeclStmt) {
    PsiElement[] retElements = currentDeclStmt.getDeclaredElements();
    for (PsiElement curElement : retElements) {
        if (curElement == null) {
            PsiCFGDebugUtil.LOG.warning("element in DeclarationStatement " + currentDeclStmt.getText() + " is null");
            continue;
        }
        if (curElement instanceof PsiLocalVariable) {
            //So it is a local variable
            PsiLocalVariable curLocal = (PsiLocalVariable) curElement;
            PsiType localType = curLocal.getType();
            //Generate the decl statement
            DeclarationStmtImpl newDecl = new DeclarationStmtImpl(localType, curLocal, currentDeclStmt);
            connectGeneratedStmt(newDecl);
            if (this.mGraph instanceof BlockGraph) {
                ((BlockGraph) (this.mGraph)).addLocal(curLocal, (LocalImpl) newDecl.getLocal());
            }
            if (curLocal.hasInitializer()) {
                //Generate Statement for the initializer
                PsiExpression initializer = curLocal.getInitializer();
                Value initExpr = dfsExpressionBuilder(initializer);
                AssignStmtImpl initializerStmt = new AssignStmtImpl(true, null, JavaTokenType.EQ);
                LocalImpl localExpr = (LocalImpl) newDecl.getLocal();
                initializerStmt.setROp(initExpr);
                initializerStmt.setLOp(localExpr);
                connectGeneratedStmt(initializerStmt);
            }
        } else if (curElement instanceof PsiClass) {
            //It declares a nested class
            mScene.getOrCreateNestedClass((PsiClass) curElement, this.containerClass, retrieveDeclaringMethod(), this.mGraph);
        } else {
            PsiCFGDebugUtil.LOG.warning("element " + curElement.getText() + " in DeclarationStmt " + currentDeclStmt.getText() + " cannot be resolved");
        }
    }
    return null;
}
Also used : AssignStmtImpl(com.android.tools.idea.experimental.codeanalysis.datastructs.stmt.impl.AssignStmtImpl) BlockGraph(com.android.tools.idea.experimental.codeanalysis.datastructs.graph.BlockGraph) DeclarationStmtImpl(com.android.tools.idea.experimental.codeanalysis.datastructs.stmt.impl.DeclarationStmtImpl)

Example 4 with BlockGraph

use of com.android.tools.idea.experimental.codeanalysis.datastructs.graph.BlockGraph in project android by JetBrains.

the class CFGBuilder method dfsPsiForStatementBuilder.

/**
   * Build nodes for "for" loop.
   * @param statement The PsiForStatement
   * @param label The identifier of the label, can be null.
   */
public void dfsPsiForStatementBuilder(@NotNull PsiForStatement statement, @Nullable PsiIdentifier label) {
    PsiStatement loopBody = statement.getBody();
    int loopType;
    LoopBranchingNodeImpl loopNode;
    GraphNode conditionCheckEntry;
    ConditionCheckNode conditionCheckExit;
    GraphNode postLoopEntry;
    GraphNode postLoopExit;
    loopType = LoopBranchingNode.FOR_LOOP;
    //Evaluate the init code
    PsiForStatement forStmt = statement;
    PsiStatement initStmt = forStmt.getInitialization();
    if (initStmt != null) {
        buildNonBranchingStatements(initStmt);
    }
    loopNode = new LoopBranchingNodeImpl(this.mGraph, loopType);
    connectCurrentWorkingNode(loopNode);
    //Push this loopNode into the stack
    pushLoopNode(loopNode, label);
    //Eval the condition check
    PsiExpression psiConditionCheckCode = forStmt.getCondition();
    Value finalCheckVal = dfsExpressionBuilder(psiConditionCheckCode);
    //Build the final condition check for this loop
    conditionCheckExit = new ConditionCheckNodeImpl(this.mGraph, finalCheckVal);
    if (loopNode.getOut().length == 0) {
        //The dummy loop node does not have any out edges
        //In this case the conditionCheckEntry is the same
        //as the conditionCheckExit
        conditionCheckEntry = conditionCheckExit;
    } else {
        //At this point the dummy LoopNode is connected to the entry
        //of the condition check code.
        conditionCheckEntry = loopNode.getOut()[0];
    }
    connectCurrentWorkingNode(conditionCheckExit);
    //Build the loop body
    BlockGraph loopBodyGraph = loopbodyBuilder(loopBody, statement);
    //Connect the condition check code true branch to loop entry
    GraphNodeUtil.connectGraphNode(conditionCheckExit.getTrueBranch(), loopBodyGraph.getEntryNode());
    curWorkingNodeList.clear();
    curWorkingNodeList.add(loopBodyGraph.getExitNode());
    //Eval Post loop code
    PsiStatement postLoopUpdateStatment = forStmt.getUpdate();
    buildNonBranchingStatements(postLoopUpdateStatment);
    postLoopEntry = loopBodyGraph.getExitNode().getOut()[0];
    postLoopExit = curWorkingNodeList.get(0);
    //Connect the post loop to the condition check entry
    connectCurrentWorkingNode(conditionCheckEntry);
    curWorkingNodeList.clear();
    curWorkingNodeList.add(conditionCheckExit.getFalseBranch());
    loopNode.setConditionCheckEntry(conditionCheckEntry);
    loopNode.setConditionCheckExitNode(conditionCheckExit);
    loopNode.setPostLoopEntryNode(postLoopEntry);
    loopNode.setPostLoopExitNode(postLoopExit);
    loopNode.setLoopBody(loopBodyGraph);
    //For loop build complete
    //Process the break and continue nodes
    loopNode.connectSpecialNodes();
    popLoopNode();
}
Also used : BlockGraph(com.android.tools.idea.experimental.codeanalysis.datastructs.graph.BlockGraph)

Example 5 with BlockGraph

use of com.android.tools.idea.experimental.codeanalysis.datastructs.graph.BlockGraph in project android by JetBrains.

the class CFGBuilder method resolveLocal.

/**
   * Resolve the local variable at the current context
   * @param localVar The local
   * @return The PsiCFG wrapper for the local.
   */
@Nullable
private Local resolveLocal(@NotNull PsiLocalVariable localVar) {
    Local l = this.mGraph.getLocalFromPsiLocal(localVar);
    if (l != null) {
        return l;
    }
    if (this.containerClass.isNested()) {
        //Nested class
        BlockGraph parentBlock = this.containerClass.getDeclaringBlock();
        l = parentBlock.getLocalFromPsiLocal(localVar);
    }
    if (l == null) {
        PsiCFGDebugUtil.LOG.warning(String.format("Local %s cannot be resolved in Class %s", localVar.getText(), this.containerClass.getQualifiedClassName()));
    }
    return l;
}
Also used : BlockGraph(com.android.tools.idea.experimental.codeanalysis.datastructs.graph.BlockGraph) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

BlockGraph (com.android.tools.idea.experimental.codeanalysis.datastructs.graph.BlockGraph)7 Nullable (org.jetbrains.annotations.Nullable)2 Graph (com.android.tools.idea.experimental.codeanalysis.datastructs.graph.Graph)1 MethodGraph (com.android.tools.idea.experimental.codeanalysis.datastructs.graph.MethodGraph)1 SwitchCaseGraph (com.android.tools.idea.experimental.codeanalysis.datastructs.graph.SwitchCaseGraph)1 AssignStmtImpl (com.android.tools.idea.experimental.codeanalysis.datastructs.stmt.impl.AssignStmtImpl)1 DeclarationStmtImpl (com.android.tools.idea.experimental.codeanalysis.datastructs.stmt.impl.DeclarationStmtImpl)1