org.evosuite.coverage.dataflow.DefUse 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.coverage.dataflow;
import org.evosuite.graphs.cfg.BytecodeInstruction;
import org.objectweb.asm.Opcodes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Abstract superclass for all Definitions and Uses
*
* @author Andre Mis
*/
public class DefUse extends BytecodeInstruction {
private static final long serialVersionUID = -2643584238269671760L;
private final static Logger logger = LoggerFactory.getLogger(DefUse.class);
protected int defuseId;
protected int defId;
protected int useId;
protected boolean isParameterUse;
protected boolean isFieldMethodCall;
protected boolean isFieldMethodCallDefinition;
protected boolean isFieldMethodCallUse;
// We store this information locally to avoid that toString tries to access
// the CFG, which would make the DefUse node dependent on the current state
// of EvoSuite
protected boolean isInStaticMethod;
protected String varName;
/**
*
* Constructor for DefUse.
*
*
* @param wrap
* a {@link org.evosuite.graphs.cfg.BytecodeInstruction} object.
* @param defuseId
* a int.
* @param defId
* a int.
* @param useId
* a int.
* @param isParameterUse
* a boolean.
*/
protected DefUse(BytecodeInstruction wrap) {
super(wrap);
if (!DefUsePool.isKnown(wrap))
throw new IllegalArgumentException(
"only instructions known by the DefUsePool are accepted");
this.defuseId = DefUsePool.getRegisteredDefUseId(wrap);
if (defuseId < 0)
throw new IllegalArgumentException("expect defUseId to be positive");
this.defId = DefUsePool.getRegisteredDefId(wrap);
this.useId = DefUsePool.getRegisteredUseId(wrap);
if (defId < 0 && useId < 0)
throw new IllegalArgumentException("expect either defId or useId to be set");
this.isParameterUse = DefUsePool.isKnownAsParameterUse(wrap);
this.isFieldMethodCall = DefUsePool.isKnownAsFieldMethodCall(wrap);
if (this.isFieldMethodCall) {
if (DefUsePool.isKnownAsDefinition(wrap))
isFieldMethodCallDefinition = true;
if (DefUsePool.isKnownAsUse(wrap))
isFieldMethodCallUse = true;
if (!(isFieldMethodCallDefinition || isFieldMethodCallUse))
throw new IllegalStateException(
"field method calls only accepted once they got categorized");
}
this.isInStaticMethod = getRawCFG().isStaticMethod();
this.varName = super.getVariableName();
if (this.varName == null)
throw new IllegalStateException(
"expect defUses to have non-null variable name. Instruction: "+wrap+","+wrap.getASMNode().getPrevious()+", method: "+wrap.getClassName()+"."+wrap.getMethodName());
}
@Override
public boolean isFieldMethodCallDefinition() {
return isFieldMethodCallDefinition;
}
@Override
public boolean isFieldMethodCallUse() {
return isFieldMethodCallUse;
}
/**
* Determines whether the given BytecodeInstruction constitutes a Definition
* that can potentially become an active Definition for this DefUse
*
* in the sense that if control flow passes through the instruction of the
* given Definition that Definition becomes active for this DefUse's
* variable
*
* This is the case if the given Definition defines the same variable as
* this DefUse So a Definition canBecomeActive for itself
*
* @param instruction
* a {@link org.evosuite.graphs.cfg.BytecodeInstruction} object.
* @return a boolean.
*/
public boolean canBecomeActiveDefinition(BytecodeInstruction instruction) {
if (!instruction.isDefinition())
return false;
// Definition otherDef = DefUseFactory.makeDefinition(instruction);
return sharesVariableWith(instruction);
}
/**
* Determines whether the given DefUse reads or writes the same variable as
* this DefUse
*
* @param du
* a {@link org.evosuite.coverage.dataflow.DefUse} object.
* @return a boolean.
*/
public boolean sharesVariableWith(DefUse du) {
return varName.equals(du.varName);
}
/**
*
* sharesVariableWith
*
*
* @param instruction
* a {@link org.evosuite.graphs.cfg.BytecodeInstruction} object.
* @return a boolean.
*/
public boolean sharesVariableWith(BytecodeInstruction instruction) {
if (!instruction.isDefUse())
return false;
return varName.equals(instruction.getVariableName());
}
/**
*
* getDUVariableType
*
*
* @return a {@link java.lang.String} object.
*/
public String getDUVariableType() {
// TODO remember that in a flag
if (isMethodCallOfField())
return "FieldMethodCall";
if (isFieldDU())
return "Field";
if (isParameterUse())
return "Parameter";
if (isLocalDU())
return "Local";
logger.warn("unexpected state");
return "UNKNOWN";
}
/** {@inheritDoc} */
@Override
public String getVariableName() {
return varName;
}
// getter
/**
*
* getDefUseId
*
*
* @return a int.
*/
public int getDefUseId() {
return defuseId;
}
/**
*
* Getter for the field useId
.
*
*
* @return a int.
*/
public int getUseId() {
return useId;
}
/**
*
* Getter for the field defId
.
*
*
* @return a int.
*/
public int getDefId() {
return defId;
}
/**
*
* isParameterUse
*
*
* @return a boolean.
*/
public boolean isParameterUse() {
return isParameterUse;
}
// inherited from Object
/** {@inheritDoc} */
@Override
public String toString() {
StringBuilder r = new StringBuilder();
if (isDefinition())
r.append("Definition " + getDefId());
if (isUse())
r.append("Use " + getUseId());
r.append(" for ");
if (isStaticDefUse())
r.append("static ");
r.append(getDUVariableType());
r.append("-Variable \"" + getVariableName() + "\"");
r.append(" in " + getMethodName() + "." + getInstructionId());
if (isRootBranchDependent())
r.append(" root-Branch");
else
r.append(" Branch " + getControlDependentBranchId()
+ (getControlDependentBranchExpressionValue() ? "t" : "f"));
r.append(" Line " + getLineNumber());
return r.toString();
}
/**
* Determines whether this is the special ALOAD that pushes 'this' onto the
* stack
*
* In non static methods the variable slot 0 holds the reference to "this".
* Loading this reference is not seen as a Use for defuse purposes. This
* method checks if this is the case
*
* @return a boolean.
*/
@Override
public boolean loadsReferenceToThis() {
if (isInStaticMethod)
return false;
return asmNode.getOpcode() == Opcodes.ALOAD && getLocalVariableSlot() == 0;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + defId;
result = prime * result + defuseId;
result = prime * result + (isFieldMethodCall ? 1231 : 1237);
result = prime * result + (isFieldMethodCallDefinition ? 1231 : 1237);
result = prime * result + (isFieldMethodCallUse ? 1231 : 1237);
result = prime * result + (isParameterUse ? 1231 : 1237);
result = prime * result + useId;
result = prime * result + ((varName == null) ? 0 : varName.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
DefUse other = (DefUse) obj;
if (defId != other.defId)
return false;
if (defuseId != other.defuseId)
return false;
if (isFieldMethodCall != other.isFieldMethodCall)
return false;
if (isFieldMethodCallDefinition != other.isFieldMethodCallDefinition)
return false;
if (isFieldMethodCallUse != other.isFieldMethodCallUse)
return false;
if (isParameterUse != other.isParameterUse)
return false;
if (useId != other.useId)
return false;
if (varName == null) {
if (other.varName != null)
return false;
} else if (!varName.equals(other.varName))
return false;
return true;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy