예제 #1
0
 /**
  * Return the operation from the name2operationOrOperations cache that matches operation. Returns
  * null if there is no operation or more than one.
  *
  * @param name2operationOrOperations
  * @param operation
  */
 protected O getExactMatchingOperation(
     Map<String, Object> name2operationOrOperations, O operation) {
   String requiredName = uml.getName(operation);
   List<PM> requiredParameters = uml.getParameters(operation);
   Object candidateOperationOrOperations = name2operationOrOperations.get(requiredName);
   if (candidateOperationOrOperations instanceof List<?>) {
     O matchingOperation = null;
     @SuppressWarnings("unchecked")
     List<O> candidateOperations = (List<O>) candidateOperationOrOperations;
     for (O candidateOperation : candidateOperations) {
       List<PM> candidateParameters = uml.getParameters(candidateOperation);
       if (exactlyMatches(requiredParameters, candidateParameters)) {
         if (matchingOperation == null) {
           matchingOperation = candidateOperation;
         } else {
           return null; // Ambiguity detected
         }
       }
     }
     return matchingOperation;
   } else if (candidateOperationOrOperations != null) {
     @SuppressWarnings("unchecked")
     O candidateOperation = (O) candidateOperationOrOperations;
     List<PM> candidateParameters = uml.getParameters(candidateOperation);
     if (exactlyMatches(requiredParameters, candidateParameters)) {
       return candidateOperation;
     } else {
       return null;
     }
   } else {
     return null;
   }
 }
예제 #2
0
  @Override
  protected List<O> getBestMatchingOperations(
      C owner, String name, List<? extends TypedElement<C>> args) {
    if (bypass) {
      return super.getBestMatchingOperations(owner, name, args);
    }
    Map<String, Object> name2operationOrOperations = getName2OperationOrOperations(owner);
    Object candidateOperationOrOperations = name2operationOrOperations.get(name);
    if (candidateOperationOrOperations instanceof List<?>) {
      List<O> matches = null;
      @SuppressWarnings("unchecked")
      List<O> candidateOperations = (List<O>) candidateOperationOrOperations;
      int bestExactitude = 0;
      for (O oper : candidateOperations) {
        int exactitude = matchArgsWithExactitude(owner, uml.getParameters(oper), args);
        if (exactitude >= bestExactitude) {
          if (exactitude > bestExactitude) {
            if (matches != null) {
              matches.clear();
            }
            bestExactitude = exactitude;
          }
          if (matches == null) {
            // assume a small number of redefinitions
            matches = new java.util.ArrayList<O>(3);
          }

          matches.add(oper);
        }
      }
      return matches;
    } else if (candidateOperationOrOperations != null) {
      @SuppressWarnings("unchecked")
      O candidateOperation = (O) candidateOperationOrOperations;
      int exactitude = matchArgsWithExactitude(owner, uml.getParameters(candidateOperation), args);
      if (exactitude >= 0) {
        return Collections.singletonList(candidateOperation);
      } else {
        return null;
      }
    } else {
      return null;
    }
  }
예제 #3
0
 /** Return the map of name to operator or list of operations for a type. */
 protected Map<String, Object> getName2OperationOrOperations(C type) {
   Map<String, Object> name2operationOrOperations = type2name2operationOrOperations.get(type);
   if (name2operationOrOperations == null) {
     name2operationOrOperations = new HashMap<String, Object>();
     type2name2operationOrOperations.put(type, name2operationOrOperations);
     List<O> allOperations = getOperations(type);
     for (O candidateOperation : allOperations) {
       String name = uml.getName(candidateOperation);
       Object overloadOrOverloads = name2operationOrOperations.get(name);
       if (overloadOrOverloads == null) {
         name2operationOrOperations.put(name, candidateOperation);
       } else {
         List<O> overloads;
         if (overloadOrOverloads instanceof List<?>) {
           @SuppressWarnings("unchecked")
           List<O> castOperations = (List<O>) overloadOrOverloads;
           overloads = castOperations;
         } else {
           overloads = new ArrayList<O>();
           name2operationOrOperations.put(name, overloads);
           @SuppressWarnings("unchecked")
           O castOperation = (O) overloadOrOverloads;
           overloads.add(castOperation);
         }
         C candidateOwner = uml.getOwningClassifier(candidateOperation);
         Collection<? extends C> candidateSupertypes = uml.getAllSupertypes(candidateOwner);
         List<PM> candidateParameters = uml.getParameters(candidateOperation);
         int iMax = candidateParameters.size();
         int j = overloads.size();
         while (--j >= 0) { // Reverse count to allow remove()
           O oldOperation = overloads.get(j);
           List<PM> oldParameters = uml.getParameters(oldOperation);
           if (iMax == oldParameters.size()) {
             int i = 0;
             for (; i < iMax; i++) {
               PM candidateParameter = candidateParameters.get(i);
               PM oldParameter = oldParameters.get(i);
               C oldType = uml.getOCLType(oldParameter);
               C candidateType = uml.getOCLType(candidateParameter);
               if (oldType != candidateType) {
                 break;
               }
             }
             if (i >= iMax) {
               C oldOwner = uml.getOwningClassifier(oldOperation);
               if (candidateSupertypes.contains(oldOwner)) {
                 overloads.remove(j);
               } else {
                 Collection<? extends C> oldSupertypes = uml.getAllSupertypes(oldOwner);
                 if (oldSupertypes.contains(candidateOwner)) {
                   break;
                 }
               }
             }
           }
         }
         if (j < 0) {
           overloads.add(candidateOperation);
         }
       }
     }
   }
   return name2operationOrOperations;
 }