Search in sources :

Example 6 with PsiCFGMethod

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

the class CFGBuilder method dfsPsiNewExpressionBuilder.

public Value dfsPsiNewExpressionBuilder(PsiNewExpression expression) {
    PsiExpressionList argumentList = expression.getArgumentList();
    Value[] paramValueArray = parseMethodCallParams(argumentList);
    PsiType newType = expression.getType();
    PsiClass classOfNewInstance;
    PsiCFGClass cfgClassOfNewInstance;
    PsiAnonymousClass anonymousClass = expression.getAnonymousClass();
    //Determine if it is a array initiation.
    if (newType instanceof PsiArrayType) {
        //TODO: Change it to use newArray
        PsiArrayType newArrayType = (PsiArrayType) newType;
        PsiType baseType = newArrayType.getComponentType();
        NewExprImpl newArrayExprImpl = new NewExprImpl(newArrayType, expression);
        newArrayExprImpl.setArray();
        //TODO: process its initiation
        SynthesizedLocal synLocal = createSynthesizeTemporalVariable(newArrayExprImpl);
        return synLocal;
    }
    if (anonymousClass != null) {
        //PsiCFGDebugUtil.LOG.warning("Currently AnonymousClass is not handled");
        cfgClassOfNewInstance = mScene.getOrCreateNestedClass(anonymousClass, this.containerClass, retrieveDeclaringMethod(), this.mGraph);
    } else {
        PsiJavaCodeReferenceElement classReference = expression.getClassReference();
        if (classReference == null) {
            PsiCFGDebugUtil.LOG.warning("classReference of the new expression is null");
            PsiCFGDebugUtil.debugOutputPsiElement(expression);
            System.out.println(expression.getText());
            PsiExpression[] dimisionExpressions = expression.getArrayDimensions();
            System.out.println("Dimision: " + dimisionExpressions.length);
            System.out.println("Type: " + newType.getCanonicalText() + " " + newType.getClass().getSimpleName());
            throw new RuntimeException("classReference in dfsNewExpressionBuilder is null");
        }
        PsiElement resolvedExpression = classReference.resolve();
        if (resolvedExpression == null || (!(resolvedExpression instanceof PsiClass))) {
            PsiCFGDebugUtil.LOG.warning("Cannot resolve the class in the new expression in " + expression.getText());
            return new DummyRef(expression.getType(), expression);
        }
        classOfNewInstance = (PsiClass) resolvedExpression;
        cfgClassOfNewInstance = mScene.getOrCreateCFGClass(classOfNewInstance);
    }
    //Resolve Constructor
    PsiMethod constructorMethod = expression.resolveConstructor();
    NewExprImpl newExprImpl = new NewExprImpl(expression.getType(), expression);
    newExprImpl.setBaseClass(cfgClassOfNewInstance);
    //Add Args/Param to the new expression
    ArrayList<Value> argsList = newExprImpl.getArgsList();
    for (Value v : paramValueArray) {
        argsList.add(v);
    }
    if (constructorMethod != null) {
        PsiClass declaringClassRef = constructorMethod.getContainingClass();
        PsiCFGClass construtorCFGClass = mScene.getOrCreateCFGClass(declaringClassRef);
        PsiCFGMethod constructorCFGMethod = construtorCFGClass.getMethod(constructorMethod);
        if (constructorCFGMethod == null) {
            PsiCFGDebugUtil.LOG.warning("Cannot resolve the constructor for " + constructorMethod.getName());
        } else {
            newExprImpl.setConstrctorInvocation(constructorCFGMethod);
        }
    }
    SynthesizedLocal synLocal = createSynthesizeTemporalVariable(newExprImpl);
    return synLocal;
}
Also used : PsiCFGMethod(com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGMethod) PsiCFGClass(com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGClass)

Example 7 with PsiCFGMethod

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

the class CFGBuilder method dfsPsiMethodCallExpressionBuilder.

