Package edu.cmu.cs.fusion.constraint.requestors

Source Code of edu.cmu.cs.fusion.constraint.requestors.EffectRequestor

package edu.cmu.cs.fusion.constraint.requestors;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IMemberValuePair;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jdt.core.search.TypeReferenceMatch;

import edu.cmu.cs.crystal.util.Utilities;
import edu.cmu.cs.fusion.Relation;
import edu.cmu.cs.fusion.RelationsEnvironment;
import edu.cmu.cs.fusion.constraint.Constraint;
import edu.cmu.cs.fusion.constraint.Effect;
import edu.cmu.cs.fusion.constraint.Operation;
import edu.cmu.cs.fusion.constraint.RelEffect;
import edu.cmu.cs.fusion.constraint.SpecVar;
import edu.cmu.cs.fusion.constraint.operations.ConstructorOp;
import edu.cmu.cs.fusion.constraint.operations.MethodInvocationOp;
import edu.cmu.cs.fusion.constraint.predicates.TruePredicate;

public class EffectRequestor extends SearchRequestor {

  private RelationsEnvironment rels;
  private HashSet<IMethod> parsed;
  private List<Constraint> constraints;
 
  public EffectRequestor(RelationsEnvironment rels) {
    this.rels = rels;
    parsed = new HashSet<IMethod>();
    constraints = new LinkedList<Constraint>();
  }

  public List<Constraint> getConstraints() {
    return constraints;
  }

  @Override
  public void acceptSearchMatch(SearchMatch match) throws CoreException {
    if (match.getAccuracy() == SearchMatch.A_INACCURATE)
      return;
    TypeReferenceMatch refMatch = (TypeReferenceMatch)match;
   
    IMethod method = (IMethod) refMatch.getElement();   
    if (parsed.contains(method))  //SYE!!!!
      return;

    List<Effect> effects = new LinkedList<Effect>();
   
    for (IAnnotation anno : method.getAnnotations()) {
      String qName = Utilities.resolveType(method.getDeclaringType(), anno.getElementName());
      Relation rel = rels.findRelation(qName);
     
      if (rel != null) {
        effects.add(parseEffect(anno, rel, method));
      }
      else {
        rel = isMultiRelation(anno, method.getDeclaringType());
        if (rel != null) {
          for (Object obj : (Object[])anno.getMemberValuePairs()[0].getValue()) {
            IAnnotation inner = (IAnnotation)obj;
            effects.add(parseEffect(inner, rel, method));
          }
        }
      }
    }
    parsed.add(method);
    assert(effects.size() > 0);
   
    Operation op;
    //this effect could be on a method OR a constructor.
    if (method.isConstructor()) {
      IType contextType = method.getDeclaringType();
      String type = contextType.getFullyQualifiedName();
      String[] paramTypes = new String[method.getParameterTypes().length];
      SpecVar[] opParams = new SpecVar[method.getParameterNames().length];
     
      for (int ndx = 0; ndx < paramTypes.length; ndx++) {
        paramTypes[ndx] = Utilities.resolveType(contextType, Signature.toString(method.getParameterTypes()[ndx]));
        opParams[ndx] = new SpecVar(method.getParameterNames()[ndx]);
      }
      op = new ConstructorOp(type, opParams, paramTypes);
   
    }
    else {
      IType contextType = method.getDeclaringType();
      String methodName = method.getElementName();
      String receiverType = contextType.getFullyQualifiedName();
      String returnType = Utilities.resolveType(contextType, Signature.toString(method.getReturnType()));
      String[] paramTypes = new String[method.getParameterTypes().length];
      SpecVar[] opParams = new SpecVar[method.getParameterNames().length];
      boolean isStatic = Flags.isStatic(method.getFlags());
     
      for (int ndx = 0; ndx < paramTypes.length; ndx++) {
        paramTypes[ndx] = Utilities.resolveType(contextType, Signature.toString(method.getParameterTypes()[ndx]));
        opParams[ndx] = new SpecVar(method.getParameterNames()[ndx]);
      }
      op = new MethodInvocationOp(methodName, receiverType, opParams, paramTypes, returnType, isStatic);
    }
    String owner = method.getDeclaringType().getFullyQualifiedName();
    constraints.add(new Constraint(owner, op, new TruePredicate(), new TruePredicate(), new TruePredicate(), effects));
  }
 
