![JAR search and dependency download from the Maven repository](/logo.png)
org.evosuite.utils.generic.GenericMethod Maven / Gradle / Ivy
The newest version!
/**
* Copyright (C) 2010-2018 Gordon Fraser, Andrea Arcuri and EvoSuite
* contributors
*
* This file is part of EvoSuite.
*
* EvoSuite is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* EvoSuite is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with EvoSuite. If not, see .
*/
/**
*
*/
package org.evosuite.utils.generic;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.evosuite.TestGenerationContext;
import org.evosuite.ga.ConstructionFailedException;
import org.evosuite.runtime.util.Inputs;
import org.evosuite.setup.TestClusterUtils;
import org.evosuite.setup.TestUsageChecker;
import org.evosuite.testcase.variable.VariableReference;
import com.googlecode.gentyref.GenericTypeReflector;
import org.evosuite.utils.LoggingUtils;
/**
* @author Gordon Fraser
*
*/
public class GenericMethod extends GenericAccessibleObject {
private static final long serialVersionUID = 6091851133071150237L;
private transient Method method;
public GenericMethod(Method method, GenericClass type) {
super(new GenericClass(type));
this.method = method;
Inputs.checkNull(method, type);
}
public GenericMethod(Method method, Class> type) {
super(new GenericClass(type));
this.method = method;
Inputs.checkNull(method, type);
}
public GenericMethod(Method method, Type type) {
super(new GenericClass(type));
this.method = method;
Inputs.checkNull(method, type);
}
@Override
public GenericMethod copyWithNewOwner(GenericClass newOwner) {
GenericMethod copy = new GenericMethod(method, newOwner);
copyTypeVariables(copy);
return copy;
}
@Override
public GenericMethod copyWithOwnerFromReturnType(GenericClass returnType)
throws ConstructionFailedException {
GenericClass newOwner = getOwnerClass().getGenericInstantiation(returnType.getTypeVariableMap());
GenericMethod copy = new GenericMethod(method, newOwner);
copyTypeVariables(copy);
return copy;
}
@Override
public GenericMethod copy() {
GenericMethod copy = new GenericMethod(method, new GenericClass(owner));
copyTypeVariables(copy);
return copy;
}
public Method getMethod() {
return method;
}
@Override
public AccessibleObject getAccessibleObject() {
return method;
}
@Override
public Class> getDeclaringClass() {
return method.getDeclaringClass();
}
public Type[] getParameterTypes() {
return getExactParameterTypes(method, owner.getType());
}
public List getParameterClasses() {
List parameters = new ArrayList<>();
if(logger.isDebugEnabled()) {
logger.debug("Parameter types: " + Arrays.asList(method.getGenericParameterTypes()));
}
for (Type parameterType : getParameterTypes()) {
logger.debug("Adding parameter: {}", parameterType);
parameters.add(new GenericClass(parameterType));
}
return parameters;
}
public Type[] getGenericParameterTypes() {
return method.getGenericParameterTypes();
}
public Class>[] getRawParameterTypes() {
return method.getParameterTypes();
}
@Override
public Type getGeneratedType() {
return getReturnType();
}
public Type getReturnType() {
Type returnType = getExactReturnType(method, owner.getType());
if (returnType == null) {
LoggingUtils.getEvoLogger().info("Exact return type is null for {} with owner {}",method, owner);
for (StackTraceElement elem : Thread.currentThread().getStackTrace()) {
LoggingUtils.getEvoLogger().info(elem.toString());
}
assert (false);
returnType = method.getGenericReturnType();
}
return returnType;
}
@Override
public Type getGenericGeneratedType() {
return method.getGenericReturnType();
}
@Override
public Class> getRawGeneratedType() {
return method.getReturnType();
}
/**
* Returns the exact return type of the given method in the given type. This
* may be different from m.getGenericReturnType() when the method
* was declared in a superclass, or type has a type parameter that
* is used in the return type, or type is a raw type.
*/
protected Type getExactReturnType(Method m, Type type) throws IllegalArgumentException{
Inputs.checkNull(m,type);
Type returnType = m.getGenericReturnType();
Type exactDeclaringType = null;
try {
exactDeclaringType = GenericTypeReflector.getExactSuperType(GenericTypeReflector.capture(type),
m.getDeclaringClass());
} catch(java.lang.TypeNotPresentException e) {
// May happen in completely intransparent circumstances when there are dependency issues with annotations:
// https://bugs.java.com/view_bug.do?bug_id=JDK-7183985
}
if (exactDeclaringType == null) { // capture(type) is not a subtype of m.getDeclaringClass()
logger.info("The method " + m + " is not a member of type " + type
+ " - declared in " + m.getDeclaringClass());
return m.getReturnType();
}
//if (exactDeclaringType.equals(type)) {
// logger.debug("Returntype: " + returnType + ", " + exactDeclaringType);
// return returnType;
//}
return mapTypeParameters(returnType, exactDeclaringType);
}
/**
* Returns the exact parameter types of the given method in the given type.
* This may be different from m.getGenericParameterTypes() when the
* method was declared in a superclass, or type has a type
* parameter that is used in one of the parameters, or type is a
* raw type.
*/
public Type[] getExactParameterTypes(Method m, Type type) {
Type[] parameterTypes = m.getGenericParameterTypes();
Type exactDeclaringType = GenericTypeReflector.getExactSuperType(GenericTypeReflector.capture(type),
m.getDeclaringClass());
if (exactDeclaringType == null) { // capture(type) is not a subtype of m.getDeclaringClass()
logger.info("The method " + m + " is not a member of type " + type
+ " - declared in " + m.getDeclaringClass());
return m.getParameterTypes();
}
Type[] result = new Type[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
result[i] = mapTypeParameters(parameterTypes[i], exactDeclaringType);
}
return result;
}
@Override
public TypeVariable>[] getTypeParameters() {
return method.getTypeParameters();
}
@Override
public boolean isAccessible() {
return TestUsageChecker.canUse(method);
}
@Override
public boolean isMethod() {
return true;
}
public boolean isAbstract() {
return Modifier.isAbstract(method.getModifiers());
}
@Override
public boolean isStatic() {
return Modifier.isStatic(method.getModifiers());
}
public boolean isOverloaded() {
String methodName = getName();
Class> declaringClass = method.getDeclaringClass();
try {
for(java.lang.reflect.Method otherMethod : declaringClass.getMethods()) {
if(otherMethod.equals(method))
continue;
if(otherMethod.getName().equals(methodName)) {
return true;
}
}
} catch (SecurityException e) {
} catch (NoClassDefFoundError e) {
}
return false;
}
public boolean isOverloaded(List parameters) {
String methodName = getName();
Class> declaringClass = method.getDeclaringClass();
Class>[] parameterTypes = method.getParameterTypes();
boolean isExact = true;
Class>[] parameterClasses = new Class>[parameters.size()];
for (int num = 0 ; num < parameters.size(); num++) {
VariableReference parameter = parameters.get(num);
parameterClasses[num] = parameter.getVariableClass();
if (!parameterClasses[num].equals(parameterTypes[num])) {
isExact = false;
break;
}
}
if (isExact) {
return false;
}
try {
for(java.lang.reflect.Method otherMethod : declaringClass.getMethods()) {
if(otherMethod.equals(method))
continue;
if(otherMethod.getName().equals(methodName)) {
if(!Arrays.equals(otherMethod.getParameterTypes(), parameterTypes)) {
return true;
}
}
}
// java.lang.reflect.Method otherMethod = declaringClass.getMethod(methodName,
// parameterTypes);
// if (otherMethod != null && !otherMethod.equals(method)) {
// return true;
// }
} catch (SecurityException e) {
//} catch (NoSuchMethodException e) {
}
return false;
}
@Override
public int getNumParameters() {
return method.getGenericParameterTypes().length;
}
public boolean isGenericMethod() {
return getNumParameters() > 0;
}
@Override
public String getName() {
return method.getName();
}
public String getNameWithDescriptor() {
return method.getName() + org.objectweb.asm.Type.getMethodDescriptor(method);
}
public String getDescriptor() {
return org.objectweb.asm.Type.getMethodDescriptor(method);
}
@Override
public String toString() {
return method.toGenericString();
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
// Write/save additional fields
oos.writeObject(method.getDeclaringClass().getName());
oos.writeObject(method.getName());
oos.writeObject(org.objectweb.asm.Type.getMethodDescriptor(method));
}
// assumes "static java.util.Date aDate;" declared
private void readObject(ObjectInputStream ois) throws ClassNotFoundException,
IOException {
ois.defaultReadObject();
// Read/initialize additional fields
Class> methodClass = TestGenerationContext.getInstance().getClassLoaderForSUT().loadClass((String) ois.readObject());
// TODO: What was the point of this??
// methodClass = TestCluster.classLoader.loadClass(methodClass.getName());
String methodName = (String) ois.readObject();
String methodDesc = (String) ois.readObject();
for (Method method : methodClass.getDeclaredMethods()) {
if (method.getName().equals(methodName)) {
if (org.objectweb.asm.Type.getMethodDescriptor(method).equals(methodDesc)) {
this.method = method;
return;
}
}
}
if (this.method==null) {
throw new IllegalStateException("Unknown method for " + methodName
+ " in class " + methodClass.getCanonicalName());
}
}
@Override
public void changeClassLoader(ClassLoader loader) {
super.changeClassLoader(loader);
try {
Class> oldClass = method.getDeclaringClass();
Class> newClass = loader.loadClass(oldClass.getName());
for (Method newMethod : TestClusterUtils.getMethods(newClass)) {
if (newMethod.getName().equals(this.method.getName())) {
boolean equals = true;
Class>[] oldParameters = this.method.getParameterTypes();
Class>[] newParameters = newMethod.getParameterTypes();
if (oldParameters.length != newParameters.length)
continue;
if(!newMethod.getDeclaringClass().getName().equals(method.getDeclaringClass().getName()))
continue;
if(!newMethod.getReturnType().getName().equals(method.getReturnType().getName()))
continue;
for (int i = 0; i < newParameters.length; i++) {
if (!oldParameters[i].getName().equals(newParameters[i].getName())) {
equals = false;
break;
}
}
if (equals) {
this.method = newMethod;
this.method.setAccessible(true);
return;
}
}
}
LoggingUtils.getEvoLogger().info("Method not found - keeping old class loader ");
} catch (ClassNotFoundException e) {
LoggingUtils.getEvoLogger().info("Class not found - keeping old class loader ", e);
} catch (SecurityException e) {
LoggingUtils.getEvoLogger().info("Class not found - keeping old class loader ",e);
}
}
@Override
public boolean isPublic() { return Modifier.isPublic(method.getModifiers()); }
@Override
public boolean isPrivate() { return Modifier.isPrivate(method.getModifiers()); }
@Override
public boolean isProtected() { return Modifier.isProtected(method.getModifiers()); }
@Override
public boolean isDefault() { return !isPublic() && !isPrivate() && !isProtected(); }
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((method == null) ? 0 : method.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
GenericMethod other = (GenericMethod) obj;
if (method == null) {
if (other.method != null)
return false;
} else if (!method.equals(other.method))
return false;
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy