Fri, 27 Feb 2015 15:43:27 -0800
Merge
.hgtags | file | annotate | diff | comparison | revisions |
1.1 --- a/.hgtags Wed Feb 25 12:59:57 2015 -0800 1.2 +++ b/.hgtags Fri Feb 27 15:43:27 2015 -0800 1.3 @@ -370,6 +370,10 @@ 1.4 0c514d1fd006fc79d35b670de10c370c8d559db7 jdk8u40-b19 1.5 c3d6d1a5339952fbe4124e700407b7211446c99c jdk8u40-b20 1.6 9113c7c8d902ec94b28ca0ef4a6466bdba65fcfc jdk8u40-b21 1.7 +79177246b3dbe5296fb53755d8695acdaef59fc8 jdk8u40-b22 1.8 +fb294b49373bda0b3afc7f011d64ecefed73b42e jdk8u40-b23 1.9 +c5d4ffa220f3824c2ea5d39dc99d41a9df9e5ae5 jdk8u40-b24 1.10 +991141080b2078e67179ff307a5051e59431762c jdk8u40-b25 1.11 0c514d1fd006fc79d35b670de10c370c8d559db7 jdk8u60-b00 1.12 0ba07c272e33c93377a5d7ed98b9de873cc91980 jdk8u60-b01 1.13 387cf62ce7895dd5e067aaa51faa93d5c078583e jdk8u60-b02
2.1 --- a/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Feb 25 12:59:57 2015 -0800 2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Feb 27 15:43:27 2015 -0800 2.3 @@ -1153,6 +1153,16 @@ 2.4 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 2.5 return v.visitClassSymbol(this, p); 2.6 } 2.7 + 2.8 + public void markAbstractIfNeeded(Types types) { 2.9 + if (types.enter.getEnv(this) != null && 2.10 + (flags() & ENUM) != 0 && types.supertype(type).tsym == types.syms.enumSym && 2.11 + (flags() & (FINAL | ABSTRACT)) == 0) { 2.12 + if (types.firstUnimplementedAbstract(this) != null) 2.13 + // add the ABSTRACT flag to an enum 2.14 + flags_field |= ABSTRACT; 2.15 + } 2.16 + } 2.17 } 2.18 2.19
3.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java Wed Feb 25 12:59:57 2015 -0800 3.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Fri Feb 27 15:43:27 2015 -0800 3.3 @@ -47,6 +47,7 @@ 3.4 import com.sun.tools.javac.util.*; 3.5 import static com.sun.tools.javac.code.BoundKind.*; 3.6 import static com.sun.tools.javac.code.Flags.*; 3.7 +import static com.sun.tools.javac.code.Kinds.MTH; 3.8 import static com.sun.tools.javac.code.Scope.*; 3.9 import static com.sun.tools.javac.code.Symbol.*; 3.10 import static com.sun.tools.javac.code.Type.*; 3.11 @@ -85,6 +86,7 @@ 3.12 final boolean allowBoxing; 3.13 final boolean allowCovariantReturns; 3.14 final boolean allowObjectToPrimitiveCast; 3.15 + final boolean allowDefaultMethods; 3.16 final ClassReader reader; 3.17 final Check chk; 3.18 final Enter enter; 3.19 @@ -111,6 +113,7 @@ 3.20 allowBoxing = source.allowBoxing(); 3.21 allowCovariantReturns = source.allowCovariantReturns(); 3.22 allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast(); 3.23 + allowDefaultMethods = source.allowDefaultMethods(); 3.24 reader = ClassReader.instance(context); 3.25 chk = Check.instance(context); 3.26 enter = Enter.instance(context); 3.27 @@ -2763,6 +2766,59 @@ 3.28 // </editor-fold> 3.29 3.30 3.31 + /** Return first abstract member of class `sym'. 3.32 + */ 3.33 + public MethodSymbol firstUnimplementedAbstract(ClassSymbol sym) { 3.34 + try { 3.35 + return firstUnimplementedAbstractImpl(sym, sym); 3.36 + } catch (CompletionFailure ex) { 3.37 + chk.completionError(enter.getEnv(sym).tree.pos(), ex); 3.38 + return null; 3.39 + } 3.40 + } 3.41 + //where: 3.42 + private MethodSymbol firstUnimplementedAbstractImpl(ClassSymbol impl, ClassSymbol c) { 3.43 + MethodSymbol undef = null; 3.44 + // Do not bother to search in classes that are not abstract, 3.45 + // since they cannot have abstract members. 3.46 + if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) { 3.47 + Scope s = c.members(); 3.48 + for (Scope.Entry e = s.elems; 3.49 + undef == null && e != null; 3.50 + e = e.sibling) { 3.51 + if (e.sym.kind == MTH && 3.52 + (e.sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) { 3.53 + MethodSymbol absmeth = (MethodSymbol)e.sym; 3.54 + MethodSymbol implmeth = absmeth.implementation(impl, this, true); 3.55 + if (implmeth == null || implmeth == absmeth) { 3.56 + //look for default implementations 3.57 + if (allowDefaultMethods) { 3.58 + MethodSymbol prov = interfaceCandidates(impl.type, absmeth).head; 3.59 + if (prov != null && prov.overrides(absmeth, impl, this, true)) { 3.60 + implmeth = prov; 3.61 + } 3.62 + } 3.63 + } 3.64 + if (implmeth == null || implmeth == absmeth) { 3.65 + undef = absmeth; 3.66 + } 3.67 + } 3.68 + } 3.69 + if (undef == null) { 3.70 + Type st = supertype(c.type); 3.71 + if (st.hasTag(CLASS)) 3.72 + undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)st.tsym); 3.73 + } 3.74 + for (List<Type> l = interfaces(c.type); 3.75 + undef == null && l.nonEmpty(); 3.76 + l = l.tail) { 3.77 + undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)l.head.tsym); 3.78 + } 3.79 + } 3.80 + return undef; 3.81 + } 3.82 + 3.83 + 3.84 //where 3.85 public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) { 3.86 Filter<Symbol> filter = new MethodFilter(ms, site);
4.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Feb 25 12:59:57 2015 -0800 4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Feb 27 15:43:27 2015 -0800 4.3 @@ -4269,6 +4269,8 @@ 4.4 chk.validate(tree.implementing, env); 4.5 } 4.6 4.7 + c.markAbstractIfNeeded(types); 4.8 + 4.9 // If this is a non-abstract class, check that it has no abstract 4.10 // methods or unimplemented methods of an implemented interface. 4.11 if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) {
5.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Feb 25 12:59:57 2015 -0800 5.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Feb 27 15:43:27 2015 -0800 5.3 @@ -2049,70 +2049,15 @@ 5.4 * @param c The class. 5.5 */ 5.6 void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) { 5.7 - try { 5.8 - MethodSymbol undef = firstUndef(c, c); 5.9 - if (undef != null) { 5.10 - if ((c.flags() & ENUM) != 0 && 5.11 - types.supertype(c.type).tsym == syms.enumSym && 5.12 - (c.flags() & FINAL) == 0) { 5.13 - // add the ABSTRACT flag to an enum 5.14 - c.flags_field |= ABSTRACT; 5.15 - } else { 5.16 - MethodSymbol undef1 = 5.17 - new MethodSymbol(undef.flags(), undef.name, 5.18 - types.memberType(c.type, undef), undef.owner); 5.19 - log.error(pos, "does.not.override.abstract", 5.20 - c, undef1, undef1.location()); 5.21 - } 5.22 - } 5.23 - } catch (CompletionFailure ex) { 5.24 - completionError(pos, ex); 5.25 + MethodSymbol undef = types.firstUnimplementedAbstract(c); 5.26 + if (undef != null) { 5.27 + MethodSymbol undef1 = 5.28 + new MethodSymbol(undef.flags(), undef.name, 5.29 + types.memberType(c.type, undef), undef.owner); 5.30 + log.error(pos, "does.not.override.abstract", 5.31 + c, undef1, undef1.location()); 5.32 } 5.33 } 5.34 -//where 5.35 - /** Return first abstract member of class `c' that is not defined 5.36 - * in `impl', null if there is none. 5.37 - */ 5.38 - private MethodSymbol firstUndef(ClassSymbol impl, ClassSymbol c) { 5.39 - MethodSymbol undef = null; 5.40 - // Do not bother to search in classes that are not abstract, 5.41 - // since they cannot have abstract members. 5.42 - if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) { 5.43 - Scope s = c.members(); 5.44 - for (Scope.Entry e = s.elems; 5.45 - undef == null && e != null; 5.46 - e = e.sibling) { 5.47 - if (e.sym.kind == MTH && 5.48 - (e.sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) { 5.49 - MethodSymbol absmeth = (MethodSymbol)e.sym; 5.50 - MethodSymbol implmeth = absmeth.implementation(impl, types, true); 5.51 - if (implmeth == null || implmeth == absmeth) { 5.52 - //look for default implementations 5.53 - if (allowDefaultMethods) { 5.54 - MethodSymbol prov = types.interfaceCandidates(impl.type, absmeth).head; 5.55 - if (prov != null && prov.overrides(absmeth, impl, types, true)) { 5.56 - implmeth = prov; 5.57 - } 5.58 - } 5.59 - } 5.60 - if (implmeth == null || implmeth == absmeth) { 5.61 - undef = absmeth; 5.62 - } 5.63 - } 5.64 - } 5.65 - if (undef == null) { 5.66 - Type st = types.supertype(c.type); 5.67 - if (st.hasTag(CLASS)) 5.68 - undef = firstUndef(impl, (ClassSymbol)st.tsym); 5.69 - } 5.70 - for (List<Type> l = types.interfaces(c.type); 5.71 - undef == null && l.nonEmpty(); 5.72 - l = l.tail) { 5.73 - undef = firstUndef(impl, (ClassSymbol)l.head.tsym); 5.74 - } 5.75 - } 5.76 - return undef; 5.77 - } 5.78 5.79 void checkNonCyclicDecl(JCClassDecl tree) { 5.80 CycleChecker cc = new CycleChecker();
6.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Wed Feb 25 12:59:57 2015 -0800 6.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Feb 27 15:43:27 2015 -0800 6.3 @@ -1027,6 +1027,7 @@ 6.4 l.nonEmpty(); 6.5 l = l.tail) { 6.6 ClassSymbol inner = l.head; 6.7 + inner.markAbstractIfNeeded(types); 6.8 char flags = (char) adjustFlags(inner.flags_field); 6.9 if ((flags & INTERFACE) != 0) flags |= ABSTRACT; // Interfaces are always ABSTRACT 6.10 if (inner.name.isEmpty()) flags &= ~FINAL; // Anonymous class: unset FINAL flag
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/tools/javac/classfiles/InnerClasses/T8068517.java Fri Feb 27 15:43:27 2015 -0800 7.3 @@ -0,0 +1,126 @@ 7.4 +/* 7.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.7 + * 7.8 + * This code is free software; you can redistribute it and/or modify it 7.9 + * under the terms of the GNU General Public License version 2 only, as 7.10 + * published by the Free Software Foundation. 7.11 + * 7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.15 + * version 2 for more details (a copy is included in the LICENSE file that 7.16 + * accompanied this code). 7.17 + * 7.18 + * You should have received a copy of the GNU General Public License version 7.19 + * 2 along with this work; if not, write to the Free Software Foundation, 7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.21 + * 7.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 7.23 + * or visit www.oracle.com if you need additional information or have any 7.24 + * questions. 7.25 + */ 7.26 + 7.27 +/** @test 7.28 + * @bug 8068517 7.29 + * @summary Verify that nested enums have correct abstract flag in the InnerClasses attribute. 7.30 + * @library /tools/javac/lib 7.31 + * @build ToolBox T8068517 7.32 + * @run main T8068517 7.33 + */ 7.34 + 7.35 +import com.sun.tools.javac.util.Assert; 7.36 +import java.io.File; 7.37 +import java.nio.file.Files; 7.38 +import java.util.Arrays; 7.39 +import java.util.List; 7.40 +import java.util.stream.Collectors; 7.41 +import java.util.stream.Stream; 7.42 +import javax.tools.JavaCompiler; 7.43 +import javax.tools.ToolProvider; 7.44 + 7.45 +public class T8068517 { 7.46 + 7.47 + public static void main(String[] args) throws Exception { 7.48 + new T8068517().run(); 7.49 + } 7.50 + 7.51 + void run() throws Exception { 7.52 + runTest("class A {\n" + 7.53 + " enum AInner implements Runnable {\n" + 7.54 + " A {\n" + 7.55 + " public void run() {}\n" + 7.56 + " };\n" + 7.57 + " }\n" + 7.58 + "}\n", 7.59 + "class B {\n" + 7.60 + " A.AInner a;\n" + 7.61 + "}"); 7.62 + runTest("class A {\n" + 7.63 + " enum AInner implements Runnable {\n" + 7.64 + " A {\n" + 7.65 + " public void run() {}\n" + 7.66 + " };\n" + 7.67 + " }\n" + 7.68 + " AInner aInner;\n" + 7.69 + "}\n", 7.70 + "class B {\n" + 7.71 + " void test(A a) {;\n" + 7.72 + " switch (a.aInner) {\n" + 7.73 + " case A: break;\n" + 7.74 + " }\n" + 7.75 + " };\n" + 7.76 + "}"); 7.77 + runTest("class A {\n" + 7.78 + " enum AInner implements Runnable {\n" + 7.79 + " A {\n" + 7.80 + " public void run() {}\n" + 7.81 + " };\n" + 7.82 + " }\n" + 7.83 + " AInner aInner;\n" + 7.84 + "}\n", 7.85 + "class B {\n" + 7.86 + " void test(A a) {;\n" + 7.87 + " System.err.println(a.aInner.toString());\n" + 7.88 + " };\n" + 7.89 + "}"); 7.90 + runTest("class A {\n" + 7.91 + " enum AInner implements Runnable {\n" + 7.92 + " A {\n" + 7.93 + " public void run() {}\n" + 7.94 + " };\n" + 7.95 + " }\n" + 7.96 + " AInner aInner() {\n" + 7.97 + " return null;\n" + 7.98 + " }\n" + 7.99 + "}\n", 7.100 + "class B {\n" + 7.101 + " void test(A a) {;\n" + 7.102 + " System.err.println(a.aInner().toString());\n" + 7.103 + " };\n" + 7.104 + "}"); 7.105 + } 7.106 + 7.107 + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 7.108 + int testN = 0; 7.109 + 7.110 + void runTest(String aJava, String bJava) throws Exception { 7.111 + File testClasses = new File(System.getProperty("test.classes")); 7.112 + File target1 = new File(testClasses, "T8068517s" + testN++); 7.113 + doCompile(target1, aJava, bJava); 7.114 + File target2 = new File(testClasses, "T8068517s" + testN++); 7.115 + doCompile(target2, bJava, aJava); 7.116 + 7.117 + Assert.check(Arrays.equals(Files.readAllBytes(new File(target1, "B.class").toPath()), 7.118 + Files.readAllBytes(new File(target2, "B.class").toPath()))); 7.119 + } 7.120 + 7.121 + void doCompile(File target, String... sources) throws Exception { 7.122 + target.mkdirs(); 7.123 + List<String> options = Arrays.asList("-d", target.getAbsolutePath()); 7.124 + List<ToolBox.JavaSource> files = Stream.of(sources) 7.125 + .map(ToolBox.JavaSource::new) 7.126 + .collect(Collectors.toList()); 7.127 + compiler.getTask(null, null, null, options, null, files).call(); 7.128 + } 7.129 +}