  private Relation isMultiRelation(IAnnotation anno, IType context) throws JavaModelException {
    //check if it has an array of annotations
    if (anno.getMemberValuePairs().length != 1)
      return null;
    IMemberValuePair pair = anno.getMemberValuePairs()[0];
    if (pair.getValueKind() != IMemberValuePair.K_ANNOTATION)
      return null;
    if (!(pair.getValue() instanceof Object[]))
      return null;
    if (((Object[])pair.getValue()).length < 2//can't be a multi-anno if there's less than two things in it
      return null;
   
   
    //check if those annotations are a relation
    IAnnotation inner = (IAnnotation)((Object[])pair.getValue())[0];
    String qName = Utilities.resolveType(context, inner.getElementName());
    return rels.findRelation(qName);
  }
 
  private RelEffect parseEffect(IAnnotation effectAnno, Relation rel, IMethod method) throws JavaModelException {
    RelEffect effect = null;
    IMemberValuePair paramsPair = null;
    IMemberValuePair actEffectPair = null;
    IMemberValuePair testPair = null;
   
    switch (effectAnno.getMemberValuePairs().length) {
    case 1:
      paramsPair = effectAnno.getMemberValuePairs()[0];
      break;
    case 2:
      if (effectAnno.getMemberValuePairs()[0].getMemberName().equals("value")) {
        paramsPair = effectAnno.getMemberValuePairs()[0];
        actEffectPair = effectAnno.getMemberValuePairs()[1];
      }
      else {
        paramsPair = effectAnno.getMemberValuePairs()[1];
        actEffectPair = effectAnno.getMemberValuePairs()[0];
     
      break;
    case 3:
      if (effectAnno.getMemberValuePairs()[0].getMemberName().equals("value")) {
        paramsPair = effectAnno.getMemberValuePairs()[0];
        if (effectAnno.getMemberValuePairs()[1].getMemberName().equals("effect")) {
          actEffectPair = effectAnno.getMemberValuePairs()[1];
          testPair = effectAnno.getMemberValuePairs()[2];
        }
        else {
          actEffectPair = effectAnno.getMemberValuePairs()[2];
          testPair = effectAnno.getMemberValuePairs()[1];
       
      }
      else if (effectAnno.getMemberValuePairs()[1].getMemberName().equals("value")) {
        paramsPair = effectAnno.getMemberValuePairs()[1];
        if (effectAnno.getMemberValuePairs()[0].getMemberName().equals("effect")) {
          actEffectPair = effectAnno.getMemberValuePairs()[0];
          testPair = effectAnno.getMemberValuePairs()[2];
        }
        else {
          actEffectPair = effectAnno.getMemberValuePairs()[2];
          testPair = effectAnno.getMemberValuePairs()[0];
       
      }
      else {
        paramsPair = effectAnno.getMemberValuePairs()[2];
        if (effectAnno.getMemberValuePairs()[0].getMemberName().equals("effect")) {
          actEffectPair = effectAnno.getMemberValuePairs()[0];
          testPair = effectAnno.getMemberValuePairs()[1];
        }
        else {
          actEffectPair = effectAnno.getMemberValuePairs()[1];
          testPair = effectAnno.getMemberValuePairs()[0];
       
      }
      break;
    }
   
    Object[] objParams = (Object[])paramsPair.getValue();
    SpecVar[] params = new SpecVar[objParams.length];
   
    for (int ndx = 0; ndx < objParams.length; ndx++) {
      if (objParams[ndx].equals(SpecVar.WILD_CARD))
        params[ndx] = SpecVar.createWildCard();
      else
        params[ndx] = new SpecVar((String)objParams[ndx]);
    }
   
/*      try {
      checkTypes(rel, params, method);
    } catch (ParseException e) {
      // TODO Put out a real error message
      e.printStackTrace();
    }
*/     
    edu.cmu.cs.fusion.annot.Relation.Effect actualEffect;
   
    if (actEffectPair != null) {
      String strEffect = ((String)actEffectPair.getValue()).substring(((String)actEffectPair.getValue()).lastIndexOf('.') + 1); //SCREW YOU ECLIPSE!!!!!
      actualEffect = edu.cmu.cs.fusion.annot.Relation.Effect.valueOf(strEffect);
    }
    else
      actualEffect = edu.cmu.cs.fusion.annot.Relation.Effect.ADD;
   
    String test = null;
   
    switch (actualEffect) {
    case ADD:
      effect = RelEffect.createAddEffect(rel, params);
      break;
    case REMOVE:
      effect = RelEffect.createRemoveEffect(rel, params);
      break;
    case TEST:
      test = (String) testPair.getValue();
      effect = RelEffect.createTestEffect(rel, params, new SpecVar(test));
      break;
    }
    return effect;
  }

/*    private void checkTypes(Relation rel, SpecVar[] params, IMethod method) throws ParseException, JavaModelException {
    String[] fqt = rel.getFullyQualifiedTypes();
    IType declType = method.getDeclaringType();
   
    for (int ndx = 0; ndx < params.length; ndx++) {
      SpecVar sVar = params[ndx];
      if (sVar.isWildCard())
        continue;
      String type = fqt[ndx];
     
      if (sVar.equals(Constraint.RECEIVER)) {
        if (!hierarchy.isSubtypeCompatible(declType.getFullyQualifiedName(), type))
          throw new ParseException("The variable " + sVar.getVar() + " does not have type " + type);
      }
      else if (sVar.equals(Constraint.RESULT)) {
        if (!hierarchy.isSubtypeCompatible(Utilities.resolveBinaryType(declType, method.getReturnType()), type))
          throw new ParseException("The variable " + sVar.getVar() + " does not have type " + type);
      }
      else {
        String paramType = null;
        for (int paramNdx = 0; paramNdx < method.getNumberOfParameters(); paramNdx++) {
          if (method.getParameterNames()[paramNdx].equals(sVar.getVar())) {
            paramType = method.getParameterTypes()[paramNdx];
            break;
          }
        }
       
        if (paramType == null)
          throw new ParseException("The parameter " + sVar.getVar() + " does not exist.");
        if (!hierarchy.isSubtypeCompatible(Utilities.resolveBinaryType(declType, paramType), type))
          throw new ParseException("The variable " + sVar.getVar() + " does not have type " + type);
      }
    }
  }
*/
TOP

Related Classes of edu.cmu.cs.fusion.constraint.requestors.EffectRequestor

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.