Mercurial > hg > openjdk > lambda > langtools
changeset 1592:dc6dec36396b
Bug fixes:
*) Spurious functional interface conversion error when target type inherits default methods (part two)
*) target-type of lambda/method reference should be well-formed w.r.t. Object overrides
author | mcimadamore |
---|---|
date | Thu, 08 Nov 2012 17:17:10 +0000 |
parents | d18de0997cba |
children | 5b858be3d094 |
files | src/share/classes/com/sun/tools/javac/code/Types.java src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/Check.java test/tools/javac/lambda/TargetType48.java test/tools/javac/lambda/TargetType49.java test/tools/javac/lambda/TargetType49.out |
diffstat | 6 files changed, 130 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Types.java Wed Nov 07 11:39:20 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Thu Nov 08 17:17:10 2012 +0000 @@ -399,15 +399,10 @@ @Override public boolean accepts(Symbol sym) { - return sym.kind == Kinds.MTH && - (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT && - !overridesObjectMethod(origin, sym) && - notOverridden(sym); - } - - private boolean notOverridden(Symbol msym) { - Symbol impl = ((MethodSymbol)msym).implementation(origin, Types.this, false); - return impl == null || (impl.flags() & (DEFAULT | ABSTRACT)) == ABSTRACT; + return sym.kind == Kinds.MTH && + (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT && + !overridesObjectMethod(origin, sym) && + (interfaceCandidates(origin.type, (MethodSymbol)sym).head.flags() & DEFAULT) == 0; } };
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Nov 07 11:39:20 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Nov 08 17:17:10 2012 +0000 @@ -2191,10 +2191,16 @@ explicitParamTypes = TreeInfo.types(that.params); } - Type target = infer.instantiateFunctionalInterface(that, adjustTarget(pt()), explicitParamTypes, resultInfo.checkContext); - Type lambdaType = (target == Type.recoveryType) ? - fallbackDescriptorType(that) : - types.findDescriptorType(target); + Type target; + Type lambdaType; + if (pt() != Type.recoveryType) { + target = infer.instantiateFunctionalInterface(that, adjustTarget(pt()), explicitParamTypes, resultInfo.checkContext); + lambdaType = types.findDescriptorType(target); + chk.checkFunctionalInterface(that, target); + } else { + target = Type.recoveryType; + lambdaType = fallbackDescriptorType(that); + } if (!TreeInfo.isExplicitLambda(that)) { //add param type info in the AST @@ -2440,10 +2446,16 @@ typeargtypes = attribTypes(that.typeargs, localEnv); } - Type target = infer.instantiateFunctionalInterface(that, adjustTarget(pt()), null, resultInfo.checkContext); - Type desc = (target == Type.recoveryType) ? - fallbackDescriptorType(that) : - types.findDescriptorType(target); + Type target; + Type desc; + if (pt() != Type.recoveryType) { + target = infer.instantiateFunctionalInterface(that, adjustTarget(pt()), null, resultInfo.checkContext); + desc = types.findDescriptorType(target); + chk.checkFunctionalInterface(that, target); + } else { + target = Type.recoveryType; + desc = fallbackDescriptorType(that); + } List<Type> argtypes = desc.getParameterTypes();
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Nov 07 11:39:20 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Nov 08 17:17:10 2012 +0000 @@ -2236,20 +2236,34 @@ c.type = types.createErrorType(c, c.type); c.flags_field |= ACYCLIC; } + + /** + * Check that functional interface methods would make sense when seen + * from the perspective of the implementing class + */ + void checkFunctionalInterface(JCTree tree, Type funcInterface) { + ClassType c = new ClassType(Type.noType, List.<Type>nil(), null); + ClassSymbol csym = new ClassSymbol(0, names.empty, c, syms.noSymbol); + c.interfaces_field = List.of(funcInterface); + c.supertype_field = syms.objectType; + c.tsym = csym; + csym.members_field = new Scope(csym); + csym.completer = null; + checkImplementations(tree, csym, csym); + } /** Check that all methods which implement some * method conform to the method they implement. * @param tree The class definition whose members are checked. */ void checkImplementations(JCClassDecl tree) { - checkImplementations(tree, tree.sym); + checkImplementations(tree, tree.sym, tree.sym); } //where /** Check that all methods which implement some * method in `ic' conform to the method they implement. */ - void checkImplementations(JCClassDecl tree, ClassSymbol ic) { - ClassSymbol origin = tree.sym; + void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) { for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) { ClassSymbol lc = (ClassSymbol)l.head.tsym; if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/TargetType48.java Thu Nov 08 17:17:10 2012 +0000 @@ -0,0 +1,46 @@ +/* + * 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 spurious functional interface conversion errors with default methods in target type + * @compile TargetType48.java + */ + +class TargetType48 { + interface I1 { + void a(); + void b(); + void c(); + } + + interface I2 extends I1 { + default void a() { } + } + + interface I3 extends I2 { + default void b() { } + } + + I3 i3 = ()->{ }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/TargetType49.java Thu Nov 08 17:17:10 2012 +0000 @@ -0,0 +1,40 @@ +/* + * 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 javac accepts ill-formed lambda/method reference targets + * @compile/fail/ref=TargetType49.out -XDrawDiagnostics TargetType49.java + */ +class TargetType49 { + + interface F { + default Object clone() { return null; } + void m(); + } + + F f1 = ()->{}; + F f2 = this::g; + + void g() { } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/TargetType49.out Thu Nov 08 17:17:10 2012 +0000 @@ -0,0 +1,3 @@ +TargetType49.java:36:12: compiler.err.override.weaker.access: (compiler.misc.cant.implement: clone(), java.lang.Object, clone(), TargetType49.F), public +TargetType49.java:37:12: compiler.err.override.weaker.access: (compiler.misc.cant.implement: clone(), java.lang.Object, clone(), TargetType49.F), public +2 errors