Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.evosuite.symbolic.expr.ExpressionEvaluator 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.symbolic.expr;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.StringTokenizer;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
import org.evosuite.symbolic.expr.bv.IntegerBinaryExpression;
import org.evosuite.symbolic.expr.bv.IntegerComparison;
import org.evosuite.symbolic.expr.bv.IntegerConstant;
import org.evosuite.symbolic.expr.bv.IntegerUnaryExpression;
import org.evosuite.symbolic.expr.bv.IntegerVariable;
import org.evosuite.symbolic.expr.bv.RealComparison;
import org.evosuite.symbolic.expr.bv.RealToIntegerCast;
import org.evosuite.symbolic.expr.bv.RealUnaryToIntegerExpression;
import org.evosuite.symbolic.expr.bv.StringBinaryComparison;
import org.evosuite.symbolic.expr.bv.StringBinaryToIntegerExpression;
import org.evosuite.symbolic.expr.bv.StringMultipleComparison;
import org.evosuite.symbolic.expr.bv.StringMultipleToIntegerExpression;
import org.evosuite.symbolic.expr.bv.StringToIntegerCast;
import org.evosuite.symbolic.expr.bv.StringUnaryToIntegerExpression;
import org.evosuite.symbolic.expr.fp.IntegerToRealCast;
import org.evosuite.symbolic.expr.fp.RealBinaryExpression;
import org.evosuite.symbolic.expr.fp.RealConstant;
import org.evosuite.symbolic.expr.fp.RealUnaryExpression;
import org.evosuite.symbolic.expr.fp.RealVariable;
import org.evosuite.symbolic.expr.reader.StringReaderExpr;
import org.evosuite.symbolic.expr.ref.GetFieldExpression;
import org.evosuite.symbolic.expr.ref.ReferenceConstant;
import org.evosuite.symbolic.expr.ref.ReferenceVariable;
import org.evosuite.symbolic.expr.str.IntegerToStringCast;
import org.evosuite.symbolic.expr.str.RealToStringCast;
import org.evosuite.symbolic.expr.str.StringBinaryExpression;
import org.evosuite.symbolic.expr.str.StringConstant;
import org.evosuite.symbolic.expr.str.StringMultipleExpression;
import org.evosuite.symbolic.expr.str.StringUnaryExpression;
import org.evosuite.symbolic.expr.str.StringVariable;
import org.evosuite.symbolic.expr.token.HasMoreTokensExpr;
import org.evosuite.symbolic.expr.token.NewTokenizerExpr;
import org.evosuite.symbolic.expr.token.NextTokenizerExpr;
import org.evosuite.symbolic.expr.token.StringNextTokenExpr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* returns the concrete evaluation for a given expression.
*
* @author galeotti
*
*/
public class ExpressionEvaluator implements ExpressionVisitor {
private static final long TRUE_VALUE = 1L;
private static final long FALSE_VALUE = 0L;
protected static final Logger log = LoggerFactory.getLogger(ExpressionEvaluator.class);
@Override
public Object visit(IntegerBinaryExpression n, Void arg) {
Long leftLong = (Long) n.getLeftOperand().accept(this, null);
Long rightLong = (Long) n.getRightOperand().accept(this, null);
long leftVal = leftLong.longValue();
long rightVal = rightLong.longValue();
Operator op = n.getOperator();
switch (op) {
case SHL:
return leftVal << rightVal;
case SHR:
return leftVal >> rightVal;
case USHR:
return leftVal >>> rightVal;
case AND:
case IAND:
return leftVal & rightVal;
case OR:
case IOR:
return leftVal | rightVal;
case XOR:
case IXOR:
return leftVal ^ rightVal;
case DIV:
return leftVal / rightVal;
case MUL:
return leftVal * rightVal;
case MINUS:
return leftVal - rightVal;
case PLUS:
return leftVal + rightVal;
case REM:
return leftVal % rightVal;
case MAX:
return Math.max(leftVal, rightVal);
case MIN:
return Math.min(leftVal, rightVal);
default:
log.warn("IntegerBinaryExpression: unimplemented operator: " + op);
return null;
}
}
@Override
public Object visit(IntegerComparison n, Void arg) {
log.warn("IntegerComparison.execute() invokation");
throw new IllegalStateException("This method should not be invoked");
}
@Override
public Object visit(IntegerConstant n, Void arg) {
return n.getConcreteValue();
}
@Override
public Object visit(IntegerUnaryExpression n, Void arg) {
Long longObject = (Long) n.getOperand().accept(this, null);
long leftVal = longObject.longValue();
Operator op = n.getOperator();
switch (op) {
case NEG:
return -leftVal;
case ABS:
return Math.abs(leftVal);
case GETNUMERICVALUE:
return (long) Character.getNumericValue((char) leftVal);
case ISLETTER:
return Character.isLetter((char) leftVal) ? TRUE_VALUE : FALSE_VALUE;
case ISDIGIT:
return Character.isDigit((char) leftVal) ? TRUE_VALUE : FALSE_VALUE;
default:
log.warn("IntegerUnaryExpression: unimplemented operator: " + op);
return null;
}
}
@Override
public Object visit(IntegerVariable n, Void arg) {
return n.getConcreteValue();
}
@Override
public Object visit(RealComparison n, Void arg) {
log.warn("RealComparison.execute() invokation");
throw new IllegalStateException("This method should not be invoked");
}
@Override
public Object visit(RealToIntegerCast n, Void arg) {
Double doubleObject = (Double) n.getArgument().accept(this, null);
return doubleObject.longValue();
}
@Override
public Object visit(RealUnaryToIntegerExpression n, Void arg) {
Double doubleObject = (Double) n.getOperand().accept(this, null);
double leftVal = doubleObject.doubleValue();
Operator op = n.getOperator();
switch (op) {
case ROUND:
return Math.round(leftVal);
case GETEXPONENT:
return (long) Math.getExponent(leftVal);
default:
log.warn("IntegerUnaryExpression: unimplemented operator: " + op);
return null;
}
}
@Override
public Object visit(StringBinaryComparison n, Void arg) {
String first = (String) n.getLeftOperand().accept(this, null);
String second = (String) n.getRightOperand().accept(this, null);
Operator op = n.getOperator();
switch (op) {
case STARTSWITH:
return first.startsWith(second) ? TRUE_VALUE : FALSE_VALUE;
case EQUALSIGNORECASE:
return first.equalsIgnoreCase(second) ? TRUE_VALUE : FALSE_VALUE;
case EQUALS:
return first.equals(second) ? TRUE_VALUE : FALSE_VALUE;
case ENDSWITH:
return first.endsWith(second) ? TRUE_VALUE : FALSE_VALUE;
case CONTAINS:
return first.contains(second) ? TRUE_VALUE : FALSE_VALUE;
case PATTERNMATCHES:
return second.matches(first) ? TRUE_VALUE : FALSE_VALUE;
case APACHE_ORO_PATTERN_MATCHES: {
Perl5Matcher matcher = new Perl5Matcher();
Perl5Compiler compiler = new Perl5Compiler();
Pattern pattern;
try {
pattern = compiler.compile(first);
} catch (MalformedPatternException e) {
throw new RuntimeException(e);
}
return matcher.matches(second, pattern) ? TRUE_VALUE : FALSE_VALUE;
}
default:
log.warn("StringComparison: unimplemented operator!" + op);
return null;
}
}
@Override
public Object visit(StringBinaryToIntegerExpression n, Void arg) {
String first = (String) n.getLeftOperand().accept(this, null);
Object second = (Object) n.getRightOperand().accept(this, null);
Operator op = n.getOperator();
switch (op) {
// returns Int
case COMPARETO: {
String string = (String) second;
return (long) first.compareTo(string);
}
case COMPARETOIGNORECASE: {
String string = (String) second;
return (long) first.compareToIgnoreCase(string);
}
case INDEXOFC: {
long ch = (Long) second;
return (long) first.indexOf((char) ch);
}
case INDEXOFS: {
String string = (String) second;
return (long) first.indexOf(string);
}
case LASTINDEXOFC: {
long ch = (Long) second;
return (long) first.lastIndexOf((char) ch);
}
case LASTINDEXOFS: {
String string = (String) second;
return (long) first.lastIndexOf(string);
}
case CHARAT: {
int indx = ((Long) second).intValue();
return (long) first.charAt(indx);
}
default:
log.warn(
"StringBinaryToIntegerExpression: unimplemented operator! Operator" + op.toString());
return null;
}
}
@Override
public Object visit(StringMultipleComparison n, Void arg) {
String first = (String) n.getLeftOperand().accept(this, null);
String second = (String) n.getRightOperand().accept(this, null);
ArrayList> other_v = n.getOther();
Operator op = n.getOperator();
switch (op) {
case STARTSWITH:
long start = (Long) other_v.get(0).accept(this, null);
return first.startsWith(second, (int) start) ? TRUE_VALUE : FALSE_VALUE;
case REGIONMATCHES:
long frstStart = (Long) other_v.get(0).accept(this, null);
long secStart = (Long) other_v.get(1).accept(this, null);
long length = (Long) other_v.get(2).accept(this, null);
long ignoreCase = (Long) other_v.get(3).accept(this, null);
return first.regionMatches(ignoreCase != 0, (int) frstStart, second, (int) secStart,
(int) length) ? TRUE_VALUE : FALSE_VALUE;
default:
log.warn("StringMultipleComparison: unimplemented operator!");
return null;
}
}
@Override
public Object visit(StringMultipleToIntegerExpression n, Void arg) {
String first = (String) n.getLeftOperand().accept(this, null);
Object second = (Object) n.getRightOperand().accept(this, null);
ArrayList> other_v = n.getOther();
long secLong, thrdLong;
String secStr;
Operator op = n.getOperator();
switch (op) {
// returns int
case INDEXOFCI:
secLong = (Long) second;
thrdLong = (Long) other_v.get(0).accept(this, null);
return (long) first.indexOf((int) secLong, (int) thrdLong);
case INDEXOFSI:
secStr = (String) second;
thrdLong = (Long) other_v.get(0).accept(this, null);
return (long) first.indexOf(secStr, (int) thrdLong);
case LASTINDEXOFCI:
secLong = (Long) second;
thrdLong = (Long) other_v.get(0).accept(this, null);
return (long) first.lastIndexOf((int) secLong, (int) thrdLong);
case LASTINDEXOFSI:
secStr = (String) second;
thrdLong = (Long) other_v.get(0).accept(this, null);
return (long) first.lastIndexOf(secStr, (int) thrdLong);
default:
log.warn("StringMultipleToIntegerExpression: unimplemented operator: " + op);
return null;
}
}
@Override
public Object visit(StringToIntegerCast n, Void arg) {
String str = (String) n.getArgument().accept(this, null);
return Long.parseLong(str);
}
@Override
public Object visit(StringUnaryToIntegerExpression n, Void arg) {
String exOn = (String) n.getOperand().accept(this, null);
Operator op = n.getOperator();
switch (op) {
case LENGTH:
return (long) exOn.length();
case IS_INTEGER: {
try {
Integer.parseInt(exOn);
return TRUE_VALUE;
} catch (NumberFormatException ex) {
return FALSE_VALUE;
}
}
default:
log.warn("StringUnaryExpression: unimplemented operator!");
return null;
}
}
@Override
public Object visit(IntegerToRealCast n, Void arg) {
Long exprVal = (Long) n.getArgument().accept(this, null);
return exprVal.doubleValue();
}
@Override
public Object visit(RealBinaryExpression n, Void arg) {
Double leftDouble = (Double) n.getLeftOperand().accept(this, null);
Double rightDouble = (Double) n.getRightOperand().accept(this, null);
double leftVal = leftDouble.doubleValue();
double rightVal = rightDouble.doubleValue();
Operator op = n.getOperator();
switch (op) {
case DIV:
return leftVal / rightVal;
case MUL:
return leftVal * rightVal;
case MINUS:
return leftVal - rightVal;
case PLUS:
return leftVal + rightVal;
case REM:
return leftVal % rightVal;
case ATAN2:
return Math.atan2(leftVal, rightVal);
case COPYSIGN:
return Math.copySign(leftVal, rightVal);
case HYPOT:
return Math.hypot(leftVal, rightVal);
case IEEEREMAINDER:
return Math.IEEEremainder(leftVal, rightVal);
case MAX:
return Math.max(leftVal, rightVal);
case MIN:
return Math.min(leftVal, rightVal);
case NEXTAFTER:
return Math.nextAfter(leftVal, rightVal);
case POW:
return Math.pow(leftVal, rightVal);
case SCALB:
return Math.scalb(leftVal, (int) rightVal);
default:
log.warn("IntegerBinaryExpression: unimplemented operator: " + op);
return null;
}
}
@Override
public Object visit(RealConstant n, Void arg) {
return n.getConcreteValue();
}
@Override
public Object visit(RealUnaryExpression n, Void arg) {
Double doubleObject = (Double) n.getOperand().accept(this, null);
double doubleVal = doubleObject.doubleValue();
Operator op = n.getOperator();
switch (op) {
case ABS:
return Math.abs(doubleVal);
case ACOS:
return Math.acos(doubleVal);
case ASIN:
return Math.asin(doubleVal);
case ATAN:
return Math.atan(doubleVal);
case CBRT:
return Math.cbrt(doubleVal);
case CEIL:
return Math.ceil(doubleVal);
case COS:
return Math.cos(doubleVal);
case COSH:
return Math.cosh(doubleVal);
case EXP:
return Math.exp(doubleVal);
case EXPM1:
return Math.expm1(doubleVal);
case FLOOR:
return Math.floor(doubleVal);
case LOG:
return Math.log(doubleVal);
case LOG10:
return Math.log10(doubleVal);
case LOG1P:
return Math.log1p(doubleVal);
case NEG:
return -doubleVal;
case NEXTUP:
return Math.nextUp(doubleVal);
case RINT:
return Math.rint(doubleVal);
case SIGNUM:
return Math.signum(doubleVal);
case SIN:
return Math.sin(doubleVal);
case SINH:
return Math.sinh(doubleVal);
case SQRT:
return Math.sqrt(doubleVal);
case TAN:
return Math.tan(doubleVal);
case TANH:
return Math.tanh(doubleVal);
case TODEGREES:
return Math.toDegrees(doubleVal);
case TORADIANS:
return Math.toRadians(doubleVal);
case ULP:
return Math.ulp(doubleVal);
default:
log.warn("RealUnaryExpression: unimplemented operator: " + op);
return null;
}
}
@Override
public Object visit(RealVariable n, Void arg) {
return n.getConcreteValue();
}
@Override
public Object visit(StringReaderExpr n, Void arg) {
String conc_string = (String) n.getString().accept(this, null);
if (n.getReaderPosition() >= conc_string.length()) {
return -TRUE_VALUE;
} else {
return (long) conc_string.charAt(n.getReaderPosition());
}
}
@Override
public Object visit(IntegerToStringCast n, Void arg) {
Long exprVal = (Long) n.getArgument().accept(this, null);
return Long.toString(exprVal);
}
@Override
public Object visit(RealToStringCast n, Void arg) {
Double doubleObject = (Double) n.getArgument().accept(this, null);
return Double.toString(doubleObject);
}
@Override
public Object visit(StringBinaryExpression n, Void arg) {
String first = (String) n.getLeftOperand().accept(this, null);
Object second = (Object) n.getRightOperand().accept(this, null);
Operator op = n.getOperator();
switch (op) {
// returns String
case CONCAT: {
String string = (String) second;
return first.concat(string);
}
case APPEND_BOOLEAN: {
Long sndLong = (Long) second;
boolean booleabValue = sndLong == 0 ? false : true;
return first + booleabValue;
}
case APPEND_CHAR: {
Long sndLong = (Long) second;
char charValue = (char) sndLong.longValue();
return first + charValue;
}
case APPEND_INTEGER: {
Long sndLong = (Long) second;
return first + sndLong;
}
case APPEND_REAL: {
Double sndLong = (Double) second;
return first + sndLong;
}
case APPEND_STRING: {
String string = (String) second;
return first + (string);
}
default:
log.warn("StringBinaryExpression: unimplemented operator! Operator" + op.toString());
return null;
}
}
@Override
public Object visit(StringConstant n, Void arg) {
return n.getConcreteValue();
}
@Override
public Object visit(StringMultipleExpression n, Void arg) {
String first = (String) n.getLeftOperand().accept(this, null);
Object right = (Object) n.getRightOperand().accept(this, null);
ArrayList> other_v = n.getOther();
long secLong, thrdLong;
String secStr, thrdStr;
Operator op = n.getOperator();
switch (op) {
// returns string
case SUBSTRING: {
secLong = (Long) right;
thrdLong = (Long) other_v.get(0).accept(this, null);
return first.substring((int) secLong, (int) thrdLong);
}
case REPLACEC:
secLong = (Long) right;
thrdLong = (Long) other_v.get(0).accept(this, null);
return first.replace((char) secLong, (char) thrdLong);
case REPLACECS:
secStr = (String) right;
thrdStr = (String) other_v.get(0).accept(this, null);
return first.replace(secStr, thrdStr);
case REPLACEALL:
secStr = (String) right;
thrdStr = (String) other_v.get(0).accept(this, null);
return first.replaceAll(secStr, thrdStr);
case REPLACEFIRST:
secStr = (String) right;
thrdStr = (String) other_v.get(0).accept(this, null);
return first.replaceFirst(secStr, thrdStr);
default:
log.warn("StringMultipleExpression: unimplemented operator: " + op);
return null;
}
}
@Override
public Object visit(StringUnaryExpression n, Void arg) {
String exOn = (String) n.getOperand().accept(this, null);
Operator op = n.getOperator();
switch (op) {
case TOLOWERCASE:
return exOn.toLowerCase();
case TOUPPERCASE:
return exOn.toUpperCase();
case TRIM:
return exOn.trim();
default:
log.warn("StringUnaryExpression: unimplemented operator!" + op);
return null;
}
}
@Override
public Object visit(StringVariable n, Void arg) {
return n.getConcreteValue();
}
@Override
public Object visit(HasMoreTokensExpr n, Void arg) {
StringTokenizer tokenizer = (StringTokenizer) n.getTokenizerExpr().accept(this, null);
return tokenizer.hasMoreTokens() ? TRUE_VALUE : FALSE_VALUE;
}
@Override
public Object visit(NewTokenizerExpr n, Void arg) {
String stringVal = (String) n.getString().accept(this, null);
String delimVal = (String) n.getDelimiter().accept(this, null);
StringTokenizer tokenizer = new StringTokenizer(stringVal, delimVal);
return tokenizer;
}
@Override
public Object visit(NextTokenizerExpr n, Void arg) {
StringTokenizer tokenizer = (StringTokenizer) n.getTokenizerExpr().accept(this, null);
tokenizer.nextToken();
return tokenizer;
}
@Override
public Object visit(StringNextTokenExpr n, Void arg) {
StringTokenizer tokenizer = (StringTokenizer) n.getTokenizerExpr().accept(this, null);
return tokenizer.nextToken();
}
@Override
public Object visit(ReferenceConstant r, Void arg) {
return r.getConcreteValue();
}
@Override
public Object visit(ReferenceVariable r, Void arg) {
return r.getConcreteValue();
}
@Override
public Object visit(GetFieldExpression r, Void arg) {
final Object conc_receiver = r.getReceiverExpr().accept(this, arg);
final String field_name = r.getFieldName();
if (conc_receiver == null) {
// TODO
throw new UnsupportedOperationException("How the null case should be handled?");
}
try {
Field field = conc_receiver.getClass().getField(field_name);
final boolean isAccessible = field.isAccessible();
field.setAccessible(true);
Object ret_value = field.get(conc_receiver);
field.setAccessible(isAccessible);
return ret_value;
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException
| IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}