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

changeset 1238
e28a06a3c5d9
parent 1221
c2234816495f
child 1239
2827076dbf64
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Mar 26 15:27:51 2012 +0100
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Mar 26 15:28:22 2012 +0100
     1.3 @@ -29,6 +29,8 @@
     1.4  import com.sun.tools.javac.code.*;
     1.5  import com.sun.tools.javac.code.Type.*;
     1.6  import com.sun.tools.javac.code.Symbol.*;
     1.7 +import com.sun.tools.javac.comp.Attr.ResultInfo;
     1.8 +import com.sun.tools.javac.comp.Check.CheckContext;
     1.9  import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
    1.10  import com.sun.tools.javac.jvm.*;
    1.11  import com.sun.tools.javac.tree.*;
    1.12 @@ -70,6 +72,7 @@
    1.13      Names names;
    1.14      Log log;
    1.15      Symtab syms;
    1.16 +    Attr attr;
    1.17      Check chk;
    1.18      Infer infer;
    1.19      ClassReader reader;
    1.20 @@ -101,6 +104,7 @@
    1.21  
    1.22          names = Names.instance(context);
    1.23          log = Log.instance(context);
    1.24 +        attr = Attr.instance(context);
    1.25          chk = Check.instance(context);
    1.26          infer = Infer.instance(context);
    1.27          reader = ClassReader.instance(context);
    1.28 @@ -627,15 +631,8 @@
    1.29          }
    1.30  
    1.31          while (argtypes.nonEmpty() && formals.head != varargsFormal) {
    1.32 -            Type undetFormal = infer.asUndetType(formals.head, undetvars);
    1.33 -            Type capturedActual = types.capture(argtypes.head);
    1.34 -            boolean works = allowBoxing ?
    1.35 -                    types.isConvertible(capturedActual, undetFormal, warn) :
    1.36 -                    types.isSubtypeUnchecked(capturedActual, undetFormal, warn);
    1.37 -            if (!works) {
    1.38 -                throw handler.argumentMismatch(false, argtypes.head, formals.head);
    1.39 -            }
    1.40 -            checkedArgs.append(capturedActual);
    1.41 +            ResultInfo resultInfo = methodCheckResult(formals.head, allowBoxing, false, undetvars, handler, warn);
    1.42 +            checkedArgs.append(resultInfo.check(env.tree.pos(), argtypes.head));
    1.43              argtypes = argtypes.tail;
    1.44              formals = formals.tail;
    1.45          }
    1.46 @@ -648,13 +645,9 @@
    1.47              //note: if applicability check is triggered by most specific test,
    1.48              //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
    1.49              Type elt = types.elemtype(varargsFormal);
    1.50 -            Type eltUndet = infer.asUndetType(elt, undetvars);
    1.51              while (argtypes.nonEmpty()) {
    1.52 -                Type capturedActual = types.capture(argtypes.head);
    1.53 -                if (!types.isConvertible(capturedActual, eltUndet, warn)) {
    1.54 -                    throw handler.argumentMismatch(true, argtypes.head, elt);
    1.55 -                }
    1.56 -                checkedArgs.append(capturedActual);
    1.57 +                ResultInfo resultInfo = methodCheckResult(elt, allowBoxing, true, undetvars, handler, warn);
    1.58 +                checkedArgs.append(resultInfo.check(env.tree.pos(), argtypes.head));
    1.59                  argtypes = argtypes.tail;
    1.60              }
    1.61              //check varargs element type accessibility
    1.62 @@ -665,39 +658,116 @@
    1.63          }
    1.64          return checkedArgs.toList();
    1.65      }
    1.66 -    // where
    1.67 -        public static class InapplicableMethodException extends RuntimeException {
    1.68 -            private static final long serialVersionUID = 0;
    1.69  
    1.70 -            JCDiagnostic diagnostic;
    1.71 -            JCDiagnostic.Factory diags;
    1.72 +    /**
    1.73 +     * Check context to be used during method applicability checks. A method check
    1.74 +     * context might contain inference variables.
    1.75 +     */
    1.76 +    abstract class MethodCheckContext implements CheckContext {
    1.77  
    1.78 -            InapplicableMethodException(JCDiagnostic.Factory diags) {
    1.79 -                this.diagnostic = null;
    1.80 -                this.diags = diags;
    1.81 +        MethodCheckHandler handler;
    1.82 +        boolean useVarargs;
    1.83 +        List<Type> undetvars;
    1.84 +        Warner rsWarner;
    1.85 +
    1.86 +        public MethodCheckContext(MethodCheckHandler handler, boolean useVarargs, List<Type> undetvars, Warner rsWarner) {
    1.87 +            this.handler = handler;
    1.88 +            this.useVarargs = useVarargs;
    1.89 +            this.undetvars = undetvars;
    1.90 +            this.rsWarner = rsWarner;
    1.91 +        }
    1.92 +
    1.93 +        public void report(DiagnosticPosition pos, Type found, Type req, JCDiagnostic details) {
    1.94 +            throw handler.argumentMismatch(useVarargs, found, req);
    1.95 +        }
    1.96 +
    1.97 +        public Type rawInstantiatePoly(ForAll found, Type req, Warner warn) {
    1.98 +            throw new AssertionError("ForAll in argument position");
    1.99 +        }
   1.100 +
   1.101 +        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
   1.102 +            return rsWarner;
   1.103 +        }
   1.104 +    }
   1.105 +
   1.106 +    /**
   1.107 +     * Subclass of method check context class that implements strict method conversion.
   1.108 +     * Strict method conversion checks compatibility between types using subtyping tests.
   1.109 +     */
   1.110 +    class StrictMethodContext extends MethodCheckContext {
   1.111 +
   1.112 +        public StrictMethodContext(MethodCheckHandler handler, boolean useVarargs, List<Type> undetvars, Warner rsWarner) {
   1.113 +            super(handler, useVarargs, undetvars, rsWarner);
   1.114 +        }
   1.115 +
   1.116 +        public boolean compatible(Type found, Type req, Warner warn) {
   1.117 +            return types.isSubtypeUnchecked(found, infer.asUndetType(req, undetvars), warn);
   1.118 +        }
   1.119 +    }
   1.120 +
   1.121 +    /**
   1.122 +     * Subclass of method check context class that implements loose method conversion.
   1.123 +     * Loose method conversion checks compatibility between types using method conversion tests.
   1.124 +     */
   1.125 +    class LooseMethodContext extends MethodCheckContext {
   1.126 +
   1.127 +        public LooseMethodContext(MethodCheckHandler handler, boolean useVarargs, List<Type> undetvars, Warner rsWarner) {
   1.128 +            super(handler, useVarargs, undetvars, rsWarner);
   1.129 +        }
   1.130 +
   1.131 +        public boolean compatible(Type found, Type req, Warner warn) {
   1.132 +            return types.isConvertible(found, infer.asUndetType(req, undetvars), warn);
   1.133 +        }
   1.134 +    }
   1.135 +
   1.136 +    /**
   1.137 +     * Create a method check context to be used during method applicability check
   1.138 +     */
   1.139 +    ResultInfo methodCheckResult(Type to, boolean allowBoxing, boolean useVarargs,
   1.140 +            List<Type> undetvars, MethodCheckHandler methodHandler, Warner rsWarner) {
   1.141 +        MethodCheckContext checkContext = allowBoxing ?
   1.142 +                new LooseMethodContext(methodHandler, useVarargs, undetvars, rsWarner) :
   1.143 +                new StrictMethodContext(methodHandler, useVarargs, undetvars, rsWarner);
   1.144 +        return attr.new ResultInfo(VAL, to, checkContext) {
   1.145 +            @Override
   1.146 +            protected Type check(DiagnosticPosition pos, Type found) {
   1.147 +                return super.check(pos, chk.checkNonVoid(pos, types.capture(types.upperBound(found))));
   1.148              }
   1.149 -            InapplicableMethodException setMessage() {
   1.150 -                this.diagnostic = null;
   1.151 -                return this;
   1.152 -            }
   1.153 -            InapplicableMethodException setMessage(String key) {
   1.154 -                this.diagnostic = key != null ? diags.fragment(key) : null;
   1.155 -                return this;
   1.156 -            }
   1.157 -            InapplicableMethodException setMessage(String key, Object... args) {
   1.158 -                this.diagnostic = key != null ? diags.fragment(key, args) : null;
   1.159 -                return this;
   1.160 -            }
   1.161 -            InapplicableMethodException setMessage(JCDiagnostic diag) {
   1.162 -                this.diagnostic = diag;
   1.163 -                return this;
   1.164 -            }
   1.165 +        };
   1.166 +    }
   1.167  
   1.168 -            public JCDiagnostic getDiagnostic() {
   1.169 -                return diagnostic;
   1.170 -            }
   1.171 +    public static class InapplicableMethodException extends RuntimeException {
   1.172 +        private static final long serialVersionUID = 0;
   1.173 +
   1.174 +        JCDiagnostic diagnostic;
   1.175 +        JCDiagnostic.Factory diags;
   1.176 +
   1.177 +        InapplicableMethodException(JCDiagnostic.Factory diags) {
   1.178 +            this.diagnostic = null;
   1.179 +            this.diags = diags;
   1.180          }
   1.181 -        private final InapplicableMethodException inapplicableMethodException;
   1.182 +        InapplicableMethodException setMessage() {
   1.183 +            this.diagnostic = null;
   1.184 +            return this;
   1.185 +        }
   1.186 +        InapplicableMethodException setMessage(String key) {
   1.187 +            this.diagnostic = key != null ? diags.fragment(key) : null;
   1.188 +            return this;
   1.189 +        }
   1.190 +        InapplicableMethodException setMessage(String key, Object... args) {
   1.191 +            this.diagnostic = key != null ? diags.fragment(key, args) : null;
   1.192 +            return this;
   1.193 +        }
   1.194 +        InapplicableMethodException setMessage(JCDiagnostic diag) {
   1.195 +            this.diagnostic = diag;
   1.196 +            return this;
   1.197 +        }
   1.198 +
   1.199 +        public JCDiagnostic getDiagnostic() {
   1.200 +            return diagnostic;
   1.201 +        }
   1.202 +    }
   1.203 +    private final InapplicableMethodException inapplicableMethodException;
   1.204  
   1.205  /* ***************************************************************************
   1.206   *  Symbol lookup

mercurial