Search in sources :

Example 11 with GenericAccessibleObject

use of org.evosuite.utils.generic.GenericAccessibleObject in project evosuite by EvoSuite.

the class TestCluster method cacheGenerators.

/**
 * Calculate and cache all generators for a particular type. All generic
 * types on the generator are instantiated according to the produced type
 *
 * @param clazz
 * @throws ConstructionFailedException
 */
private void cacheGenerators(GenericClass clazz) throws ConstructionFailedException {
    if (generatorCache.containsKey(clazz)) {
        return;
    }
    logger.debug("1. Caching generators for {}", clazz);
    Set<GenericAccessibleObject<?>> targetGenerators = new LinkedHashSet<>();
    if (clazz.isObject()) {
        logger.debug("2. Target class is object: {}", clazz);
        for (GenericClass generatorClazz : generators.keySet()) {
            if (generatorClazz.isObject()) {
                targetGenerators.addAll(generators.get(generatorClazz));
            }
        }
    } else {
        logger.debug("2. Target class is not object: {}", clazz);
        for (GenericClass generatorClazz : generators.keySet()) {
            if (generatorClazz.canBeInstantiatedTo(clazz)) {
                // logger.debug("4. generator " + generatorClazz + " can be instantiated to " + clazz);
                GenericClass instantiatedGeneratorClazz = generatorClazz.getWithParametersFromSuperclass(clazz);
                logger.debug("Instantiated type: {} for {} and superclass {}", instantiatedGeneratorClazz, generatorClazz, clazz);
                for (GenericAccessibleObject<?> generator : generators.get(generatorClazz)) {
                    logger.debug("5. current instantiated generator: {}", generator);
                    try {
                        if ((generator.isMethod() || generator.isField()) && clazz.isParameterizedType() && GenericClass.isMissingTypeParameters(generator.getGenericGeneratedType())) {
                            logger.debug("No type parameters present in generator for {}: {}", clazz, generator);
                            continue;
                        }
                        // Set owner type parameters from new return type
                        GenericAccessibleObject<?> newGenerator = generator.copyWithOwnerFromReturnType(instantiatedGeneratorClazz);
                        boolean hadTypeParameters = false;
                        // Instantiate potential further type variables based on type variables of return type
                        if (newGenerator.getOwnerClass().hasWildcardOrTypeVariables()) {
                            logger.debug("Instantiating type parameters of owner type: {}", newGenerator.getOwnerClass());
                            GenericClass concreteClass = newGenerator.getOwnerClass().getGenericInstantiation(clazz.getTypeVariableMap());
                            newGenerator = newGenerator.copyWithNewOwner(concreteClass);
                            hadTypeParameters = true;
                        }
                        // If it is a generic method, instantiate generic type variables for the produced class
                        if (newGenerator.hasTypeParameters()) {
                            logger.debug("Instantiating type parameters");
                            /*
								 * TODO:
								 * public class Foo<X> {
								 *   public <X> Foo<X> getFoo() {
								 *     // ...
								 *   }
								 * }
								 *
								 * Here X and X are two different type variables, and these need to be matched here!
								 *
								 */
                            newGenerator = newGenerator.getGenericInstantiationFromReturnValue(clazz);
                            hadTypeParameters = true;
                        // newGenerator = newGenerator.getGenericInstantiation(clazz);
                        }
                        logger.debug("Current generator: {}", newGenerator);
                        if ((!hadTypeParameters && generatorClazz.equals(clazz)) || clazz.isAssignableFrom(newGenerator.getGeneratedType())) {
                            logger.debug("Got new generator: {} which generated: {}", newGenerator, newGenerator.getGeneratedClass());
                            logger.debug("{} vs {}", (!hadTypeParameters && generatorClazz.equals(clazz)), clazz.isAssignableFrom(newGenerator.getGeneratedType()));
                            targetGenerators.add(newGenerator);
                        } else if (logger.isDebugEnabled()) {
                            logger.debug("New generator not assignable: {}", newGenerator);
                            logger.debug("Had type parameters: {}", hadTypeParameters);
                            logger.debug("generatorClazz.equals(clazz): {}", generatorClazz.equals(clazz));
                            try {
                                logger.debug("clazz.isAssignableFrom({}): ", newGenerator.getGeneratedType());
                                logger.debug("                        {}", clazz.isAssignableFrom(newGenerator.getGeneratedType()));
                            } catch (Throwable t) {
                                logger.debug("Error", t);
                            }
                        }
                    } catch (ConstructionFailedException e) {
                        logger.debug("5. ERROR", e);
                    }
                }
            // FIXME:
            // There are cases where this might lead to relevant cast classes not being included
            // but in manycases it will pull in large numbers of useless dependencies.
            // Commented out for now, until we find a case where the problem can be properly studied.
            // } else {
            // logger.debug("4. generator {} CANNOT be instantiated to {}", generatorClazz, clazz);
            // for(GenericClass boundClass : generatorClazz.getGenericBounds()) {
            // CastClassManager.getInstance().addCastClass(boundClass, 0);
            // }
            }
        }
        logger.debug("Found generators for {}: {}", clazz, targetGenerators.size());
    }
    logger.debug("]");
    generatorCache.put(clazz, targetGenerators);
}
Also used : GenericAccessibleObject(org.evosuite.utils.generic.GenericAccessibleObject) GenericClass(org.evosuite.utils.generic.GenericClass) ConstructionFailedException(org.evosuite.ga.ConstructionFailedException)

