Package ai.domain.intervals.eval

Source Code of ai.domain.intervals.eval.EvaluationUtils$ValueGetter

package ai.domain.intervals.eval;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.BooleanLiteral;
import org.eclipse.jdt.core.dom.CharacterLiteral;
import org.eclipse.jdt.core.dom.ConditionalExpression;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NumberLiteral;
import org.eclipse.jdt.core.dom.SuperFieldAccess;
import org.eclipse.jdt.core.dom.VariableDeclaration;

import ai.common.ASTUtils;
import ai.common.FatalAIError;
import ai.common.Pair;
import ai.domain.DomainException;
import ai.domain.DomainIntf;
import ai.domain.Variable;
import ai.domain.expressions.ExpressionEvaluatorBase;
import ai.domain.expressions.ExpressionEvaluatorIntf;
import ai.domain.expressions.bool.BooleanConditionEvaluatorIntf;
import ai.domain.expressions.bool.BooleanEvaluationState;
import ai.domain.expressions.integer.ExpressionEvaluationMap;
import ai.domain.generic.NonRelationalDomain;
import ai.domain.interval.Interval;
import ai.domain.interval.IntervalComparisonEvaluator;
import ai.domain.interval.IntervalValue;

public class EvaluationUtils {
  private static abstract class ValueGetter<T> {
    public abstract T getValue(Object constant);

    public T getValue(Expression exprNode) {
      T value = getValue(exprNode.resolveConstantExpressionValue());
      if (value != null)
        return value;
      // field access??
      if (exprNode.getNodeType() == ASTNode.FIELD_ACCESS) {
        IVariableBinding fieldBinding = ((FieldAccess) exprNode).resolveFieldBinding();
        return getValue(fieldBinding.getConstantValue());
      } else if (exprNode.getNodeType() == ASTNode.SUPER_FIELD_ACCESS) {
        IVariableBinding fieldBinding = ((SuperFieldAccess) exprNode).resolveFieldBinding();
        return getValue(fieldBinding.getConstantValue());
      } else
        return null;
    }
  }

  private static final ValueGetter<IntervalValue> INTERVAL_VALUE_GETTER = new ValueGetter<IntervalValue>() {
    @Override
    public IntervalValue getValue(Object constant) {
      if (constant == null)
        return null;
      if (constant instanceof Integer)
        return new IntervalValue((Integer) constant);
      if (constant instanceof Long)
        return new IntervalValue((Long) constant);
      if (constant instanceof Short)
        return new IntervalValue((Short) constant);
      if (constant instanceof Byte)
        return new IntervalValue((Byte) constant);
      if (constant instanceof Character)
        return new IntervalValue((Character) constant);
      throw new EvaluatorException("Unhandled constant type '%s'(%s)", constant, constant.getClass());
    }
  };

  private static final ValueGetter<Boolean> BOOLEAN_VALUE_GETTER = new ValueGetter<Boolean>() {
    @Override
    public Boolean getValue(Object constant) {
      if (constant == null)
        return null;
      if (constant instanceof Boolean)
        return (Boolean) constant;
      throw new EvaluatorException("Not a boolean constant '%s'(%s)", constant, constant.getClass());
    }
  };

  private static boolean isBooleanTypeBoxing(ITypeBinding typeBinding) {
    return typeBinding.getQualifiedName().equals("java.lang.Boolean");
  }

  public static boolean isBooleanType(Expression expr) {
    ITypeBinding typeBinding = expr.resolveTypeBinding();
    if (typeBinding == null)
      throw new FatalAIError("Cannot resolve type binding for: '%s'", expr);
    return typeBinding.isPrimitive() && typeBinding.getQualifiedName().equals("boolean");
  }
 
  public static boolean isBooleanTypeBoxing(Expression expr) {
    return isBooleanTypeBoxing(expr.resolveTypeBinding());
  }

  private static final Set<String> INTEGER_PRIMITIVE_TYPES = new HashSet<String>(Arrays.asList(new String[] { "int",
      "byte", "short", "long", "char" }));
  private static final Set<String> INTEGER_TYPES = new HashSet<String>(Arrays.asList(new String[] { "java.lang.Integer",
      "java.lang.Byte", "java.lang.Short", "java.lang.Long", "java.lang.Character" }));

  private static final Set<String> FLOAT_PRIMITIVE_TYPES = new HashSet<String>(Arrays.asList(new String[] { "float", "double" }));

  private static boolean isIntegerType(ITypeBinding aType) {
    String typeName = aType.getQualifiedName();
    return aType.isPrimitive() && INTEGER_PRIMITIVE_TYPES.contains(typeName);
  }

  private static boolean isFloatType(ITypeBinding aType) {
    String typeName = aType.getQualifiedName();
    return aType.isPrimitive() && FLOAT_PRIMITIVE_TYPES.contains(typeName);
  }
 
  private static boolean isIntegerTypeBoxing(ITypeBinding aType) {
    return INTEGER_TYPES.contains(aType.getQualifiedName());
  }
 
  public static boolean isIntegerType(Expression expr) {
    return isIntegerType(expr.resolveTypeBinding());
  }
 
  public static boolean isFloatType(Expression expr) {
    return isFloatType(expr.resolveTypeBinding());
  }

  public static boolean isIntegerType(VariableDeclaration variableDeclaration) {
    IVariableBinding variableBinding = variableDeclaration.resolveBinding();
    return isIntegerType(variableBinding.getType());
  }

  public static boolean isIntegerTypeBoxing(Expression expr) {
    return isIntegerTypeBoxing(expr.resolveTypeBinding());
  }

//  public static boolean isInterestingType(Expression expr) {
//    return isInterestingType(expr.resolveTypeBinding());
//  }
// 
//  private static boolean isInterestingType(ITypeBinding aType) {
//    return aType.isPrimitive() && INTERESTING_TYPES.contains(aType.getQualifiedName());
//  }
//
  public static long getIntegerValue(NumberLiteral node) {
    Object constant = node.resolveConstantExpressionValue();
    if (constant == null)
      throw new DomainException("Hmm");
    if (constant instanceof Integer)
      return (Integer) constant;
    if (constant instanceof Long)
      return (Long) constant;
    if (constant instanceof Short)
      return (Short) constant;
    if (constant instanceof Byte)
      return (Byte) constant;
    throw new DomainException("Unhandled number literal type '%s'(%s)", constant, constant.getClass());
  }
 
  public static long getIntegerValue(CharacterLiteral node) {
    Object constant = node.resolveConstantExpressionValue();
    if (constant == null)
      throw new DomainException("Hmm");
    if (constant instanceof Character)
      return (Character) constant;
    throw new DomainException("Unhandled character literal type '%s'(%s)", constant, constant.getClass());
  }

  public static boolean getBooleanValue(BooleanLiteral node) {
    Object constant = node.resolveConstantExpressionValue();
    if (constant == null)
      throw new DomainException("Hmm");
    if (constant instanceof Boolean)
      return (Boolean) constant;
    throw new DomainException("Unhandled boolean literal type '%s'(%s)", constant, constant.getClass());
  }

  /**
   * return variable (only local and parameters are interesting)
   *
   * @param expr
   * @return
   */
  public static Variable tryGetVariable(Expression expr) {
    if (expr.getNodeType() == ASTNode.FIELD_ACCESS)
      return null;
    if (expr.getNodeType() == ASTNode.ARRAY_ACCESS)
      return null;
    if (expr.getNodeType() == ASTNode.SUPER_FIELD_ACCESS)
      return null;
    if (!(expr instanceof Name)) {
      throw new EvaluatorException("Not a variable node '%s(%s)'", expr.getClass(), expr);
    }
    return tryGetVariable((Name) expr);
  }
 
  public static Variable tryGetVariable(Name name) {
    IBinding binding = name.resolveBinding();
    if (binding == null)
      throw new FatalAIError("Cannot resolve type binding for: '%s'", name);
    if (binding.getKind() != IBinding.VARIABLE)
      return null;
    IVariableBinding varBinding = (IVariableBinding) binding;
    if (varBinding.isField())
      return null;
    IMethodBinding variableMethod = varBinding.getDeclaringMethod();
    //match declaration block
    ASTNode enclosingDeclarationBlock = ASTUtils.findAncestorOfType(name, ASTNode.METHOD_DECLARATION, ASTNode.INITIALIZER);
    if (variableMethod != null) {
      if (enclosingDeclarationBlock.getNodeType() != ASTNode.METHOD_DECLARATION)
        return null; // we are in initializer
      IMethodBinding enclosingMethod = ((MethodDeclaration)enclosingDeclarationBlock).resolveBinding();
      if (varBinding.getDeclaringMethod() != enclosingMethod)
        return null;
    } else {//variable is defined in initializer
      if (enclosingDeclarationBlock.getNodeType() != ASTNode.INITIALIZER)
        return null; // we are some method
      //hopefully we are ok :/
    }
    return new Variable(varBinding);
  }

