org.evosuite.testcase.statements.PrimitiveStatement 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.testcase.statements;
import com.googlecode.gentyref.GenericTypeReflector;
import org.evosuite.Properties;
import org.evosuite.testcase.TestCase;
import org.evosuite.testcase.TestFactory;
import org.evosuite.testcase.variable.VariableReference;
import org.evosuite.testcase.variable.VariableReferenceImpl;
import org.evosuite.testcase.statements.environment.EnvironmentStatements;
import org.evosuite.testcase.execution.CodeUnderTestException;
import org.evosuite.testcase.execution.Scope;
import org.evosuite.testcase.statements.numeric.*;
import org.evosuite.utils.generic.GenericAccessibleObject;
import org.evosuite.utils.generic.GenericClass;
import org.evosuite.utils.Randomness;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.*;
/**
* Statement assigning a primitive numeric value
*
* @param
* @author Gordon Fraser
*/
public abstract class PrimitiveStatement extends AbstractStatement {
private static final long serialVersionUID = -7721106626421922833L;
/**
* The value
*/
protected transient T value;
/**
*
* Constructor for PrimitiveStatement.
*
*
* @param tc a {@link org.evosuite.testcase.TestCase} object.
* @param varRef a {@link org.evosuite.testcase.variable.VariableReference} object.
* @param value a T object.
*/
public PrimitiveStatement(TestCase tc, VariableReference varRef, T value) {
super(tc, varRef);
this.value = value;
}
/**
* Constructor
*
* @param value a T object.
* @param tc a {@link org.evosuite.testcase.TestCase} object.
* @param type a {@link java.lang.reflect.Type} object.
*/
public PrimitiveStatement(TestCase tc, Type type, T value) {
super(tc, new VariableReferenceImpl(tc, type));
this.value = value;
}
public PrimitiveStatement(TestCase tc, GenericClass clazz, T value) {
super(tc, new VariableReferenceImpl(tc, clazz));
this.value = value;
}
/**
* Access the value
*
* @return a T object.
*/
public T getValue() {
return value;
}
/**
* Set the value
*
* @param val a T object.
*/
public void setValue(T val) {
this.value = val;
}
public boolean hasMoreThanOneValue() {
return true;
}
public static PrimitiveStatement> getPrimitiveStatement(TestCase tc, Class> clazz) {
return getPrimitiveStatement(tc, new GenericClass(clazz));
}
/**
* Generate a primitive statement for given type initialized with default
* value (0)
*
* @param tc a {@link org.evosuite.testcase.TestCase} object.
* @param genericClass a {@link java.lang.reflect.Type} object.
* @return a {@link org.evosuite.testcase.statements.PrimitiveStatement} object.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public static PrimitiveStatement> getPrimitiveStatement(TestCase tc,
GenericClass genericClass) {
// TODO This kills the benefit of inheritance.
// Let each class implement the clone method instead
Class> clazz = genericClass.getRawClass();
PrimitiveStatement> statement;
if (clazz == boolean.class) {
statement = new BooleanPrimitiveStatement(tc);
} else if (clazz == int.class) {
statement = new IntPrimitiveStatement(tc);
} else if (clazz == char.class) {
statement = new CharPrimitiveStatement(tc);
} else if (clazz == long.class) {
statement = new LongPrimitiveStatement(tc);
} else if (clazz.equals(double.class)) {
statement = new DoublePrimitiveStatement(tc);
} else if (clazz == float.class) {
statement = new FloatPrimitiveStatement(tc);
} else if (clazz == short.class) {
statement = new ShortPrimitiveStatement(tc);
} else if (clazz == byte.class) {
statement = new BytePrimitiveStatement(tc);
} else if (clazz.equals(String.class)) {
statement = new StringPrimitiveStatement(tc);
} else if (GenericTypeReflector.erase(clazz).isEnum()) {
statement = new EnumPrimitiveStatement(tc, GenericTypeReflector.erase(clazz));
} else if (EnvironmentStatements.isEnvironmentData(clazz)) {
statement = EnvironmentStatements.getStatement(clazz, tc);
} else if (clazz == Class.class) {
final List types = genericClass.getParameterTypes();
Type typeParameter = null;
if (!types.isEmpty()) {
typeParameter = types.get(0);
logger.debug("Creating class primitive with value " + typeParameter);
if (typeParameter instanceof WildcardType) {
statement = new ClassPrimitiveStatement(
tc,
GenericTypeReflector.erase(((WildcardType) typeParameter).getUpperBounds()[0]));
} else {
statement = new ClassPrimitiveStatement(tc,
GenericTypeReflector.erase(typeParameter));
}
} else {
logger.debug("Creating class primitive with random value / "
+ genericClass);
statement = new ClassPrimitiveStatement(tc);
}
/*
if (genericClass.hasWildcardTypes()) {
Class> bound = GenericTypeReflector.erase(TypeUtils.getImplicitUpperBounds((WildcardType) typeParameter)[0]);
if (!bound.equals(Object.class)) {
Set> assignableClasses = TestClusterGenerator.getConcreteClasses(bound,
DependencyAnalysis.getInheritanceTree());
statement = new ClassPrimitiveStatement(tc, genericClass,
assignableClasses);
} else {
statement = new ClassPrimitiveStatement(tc);
}
} else {
*/
/*
if (typeParameter instanceof Class>) {
logger.debug("Creating class primitive with value " + typeParameter);
statement = new ClassPrimitiveStatement(tc, (Class>) typeParameter);
} else {
logger.debug("Creating class primitive with random value / "
+ typeParameter);
statement = new ClassPrimitiveStatement(tc);
}
*/
//}
} else {
throw new RuntimeException("Getting unknown type: " + clazz + " / "
+ clazz.getClass());
}
return statement;
}
/**
* Create random primitive statement
*
* @param tc a {@link org.evosuite.testcase.TestCase} object.
* @param clazz a {@link java.lang.reflect.Type} object.
* @param position an integer.
* @return a {@link org.evosuite.testcase.statements.PrimitiveStatement} object.
*/
public static PrimitiveStatement> getRandomStatement(TestCase tc,
GenericClass clazz, int position) {
PrimitiveStatement> statement = getPrimitiveStatement(tc, clazz);
statement.randomize();
return statement;
}
/**
* {@inheritDoc}
*/
@Override
public Statement copy(TestCase newTestCase, int offset) {
@SuppressWarnings("unchecked")
PrimitiveStatement clone = (PrimitiveStatement) getPrimitiveStatement(newTestCase,
retval.getGenericClass());
clone.setValue(value);
// clone.assertions = copyAssertions(newTestCase, offset);
return clone;
}
/**
* {@inheritDoc}
*/
@Override
public Throwable execute(Scope scope, PrintStream out)
throws InvocationTargetException, IllegalArgumentException,
IllegalAccessException, InstantiationException {
Throwable exceptionThrown = null;
try {
retval.setObject(scope, value);
} catch (CodeUnderTestException e) {
exceptionThrown = e;
}
return exceptionThrown;
}
/**
* {@inheritDoc}
*/
@Override
public Set getVariableReferences() {
Set references = new LinkedHashSet<>();
references.add(retval);
return references;
}
/**
* {@inheritDoc}
*/
@Override
public void replace(VariableReference var1, VariableReference var2) {
if (retval.equals(var1)) {
retval = var2;
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object s) {
if (this == s)
return true;
if (s == null)
return false;
if (getClass() != s.getClass())
return false;
PrimitiveStatement> ps = (PrimitiveStatement>) s;
return (retval.equals(ps.retval) && value.equals(ps.value));
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
final int prime = 21;
int result = 1;
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
/**
* Add a random delta to the value
*/
public abstract void delta();
/**
* Reset value to default value 0
*/
public abstract void zero();
/**
* {@inheritDoc}
*/
@Override
public List getUniqueVariableReferences() {
return new ArrayList(getVariableReferences());
}
/**
* {@inheritDoc}
*/
@Override
public boolean same(Statement s) {
if (this == s)
return true;
if (s == null)
return false;
if (getClass() != s.getClass())
return false;
PrimitiveStatement> ps = (PrimitiveStatement>) s;
boolean sameValue = false;
if (value == null) {
sameValue = (ps.value == null);
} else {
sameValue = value.equals(ps.value);
}
assert retval != null && ps.retval != null;
return (sameValue && retval.same(ps.retval));
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return getCode();
}
@SuppressWarnings("unused")
private void mutateTransformedBoolean(TestCase test) {
if (Randomness.nextDouble() > Properties.RANDOM_PERTURBATION) {
boolean done = false;
for (Statement s : test) {
if (s instanceof MethodStatement) {
MethodStatement ms = (MethodStatement) s;
List parameters = ms.getParameterReferences();
int index = parameters.indexOf(retval);
if (index >= 0) {
Method m = ms.getMethod().getMethod();
org.objectweb.asm.Type[] types = org.objectweb.asm.Type.getArgumentTypes(m);
if (types[index].equals(org.objectweb.asm.Type.BOOLEAN_TYPE)) {
logger.warn("MUTATING");
((IntPrimitiveStatement) this).negate();
done = true;
break;
}
}
}
}
if (!done)
randomize();
} else {
randomize();
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean mutate(TestCase test, TestFactory factory) {
if (!hasMoreThanOneValue())
return false;
T oldVal = value;
while (value == oldVal && value != null) {
if (Randomness.nextDouble() <= Properties.RANDOM_PERTURBATION) {
// When using TT, then an integer may represent a boolean,
// and we would lose "negation" as a mutation
if (Properties.TT && getClass().equals(IntPrimitiveStatement.class)) {
if (Randomness.nextDouble() <= Properties.RANDOM_PERTURBATION) {
// mutateTransformedBoolean(test);
((IntPrimitiveStatement) this).negate();
} else
randomize();
} else {
randomize();
}
} else
delta();
}
return true;
}
/**
* Set to a random value
*/
public abstract void randomize();
/**
* {@inheritDoc}
*/
@Override
public GenericAccessibleObject> getAccessibleObject() {
return null;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isAssignmentStatement() {
return false;
}
/**
* {@inheritDoc}
*/
@Override
public void changeClassLoader(ClassLoader loader) {
super.changeClassLoader(loader);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy