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);
}
}
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;
}
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;
}
Aggregations