예제 #1
0
 private int sumConversionCost(List<Resolver.Conversion> conversionList) {
   int cost = 0;
   for (Resolver.Conversion conversion : conversionList) {
     cost += conversion.getCost();
   }
   return cost;
 }
예제 #2
0
  public FunDef getDef(Exp[] args, String funName, Syntax syntax) {
    // Compute signature first. It makes debugging easier.
    final String signature = syntax.getSignature(funName, Category.Unknown, ExpBase.getTypes(args));

    // Resolve function by its upper-case name first.  If there is only one
    // function with that name, stop immediately.  If there is more than
    // function, use some custom method, which generally involves looking
    // at the type of one of its arguments.
    List<Resolver> resolvers = funTable.getResolvers(funName, syntax);
    assert resolvers != null;

    final List<Resolver.Conversion> conversionList = new ArrayList<Resolver.Conversion>();
    int minConversionCost = Integer.MAX_VALUE;
    List<FunDef> matchDefs = new ArrayList<FunDef>();
    List<Resolver.Conversion> matchConversionList = null;
    for (Resolver resolver : resolvers) {
      conversionList.clear();
      FunDef def = resolver.resolve(args, this, conversionList);
      if (def != null) {
        int conversionCost = sumConversionCost(conversionList);
        if (conversionCost < minConversionCost) {
          minConversionCost = conversionCost;
          matchDefs.clear();
          matchDefs.add(def);
          matchConversionList = new ArrayList<Resolver.Conversion>(conversionList);
        } else if (conversionCost == minConversionCost) {
          matchDefs.add(def);
        } else {
          // ignore this match -- it required more coercions than
          // other overloadings we've seen
        }
      }
    }
    switch (matchDefs.size()) {
      case 0:
        throw MondrianResource.instance().NoFunctionMatchesSignature.ex(signature);
      case 1:
        break;
      default:
        final StringBuilder buf = new StringBuilder();
        for (FunDef matchDef : matchDefs) {
          if (buf.length() > 0) {
            buf.append(", ");
          }
          buf.append(matchDef.getSignature());
        }
        throw MondrianResource.instance()
            .MoreThanOneFunctionMatchesSignature
            .ex(signature, buf.toString());
    }

    final FunDef matchDef = matchDefs.get(0);
    for (Resolver.Conversion conversion : matchConversionList) {
      conversion.checkValid();
      conversion.apply(this, Arrays.asList(args));
    }

    return matchDef;
  }