Example 12 with GenericAccessibleObject

use of org.evosuite.utils.generic.GenericAccessibleObject in project evosuite by EvoSuite.

the class TestCluster method getRandomTestCall.

/**
 * Get random method or constructor of unit under test
 *
 * @return
 * @throws ConstructionFailedException
 */
public GenericAccessibleObject<?> getRandomTestCall(TestCase test) throws ConstructionFailedException {
    List<GenericAccessibleObject<?>> candidateTestMethods = new ArrayList<>(testMethods);
    if (candidateTestMethods.isEmpty()) {
        logger.debug("No more calls");
        // TODO: return null, or throw ConstructionFailedException?
        return null;
    }
    // If test already has a SUT call, remove all constructors
    if (doesTestHaveSUTInstance(test)) {
        candidateTestMethods = filterConstructors(candidateTestMethods);
        // It may happen that all remaining test calls are constructors. In this case it's ok.
        if (candidateTestMethods.isEmpty())
            candidateTestMethods = new ArrayList<>(testMethods);
    }
    if (Properties.SORT_CALLS) {
        candidateTestMethods = sortCalls(candidateTestMethods);
    }
    GenericAccessibleObject<?> choice = Properties.SORT_CALLS ? ListUtil.selectRankBiased(candidateTestMethods) : Randomness.choice(candidateTestMethods);
    logger.debug("Chosen call: " + choice);
    if (choice.getOwnerClass().hasWildcardOrTypeVariables()) {
        GenericClass concreteClass = choice.getOwnerClass().getGenericInstantiation();
        logger.debug("Concrete class is: " + concreteClass.getTypeName());
        choice = choice.copyWithNewOwner(concreteClass);
        logger.debug("Concrete class is: " + choice.getOwnerClass().getTypeName());
        logger.debug("Type variables: " + choice.getOwnerClass().getTypeVariableMap());
        logger.debug(Arrays.asList(choice.getTypeParameters()).toString());
        logger.debug("Chosen call with generic parameter set: " + choice);
        logger.debug("Call owner type: " + choice.getOwnerClass().getTypeName());
    }
    if (choice.hasTypeParameters()) {
        logger.debug("Instantiating chosen call: " + choice);
        choice = choice.getGenericInstantiation();
        logger.debug("Chosen instantiation: " + choice);
    }
    return choice;
}
Also used : GenericAccessibleObject(org.evosuite.utils.generic.GenericAccessibleObject) GenericClass(org.evosuite.utils.generic.GenericClass)

Example 13 with GenericAccessibleObject

use of org.evosuite.utils.generic.GenericAccessibleObject in project evosuite by EvoSuite.

the class TestCluster method invalidateGeneratorCache.

public void invalidateGeneratorCache(GenericClass klass) {
    Iterator<Map.Entry<GenericClass, Set<GenericAccessibleObject<?>>>> iter = generatorCache.entrySet().iterator();
    while (iter.hasNext()) {
        Map.Entry entry = iter.next();
        GenericClass gen = (GenericClass) entry.getKey();
        if (gen.isAssignableFrom(klass)) {
            iter.remove();
        }
    }
}
Also used : GenericAccessibleObject(org.evosuite.utils.generic.GenericAccessibleObject) Entry(java.util.Map.Entry) Entry(java.util.Map.Entry) GenericClass(org.evosuite.utils.generic.GenericClass)

