# HG changeset patch # User jlahoda # Date 1384951479 -3600 # Node ID 7c89d200781bfaf170cfb3ea1ffcd4778b329f4b # Parent 66bcd5d4b3d15c12013927211276710b56f7fb13 6557966: Multiple upper bounds of the TypeVariable Summary: Adjusting javax.lang.model javadoc regarding IntersectionType, IntersectionType.accept now calls visitIntersection for all kinds of IntersectionTypes. Reviewed-by: darcy, vromero Contributed-by: joe.darcy@oracle.com, jan.lahoda@oracle.com diff -r 66bcd5d4b3d1 -r 7c89d200781b src/share/classes/com/sun/tools/javac/code/Type.java --- a/src/share/classes/com/sun/tools/javac/code/Type.java Tue Nov 19 23:35:43 2013 +0000 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java Wed Nov 20 13:44:39 2013 +0100 @@ -970,13 +970,6 @@ public boolean allInterfaces; - public enum IntersectionKind { - EXPLICIT, - IMPLICT; - } - - public IntersectionKind intersectionKind; - public IntersectionClassType(List bounds, ClassSymbol csym, boolean allInterfaces) { super(Type.noType, List.nil(), csym); this.allInterfaces = allInterfaces; @@ -1008,9 +1001,7 @@ @Override public R accept(TypeVisitor v, P p) { - return intersectionKind == IntersectionKind.EXPLICIT ? - v.visitIntersection(this, p) : - v.visitDeclared(this, p); + return v.visitIntersection(this, p); } } diff -r 66bcd5d4b3d1 -r 7c89d200781b src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Nov 19 23:35:43 2013 +0000 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Nov 20 13:44:39 2013 +0100 @@ -3982,10 +3982,6 @@ return bounds.head.type; } else { Type owntype = types.makeCompoundType(TreeInfo.types(bounds)); - if (tree.hasTag(TYPEINTERSECTION)) { - ((IntersectionClassType)owntype).intersectionKind = - IntersectionClassType.IntersectionKind.EXPLICIT; - } // ... the variable's bound is a class type flagged COMPOUND // (see comment for TypeVar.bound). // In this case, generate a class tree that represents the diff -r 66bcd5d4b3d1 -r 7c89d200781b src/share/classes/javax/lang/model/type/DeclaredType.java --- a/src/share/classes/javax/lang/model/type/DeclaredType.java Tue Nov 19 23:35:43 2013 +0000 +++ b/src/share/classes/javax/lang/model/type/DeclaredType.java Wed Nov 20 13:44:39 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -49,14 +49,6 @@ * Types#directSupertypes(TypeMirror)} method. This returns the * supertypes with any type arguments substituted in. * - *

This interface is also used to represent intersection types. - * An intersection type is implicit in a program rather than being - * explictly declared. For example, the bound of the type parameter - * {@code } - * is an intersection type. It is represented by a {@code DeclaredType} - * with {@code Number} as its superclass and {@code Runnable} as its - * lone superinterface. - * * @author Joseph D. Darcy * @author Scott Seligman * @author Peter von der Ahé diff -r 66bcd5d4b3d1 -r 7c89d200781b src/share/classes/javax/lang/model/type/IntersectionType.java --- a/src/share/classes/javax/lang/model/type/IntersectionType.java Tue Nov 19 23:35:43 2013 +0000 +++ b/src/share/classes/javax/lang/model/type/IntersectionType.java Wed Nov 20 13:44:39 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -30,9 +30,15 @@ /** * Represents an intersection type. * - * As of the {@link javax.lang.model.SourceVersion#RELEASE_8 - * RELEASE_8} source version, intersection types can appear as the target type - * of a cast expression. + *

An intersection type can be either implicitly or explicitly + * declared in a program. For example, the bound of the type parameter + * {@code } is an (implicit) intersection + * type. As of {@link javax.lang.model.SourceVersion#RELEASE_8 + * RELEASE_8}, this is represented by an {@code IntersectionType} with + * {@code Number} and {@code Runnable} as its bounds. Also as of the + * {@link javax.lang.model.SourceVersion#RELEASE_8 RELEASE_8}, + * intersection types can explicitly appear as the target type of a + * cast expression. * * @since 1.8 */ diff -r 66bcd5d4b3d1 -r 7c89d200781b src/share/classes/javax/lang/model/type/TypeVariable.java --- a/src/share/classes/javax/lang/model/type/TypeVariable.java Tue Nov 19 23:35:43 2013 +0000 +++ b/src/share/classes/javax/lang/model/type/TypeVariable.java Wed Nov 20 13:44:39 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -62,10 +62,9 @@ *

If this type variable was declared with no explicit * upper bounds, the result is {@code java.lang.Object}. * If it was declared with multiple upper bounds, - * the result is an intersection type (modeled as a - * {@link DeclaredType}). - * Individual bounds can be found by examining the result's - * {@linkplain Types#directSupertypes(TypeMirror) supertypes}. + * the result is an {@linkplain IntersectionType intersection type}; + * individual bounds can be found by examining the result's + * {@linkplain IntersectionType#getBounds() bounds}. * * @return the upper bound of this type variable */ diff -r 66bcd5d4b3d1 -r 7c89d200781b test/tools/javac/processing/model/type/IntersectionPropertiesTest.java --- a/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java Tue Nov 19 23:35:43 2013 +0000 +++ b/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java Wed Nov 20 13:44:39 2013 +0100 @@ -31,26 +31,27 @@ */ import com.sun.source.util.*; -import com.sun.tools.javac.api.*; -import com.sun.tools.javac.file.*; +import com.sun.tools.javac.util.Assert; import javax.annotation.processing.*; -import javax.lang.model.SourceVersion; import javax.lang.model.type.*; import javax.lang.model.util.ElementFilter; import javax.lang.model.element.*; import javax.tools.*; import java.util.*; import java.io.*; +import javax.lang.model.util.Types; public class IntersectionPropertiesTest { private int errors = 0; private static final String Intersection_name = "IntersectionTest.java"; private static final String Intersection_contents = + "import java.util.AbstractList;\n" + "import java.util.List;\n" + "import java.io.Serializable;\t" + - "public class IntersectionTest {\n" + - " void method(S s) { }\n" + + "public class IntersectionTest {\n" + + " void method(S s, One o, Two t) { }\n" + + " public static abstract class SubType extends AbstractList implements Runnable, Serializable { } \n" + "}"; private static final File classesdir = new File("intersectionproperties"); @@ -116,7 +117,8 @@ TypeParameterElement typeParameterElement = ((TypeParameterElement) typeVariable.asElement()); final List bounds = typeParameterElement.getBounds(); - final HashSet actual = new HashSet(processingEnv.getTypeUtils().directSupertypes(upperBound)); + Types types = processingEnv.getTypeUtils(); + final HashSet actual = new HashSet(types.directSupertypes(upperBound)); final HashSet expected = new HashSet(bounds); if (!expected.equals(actual)) { System.err.println("Mismatched expected and actual bounds."); @@ -128,6 +130,40 @@ System.err.println(" " + tm); errors++; } + + TypeVariable oneTypeVariable = (TypeVariable) method.getParameters().get(1).asType(); + TypeMirror oneUpperBound = oneTypeVariable.getUpperBound(); + TypeVariable twoTypeVariable = (TypeVariable) method.getParameters().get(2).asType(); + TypeMirror twoUpperBound = twoTypeVariable.getUpperBound(); + TypeElement oneUpperBoundElement = (TypeElement) types.asElement(oneUpperBound); + + Assert.checkNonNull(oneUpperBoundElement); + + Assert.check("java.util.AbstractList".equals(oneUpperBoundElement.getSuperclass().toString()), + oneUpperBoundElement.getSuperclass().toString()); + + List superInterfaces = new java.util.ArrayList<>(); + + for (TypeMirror tm : oneUpperBoundElement.getInterfaces()) { + superInterfaces.add(tm.toString()); + } + + Assert.check(java.util.Arrays.asList("java.lang.Runnable", + "java.io.Serializable").equals(superInterfaces), + superInterfaces); + + Assert.check(types.isSameType(upperBound, types.capture(upperBound))); + Assert.check(types.isSameType(types.erasure(typeVariable), types.erasure(upperBound))); + + TypeElement subTypeClass = processingEnv.getElementUtils().getTypeElement("IntersectionTest.SubType"); + + Assert.checkNonNull(subTypeClass); + + Assert.check(types.isAssignable(subTypeClass.asType(), oneUpperBound)); + Assert.check(types.isSameType(oneUpperBound, twoUpperBound)); + Assert.check(!types.isSameType(upperBound, twoUpperBound)); + Assert.check(types.isSubtype(subTypeClass.asType(), oneUpperBound)); + Assert.check(types.isSubtype(oneUpperBound, upperBound)); } }