/**
*
*/
package soottocfg.cfg.expression;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import soottocfg.cfg.Node;
import soottocfg.cfg.SourceLocation;
import soottocfg.cfg.expression.BinaryExpression.BinaryOperator;
import soottocfg.cfg.expression.literal.BooleanLiteral;
import soottocfg.cfg.expression.literal.IntegerLiteral;
import soottocfg.cfg.type.BoolType;
import soottocfg.cfg.type.IntType;
import soottocfg.cfg.type.Type;
import soottocfg.cfg.variable.Variable;
import soottocfg.soot.util.SootTranslationHelpers;
/**
* @author schaef
*
*/
public abstract class Expression implements Node, Serializable {
/**
*
*/
private static final long serialVersionUID = 6933938841592139875L;
public abstract Set<IdentifierExpression> getUseIdentifierExpressions();
public Set<Variable> getUseVariables() {
Set<Variable> res = new HashSet<Variable>();
for (IdentifierExpression id : this.getUseIdentifierExpressions()) {
res.add(id.getVariable());
}
return res;
}
private final SourceLocation sourceLocation;
public Expression(SourceLocation loc) {
this.sourceLocation = loc;
}
public SourceLocation getSourceLocation() {
return this.sourceLocation;
}
public abstract Type getType();
/**
* TODO: this one should be replaced by something that is easier to remove
* when restoring boolean types.
*
* @return
*/
public Expression castToBoolIfNecessary() {
if (this.getType() == IntType.instance()) {
return new IteExpression(this.sourceLocation, new BinaryExpression(this.sourceLocation, BinaryOperator.Eq, this, IntegerLiteral.zero()),
BooleanLiteral.falseLiteral(), BooleanLiteral.trueLiteral());
} else if (this.getType() == BoolType.instance()) {
return this;
} else {
throw new RuntimeException("Cannot cast " + this + " of type" + this.getType() + " to Boolean.");
}
}
/**
* Returns true, if this can be assigned to other. That is, if either
* the types match or this is a sub-type of other.
* @param other
* @return true if this is sub- or equal-type to other.
*/
public boolean canBeAssignedTo(Expression other) {
if (other.getType().getClass() != this.getType().getClass()
&& !SootTranslationHelpers.v().getMemoryModel().isNullReference(this)) {
return false;
}
return true;
}
public boolean canBeAssignedToType(Type t) {
if (t.getClass() != this.getType().getClass()) {
return false;
}
return true;
}
public abstract Expression deepCopy();
/**
* Substitute variables in subs and return
* a clone of the original expression
* @param subs
* @return
*/
public abstract Expression substitute(Map<Variable, Variable> subs);
/**
* Substitute variables with the expressions in subs and return
* a clone of the original expression
* @param subs
* @return
*/
public abstract Expression substituteVarWithExpression(Map<Variable, Expression> subs);
}