public Value dfsPsiMethodCallExpressionBuilder(PsiMethodCallExpression expression) {
    PsiExpressionList argsList = expression.getArgumentList();
    PsiReferenceExpression methodRef = expression.getMethodExpression();
    PsiExpression qualifier = methodRef.getQualifierExpression();
    Value[] argsValueArray = parseMethodCallParams(argsList);
    if (methodRef instanceof PsiMethodReferenceExpression) {
        PsiMethodReferenceExpression psiMethodRef = (PsiMethodReferenceExpression) methodRef;
        PsiCFGDebugUtil.LOG.info("The MethodCallExpression contains a PsiMethodReferenceExpression");
    }
    //In the PsiMethodCallExpression, The PsiReferenceExpression Should always
    //refer to the PsiMethod it should invoke.
    PsiElement resolvedElement = methodRef.resolve();
    if (resolvedElement instanceof PsiMethod) {
        //The resolvedElement is a PsiMethod. As expected
        PsiMethod resolvedMethod = (PsiMethod) resolvedElement;
        //Check if it is a static invocation
        //If it is a static invocation. The qualifier should be PsiReferenceExpress
        //That refer to a PsiClass
        PsiClass declaringClass = resolvedMethod.getContainingClass();
        PsiCFGClass cfgClass = mScene.getOrCreateCFGClass(declaringClass);
        PsiCFGMethod cfgMethod = cfgClass.getMethod(resolvedMethod);
        if (isQualifierPsiClass(qualifier) || cfgMethod.isStatic()) {
            //It is a static invocation
            return createStaticInvocation(cfgMethod, cfgClass, resolvedMethod, argsValueArray, expression);
        } else if (qualifier == null) {
            if (cfgMethod.isStatic()) {
                return createStaticInvocation(cfgMethod, cfgClass, resolvedMethod, argsValueArray, expression);
            }
            PsiType thisType = retrieveTypeByPsiClass(this.containerClass.getPsiClass());
            ThisRefImpl synThisRef = new ThisRefImpl(null, this.containerClass, thisType);
            InstanceInvokeExprImpl instanceInvoke = new InstanceInvokeExprImpl(cfgMethod, resolvedMethod.getReturnType(), expression);
            instanceInvoke.setBase(synThisRef);
            for (Value v : argsValueArray) {
                instanceInvoke.addArg(v);
            }
            SynthesizedLocal synLocal = createSynthesizeTemporalVariable(instanceInvoke);
            return synLocal;
        } else if (qualifier instanceof PsiReferenceExpression) {
            //The method invocation is obj.method()
            Value objLocal = dfsRHSReferenceExpressionBuilder((PsiReferenceExpression) qualifier);
            InstanceInvokeExprImpl instanceInvoke = new InstanceInvokeExprImpl(cfgMethod, resolvedMethod.getReturnType(), expression);
            instanceInvoke.setBase(objLocal);
            for (Value v : argsValueArray) {
                instanceInvoke.addArg(v);
            }
            if (objLocal == null) {
                throw new RuntimeException("objectLocal in MethodCallExpression is null");
            }
            PsiType baseType = objLocal.getType();
            if (baseType instanceof PsiClassType) {
                PsiClass classRef = ((PsiClassType) baseType).resolve();
                mScene.getOrCreateCFGClass(classRef);
            }
            SynthesizedLocal synLocal = createSynthesizeTemporalVariable(instanceInvoke);
            return synLocal;
        } else {
            //Unexpected
            PsiCFGDebugUtil.LOG.warning("Did not recognize PsiMethodCallExpression: " + expression.getText() + " of type " + qualifier.getClass().getName());
        }
    } else {
        //A method call expression without a reference to the method.
        //Unexpected
        PsiCFGDebugUtil.LOG.warning("Cannot resolve PsiMethodCallExpression e to PsiMethod: " + expression.getText() + "   " + (resolvedElement == null ? "null" : resolvedElement.getClass().getName()));
    }
    return new DummyRef(expression.getType(), resolvedElement);
}
Also used : PsiCFGMethod(com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGMethod) PsiCFGClass(com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGClass)

Example 8 with PsiCFGMethod

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

the class CFGUtil method getAllMethodNodesFromCallGraph.

private static Map<PsiCFGMethod, Integer> getAllMethodNodesFromCallGraph(Callgraph cg) {
    Map<PsiCFGMethod, Integer> retMap = Maps.newHashMap();
    Set<PsiCFGMethod> allMethods = cg.allMethodsInGraph;
    int i = 0;
    for (PsiCFGMethod curMethod : allMethods) {
        retMap.put(curMethod, i);
        i++;
    }
    return retMap;
}
Also used : PsiCFGMethod(com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGMethod)

Example 9 with PsiCFGMethod

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

the class CallgraphBuilder method getNearestConcreteMethod.

public PsiCFGMethod getNearestConcreteMethod(PsiCFGClass receiverClass, PsiCFGPartialMethodSignature signature) {
    while (receiverClass != null && !receiverClass.equals(JAVA_LANG_OBJECT)) {
        PsiCFGMethod methodInCurClass = receiverClass.getMethod(signature);
        if (methodInCurClass != null && (!methodInCurClass.isAbstract())) {
            return methodInCurClass;
        }
        receiverClass = receiverClass.getSuperClass();
    }
    return null;
}
Also used : PsiCFGMethod(com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGMethod)

Example 10 with PsiCFGMethod

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

the class CallgraphBuilder method addInvokeExprWithThisRef.

public void addInvokeExprWithThisRef(GraphNode node, PsiType thisBaseType, PsiCFGMethod method) {
    if (!method.isAbstract()) {
        addToCallGraph(node, method);
    } else {
        PsiClassType classType = null;
        PsiCFGClass cfgClass = null;
        if (thisBaseType instanceof PsiClassType) {
            classType = (PsiClassType) thisBaseType;
            cfgClass = mScene.getPsiCFGClass(classType.resolve());
        } else {
            PsiCFGDebugUtil.LOG.warning("PsiType of ThisRef is not a PsiClassType :" + thisBaseType.getClass().getSimpleName());
            return;
        }
        if (cfgClass == null) {
            PsiCFGDebugUtil.LOG.warning("PsiType of ThisRef cannot be resolved to cfgClass :" + thisBaseType.getClass().getSimpleName());
        }
        ArrayList<PsiCFGMethod> methodsList = Lists.newArrayList();
        recursivelyQueryConcreteMethodFromChildrenWithCache(methodsList, cfgClass, method.getSignature());
    }
}
Also used : PsiCFGMethod(com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGMethod) PsiClassType(com.intellij.psi.PsiClassType) PsiCFGClass(com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGClass)

Aggregations

PsiCFGMethod (com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGMethod)17 PsiCFGClass (com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGClass)8 PsiCFGPartialMethodSignature (com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGPartialMethodSignature)3 GraphNode (com.android.tools.idea.experimental.codeanalysis.datastructs.graph.node.GraphNode)3 PsiClassType (com.intellij.psi.PsiClassType)2 MethodGraph (com.android.tools.idea.experimental.codeanalysis.datastructs.graph.MethodGraph)1 Pair (com.intellij.openapi.util.Pair)1 PsiClass (com.intellij.psi.PsiClass)1 BufferedWriter (java.io.BufferedWriter)1 File (java.io.File)1 FileWriter (java.io.FileWriter)1 IOException (java.io.IOException)1