OpenJDK / lambda / lambda / langtools
changeset 1459:2a4b8b31381b
Misc improvements to deferred attribution architecture:
*) out-of-order method checking should check as many arguments as possible in cases where method is not applicable
*) fixed bug that caused silent compiler crash where void expression passed as argument to overloaded method
author | mcimadamore |
---|---|
date | Fri, 31 Aug 2012 18:03:48 +0100 |
parents | 83720b655da4 |
children | 0ea8d35cbe12 |
files | src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java src/share/classes/com/sun/tools/javac/comp/Resolve.java test/tools/javac/lambda/TargetType40.java test/tools/javac/lambda/TargetType40.out test/tools/javac/lambda/TargetType41.java test/tools/javac/lambda/TargetType41.out |
diffstat | 6 files changed, 117 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Fri Aug 31 13:42:13 2012 +0100 +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Fri Aug 31 18:03:48 2012 +0100 @@ -113,9 +113,15 @@ this.env = env.dup(tree, env.info.dup()); this.speculativeCache = new SpeculativeCache(); } + + @Override + public boolean isErroneous() { + return tree.type != null && + tree.type.isErroneous(); + } - void attribDeferred(AttrMode mode, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) { - mode.attribDeferred(this, resultInfo, deferredAttrContext); + void attribDeferred(ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) { + deferredAttrContext.mode.attribDeferred(this, resultInfo, deferredAttrContext); } class SpeculativeCache { @@ -388,7 +394,7 @@ if (isStuck()) { throw new IllegalStateException("Cannot process a stuck deferred node"); } - dt.attribDeferred(mode, resultInfo, DeferredAttrContext.this); + dt.attribDeferred(resultInfo, DeferredAttrContext.this); } } } @@ -475,10 +481,10 @@ return dt; default: return attr.attribTree(tree2, dt.env, attr.new ResultInfo(Kinds.VAL, Type.noType) { - @Override - protected Type check(DiagnosticPosition pos, Type found) { - return chk.checkNonVoid(pos, super.check(pos, found)); - } + @Override + protected Type check(DiagnosticPosition pos, Type found) { + return chk.checkNonVoid(pos, super.check(pos, found)); + } }); } }
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Aug 31 13:42:13 2012 +0100 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Aug 31 18:03:48 2012 +0100 @@ -672,15 +672,12 @@ DeferredAttr.DeferredAttrContext deferredAttrContext = deferredAttr.new DeferredAttrContext(mode, msym, currentResolutionContext.step, inferenceContext); - + + ListBuffer<InapplicableMethodException> ex_list = ListBuffer.lb(); + while (argtypes.nonEmpty() && formals.head != varargsFormal) { ResultInfo mresult = methodCheckResult(formals.head, allowBoxing, false, inferenceContext, deferredAttrContext, handler, warn); - if (argtypes.head.tag == DEFERRED) { - DeferredType<?> dt = (DeferredType<?>)argtypes.head; - dt.attribDeferred(mode, mresult, deferredAttrContext); - } else { - mresult.check(null, argtypes.head); - } + argumentApplicable(argtypes.head, mresult, deferredAttrContext, ex_list); argtypes = argtypes.tail; formals = formals.tail; } @@ -695,20 +692,35 @@ final Type elt = types.elemtype(varargsFormal); ResultInfo mresult = methodCheckResult(elt, allowBoxing, true, inferenceContext, deferredAttrContext, handler, warn); while (argtypes.nonEmpty()) { - if (argtypes.head.tag == DEFERRED) { - DeferredType<?> dt = (DeferredType<?>)argtypes.head; - dt.attribDeferred(mode, mresult, deferredAttrContext); - } else { - mresult.check(null, argtypes.head); - } + argumentApplicable(argtypes.head, mresult, deferredAttrContext, ex_list); argtypes = argtypes.tail; } //check varargs element type accessibility varargsAccessible(env, elt, handler, inferenceContext); } + //exception multiplexing - accumulate all inapplcable method exceptions during + //method applicability then propagate the first one - ensures all (non-stuck) + //arguments are type-checked - which allows for better diagnostics + if (ex_list.nonEmpty()) { + throw ex_list.first(); + } + deferredAttrContext.complete(); } + //where + void argumentApplicable(Type actual, ResultInfo mresult, DeferredAttrContext deferredAttrContext, ListBuffer<InapplicableMethodException> ex_list) { + try { + if (actual.tag == DEFERRED) { + DeferredType<?> dt = (DeferredType<?>)actual; + dt.attribDeferred(mresult, deferredAttrContext); + } else { + mresult.check(null, actual); + } + } catch (InapplicableMethodException ex) { + ex_list.append(ex); + } + } void varargsAccessible(final Env<AttrContext> env, final Type t, final Resolve.MethodCheckHandler handler, final InferenceContext inferenceContext) { if (inferenceContext.free(t)) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/TargetType40.java Fri Aug 31 18:03:48 2012 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary compiler silently crashes when void method is passed as argument in overloaded call site + * @compile/fail/ref=TargetType40.out -XDrawDiagnostics TargetType40.java + */ + +class TargetType40 { + void m(String s) { } + void m(Integer i) { } + + void void_method() {} + + void test() { + m(void_method()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/TargetType40.out Fri Aug 31 18:03:48 2012 +0100 @@ -0,0 +1,2 @@ +TargetType40.java:37:21: compiler.err.void.not.allowed.here +1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/TargetType41.java Fri Aug 31 18:03:48 2012 +0100 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary out-of-order method checking should check as many arguments as possible + * @compile/fail/ref=TargetType41.out -XDrawDiagnostics TargetType41.java + */ + +class TargetType40 { + <X> void m(String s, java.util.List<String> lx) { } + + void test() { + m(1, new java.util.ArrayList<>()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/TargetType41.out Fri Aug 31 18:03:48 2012 +0100 @@ -0,0 +1,2 @@ +TargetType41.java:34:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.String,java.util.List<java.lang.String>, int,java.util.ArrayList<java.lang.String>, kindname.class, TargetType40, null +1 error