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

changeset 775
536ee9f126b1
parent 741
58ceeff50af8
child 787
b1c98bfd4709
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Dec 06 11:50:37 2010 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Dec 06 11:51:02 2010 +0000
     1.3 @@ -724,23 +724,11 @@
     1.4          switch (m2.kind) {
     1.5          case MTH:
     1.6              if (m1 == m2) return m1;
     1.7 -            Type mt1 = types.memberType(site, m1);
     1.8 -            noteWarner.unchecked = false;
     1.9 -            boolean m1SignatureMoreSpecific =
    1.10 -                (instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null,
    1.11 -                             allowBoxing, false, noteWarner) != null ||
    1.12 -                 useVarargs && instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null,
    1.13 -                                           allowBoxing, true, noteWarner) != null) &&
    1.14 -                !noteWarner.unchecked;
    1.15 -            Type mt2 = types.memberType(site, m2);
    1.16 -            noteWarner.unchecked = false;
    1.17 -            boolean m2SignatureMoreSpecific =
    1.18 -                (instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null,
    1.19 -                             allowBoxing, false, noteWarner) != null ||
    1.20 -                 useVarargs && instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null,
    1.21 -                                           allowBoxing, true, noteWarner) != null) &&
    1.22 -                !noteWarner.unchecked;
    1.23 +            boolean m1SignatureMoreSpecific = signatureMoreSpecific(env, site, m1, m2, allowBoxing, useVarargs);
    1.24 +            boolean m2SignatureMoreSpecific = signatureMoreSpecific(env, site, m2, m1, allowBoxing, useVarargs);
    1.25              if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
    1.26 +                Type mt1 = types.memberType(site, m1);
    1.27 +                Type mt2 = types.memberType(site, m2);
    1.28                  if (!types.overrideEquivalent(mt1, mt2))
    1.29                      return new AmbiguityError(m1, m2);
    1.30                  // same signature; select (a) the non-bridge method, or
    1.31 @@ -824,6 +812,50 @@
    1.32              throw new AssertionError();
    1.33          }
    1.34      }
    1.35 +    //where
    1.36 +    private boolean signatureMoreSpecific(Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
    1.37 +        Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs));
    1.38 +        noteWarner.unchecked = false;
    1.39 +        return (instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null,
    1.40 +                             allowBoxing, false, noteWarner) != null ||
    1.41 +                 useVarargs && instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null,
    1.42 +                                           allowBoxing, true, noteWarner) != null) &&
    1.43 +                !noteWarner.unchecked;
    1.44 +    }
    1.45 +    //where
    1.46 +    private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) {
    1.47 +        List<Type> fromArgs = from.type.getParameterTypes();
    1.48 +        List<Type> toArgs = to.type.getParameterTypes();
    1.49 +        if (useVarargs &&
    1.50 +                toArgs.length() < fromArgs.length() &&
    1.51 +                (from.flags() & VARARGS) != 0 &&
    1.52 +                (to.flags() & VARARGS) != 0) {
    1.53 +            //if we are checking a varargs method 'from' against another varargs
    1.54 +            //method 'to' (where arity of 'to' < arity of 'from') then expand signature
    1.55 +            //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to'
    1.56 +            //until 'to' signature has the same arity as 'from')
    1.57 +            ListBuffer<Type> args = ListBuffer.lb();
    1.58 +            Type varargsTypeFrom = fromArgs.last();
    1.59 +            Type varargsTypeTo = toArgs.last();
    1.60 +            while (fromArgs.head != varargsTypeFrom) {
    1.61 +                args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head);
    1.62 +                fromArgs = fromArgs.tail;
    1.63 +                toArgs = toArgs.head == varargsTypeTo ?
    1.64 +                    toArgs :
    1.65 +                    toArgs.tail;
    1.66 +            }
    1.67 +            args.append(varargsTypeTo);
    1.68 +            MethodSymbol msym = new MethodSymbol(to.flags_field,
    1.69 +                                                 to.name,
    1.70 +                                                 (Type)to.type.clone(), //see: 6990136
    1.71 +                                                 to.owner);
    1.72 +            MethodType mtype = msym.type.asMethodType();
    1.73 +            mtype.argtypes = args.toList();
    1.74 +            return msym;
    1.75 +        } else {
    1.76 +            return to;
    1.77 +        }
    1.78 +    }
    1.79  
    1.80      /** Find best qualified method matching given name, type and value
    1.81       *  arguments.

mercurial