Example 14 with GenericAccessibleObject

use of org.evosuite.utils.generic.GenericAccessibleObject in project evosuite by EvoSuite.

the class TestCluster method getRandomizedCallsToEnvironment.

public List<GenericAccessibleObject<?>> getRandomizedCallsToEnvironment() {
    if (environmentMethods.isEmpty()) {
        return null;
    }
    List<GenericAccessibleObject<?>> list = new ArrayList<>();
    for (GenericAccessibleObject<?> obj : environmentMethods) {
        try {
            if (obj.getOwnerClass().hasWildcardOrTypeVariables()) {
                GenericClass concreteClass = obj.getOwnerClass().getGenericInstantiation();
                obj = obj.copyWithNewOwner(concreteClass);
            }
            if (obj.hasTypeParameters()) {
                obj = obj.getGenericInstantiation();
            }
        } catch (ConstructionFailedException e) {
            logger.error("Failed generic instantiation in " + obj);
            continue;
        }
        list.add(obj);
    }
    Collections.shuffle(list);
    return list;
}
Also used : GenericAccessibleObject(org.evosuite.utils.generic.GenericAccessibleObject) GenericClass(org.evosuite.utils.generic.GenericClass) ConstructionFailedException(org.evosuite.ga.ConstructionFailedException)

Example 15 with GenericAccessibleObject

use of org.evosuite.utils.generic.GenericAccessibleObject in project evosuite by EvoSuite.

the class TestCluster method getRandomGenerator.

/**
 * Randomly select one generator
 *
 * @param clazz
 * @return
 * @throws ConstructionFailedException
 */
public GenericAccessibleObject<?> getRandomGenerator(GenericClass clazz) throws ConstructionFailedException {
    if (clazz.hasWildcardOrTypeVariables()) {
        GenericClass concreteClass = clazz.getGenericInstantiation();
        if (concreteClass.hasWildcardOrTypeVariables())
            throw new ConstructionFailedException("Could not found concrete instantiation of generic type");
        return getRandomGenerator(concreteClass);
    }
    GenericAccessibleObject<?> generator = null;
    if (isSpecialCase(clazz)) {
        Collection<GenericAccessibleObject<?>> generators = getGeneratorsForSpecialCase(clazz);
        if (generators.isEmpty()) {
            logger.warn("No generators for class: " + clazz);
        }
        generator = Randomness.choice(generators);
    } else {
        if (!hasGenerator(clazz))
            throw new ConstructionFailedException("No generators of type " + clazz);
        generator = Randomness.choice(generatorCache.get(clazz));
    }
    if (generator == null)
        throw new ConstructionFailedException("No generators of type " + clazz);
    if (generator.hasTypeParameters()) {
        generator = generator.getGenericInstantiation(clazz);
    }
    return generator;
}
Also used : GenericAccessibleObject(org.evosuite.utils.generic.GenericAccessibleObject) GenericClass(org.evosuite.utils.generic.GenericClass) ConstructionFailedException(org.evosuite.ga.ConstructionFailedException)

Aggregations

GenericAccessibleObject (org.evosuite.utils.generic.GenericAccessibleObject)20 GenericClass (org.evosuite.utils.generic.GenericClass)14 ConstructionFailedException (org.evosuite.ga.ConstructionFailedException)11 GenericMethod (org.evosuite.utils.generic.GenericMethod)8 GenericConstructor (org.evosuite.utils.generic.GenericConstructor)7 CaptureType (com.googlecode.gentyref.CaptureType)3 Constructor (java.lang.reflect.Constructor)3 ArrayList (java.util.ArrayList)3 Entry (java.util.Map.Entry)3 Collectors (java.util.stream.Collectors)3 Properties (org.evosuite.Properties)3 TestGenerationContext (org.evosuite.TestGenerationContext)3 AtMostOnceLogger (org.evosuite.runtime.util.AtMostOnceLogger)3 Inputs (org.evosuite.runtime.util.Inputs)3 CastClassManager (org.evosuite.seeding.CastClassManager)3 TestCluster (org.evosuite.setup.TestCluster)3 InstanceOnlyOnce (org.evosuite.testcase.jee.InstanceOnlyOnce)3 Method (java.lang.reflect.Method)2 Type (java.lang.reflect.Type)2 java.util (java.util)2