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