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

changeset 1186
51fb17abfc32
parent 1178
133744729455
child 1219
48ee63caaa93
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Wed Jan 18 18:26:36 2012 -0800
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Tue Jan 24 17:52:02 2012 +0000
     1.3 @@ -34,6 +34,7 @@
     1.4  import com.sun.tools.javac.code.Type.*;
     1.5  import com.sun.tools.javac.code.Type.ForAll.ConstraintKind;
     1.6  import com.sun.tools.javac.code.Symbol.*;
     1.7 +import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
     1.8  import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
     1.9  import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    1.10  
    1.11 @@ -84,7 +85,7 @@
    1.12  
    1.13      }
    1.14  
    1.15 -    public static class InferenceException extends Resolve.InapplicableMethodException {
    1.16 +    public static class InferenceException extends InapplicableMethodException {
    1.17          private static final long serialVersionUID = 0;
    1.18  
    1.19          InferenceException(JCDiagnostic.Factory diags) {
    1.20 @@ -287,6 +288,18 @@
    1.21          }
    1.22      }
    1.23  
    1.24 +    Type asUndetType(Type t, List<Type> undetvars) {
    1.25 +        return types.subst(t, inferenceVars(undetvars), undetvars);
    1.26 +    }
    1.27 +
    1.28 +    List<Type> inferenceVars(List<Type> undetvars) {
    1.29 +        ListBuffer<Type> tvars = ListBuffer.lb();
    1.30 +        for (Type uv : undetvars) {
    1.31 +            tvars.append(((UndetVar)uv).qtype);
    1.32 +        }
    1.33 +        return tvars.toList();
    1.34 +    }
    1.35 +
    1.36  /***************************************************************************
    1.37   * Exported Methods
    1.38   ***************************************************************************/
    1.39 @@ -372,62 +385,11 @@
    1.40                                    final Warner warn) throws InferenceException {
    1.41          //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
    1.42          List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
    1.43 -        List<Type> formals = mt.argtypes;
    1.44 -        //need to capture exactly once - otherwise subsequent
    1.45 -        //applicability checks might fail
    1.46 -        final List<Type> capturedArgs = types.capture(argtypes);
    1.47 -        List<Type> actuals = capturedArgs;
    1.48 -        List<Type> actualsNoCapture = argtypes;
    1.49 -        // instantiate all polymorphic argument types and
    1.50 -        // set up lower bounds constraints for undetvars
    1.51 -        Type varargsFormal = useVarargs ? formals.last() : null;
    1.52 -        if (varargsFormal == null &&
    1.53 -                actuals.size() != formals.size()) {
    1.54 -            throw unambiguousNoInstanceException
    1.55 -                .setMessage("infer.arg.length.mismatch");
    1.56 -        }
    1.57 -        while (actuals.nonEmpty() && formals.head != varargsFormal) {
    1.58 -            Type formal = formals.head;
    1.59 -            Type actual = actuals.head.baseType();
    1.60 -            Type actualNoCapture = actualsNoCapture.head.baseType();
    1.61 -            if (actual.tag == FORALL)
    1.62 -                actual = instantiateArg((ForAll)actual, formal, tvars, warn);
    1.63 -            Type undetFormal = types.subst(formal, tvars, undetvars);
    1.64 -            boolean works = allowBoxing
    1.65 -                ? types.isConvertible(actual, undetFormal, warn)
    1.66 -                : types.isSubtypeUnchecked(actual, undetFormal, warn);
    1.67 -            if (!works) {
    1.68 -                throw unambiguousNoInstanceException
    1.69 -                    .setMessage("infer.no.conforming.assignment.exists",
    1.70 -                                tvars, actualNoCapture, formal);
    1.71 -            }
    1.72 -            formals = formals.tail;
    1.73 -            actuals = actuals.tail;
    1.74 -            actualsNoCapture = actualsNoCapture.tail;
    1.75 -        }
    1.76 +        //final List<Type> capturedArgs = types.capture(argtypes);
    1.77  
    1.78 -        if (formals.head != varargsFormal) // not enough args
    1.79 -            throw unambiguousNoInstanceException.setMessage("infer.arg.length.mismatch");
    1.80 -
    1.81 -        // for varargs arguments as well
    1.82 -        if (useVarargs) {
    1.83 -            Type elemType = types.elemtype(varargsFormal);
    1.84 -            Type elemUndet = types.subst(elemType, tvars, undetvars);
    1.85 -            while (actuals.nonEmpty()) {
    1.86 -                Type actual = actuals.head.baseType();
    1.87 -                Type actualNoCapture = actualsNoCapture.head.baseType();
    1.88 -                if (actual.tag == FORALL)
    1.89 -                    actual = instantiateArg((ForAll)actual, elemType, tvars, warn);
    1.90 -                boolean works = types.isConvertible(actual, elemUndet, warn);
    1.91 -                if (!works) {
    1.92 -                    throw unambiguousNoInstanceException
    1.93 -                        .setMessage("infer.no.conforming.assignment.exists",
    1.94 -                                    tvars, actualNoCapture, elemType);
    1.95 -                }
    1.96 -                actuals = actuals.tail;
    1.97 -                actualsNoCapture = actualsNoCapture.tail;
    1.98 -            }
    1.99 -        }
   1.100 +        final List<Type> capturedArgs =
   1.101 +                rs.checkRawArgumentsAcceptable(env, undetvars, argtypes, mt.getParameterTypes(),
   1.102 +                    allowBoxing, useVarargs, warn, new InferenceCheckHandler(undetvars));
   1.103  
   1.104          // minimize as yet undetermined type variables
   1.105          for (Type t : undetvars)
   1.106 @@ -503,6 +465,31 @@
   1.107      }
   1.108      //where
   1.109  
   1.110 +        /** inference check handler **/
   1.111 +        class InferenceCheckHandler implements Resolve.MethodCheckHandler {
   1.112 +
   1.113 +            List<Type> undetvars;
   1.114 +
   1.115 +            public InferenceCheckHandler(List<Type> undetvars) {
   1.116 +                this.undetvars = undetvars;
   1.117 +            }
   1.118 +
   1.119 +            public InapplicableMethodException arityMismatch() {
   1.120 +                return unambiguousNoInstanceException.setMessage("infer.arg.length.mismatch");
   1.121 +            }
   1.122 +            public InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected) {
   1.123 +                String key = varargs ?
   1.124 +                    "infer.varargs.argument.mismatch" :
   1.125 +                    "infer.no.conforming.assignment.exists";
   1.126 +                return unambiguousNoInstanceException.setMessage(key,
   1.127 +                        inferenceVars(undetvars), found, expected);
   1.128 +            }
   1.129 +            public InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected) {
   1.130 +                return unambiguousNoInstanceException.setMessage("inaccessible.varargs.type",
   1.131 +                        expected, Kinds.kindName(location), location);
   1.132 +            }
   1.133 +        }
   1.134 +
   1.135          /**
   1.136           * A delegated type representing a partially uninferred method type.
   1.137           * The return type of a partially uninferred method type is a ForAll
   1.138 @@ -572,7 +559,7 @@
   1.139                  rs.checkRawArgumentsAcceptable(env, actuals, formals,
   1.140                         allowBoxing, useVarargs, warn);
   1.141              }
   1.142 -            catch (Resolve.InapplicableMethodException ex) {
   1.143 +            catch (InapplicableMethodException ex) {
   1.144                  // inferred method is not applicable
   1.145                  throw invalidInstanceException.setMessage(ex.getDiagnostic());
   1.146              }

mercurial