Search in sources :

Example 1 with PsiCFGField

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

the class PsiCFGAnalysisUtil method parseFields.

/**
   * The purpose of this method is to create wrapper class for all fields and
   * methods and its modifiers and annotations
   */
public void parseFields(@NotNull PsiCFGClass clazz) {
    PsiField[] fields = clazz.getPsiClass().getFields();
    for (PsiField curField : fields) {
        PsiCFGField curCFGField = new PsiCFGField(curField, clazz);
        clazz.addField(curCFGField);
    }
}
Also used : PsiCFGField(com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGField)

Example 2 with PsiCFGField

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

the class CFGBuilder method dfsRHSReferenceExpressionBuilder.

/**
   * Reference handling needs more thoughts. Due to the limitation
   * of the intelliJ. Perhaps we need a implement our own reference
   * resolve system.
   *
   * @param expression
   * @return
   */
public Value dfsRHSReferenceExpressionBuilder(PsiReferenceExpression expression) {
    //Debug info
    //PsiCFGDebugUtil.debugOutputPsiElement(expression);
    //First, determine if the ReferenceExpression is referring to a local
    PsiElement target = expression.resolve();
    if (target == null) {
        PsiCFGDebugUtil.LOG.warning("ReferenceExpression cannot be resolved: " + expression.getText());
    }
    if (target instanceof PsiLocalVariable) {
        Local l = resolveLocal((PsiLocalVariable) target);
        //return this.mGraph.getLocalFromPsiLocal((PsiLocalVariable)target);
        if (l == null) {
            return new DummyRef(expression.getType(), expression);
        } else {
            return l;
        }
    }
    //Second, determine if the ReferenceExpression is refering to a param
    if (target instanceof PsiParameter) {
        //The this.mGraph should be a methodGraph or a try catch block to have parameters
        //if (this.mGraph instanceof MethodGraph) {
        //  Param v = ((MethodGraphImpl)this.mGraph).getParamFromPsiParam((PsiParameter)target);
        //  return v;
        //}
        //else {
        //  //TODO: Make necessary changes to support try catch block
        //  PsiCFGDebugUtil.LOG.warning("Refering a param that is not available in this context\n "
        //                           + expression.getText() + "\n");
        //  return new DummyRef(expression.getType(), expression);
        //}
        Param p = resolveParam((PsiParameter) target);
        if (p == null) {
            return new DummyRef(expression.getType(), expression);
        } else {
            return p;
        }
    }
    //So now the reference is referring to an field/ method/class etc
    PsiExpression qualifier = expression.getQualifierExpression();
    //The reference target is a field
    if (target instanceof PsiField) {
        PsiField fieldTarget = (PsiField) target;
        PsiCFGClass cfgClass = mScene.getOrCreateCFGClass(fieldTarget.getContainingClass());
        PsiCFGField cfgField = cfgClass.getField(fieldTarget.getName());
        if (qualifier == null) {
            //TODO: Inner Class/ Anonymous Class might have difference reference to this.
            return processRefExprWithTgtPsiFieldQualifierNull(fieldTarget, cfgClass, cfgField, expression);
        } else if (qualifier instanceof PsiThisExpression) {
            //this.sth
            PsiCFGClass thisClass = this.containerClass;
            PsiThisExpression thisPsiExpression = (PsiThisExpression) qualifier;
            ThisRefImpl thisRefImpl = new ThisRefImpl(thisPsiExpression, thisClass, fieldTarget.getType());
            InstanceFieldRefImpl instanceFieldRef = new InstanceFieldRefImpl(fieldTarget.getType(), cfgField, expression);
            instanceFieldRef.setBase(thisRefImpl);
            SynthesizedLocal synLocal = createSynthesizeTemporalVariable(instanceFieldRef);
            return synLocal;
        } else if (qualifier instanceof PsiSuperExpression) {
            //super.sth
            //Should not happen here
            PsiCFGDebugUtil.LOG.warning("Super.field happened at expression: " + expression.getText());
            return new DummyRef(expression.getType(), expression);
        } else if (qualifier instanceof PsiReferenceExpression) {
            PsiElement resolveOfQualifier = ((PsiReferenceExpression) qualifier).resolve();
            if (resolveOfQualifier instanceof PsiClass) {
                //Consider it is a static reference
                return createRHSStaticRefExpression(fieldTarget.getType(), cfgField, expression);
            } else if (resolveOfQualifier instanceof PsiReferenceExpression) {
                //qualifier is a PsiReferenceExpression
                Value qualifierValue = dfsRHSReferenceExpressionBuilder((PsiReferenceExpression) resolveOfQualifier);
                InstanceFieldRef instanceFieldRef = new InstanceFieldRefImpl(fieldTarget.getType(), cfgField, expression);
                instanceFieldRef.setBase(qualifierValue);
                SynthesizedLocal synLocal = createSynthesizeTemporalVariable(instanceFieldRef);
                return synLocal;
            } else if (resolveOfQualifier instanceof PsiLocalVariable) {
                //Qualifier is a local
                //Local.field
                Local local = resolveLocal((PsiLocalVariable) resolveOfQualifier);
                if (local == null) {
                    local = new LocalImpl(qualifier.getType(), (PsiLocalVariable) resolveOfQualifier);
                }
                InstanceFieldRef instanceFieldRef = new InstanceFieldRefImpl(fieldTarget.getType(), cfgField, expression);
                instanceFieldRef.setBase(local);
                SynthesizedLocal synLocal = createSynthesizeTemporalVariable(instanceFieldRef);
                return synLocal;
            } else if (resolveOfQualifier instanceof PsiField || resolveOfQualifier instanceof PsiParameter) {
                Value field = dfsRHSReferenceExpressionBuilder((PsiReferenceExpression) qualifier);
                InstanceFieldRef instanceFieldRef = new InstanceFieldRefImpl(fieldTarget.getType(), cfgField, expression);
                instanceFieldRef.setBase(field);
                SynthesizedLocal synLocal = createSynthesizeTemporalVariable(instanceFieldRef);
                return synLocal;
            } else {
                PsiCFGDebugUtil.LOG.warning("Unknown resolve type of qualifer ");
                PsiCFGDebugUtil.debugOutputPsiElement(resolveOfQualifier);
            }
        } else if (qualifier instanceof PsiMethodCallExpression) {
            //a.method().field
            Value methodCallLocal = dfsPsiMethodCallExpressionBuilder((PsiMethodCallExpression) qualifier);
            InstanceFieldRefImpl instanceFieldRef = new InstanceFieldRefImpl(fieldTarget.getType(), cfgField, expression);
            instanceFieldRef.setBase(methodCallLocal);
            SynthesizedLocal synLocal = createSynthesizeTemporalVariable(instanceFieldRef);
            return synLocal;
        } else {
            //Unsupported Qualifier
            PsiCFGDebugUtil.LOG.warning("Unsupported Qualifier in expression: " + expression.getText());
            PsiCFGDebugUtil.debugOutputPsiElement(qualifier);
        }
    } else if (target instanceof PsiMethod) {
        PsiCFGDebugUtil.LOG.info("Refering to a method: " + ((PsiMethod) target).getName());
    } else {
        PsiCFGDebugUtil.LOG.info("Other circumstances: target of the Reference Expression is : " + target.getClass().getSimpleName());
    }
    DummyRef ref = new DummyRef(expression.getType(), expression);
    return ref;
}
Also used : PsiCFGField(com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGField) PsiCFGClass(com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGClass)

