All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.evosuite.testcase.variable.VariableReferenceImpl Maven / Gradle / Ivy

/**
 * 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.variable;

import java.lang.reflect.Type;
import java.util.Map;

import org.evosuite.testcase.statements.Statement;
import org.evosuite.testcase.TestCase;
import org.evosuite.testcase.execution.CodeUnderTestException;
import org.evosuite.testcase.execution.Scope;
import org.evosuite.utils.generic.GenericClass;
import org.evosuite.utils.PassiveChangeListener;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class VariableReferenceImpl implements VariableReference {

	private static final long serialVersionUID = -2621368452798208805L;

	private int distance = 0;

	private static final Logger logger = LoggerFactory.getLogger(VariableReferenceImpl.class);

	/**
	 * Type (class) of the variable
	 */
	protected GenericClass type;

	/**
	 * The testCase in which this VariableReference is valid
	 */
	protected TestCase testCase;
	protected final PassiveChangeListener changeListener = new PassiveChangeListener();
	protected Integer stPosition;
	private String originalCode;

	/**
	 * Constructor
	 * 
	 * @param testCase
	 *            The TestCase which defines the statement which defines this
	 * @param type
	 *            The type (class) of the variable
	 */
	public VariableReferenceImpl(TestCase testCase, GenericClass type) {
		this.testCase = testCase;
		this.type = type;
		testCase.addListener(changeListener);
	}

	/**
	 * 

* Constructor for VariableReferenceImpl. *

* * @param testCase * a {@link org.evosuite.testcase.TestCase} object. * @param type * a {@link java.lang.reflect.Type} object. */ public VariableReferenceImpl(TestCase testCase, Type type) { this(testCase, new GenericClass(type)); } /** * {@inheritDoc} * * The position of the statement, defining this VariableReference, in the * testcase. * * TODO: Notify change listener also when return value changes * */ @Override public synchronized int getStPosition() { if (stPosition == null || changeListener.hasChanged()) { stPosition = null; for (int i = 0; i < testCase.size(); i++) { Statement stmt = testCase.getStatement(i); if (stmt.getReturnValue().equals(this)) { stPosition = i; break; } } if (stPosition == null) { String msg = "Bloody annoying bug \n"; msg += "Test case has " + testCase.size() + " function calls \n"; for (int i = 0; i < testCase.size(); i++) { msg += testCase.getStatement(i).getCode(null) + "\n"; } msg += "failed to find type " + this.type.getTypeName() + "\n"; throw new AssertionError( msg + "A VariableReferences position is only defined if the VariableReference is defined by a statement in the testCase"); } } else { int position = stPosition; //somehow this could be null, leading to NPE. Synchronization issue? stPosition = null; stPosition = getStPosition(); assert (stPosition == position); } return stPosition; } @Override public TestCase getTestCase() { return testCase; } /** * {@inheritDoc} * * Create a copy of the current variable */ @Override public VariableReference clone() { throw new UnsupportedOperationException( "This method SHOULD not be used, as only the original reference is keeped up to date"); /*VariableReference copy = new VariableReference(type, statement); if (array != null) { copy.array = array.clone(); copy.array_index = array_index; copy.array_length = array_length; } return copy;*/ } /** * {@inheritDoc} * * Create a copy of the current variable */ @Override public VariableReference clone(TestCase newTestCase) { return newTestCase.getStatement(getStPosition()).getReturnValue(); } /** {@inheritDoc} */ @Override public VariableReference copy(TestCase newTestCase, int offset) { return newTestCase.getStatement(getStPosition() + offset).getReturnValue(); } /** * {@inheritDoc} * * Return simple class name */ @Override public String getSimpleClassName() { // TODO: Workaround for bug in commons lang if (type.isPrimitive() || (type.isArray() && new GenericClass(type.getComponentType()).isPrimitive())) return type.getRawClass().getSimpleName(); return type.getSimpleName(); } /** * {@inheritDoc} * * Return class name */ @Override public String getClassName() { return type.getClassName(); } /** {@inheritDoc} */ @Override public String getComponentName() { return type.getComponentName(); } /** {@inheritDoc} */ @Override public Type getComponentType() { return type.getComponentType(); } /** * {@inheritDoc} * * Return true if variable is an enumeration */ @Override public boolean isEnum() { return type.isEnum(); } /* (non-Javadoc) * @see org.evosuite.testcase.VariableReference#isArray() */ @Override public boolean isArray() { return type.isArray(); } @Override public boolean isArrayIndex() { return false; } @Override public boolean isFieldReference() { return false; } /** * {@inheritDoc} * * Return true if variable is a primitive type */ @Override public boolean isPrimitive() { return type.isPrimitive(); } /** * {@inheritDoc} * * Return true if variable is void */ @Override public boolean isVoid() { return type.isVoid(); } /** * {@inheritDoc} * * Return true if variable is a string */ @Override public boolean isString() { return type.isString(); } /** * {@inheritDoc} * * Return true if type of variable is a primitive wrapper */ @Override public boolean isWrapperType() { return type.isWrapperType(); } @Override public boolean isAccessible() { return true; } /** * {@inheritDoc} * * Return true if other type can be assigned to this variable */ @Override public boolean isAssignableFrom(Type other) { return type.isAssignableFrom(other); } /** * {@inheritDoc} * * Return true if this variable can by assigned to a variable of other type */ @Override public boolean isAssignableTo(Type other) { //if (type.hasWildcardTypes()) { // GenericClass rawClass = new GenericClass(other); // logger.warn("Getting raw assignables for: "+other +" and "+type); // logger.warn(testCase.toCode()); // TypeUtils.isAssignable(other, getType()); // return GenericClass.isAssignable(rawClass.getRawClass(), type.getRawClass()); //} else { return type.isAssignableTo(other); //} } /** * {@inheritDoc} * * Return true if other type can be assigned to this variable */ @Override public boolean isAssignableFrom(VariableReference other) { return type.isAssignableFrom(other.getType()); } /** * {@inheritDoc} * * Return true if this variable can by assigned to a variable of other type */ @Override public boolean isAssignableTo(VariableReference other) { return type.isAssignableTo(other.getType()); } /** * {@inheritDoc} * * Return type of this variable */ @Override public Type getType() { return type.getType(); } /** * {@inheritDoc} * * Set type of this variable */ @Override public void setType(Type type) { this.type = new GenericClass(type); } /** * {@inheritDoc} * * Return raw class of this variable */ @Override public Class getVariableClass() { return type.getRawClass(); } /** * {@inheritDoc} * * Return raw class of this variable's component */ @Override public Class getComponentClass() { return type.getRawClass().getComponentType(); } /** * {@inheritDoc} * * Return the actual object represented by this variable for a given scope */ @Override public Object getObject(Scope scope) throws CodeUnderTestException { return scope.getObject(this); } /** {@inheritDoc} */ @Override public String getOriginalCode() { return originalCode; } /** * {@inheritDoc} * * Set the actual object represented by this variable in a given scope */ @Override public void setObject(Scope scope, Object value) throws CodeUnderTestException { scope.setObject(this, value); } /** {@inheritDoc} */ @Override public void setOriginalCode(String code) { if (originalCode != null) { logger.debug("Original code already set to '{}', skip setting it to '{}'.", originalCode, code); return; } if (code != null) { this.originalCode = code.trim(); } } /** * {@inheritDoc} * * Return string representation of the variable */ @Override public String toString() { if (originalCode != null) { return originalCode; } return "VariableReference: Statement " + getStPosition() + ", type " + type.getTypeName(); } /** * {@inheritDoc} * * Return name for source code representation */ @Override public String getName() { return "var" + getStPosition(); } /** {@inheritDoc} */ @Override public void loadBytecode(GeneratorAdapter mg, Map locals) { logger.debug("Loading variable in bytecode: " + getStPosition()); if (getStPosition() < 0) { mg.visitInsn(Opcodes.ACONST_NULL); } else mg.loadLocal(locals.get(getStPosition()), org.objectweb.asm.Type.getType(type.getRawClass())); } /** {@inheritDoc} */ @Override public void storeBytecode(GeneratorAdapter mg, Map locals) { logger.debug("Storing variable in bytecode: " + getStPosition() + " of type " + org.objectweb.asm.Type.getType(type.getRawClass())); if (!locals.containsKey(getStPosition())) locals.put(getStPosition(), mg.newLocal(org.objectweb.asm.Type.getType(type.getRawClass()))); mg.storeLocal(locals.get(getStPosition()), org.objectweb.asm.Type.getType(type.getRawClass())); } /** {@inheritDoc} */ @Override public Object getDefaultValue() { if (isVoid()) return null; else if (type.isString()) return ""; else if (isPrimitive()) { if (type.getRawClass().equals(float.class)) return 0.0F; else if (type.getRawClass().equals(long.class)) return 0L; else if (type.getRawClass().equals(boolean.class)) return false; else return 0; } else return null; } /** {@inheritDoc} */ @Override public String getDefaultValueString() { if (isVoid()) return ""; else if (type.isString()) return "\"\""; else if (isPrimitive()) { if (type.getRawClass().equals(float.class)) return "0.0F"; else if (type.getRawClass().equals(long.class)) return "0L"; else if (type.getRawClass().equals(boolean.class)) return "false"; else return "0"; } else return "null"; } /* * (non-Javadoc) * * @see java.lang.Comparable#compareTo(java.lang.Object) */ /** {@inheritDoc} */ @Override public int compareTo(VariableReference other) { return getStPosition() - other.getStPosition(); } /** {@inheritDoc} */ @Override public boolean same(VariableReference r) { if (r == null) return false; if (this.getStPosition() != r.getStPosition()) return false; if (this.type.equals(r.getGenericClass())) return true; return false; } /** {@inheritDoc} */ @Override public GenericClass getGenericClass() { return type; } /* (non-Javadoc) * @see org.evosuite.testcase.VariableReference#getAdditionalVariableReference() */ /** {@inheritDoc} */ @Override public VariableReference getAdditionalVariableReference() { return null; } /* (non-Javadoc) * @see org.evosuite.testcase.VariableReference#setAdditionalVariableReference(org.evosuite.testcase.VariableReference) */ /** {@inheritDoc} */ @Override public void setAdditionalVariableReference(VariableReference var) { // Do nothing by default } /* (non-Javadoc) * @see org.evosuite.testcase.VariableReference#replaceAdditionalVariableReference(org.evosuite.testcase.VariableReference, org.evosuite.testcase.VariableReference) */ /** {@inheritDoc} */ @Override public void replaceAdditionalVariableReference(VariableReference var1, VariableReference var2) { // no op } /* (non-Javadoc) * @see org.evosuite.testcase.VariableReference#getDistance() */ /** {@inheritDoc} */ @Override public int getDistance() { return distance; } /* (non-Javadoc) * @see org.evosuite.testcase.VariableReference#setDistance(int) */ /** {@inheritDoc} */ @Override public void setDistance(int distance) { this.distance = distance; } /* (non-Javadoc) * @see org.evosuite.testcase.VariableReference#changeClassLoader(java.lang.ClassLoader) */ /** {@inheritDoc} */ @Override public void changeClassLoader(ClassLoader loader) { type.changeClassLoader(loader); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy