Package org.noname.designer.core.internal.evaluators

Source Code of org.noname.designer.core.internal.evaluators.MethodInvocationEvaluator

package org.noname.designer.core.internal.evaluators;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ArrayType;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.PrimitiveType.Code;
import org.eclipse.jdt.core.dom.QualifiedType;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.ThisExpression;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.noname.designer.core.interfaces.EvaluationContext;
import org.noname.designer.core.interfaces.FrameContext;
import org.noname.designer.core.interfaces.IEvaluator;
import org.noname.designer.core.interfaces.ITypeInferer;
import org.noname.designer.core.interfaces.VariableContext;

public class MethodInvocationEvaluator implements IEvaluator {
  private MethodInvocation invocation;

  public MethodInvocationEvaluator(MethodInvocation mi) {
    invocation = mi;
  }

  /**
   * @return OK | THROW
   */
  @Override
  public int evaluate(EvaluationContext context) {
    Expression expression = invocation.getExpression();
    FrameContext frame = context.peek();
    VariableContext ctx = frame.peek();
    Stack<Object> stack = ctx.getStack();
    if (expression != null && !(expression instanceof ThisExpression)) {
      IEvaluator evaluator = (IEvaluator) Platform.getAdapterManager()
          .getAdapter(expression, IEvaluator.class);
      int result = evaluator.evaluate(context);
      switch (result) {
      case THROW:
        return THROW;
      }
    } else {
      MethodDeclaration mi = getMethodDeclaration();
      if (mi != null) {
        return evaluateMethodInvocation(context, mi);
      } else {
        stack.push(context.getThisObject());
      }
    }
    int result = evaluateArguments(context);
    switch (result) {
    case THROW:
      return THROW;
    }
    List args = invocation.arguments();
    int size = args == null ? 0 : args.size();
    List<Object> arguments = new ArrayList<Object>();
    for (int i = 0; i < size; i++) {
      args.add(0, stack.pop());
    }
    Object[] params = args.toArray();
    Object obj = stack.pop();

    return OK;
  }

  private int evaluateArguments(EvaluationContext context) {
    // TODO Auto-generated method stub
    return 0;
  }

  private int evaluateMethodInvocation(EvaluationContext context,
      MethodDeclaration mi) {
    FrameContext frame = new FrameContext();
    context.push(frame);
    VariableContext arguments = new VariableContext();
    frame.push(arguments);
    IEvaluator evaluator = (IEvaluator) Platform.getAdapterManager()
        .getAdapter(mi, IEvaluator.class);
    int ret = evaluator.evaluate(context);
    frame = context.popup();
    Object result = frame.getResult();
    switch (ret) {
    case THROW:
      context.peek().setResult(result);
      return THROW;
    case RETURN:
      return OK;
    }
    frame = context.peek();
    VariableContext varCtx = frame.peek();
    Stack<Object> stack = varCtx.getStack();
    stack.addElement(result);
    return OK;
  }

  private MethodDeclaration getMethodDeclaration() {
    String name = invocation.getName().getIdentifier();
    ASTNode root = invocation.getRoot();
    CompilationUnit unit = (CompilationUnit) root;
    TypeDeclaration typeDec = (TypeDeclaration) unit.types().get(0);
    MethodDeclaration[] methods = typeDec.getMethods();
    MethodDeclaration mi = null;
con:    for (MethodDeclaration method : methods) {
      String methodName = method.getName().getIdentifier();
      if (name.equals(methodName)) {
        List<Type> mParamTypes = getMethodParamTypes(method);
        List<Type> argTypes = inferArgumentTypes();
        if(mParamTypes.size()!=argTypes.size())
          continue;
        for(int i=0;i<mParamTypes.size();i++){
          Type mType = mParamTypes.get(i);
          Type aType = argTypes.get(i);
          if(!isAssignable(mType, aType)){
            continue con;
          }
        }
        mi = method;
        break;
      }
    }
    return mi;
  }

  private boolean isAssignable(Type left, Type right) {
    if (left.isArrayType()) {
      if (right.isArrayType()) {
        int dimLeft = ((ArrayType) left).getDimensions();
        int dimRight = ((ArrayType) right).getDimensions();
        if (dimLeft == dimRight) {
          Type leftElement = ((ArrayType) left).getElementType();
          Type rightElment = ((ArrayType) right).getElementType();
          return isAssignable(leftElement, rightElment);
        }
      }
    } else if (left.isPrimitiveType()) {
      if (right.isPrimitiveType()) {
        PrimitiveType leftType = (PrimitiveType) left;
        PrimitiveType rightType = (PrimitiveType) right;
        Code leftCode = leftType.getPrimitiveTypeCode();
        Code rightCode = leftType.getPrimitiveTypeCode();
        if (leftCode.toString().equals(rightCode.toString()))
          return true;
      }
    } else if (left.isParameterizedType()) {
      if (right.isParameterizedType()) {
        ParameterizedType leftType = (ParameterizedType) left;
        ParameterizedType rightType = (ParameterizedType) right;
        Type leftBaseType = leftType.getType();
        Type rightBaseType = rightType.getType();
        boolean baseAssignable = isAssignable(leftBaseType,
            rightBaseType);
        if (baseAssignable) {
          List leftArgs = leftType.typeArguments();
          List rightArgs = rightType.typeArguments();
          if (leftArgs.size() != rightArgs.size())
            return false;
          for (int i = 0; i < leftArgs.size(); i++) {
            Type leftArgType = (Type) leftArgs.get(i);
            Type rightArgType = (Type) rightArgs.get(i);
            if (!isAssignable(leftArgType, rightArgType)) {
              return false;
            }
          }
          return true;
        }
      }
    } else if (left.isQualifiedType()) {
      if(right.isQualifiedType()){
        QualifiedType leftType = (QualifiedType) left;
        QualifiedType rightType = (QualifiedType) right;
        Type leftQualifier = leftType.getQualifier();
        Type rightQualifier = rightType.getQualifier();
        SimpleName leftName = leftType.getName();
        SimpleName rightName = rightType.getName();
        boolean assignable = isAssignable(leftQualifier, rightQualifier);
        return assignable && leftName.getIdentifier().equals(rightName.getIdentifier());
      }
    } else if(left.isSimpleType()){
      if(right.isSimpleType()){
        SimpleType leftType = (SimpleType) left;
        SimpleType rightType = (SimpleType) right;
        if(leftType.getName().equals(rightType.getName()))
          return true;
      }
    }
    return false;
  }

  private List<Type> getMethodParamTypes(MethodDeclaration method) {
    List params = method.parameters();
    List<Type> types = new ArrayList<Type>();
    for (int i = 0; i < params.size(); i++) {
      SingleVariableDeclaration svd = (SingleVariableDeclaration) params
          .get(i);
      types.add(svd.getType());
    }
    return types;
  }

  private List<Type> inferArgumentTypes() {
    List arguments = invocation.arguments();
    List<Type> types = new ArrayList<Type>();
    for (int i = 0; i < arguments.size(); i++) {
      Expression expression = (Expression) arguments.get(i);
      ITypeInferer inferer = (ITypeInferer) Platform.getAdapterManager()
          .getAdapter(expression, ITypeInferer.class);
      types.add(inferer.inferType());
    }
    return types;
  }
}
TOP

Related Classes of org.noname.designer.core.internal.evaluators.MethodInvocationEvaluator

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.