  public static IntervalValue tryGetIntervalValue(Expression node) {
    return INTERVAL_VALUE_GETTER.getValue(node);
  }

  public static Boolean tryGetBooleanValue(Expression node) {
    return BOOLEAN_VALUE_GETTER.getValue(node);
  }
 
  public static <DI extends DomainIntf<DI>> Pair<DI, ArrayList<DI>> defaultSwitchProcess(ExpressionEvaluatorIntf<DI> eval,
      DI input, Expression expr, Expression[] switchCases){
    input = eval.evaluate(expr, input);
    ArrayList<DI> result  = new ArrayList<DI>(switchCases.length);
    for(int i=0; i< switchCases.length; i++)
      result.add(input);
    return Pair.create(input, result);
  }
 
  public static <DI extends DomainIntf<DI>> Pair<DI, ArrayList<DI>> evaluateSwitchInteger(DI input, Expression expr,
      Expression[] switchCases, IntervalComparisonEvaluator<DI> eval) {
    Expression[] allExpressions = new Expression[switchCases.length + 1];
    allExpressions[0] = expr;
    for(int i=0; i< switchCases.length; i++)
      allExpressions[i+1] = switchCases[i];
    Pair<ExpressionEvaluationMap<Interval>, DI> evalMap = eval.prepareEvaluationMap(input, allExpressions);
    ArrayList<DI> result = new ArrayList<DI>(switchCases.length);
    for(int i=0; i< switchCases.length; i++) {
      BooleanEvaluationState<DI> res = eval.evaluateComparisonNoEval(input, InfixExpression.Operator.EQUALS, expr, switchCases[i], evalMap);
      input = res.conditionNotMet;
      result.add(res.conditionMet);
    }
    return Pair.create(input, result);
  }
 
  public static <DI extends DomainIntf<DI>> Pair<Interval, DI> evaluateConditionalExpression(ConditionalExpression expr, BooleanConditionEvaluatorIntf<DI> condEval,
      Pair<Interval, DI> input, ExpressionEvaluatorBase<DI, Pair<Interval, DI>> eval) {
    BooleanEvaluationState<DI> condEvalResult = condEval.evaluateCondition(input.right, expr.getExpression());
    Pair<Interval, DI> thenResult = null;
    if (!condEvalResult.conditionMet.isBottom())
      thenResult = eval.evaluateExpression(expr.getThenExpression(), Pair.create(Interval.BOTTOM, condEvalResult.conditionMet));
    Pair<Interval, DI> elseResult = null;
    if (!condEvalResult.conditionNotMet.isBottom())
      elseResult = eval.evaluateExpression(expr.getElseExpression(), Pair.create(Interval.BOTTOM, condEvalResult.conditionNotMet));
    if (thenResult == null)
      return elseResult;
    if (elseResult == null)
      return thenResult;
    return Pair.create(thenResult.left.join(elseResult.left), thenResult.right.join(elseResult.right));
  }
 
  public static <DI extends DomainIntf<DI>> DI getValueForVariable(NonRelationalDomain<DI> di, Variable var) {
    if (di.containsValue(var))
      return di.getValueFor(var);
    throw new DomainException("Missing variable '%s': '%s'", var, di);
  }
 
//  public static Bool getValueForVariable(NonRelationalDomain<Bool> di, Variable var) {
//    if (di.containsValue(var))
//      return di.getValueFor(var);
//    System.err.println("MISSING BOOLEAN VARIABLE:" + var);
//    return Bool.TOP;
//  }
//
//  public static Interval getValueForVariable(NonRelationalDomain<Interval> di, Variable var) {
//    if (di.containsValue(var))
//      return di.getValueFor(var);
//    System.err.println("MISSING INTEGER VARIABLE:" + var);
//    return Interval.TOP;
//  }
//
  public static <DI extends DomainIntf<DI>> NonRelationalDomain<DI> updateValueOfVariable(NonRelationalDomain<DI> di,
      Variable var, DI value) {
    if (di.containsValue(var))
      return di.updateVariable(var, value);
    System.err.println("MISSING VARIABLE TO UPDATE:" + var);
    return di;
  }
}
TOP

Related Classes of ai.domain.intervals.eval.EvaluationUtils$ValueGetter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.