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