org.evosuite.testcase.statements.ArrayStatement 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 java.io.PrintStream;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.ArrayUtils;
import org.evosuite.Properties;
import org.evosuite.testcase.variable.ArrayIndex;
import org.evosuite.testcase.variable.ArrayReference;
import org.evosuite.testcase.variable.FieldReference;
import org.evosuite.testcase.TestCase;
import org.evosuite.testcase.TestFactory;
import org.evosuite.testcase.variable.VariableReference;
import org.evosuite.testcase.execution.CodeUnderTestException;
import org.evosuite.testcase.execution.Scope;
import org.evosuite.utils.generic.GenericAccessibleObject;
import org.evosuite.utils.generic.GenericClass;
import org.evosuite.utils.LoggingUtils;
import org.evosuite.utils.Randomness;
/**
* An array statement creates a new array
*
* @author Gordon Fraser
*/
/*
* TODO: The length is currently stored in ArrayReference and the ArrayStatement.
* This is bound to lead to inconsistencies.
*/
public class ArrayStatement extends AbstractStatement {
private static final long serialVersionUID = -2858236370873914156L;
private static int[] createRandom(int dimensions) {
int[] result = new int[dimensions];
for (int idx = 0; idx < dimensions; idx++) {
result[idx] = Randomness.nextInt(Properties.MAX_ARRAY);
}
return result;
}
/**
*
* determineDimensions
*
*
* @param type
* a {@link java.lang.reflect.Type} object.
* @return a int.
*/
public static int determineDimensions(java.lang.reflect.Type type) {
String name = type.toString().replace("class", "").trim();
int count = 0;
for (int i = 0; i < name.length(); i++) {
if (name.charAt(i) == '[') {
count++;
}
}
return count;
}
private int[] lengths;
/**
*
* Constructor for ArrayStatement.
*
*
* @param tc
* a {@link org.evosuite.testcase.TestCase} object.
* @param arrayReference
* a {@link org.evosuite.testcase.variable.ArrayReference} object.
*/
public ArrayStatement(TestCase tc, ArrayReference arrayReference) {
this(tc, arrayReference,
createRandom(determineDimensions(arrayReference.getType())));
}
/**
*
* Constructor for ArrayStatement.
*
*
* @param tc
* a {@link org.evosuite.testcase.TestCase} object.
* @param arrayReference
* a {@link org.evosuite.testcase.variable.ArrayReference} object.
* @param length
* an array of int.
*/
public ArrayStatement(TestCase tc, ArrayReference arrayReference, int[] length) {
super(tc, arrayReference);
setLengths(length);
arrayReference.setLengths(lengths);
}
/**
*
* Constructor for ArrayStatement.
*
*
* @param tc
* a {@link org.evosuite.testcase.TestCase} object.
* @param type
* a {@link java.lang.reflect.Type} object.
*/
public ArrayStatement(TestCase tc, java.lang.reflect.Type type) {
this(tc, type, createRandom(determineDimensions(type)));
}
/**
*
* Constructor for ArrayStatement.
*
*
* @param tc
* a {@link org.evosuite.testcase.TestCase} object.
* @param type
* a {@link java.lang.reflect.Type} object.
* @param length
* a int.
*/
public ArrayStatement(TestCase tc, java.lang.reflect.Type type, int length) {
this(tc, type, new int[] { length });
}
/**
*
* Constructor for ArrayStatement.
*
*
* @param tc
* a {@link org.evosuite.testcase.TestCase} object.
* @param type
* a {@link java.lang.reflect.Type} object.
* @param length
* an array of int.
*/
public ArrayStatement(TestCase tc, java.lang.reflect.Type type, int[] length) {
this(tc, new ArrayReference(tc, new GenericClass(type), length), length);
}
/** {@inheritDoc} */
@Override
public Statement copy(TestCase newTestCase, int offset) {
ArrayStatement copy = new ArrayStatement(newTestCase, retval.getType(), lengths);
// copy.assertions = copyAssertions(newTestCase, offset);
return copy;
}
/** {@inheritDoc} */
@Override
public boolean equals(Object s) {
if (this == s)
return true;
if (s == null)
return false;
if (getClass() != s.getClass())
return false;
ArrayStatement as = (ArrayStatement) s;
if (!Arrays.equals(lengths, as.lengths))
return false;
if (retval.equals(as.retval)) {
return true;
} else {
return false;
}
// if (!Arrays.equals(variables, other.variables))
// return false;
}
/** {@inheritDoc} */
@Override
public Throwable execute(Scope scope, PrintStream out)
throws InvocationTargetException, IllegalArgumentException,
IllegalAccessException, InstantiationException {
Throwable exceptionThrown = null;
// Add array variable to pool
try {
Class> componentType = retval.getComponentClass();
while (componentType.isArray())
componentType = componentType.getComponentType();
retval.setObject(scope, Array.newInstance(componentType, lengths));
} catch (CodeUnderTestException e) {
exceptionThrown = e.getCause();
}
return exceptionThrown;
}
/** {@inheritDoc} */
@Override
public GenericAccessibleObject> getAccessibleObject() {
return null;
}
/**
*
* Getter for the field lengths
.
*
*
* @return an array of int.
*/
public List getLengths() {
return Arrays.asList(ArrayUtils.toObject(lengths));
}
/*
* (non-Javadoc)
*
* @see
* org.evosuite.testcase.Statement#getUniqueVariableReferences()
*/
/** {@inheritDoc} */
@Override
public List getUniqueVariableReferences() {
return new ArrayList(getVariableReferences());
}
/** {@inheritDoc} */
@Override
public Set getVariableReferences() {
Set references = new LinkedHashSet();
references.add(retval);
return references;
}
/** {@inheritDoc} */
@Override
public int hashCode() {
final int prime = 31;
int result = retval.hashCode();
result = prime * result + Arrays.hashCode(lengths);
return result;
}
/** {@inheritDoc} */
@Override
public boolean isAssignmentStatement() {
return false;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.StatementInterface#isValid()
*/
/** {@inheritDoc} */
@Override
public boolean isValid() {
int maxAssignment = 0;
for (Statement statement : this.tc) {
for (VariableReference var : statement.getVariableReferences()) {
if (var.getAdditionalVariableReference() == this.retval) {
VariableReference currentVar = var;
while (currentVar instanceof FieldReference) {
currentVar = ((FieldReference) currentVar).getSource();
}
ArrayIndex index = (ArrayIndex) currentVar;
maxAssignment = Math.max(maxAssignment, index.getArrayIndex());
}
}
}
if (maxAssignment > lengths[0]) {
logger.warn("Max assignment = "+maxAssignment+", length = "+lengths[0]);
return false;
}
return super.isValid();
}
/* (non-Javadoc)
* @see org.evosuite.testcase.AbstractStatement#mutate(org.evosuite.testcase.TestCase, org.evosuite.testcase.AbstractTestFactory)
*/
/** {@inheritDoc} */
@Override
public boolean mutate(TestCase test, TestFactory factory) {
int maxAssignment = 0;
for (Statement statement : test) {
for (VariableReference var : statement.getVariableReferences()) {
if (var.getAdditionalVariableReference() == this.retval) {
VariableReference currentVar = var;
while (currentVar instanceof FieldReference) {
currentVar = ((FieldReference) currentVar).getSource();
}
if (!(currentVar instanceof ArrayIndex)) {
LoggingUtils.getEvoLogger().error("Found assignment to array without ArrayIndex:");
LoggingUtils.getEvoLogger().error(test.toCode());
LoggingUtils.getEvoLogger().error(statement.getPosition() + ", "
+ statement.getCode());
}
ArrayIndex index = (ArrayIndex) currentVar;
maxAssignment = Math.max(maxAssignment, index.getArrayIndex());
}
}
}
int dim = 0;
if (lengths.length > 1) {
dim = Randomness.nextInt(lengths.length - 1);
}
int newLength = lengths[dim];
while (newLength == lengths[dim]) {
if (Randomness.nextDouble() <= Properties.RANDOM_PERTURBATION) {
newLength = Randomness.nextInt(maxAssignment,
Math.max(maxAssignment + 1,
Properties.MAX_ARRAY)) + 1;
} else {
int max = Math.min(Math.abs(lengths[dim] - maxAssignment - 1),
Properties.MAX_DELTA);
if (max > 0)
newLength = lengths[dim] + Randomness.nextInt(2 * max) - max;
else
newLength = lengths[dim] + Randomness.nextInt(Properties.MAX_DELTA);
}
}
// TODO: Need to make sure this doesn't happen by construction
if (newLength <= 0)
newLength = 1;
lengths[dim] = newLength;
((ArrayReference) retval).setLengths(lengths);
return true;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.StatementInterface#replace(org.evosuite.testcase.VariableReference, org.evosuite.testcase.VariableReference)
*/
/** {@inheritDoc} */
@Override
public void replace(VariableReference var1, VariableReference var2) {
}
/** {@inheritDoc} */
@Override
public boolean same(Statement s) {
if (this == s)
return true;
if (s == null)
return false;
if (getClass() != s.getClass())
return false;
ArrayStatement as = (ArrayStatement) s;
if (!Arrays.equals(lengths, as.lengths))
return false;
if (retval.same(as.retval)) {
return true;
} else {
return false;
}
}
/**
*
* Setter for the field lengths
.
*
*
* @param lengths
* an array of int.
*/
public void setLengths(int[] lengths) {
this.lengths = new int[lengths.length];
for (int i = 0; i < lengths.length; i++) {
this.lengths[i] = lengths[i];
}
((ArrayReference) retval).setLengths(lengths);
}
/**
*
* setSize
*
*
* @param size
* a int.
*/
public void setSize(int size) {
/// assert lengths.length == 1;
this.lengths[0] = size;
((ArrayReference) retval).setArrayLength(size);
}
/**
*
* size
*
*
* @return a int.
*/
public int size() {
// assert lengths.length == 1;
return lengths[0];
}
public ArrayReference getArrayReference() {
return (ArrayReference) getReturnValue();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy