src/share/classes/com/sun/tools/javac/comp/Resolve.java

changeset 1348
573ceb23beeb
parent 1347
1408af4cd8b0
child 1352
d4b3cb1ece84
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Oct 04 13:04:53 2012 +0100
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Oct 05 14:35:24 2012 +0100
     1.3 @@ -753,6 +753,10 @@
     1.4          public boolean compatible(Type found, Type req, Warner warn) {
     1.5              return types.isSubtypeUnchecked(found, inferenceContext.asFree(req, types), warn);
     1.6          }
     1.7 +
     1.8 +        public boolean allowBoxing() {
     1.9 +            return false;
    1.10 +        }
    1.11      }
    1.12  
    1.13      /**
    1.14 @@ -769,6 +773,10 @@
    1.15          public boolean compatible(Type found, Type req, Warner warn) {
    1.16              return types.isConvertible(found, inferenceContext.asFree(req, types), warn);
    1.17          }
    1.18 +
    1.19 +        public boolean allowBoxing() {
    1.20 +            return true;
    1.21 +        }
    1.22      }
    1.23  
    1.24      /**
    1.25 @@ -1036,7 +1044,7 @@
    1.26          }
    1.27          return (bestSoFar.kind > AMBIGUOUS)
    1.28              ? sym
    1.29 -            : mostSpecific(sym, bestSoFar, env, site,
    1.30 +            : mostSpecific(argtypes, sym, bestSoFar, env, site,
    1.31                             allowBoxing && operator, useVarargs);
    1.32      }
    1.33  
    1.34 @@ -1050,7 +1058,7 @@
    1.35       *  @param allowBoxing Allow boxing conversions of arguments.
    1.36       *  @param useVarargs Box trailing arguments into an array for varargs.
    1.37       */
    1.38 -    Symbol mostSpecific(Symbol m1,
    1.39 +    Symbol mostSpecific(List<Type> argtypes, Symbol m1,
    1.40                          Symbol m2,
    1.41                          Env<AttrContext> env,
    1.42                          final Type site,
    1.43 @@ -1059,8 +1067,10 @@
    1.44          switch (m2.kind) {
    1.45          case MTH:
    1.46              if (m1 == m2) return m1;
    1.47 -            boolean m1SignatureMoreSpecific = signatureMoreSpecific(env, site, m1, m2, allowBoxing, useVarargs);
    1.48 -            boolean m2SignatureMoreSpecific = signatureMoreSpecific(env, site, m2, m1, allowBoxing, useVarargs);
    1.49 +            boolean m1SignatureMoreSpecific =
    1.50 +                    signatureMoreSpecific(argtypes, env, site, m1, m2, allowBoxing, useVarargs);
    1.51 +            boolean m2SignatureMoreSpecific =
    1.52 +                    signatureMoreSpecific(argtypes, env, site, m2, m1, allowBoxing, useVarargs);
    1.53              if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
    1.54                  Type mt1 = types.memberType(site, m1);
    1.55                  Type mt2 = types.memberType(site, m2);
    1.56 @@ -1127,8 +1137,8 @@
    1.57              return ambiguityError(m1, m2);
    1.58          case AMBIGUOUS:
    1.59              AmbiguityError e = (AmbiguityError)m2;
    1.60 -            Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs);
    1.61 -            Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs);
    1.62 +            Symbol err1 = mostSpecific(argtypes, m1, e.sym, env, site, allowBoxing, useVarargs);
    1.63 +            Symbol err2 = mostSpecific(argtypes, m1, e.sym2, env, site, allowBoxing, useVarargs);
    1.64              if (err1 == err2) return err1;
    1.65              if (err1 == e.sym && err2 == e.sym2) return m2;
    1.66              if (err1 instanceof AmbiguityError &&
    1.67 @@ -1142,13 +1152,82 @@
    1.68          }
    1.69      }
    1.70      //where
    1.71 -    private boolean signatureMoreSpecific(Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
    1.72 +    private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
    1.73 +        Symbol m12 = adjustVarargs(m1, m2, useVarargs);
    1.74 +        Symbol m22 = adjustVarargs(m2, m1, useVarargs);
    1.75 +        Type mtype1 = types.memberType(site, m12);
    1.76 +        Type mtype2 = types.memberType(site, m22);
    1.77 +
    1.78 +        //check if invocation is more specific
    1.79 +        if (invocationMoreSpecific(env, site, m22, mtype1.getParameterTypes(), allowBoxing, useVarargs)) {
    1.80 +            return true;
    1.81 +        }
    1.82 +
    1.83 +        //perform structural check
    1.84 +
    1.85 +        List<Type> formals1 = mtype1.getParameterTypes();
    1.86 +        Type lastFormal1 = formals1.last();
    1.87 +        List<Type> formals2 = mtype2.getParameterTypes();
    1.88 +        Type lastFormal2 = formals2.last();
    1.89 +        ListBuffer<Type> newFormals = ListBuffer.lb();
    1.90 +
    1.91 +        boolean hasStructuralPoly = false;
    1.92 +        for (Type actual : actuals) {
    1.93 +            //perform formal argument adaptation in case actuals > formals (varargs)
    1.94 +            Type f1 = formals1.isEmpty() ?
    1.95 +                    lastFormal1 : formals1.head;
    1.96 +            Type f2 = formals2.isEmpty() ?
    1.97 +                    lastFormal2 : formals2.head;
    1.98 +
    1.99 +            //is this a structural actual argument?
   1.100 +            boolean isStructuralPoly = actual.tag == DEFERRED &&
   1.101 +                    ((DeferredType)actual).tree.hasTag(LAMBDA);
   1.102 +
   1.103 +            Type newFormal = f1;
   1.104 +
   1.105 +            if (isStructuralPoly) {
   1.106 +                //for structural arguments only - check that corresponding formals
   1.107 +                //are related - if so replace formal with <null>
   1.108 +                hasStructuralPoly = true;
   1.109 +                DeferredType dt = (DeferredType)actual;
   1.110 +                Type t1 = deferredAttr.new DeferredTypeMap(AttrMode.SPECULATIVE, m1, currentResolutionContext.step).apply(dt);
   1.111 +                Type t2 = deferredAttr.new DeferredTypeMap(AttrMode.SPECULATIVE, m2, currentResolutionContext.step).apply(dt);
   1.112 +                if (t1.isErroneous() || t2.isErroneous() || !isStructuralSubtype(t1, t2)) {
   1.113 +                    //not structural subtypes - simply fail
   1.114 +                    return false;
   1.115 +                } else {
   1.116 +                    newFormal = syms.botType;
   1.117 +                }
   1.118 +            }
   1.119 +
   1.120 +            newFormals.append(newFormal);
   1.121 +            if (newFormals.length() > mtype2.getParameterTypes().length()) {
   1.122 +                //expand m2's type so as to fit the new formal arity (varargs)
   1.123 +                m22.type = types.createMethodTypeWithParameters(m22.type, m22.type.getParameterTypes().append(f2));
   1.124 +            }
   1.125 +
   1.126 +            formals1 = formals1.isEmpty() ? formals1 : formals1.tail;
   1.127 +            formals2 = formals2.isEmpty() ? formals2 : formals2.tail;
   1.128 +        }
   1.129 +
   1.130 +        if (!hasStructuralPoly) {
   1.131 +            //if no structural actual was found, we're done
   1.132 +            return false;
   1.133 +        }
   1.134 +        //perform additional adaptation if actuals < formals (varargs)
   1.135 +        for (Type t : formals1) {
   1.136 +            newFormals.append(t);
   1.137 +        }
   1.138 +        //check if invocation (with tweaked args) is more specific
   1.139 +        return invocationMoreSpecific(env, site, m22, newFormals.toList(), allowBoxing, useVarargs);
   1.140 +    }
   1.141 +    //where
   1.142 +    private boolean invocationMoreSpecific(Env<AttrContext> env, Type site, Symbol m2, List<Type> argtypes1, boolean allowBoxing, boolean useVarargs) {
   1.143          noteWarner.clear();
   1.144 -        Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs));
   1.145 -        Type mtype2 = instantiate(env, site, adjustVarargs(m2, m1, useVarargs), null,
   1.146 -                types.lowerBoundArgtypes(mtype1), null,
   1.147 +        Type mst = instantiate(env, site, m2, null,
   1.148 +                types.lowerBounds(argtypes1), null,
   1.149                  allowBoxing, false, noteWarner);
   1.150 -        return mtype2 != null &&
   1.151 +        return mst != null &&
   1.152                  !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
   1.153      }
   1.154      //where
   1.155 @@ -1187,6 +1266,32 @@
   1.156          }
   1.157      }
   1.158      //where
   1.159 +    boolean isStructuralSubtype(Type s, Type t) {
   1.160 +
   1.161 +        Type ret_s = types.findDescriptorType(s).getReturnType();
   1.162 +        Type ret_t = types.findDescriptorType(t).getReturnType();
   1.163 +
   1.164 +        //covariant most specific check for function descriptor return type
   1.165 +        if (!types.isSubtype(ret_s, ret_t)) {
   1.166 +            return false;
   1.167 +        }
   1.168 +
   1.169 +        List<Type> args_s = types.findDescriptorType(s).getParameterTypes();
   1.170 +        List<Type> args_t = types.findDescriptorType(t).getParameterTypes();
   1.171 +
   1.172 +        //arity must be identical
   1.173 +        if (args_s.length() != args_t.length()) {
   1.174 +            return false;
   1.175 +        }
   1.176 +
   1.177 +        //invariant most specific check for function descriptor parameter types
   1.178 +        if (!types.isSameTypes(args_t, args_s)) {
   1.179 +            return false;
   1.180 +        }
   1.181 +
   1.182 +        return true;
   1.183 +    }
   1.184 +    //where
   1.185      Type mostSpecificReturnType(Type mt1, Type mt2) {
   1.186          Type rt1 = mt1.getReturnType();
   1.187          Type rt2 = mt2.getReturnType();
   1.188 @@ -2388,7 +2493,19 @@
   1.189      private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
   1.190  
   1.191      public Object methodArguments(List<Type> argtypes) {
   1.192 -        return argtypes == null || argtypes.isEmpty() ? noArgs : argtypes;
   1.193 +        if (argtypes == null || argtypes.isEmpty()) {
   1.194 +            return noArgs;
   1.195 +        } else {
   1.196 +            ListBuffer<Object> diagArgs = ListBuffer.lb();
   1.197 +            for (Type t : argtypes) {
   1.198 +                if (t.tag == DEFERRED) {
   1.199 +                    diagArgs.append(((DeferredAttr.DeferredType)t).tree);
   1.200 +                } else {
   1.201 +                    diagArgs.append(t);
   1.202 +                }
   1.203 +            }
   1.204 +            return diagArgs;
   1.205 +        }
   1.206      }
   1.207  
   1.208      /**

mercurial