Example 3 with PsiCFGField

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

the class CFGBuilder method dfsLHSReferenceExpressionBuilder.

/**
   * @param expression
   * @return
   */
public Value dfsLHSReferenceExpressionBuilder(PsiReferenceExpression expression) {
    PsiElement target = expression.resolve();
    if (target == null) {
        PsiCFGDebugUtil.LOG.warning("ReferenceExpression cannot be resolved: " + expression.getText());
    }
    if (target instanceof PsiLocalVariable) {
        Local l = resolveLocal((PsiLocalVariable) target);
        //return this.mGraph.getLocalFromPsiLocal((PsiLocalVariable)target);
        if (l == null) {
            return new DummyRef(expression.getType(), expression);
        } else {
            return l;
        }
    }
    //Second, determine if the ReferenceExpression is refering to a param
    if (target instanceof PsiParameter) {
        Param p = resolveParam((PsiParameter) target);
        if (p == null) {
            return new DummyRef(expression.getType(), expression);
        } else {
            return p;
        }
    }
    //So now it refers to a field/method/class
    PsiExpression qualifier = expression.getQualifierExpression();
    if (qualifier == null) {
    }
    if (target instanceof PsiField) {
        PsiField fieldTarget = (PsiField) target;
        PsiCFGClass cfgClass = mScene.getOrCreateCFGClass(fieldTarget.getContainingClass());
        PsiCFGField cfgField = cfgClass.getField(fieldTarget.getName());
        if (qualifier == null) {
            //TODO: Inner Class/ Anonymous Class might have difference reference to this.
            return processLHSRefExprWithTgtPsiFieldQualifierNull(fieldTarget, cfgClass, cfgField, expression);
        } else if (qualifier instanceof PsiThisExpression) {
            //this.sth
            PsiCFGClass thisClass = this.containerClass;
            PsiThisExpression thisPsiExpression = (PsiThisExpression) qualifier;
            ThisRefImpl thisRefImpl = new ThisRefImpl(thisPsiExpression, thisClass, fieldTarget.getType());
            InstanceFieldRefImpl instanceFieldRef = new InstanceFieldRefImpl(fieldTarget.getType(), cfgField, expression);
            instanceFieldRef.setBase(thisRefImpl);
            //SynthesizedLocal synLocal = createSynthesizeTemporalVariable(instanceFieldRef);
            return instanceFieldRef;
        } else if (qualifier instanceof PsiSuperExpression) {
            //super.sth
            //Should not happen here
            PsiCFGDebugUtil.LOG.warning("Super.field happened at expression: " + expression.getText());
            return new DummyRef(expression.getType(), expression);
        } else if (qualifier instanceof PsiReferenceExpression) {
            PsiElement resolveOfQualifier = ((PsiReferenceExpression) qualifier).resolve();
            if (resolveOfQualifier instanceof PsiClass) {
                //Consider it is a static reference
                return createLHSStaticRefExpression(fieldTarget.getType(), cfgField, expression);
            } else if (resolveOfQualifier instanceof PsiReferenceExpression) {
                //qualifier is a PsiReferenceExpression
                Value qualifierValue = dfsRHSReferenceExpressionBuilder((PsiReferenceExpression) resolveOfQualifier);
                InstanceFieldRef instanceFieldRef = new InstanceFieldRefImpl(fieldTarget.getType(), cfgField, expression);
                instanceFieldRef.setBase(qualifierValue);
                return instanceFieldRef;
            } else if (resolveOfQualifier instanceof PsiLocalVariable) {
                //Qualifier is a local
                //Local.field
                Local local = resolveLocal((PsiLocalVariable) resolveOfQualifier);
                if (local == null) {
                    local = new LocalImpl(qualifier.getType(), (PsiLocalVariable) resolveOfQualifier);
                }
                InstanceFieldRef instanceFieldRef = new InstanceFieldRefImpl(fieldTarget.getType(), cfgField, expression);
                instanceFieldRef.setBase(local);
                return instanceFieldRef;
            } else if (resolveOfQualifier instanceof PsiField || resolveOfQualifier instanceof PsiParameter) {
                Value field = dfsRHSReferenceExpressionBuilder((PsiReferenceExpression) qualifier);
                InstanceFieldRef instanceFieldRef = new InstanceFieldRefImpl(fieldTarget.getType(), cfgField, expression);
                instanceFieldRef.setBase(field);
                return instanceFieldRef;
            } else {
                PsiCFGDebugUtil.LOG.warning("Unknown resolve type of qualifer ");
                PsiCFGDebugUtil.debugOutputPsiElement(resolveOfQualifier);
            }
        } else if (qualifier instanceof PsiMethodCallExpression) {
            //a.method().field
            Value methodCallLocal = dfsPsiMethodCallExpressionBuilder((PsiMethodCallExpression) qualifier);
            InstanceFieldRefImpl instanceFieldRef = new InstanceFieldRefImpl(fieldTarget.getType(), cfgField, expression);
            instanceFieldRef.setBase(methodCallLocal);
            return instanceFieldRef;
        } else {
            //Unsupported Qualifier
            PsiCFGDebugUtil.LOG.warning("Unsupported Qualifier in expression: " + expression.getText());
            PsiCFGDebugUtil.debugOutputPsiElement(qualifier);
        }
    } else if (target instanceof PsiMethod) {
        PsiCFGDebugUtil.LOG.info("Refering to a method: " + ((PsiMethod) target).getName());
    } else {
        PsiCFGDebugUtil.LOG.info("Other circumstances: target of the Reference Expression is : " + target.getClass().getSimpleName());
    }
    DummyRef ref = new DummyRef(expression.getType(), expression);
    return ref;
}
Also used : PsiCFGField(com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGField) PsiCFGClass(com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGClass)

Aggregations

PsiCFGField (com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGField)3 PsiCFGClass (com.android.tools.idea.experimental.codeanalysis.datastructs.PsiCFGClass)2