Mon, 23 Sep 2013 15:37:59 -0400
6499673: Assertion check for TypeVariable.getUpperBound() fails.
Summary: Fix TypeVariable.getUpperBound to return results as specified
Reviewed-by: jjg
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Type.java Mon Sep 23 18:29:27 2013 +0400 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java Mon Sep 23 15:37:59 2013 -0400 1.3 @@ -977,7 +977,7 @@ 1.4 } 1.5 1.6 public java.util.List<? extends TypeMirror> getBounds() { 1.7 - return Collections.unmodifiableList(getComponents()); 1.8 + return Collections.unmodifiableList(getExplicitComponents()); 1.9 } 1.10 1.11 public List<Type> getComponents() {
2.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java Mon Sep 23 18:29:27 2013 +0400 2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Mon Sep 23 15:37:59 2013 -0400 2.3 @@ -2414,6 +2414,29 @@ 2.4 } 2.5 }; 2.6 2.7 + public List<Type> directSupertypes(Type t) { 2.8 + return directSupertypes.visit(t); 2.9 + } 2.10 + // where 2.11 + private final UnaryVisitor<List<Type>> directSupertypes = new UnaryVisitor<List<Type>>() { 2.12 + 2.13 + public List<Type> visitType(final Type type, final Void ignored) { 2.14 + if (!type.isCompound()) { 2.15 + final Type sup = supertype(type); 2.16 + return (sup == Type.noType || sup == type || sup == null) 2.17 + ? interfaces(type) 2.18 + : interfaces(type).prepend(sup); 2.19 + } else { 2.20 + return visitIntersectionType((IntersectionClassType) type); 2.21 + } 2.22 + } 2.23 + 2.24 + private List<Type> visitIntersectionType(final IntersectionClassType it) { 2.25 + return it.getExplicitComponents(); 2.26 + } 2.27 + 2.28 + }; 2.29 + 2.30 public boolean isDirectSuperInterface(TypeSymbol isym, TypeSymbol origin) { 2.31 for (Type i2 : interfaces(origin.type)) { 2.32 if (isym == i2.tsym) return true;
3.1 --- a/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Mon Sep 23 18:29:27 2013 +0400 3.2 +++ b/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Mon Sep 23 15:37:59 2013 -0400 3.3 @@ -116,11 +116,7 @@ 3.4 3.5 public List<Type> directSupertypes(TypeMirror t) { 3.6 validateTypeNotIn(t, EXEC_OR_PKG); 3.7 - Type type = (Type) t; 3.8 - Type sup = types.supertype(type); 3.9 - return (sup == Type.noType || sup == type || sup == null) 3.10 - ? types.interfaces(type) 3.11 - : types.interfaces(type).prepend(sup); 3.12 + return types.directSupertypes((Type) t); 3.13 } 3.14 3.15 public TypeMirror erasure(TypeMirror t) {
4.1 --- a/test/tools/javac/cast/intersection/model/Model01.java Mon Sep 23 18:29:27 2013 +0400 4.2 +++ b/test/tools/javac/cast/intersection/model/Model01.java Mon Sep 23 15:37:59 2013 -0400 4.3 @@ -23,7 +23,7 @@ 4.4 4.5 /* 4.6 * @test 4.7 - * @bug 8002099 4.8 + * @bug 8002099 6499673 4.9 * @summary Add support for intersection types in cast expression 4.10 * @library /tools/javac/lib 4.11 * @build JavacTestingAbstractProcessor ModelChecker 4.12 @@ -46,7 +46,7 @@ 4.13 } 4.14 4.15 void test(){ 4.16 - @IntersectionTypeInfo({"java.lang.Object", "Test.A", "Test.B"}) 4.17 + @IntersectionTypeInfo({"Test.A", "Test.B"}) 4.18 Object o = (A & B)null; 4.19 } 4.20 }
5.1 --- a/test/tools/javac/cast/intersection/model/ModelChecker.java Mon Sep 23 18:29:27 2013 +0400 5.2 +++ b/test/tools/javac/cast/intersection/model/ModelChecker.java Mon Sep 23 15:37:59 2013 -0400 5.3 @@ -97,7 +97,7 @@ 5.4 } 5.5 } 5.6 5.7 - assertTrue(assertionCount == 10, "Expected 10 assertions - found " + assertionCount); 5.8 + assertTrue(assertionCount == 9, "Expected 9 assertions - found " + assertionCount); 5.9 return super.visitVariable(node, p); 5.10 } 5.11 }
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/tools/javac/processing/model/type/BoundsTest.java Mon Sep 23 15:37:59 2013 -0400 6.3 @@ -0,0 +1,200 @@ 6.4 +/* 6.5 + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.23 + * or visit www.oracle.com if you need additional information or have any 6.24 + * questions. 6.25 + */ 6.26 + 6.27 +/* 6.28 + * @test 6.29 + * @bug 6499673 6.30 + * @library /tools/javac/lib 6.31 + * @build JavacTestingAbstractProcessor BoundsTest 6.32 + * @run main BoundsTest 6.33 + * @summary Assertion check for TypeVariable.getUpperBound() fails 6.34 + */ 6.35 + 6.36 +import com.sun.source.util.*; 6.37 +import com.sun.tools.javac.api.*; 6.38 +import com.sun.tools.javac.file.*; 6.39 +import javax.annotation.processing.*; 6.40 +import javax.lang.model.SourceVersion; 6.41 +import javax.lang.model.type.*; 6.42 +import javax.lang.model.util.ElementFilter; 6.43 +import javax.lang.model.element.*; 6.44 +import javax.tools.*; 6.45 +import java.util.*; 6.46 +import java.io.*; 6.47 + 6.48 +public class BoundsTest { 6.49 + 6.50 + private int errors = 0; 6.51 + private static final String Intersection_name = "IntersectionTest.java"; 6.52 + private static final String Intersection_contents = 6.53 + "import java.util.List;\n" + 6.54 + "import java.io.Serializable;\t" + 6.55 + "public class IntersectionTest<S extends List & Serializable> {\n" + 6.56 + " void method(S s) { }\n" + 6.57 + "}"; 6.58 + private static final String[] Intersection_bounds = { 6.59 + "java.util.List", 6.60 + "java.io.Serializable" 6.61 + }; 6.62 + private static final String[] Intersection_supers = { 6.63 + "java.util.List", 6.64 + "java.io.Serializable" 6.65 + }; 6.66 + 6.67 + private static final String Single_name = "SingleTest.java"; 6.68 + private static final String Single_contents = 6.69 + "import java.util.List;\n" + 6.70 + "public class SingleTest<S extends List> {\n" + 6.71 + " void method(S s) { }\n" + 6.72 + "}"; 6.73 + private static final String[] Single_bounds = { 6.74 + "java.util.List", 6.75 + }; 6.76 + private static final String[] Single_supers = { 6.77 + "java.lang.Object", 6.78 + "java.util.Collection" 6.79 + }; 6.80 + 6.81 + private static final String NoBounds_name = "NoBoundsTest.java"; 6.82 + private static final String NoBounds_contents = 6.83 + "public class NoBoundsTest<S> {\n" + 6.84 + " void method(S s) { }\n" + 6.85 + "}"; 6.86 + private static final String[] NoBounds_bounds = { 6.87 + "java.lang.Object", 6.88 + }; 6.89 + private static final String[] NoBounds_supers = {}; 6.90 + 6.91 + private HashSet<CharSequence> expected_bounds; 6.92 + private HashSet<CharSequence> expected_supers; 6.93 + 6.94 + private static final File classesdir = new File("intersectionproperties"); 6.95 + private static final JavaCompiler comp = 6.96 + ToolProvider.getSystemJavaCompiler(); 6.97 + private static final StandardJavaFileManager fm = 6.98 + comp.getStandardFileManager(null, null, null); 6.99 + 6.100 + public void runOne(final String Test_name, final String Test_contents, 6.101 + final String[] Test_bounds, final String[] Test_supers) 6.102 + throws IOException { 6.103 + System.err.println("Testing " + Test_name); 6.104 + expected_bounds = new HashSet<CharSequence>(Arrays.asList(Test_bounds)); 6.105 + expected_supers = new HashSet<CharSequence>(Arrays.asList(Test_supers)); 6.106 + final Iterable<? extends JavaFileObject> files = 6.107 + fm.getJavaFileObjectsFromFiles(Collections.singleton(writeFile(classesdir, Test_name, Test_contents))); 6.108 + final JavacTask ct = 6.109 + (JavacTask)comp.getTask(null, fm, null, null, null, files); 6.110 + ct.setProcessors(Collections.singleton(new TestProcessor())); 6.111 + 6.112 + if (!ct.call()) { 6.113 + System.err.println("Compilation unexpectedly failed"); 6.114 + errors++; 6.115 + } 6.116 + } 6.117 + 6.118 + public void run() throws IOException { 6.119 + runOne(Intersection_name, Intersection_contents, 6.120 + Intersection_bounds, Intersection_supers); 6.121 + runOne(Single_name, Single_contents, 6.122 + Single_bounds, Single_supers); 6.123 + runOne(NoBounds_name, NoBounds_contents, 6.124 + NoBounds_bounds, NoBounds_supers); 6.125 + 6.126 + if (0 != errors) 6.127 + throw new RuntimeException(errors + " errors occurred"); 6.128 + } 6.129 + 6.130 + public static void main(String... args) throws IOException { 6.131 + new IntersectionPropertiesTest().run(); 6.132 + } 6.133 + 6.134 + private static File writeFile(File dir, String path, String body) 6.135 + throws IOException { 6.136 + File f = new File(dir, path); 6.137 + f.getParentFile().mkdirs(); 6.138 + try (FileWriter out = new FileWriter(f)) { 6.139 + out.write(body); 6.140 + } 6.141 + return f; 6.142 + } 6.143 + 6.144 + private class TestProcessor extends JavacTestingAbstractProcessor { 6.145 + 6.146 + private Set<? extends Element> rootElements; 6.147 + 6.148 + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 6.149 + rootElements = roundEnv.getRootElements(); 6.150 + if (!rootElements.isEmpty()) { 6.151 + performCheck(); 6.152 + } 6.153 + return true; 6.154 + } 6.155 + 6.156 + private void performCheck() { 6.157 + TypeElement typeElement = (TypeElement) rootElements.iterator().next(); 6.158 + ExecutableElement method = ElementFilter.methodsIn(typeElement.getEnclosedElements()).get(0); 6.159 + TypeVariable typeVariable = (TypeVariable) method.getParameters().get(0).asType(); 6.160 + 6.161 + final TypeMirror upperBound = typeVariable.getUpperBound(); 6.162 + 6.163 + TypeParameterElement typeParameterElement = ((TypeParameterElement) typeVariable.asElement()); 6.164 + final List<? extends TypeMirror> bounds = typeParameterElement.getBounds(); 6.165 + final List<? extends TypeMirror> supers = processingEnv.getTypeUtils().directSupertypes(upperBound); 6.166 + 6.167 + final HashSet<CharSequence> actual_bounds = new HashSet<CharSequence>(); 6.168 + final HashSet<CharSequence> actual_supers = new HashSet<CharSequence>(); 6.169 + 6.170 + for(TypeMirror ty : bounds) { 6.171 + actual_bounds.add(((TypeElement)((DeclaredType)ty).asElement()).getQualifiedName()); 6.172 + } 6.173 + 6.174 + for(TypeMirror ty : supers) { 6.175 + actual_supers.add(((TypeElement)((DeclaredType)ty).asElement()).getQualifiedName()); 6.176 + } 6.177 + 6.178 + 6.179 + if (!expected_bounds.equals(actual_bounds)) { 6.180 + System.err.println("Mismatched expected and actual bounds."); 6.181 + System.err.println("Expected:"); 6.182 + for(CharSequence tm : expected_bounds) 6.183 + System.err.println(" " + tm); 6.184 + System.err.println("Actual:"); 6.185 + for(CharSequence tm : actual_bounds) 6.186 + System.err.println(" " + tm); 6.187 + errors++; 6.188 + } 6.189 + 6.190 + if (!expected_supers.equals(actual_supers)) { 6.191 + System.err.println("Mismatched expected and actual bounds."); 6.192 + System.err.println("Expected:"); 6.193 + for(CharSequence tm : expected_supers) 6.194 + System.err.println(" " + tm); 6.195 + System.err.println("Actual:"); 6.196 + for(CharSequence tm : actual_supers) 6.197 + System.err.println(" " + tm); 6.198 + errors++; 6.199 + } 6.200 + } 6.201 + } 6.202 + 6.203 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java Mon Sep 23 15:37:59 2013 -0400 7.3 @@ -0,0 +1,135 @@ 7.4 +/* 7.5 + * Copyright (c) 2012, 2013, 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 +/* 7.28 + * @test 7.29 + * @bug 6499673 7.30 + * @library /tools/javac/lib 7.31 + * @build JavacTestingAbstractProcessor IntersectionPropertiesTest 7.32 + * @run main IntersectionPropertiesTest 7.33 + * @summary Assertion check for TypeVariable.getUpperBound() fails 7.34 + */ 7.35 + 7.36 +import com.sun.source.util.*; 7.37 +import com.sun.tools.javac.api.*; 7.38 +import com.sun.tools.javac.file.*; 7.39 +import javax.annotation.processing.*; 7.40 +import javax.lang.model.SourceVersion; 7.41 +import javax.lang.model.type.*; 7.42 +import javax.lang.model.util.ElementFilter; 7.43 +import javax.lang.model.element.*; 7.44 +import javax.tools.*; 7.45 +import java.util.*; 7.46 +import java.io.*; 7.47 + 7.48 +public class IntersectionPropertiesTest { 7.49 + 7.50 + private int errors = 0; 7.51 + private static final String Intersection_name = "IntersectionTest.java"; 7.52 + private static final String Intersection_contents = 7.53 + "import java.util.List;\n" + 7.54 + "import java.io.Serializable;\t" + 7.55 + "public class IntersectionTest<S extends List & Serializable> {\n" + 7.56 + " void method(S s) { }\n" + 7.57 + "}"; 7.58 + 7.59 + private static final File classesdir = new File("intersectionproperties"); 7.60 + private static final JavaCompiler comp = 7.61 + ToolProvider.getSystemJavaCompiler(); 7.62 + private static final StandardJavaFileManager fm = 7.63 + comp.getStandardFileManager(null, null, null); 7.64 + 7.65 + public void runOne(final String Test_name, final String Test_contents) 7.66 + throws IOException { 7.67 + System.err.println("Testing " + Test_name); 7.68 + final Iterable<? extends JavaFileObject> files = 7.69 + fm.getJavaFileObjectsFromFiles(Collections.singleton(writeFile(classesdir, Test_name, Test_contents))); 7.70 + final JavacTask ct = 7.71 + (JavacTask)comp.getTask(null, fm, null, null, null, files); 7.72 + ct.setProcessors(Collections.singleton(new TestProcessor())); 7.73 + 7.74 + if (!ct.call()) { 7.75 + System.err.println("Compilation unexpectedly failed"); 7.76 + errors++; 7.77 + } 7.78 + } 7.79 + 7.80 + public void run() throws IOException { 7.81 + runOne(Intersection_name, Intersection_contents); 7.82 + 7.83 + if (0 != errors) 7.84 + throw new RuntimeException(errors + " errors occurred"); 7.85 + } 7.86 + 7.87 + public static void main(String... args) throws IOException { 7.88 + new IntersectionPropertiesTest().run(); 7.89 + } 7.90 + 7.91 + private static File writeFile(File dir, String path, String body) 7.92 + throws IOException { 7.93 + File f = new File(dir, path); 7.94 + f.getParentFile().mkdirs(); 7.95 + try (FileWriter out = new FileWriter(f)) { 7.96 + out.write(body); 7.97 + } 7.98 + return f; 7.99 + } 7.100 + 7.101 + private class TestProcessor extends JavacTestingAbstractProcessor { 7.102 + 7.103 + private Set<? extends Element> rootElements; 7.104 + 7.105 + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 7.106 + rootElements = roundEnv.getRootElements(); 7.107 + if (!rootElements.isEmpty()) { 7.108 + performCheck(); 7.109 + } 7.110 + return true; 7.111 + } 7.112 + 7.113 + private void performCheck() { 7.114 + TypeElement typeElement = (TypeElement) rootElements.iterator().next(); 7.115 + ExecutableElement method = ElementFilter.methodsIn(typeElement.getEnclosedElements()).get(0); 7.116 + TypeVariable typeVariable = (TypeVariable) method.getParameters().get(0).asType(); 7.117 + 7.118 + final TypeMirror upperBound = typeVariable.getUpperBound(); 7.119 + 7.120 + TypeParameterElement typeParameterElement = ((TypeParameterElement) typeVariable.asElement()); 7.121 + final List<? extends TypeMirror> bounds = typeParameterElement.getBounds(); 7.122 + final HashSet<TypeMirror> actual = new HashSet<TypeMirror>(processingEnv.getTypeUtils().directSupertypes(upperBound)); 7.123 + final HashSet<TypeMirror> expected = new HashSet<TypeMirror>(bounds); 7.124 + if (!expected.equals(actual)) { 7.125 + System.err.println("Mismatched expected and actual bounds."); 7.126 + System.err.println("Expected:"); 7.127 + for(TypeMirror tm : expected) 7.128 + System.err.println(" " + tm); 7.129 + System.err.println("Actual:"); 7.130 + for(TypeMirror tm : actual) 7.131 + System.err.println(" " + tm); 7.132 + errors++; 7.133 + } 7.134 + } 7.135 + 7.136 + } 7.137 + 7.138 +}