Fixes issue 1985. Moved all subtype tests into JClassType. Added a new superclass for JParameterizedType and JRawType to make the new subtype tests simpler. Also implemented JWildcardType.getErasedType() since it was using JDelegatingClassType's version which was wrong. Patch by: mmendez, rdayal, spoon Review by: spoon, rdayal, mmendez git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1791 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JArrayType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JArrayType.java index d1e1b9f..fd67a67 100644 --- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JArrayType.java +++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JArrayType.java
@@ -1,5 +1,5 @@ /* - * Copyright 2007 Google Inc. + * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -301,45 +301,6 @@ } @Override - public boolean isAssignableFrom(JClassType possibleSubtype) { - if (this == possibleSubtype) { - // type is assignable to itself - return true; - } - - JArrayType possibleSubtypeArray = possibleSubtype.isArray(); - if (possibleSubtypeArray == null) { - // possible subtype must be an array to be assignable - return false; - } - - JType thisComponentType = getComponentType(); - JType otherComponentType = possibleSubtypeArray.getComponentType(); - - if (thisComponentType.isPrimitive() != null - || otherComponentType.isPrimitive() != null) { - /* - * Since this was not equal to the possible subtype, we know that either - * the dimensions are off or the component types are off - */ - return false; - } - - assert (thisComponentType instanceof JClassType); - assert (otherComponentType instanceof JClassType); - - JClassType thisComponentClassType = (JClassType) thisComponentType; - JClassType otherComponentClassType = (JClassType) otherComponentType; - - return thisComponentClassType.isAssignableFrom(otherComponentClassType); - } - - @Override - public boolean isAssignableTo(JClassType possibleSupertype) { - return possibleSupertype.isAssignableFrom(this); - } - - @Override public JClassType isClass() { // intentional null return null;
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java index 1f67de2..be49e4e 100644 --- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java +++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
@@ -1,5 +1,5 @@ /* - * Copyright 2007 Google Inc. + * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -23,7 +23,7 @@ import java.util.Set; /** - * Type representing a Java class or interface type. + * Type used to represent any non-primitive type. */ public abstract class JClassType extends JType implements HasAnnotations, HasMetaData { @@ -40,17 +40,268 @@ } /** - * Returns the {@link JGenericType} base type if the otherType is raw or - * parameterized type. + * Returns <code>true</code> if the rhs array type can be assigned to the + * lhs array type. */ - protected static JClassType maybeGetGenericBaseType(JClassType otherType) { - if (otherType.isParameterized() != null) { - return otherType.isParameterized().getBaseType(); - } else if (otherType.isRawType() != null) { - return otherType.isRawType().getGenericType(); + private static boolean areArraysAssignable(JArrayType lhsType, + JArrayType rhsType) { + // areClassTypesAssignable should prevent us from getting here if the types + // are referentially equal. + assert (lhsType != rhsType); + + JType lhsComponentType = lhsType.getComponentType(); + JType rhsComponentType = rhsType.getComponentType(); + + if (lhsComponentType.isPrimitive() != null + || rhsComponentType.isPrimitive() != null) { + /* + * Arrays are referentially stable so there will only be one int[] no + * matter how many times it is referenced in the code. So, if either + * component type is a primitive then we know that we are not assignable. + */ + return false; } - - return otherType; + + assert (lhsComponentType instanceof JClassType); + assert (rhsComponentType instanceof JClassType); + + JClassType thisComponentClass = (JClassType) lhsComponentType; + JClassType subtypeComponentClass = (JClassType) rhsComponentType; + + return areClassTypesAssignable(thisComponentClass, subtypeComponentClass); + } + + /** + * Returns <code>true</code> if the rhsType can be assigned to the lhsType. + */ + private static boolean areClassTypesAssignable(JClassType lhsType, + JClassType rhsType) { + // The supertypes of rhs will include rhs. + Set<JClassType> rhsSupertypes = getFlattenedSuperTypeHierarchy(rhsType); + for (JClassType rhsSupertype : rhsSupertypes) { + if (areClassTypesAssignableNoSupers(lhsType, rhsSupertype)) { + return true; + } + } + + return false; + } + + /** + * Returns <code>true</code> if the lhs and rhs are assignable without + * consideration of the supertypes of the rhs. + * + * @param lhsType + * @param rhsType + * @return + */ + private static boolean areClassTypesAssignableNoSupers(JClassType lhsType, + JClassType rhsType) { + if (lhsType == rhsType) { + // Done, these are the same types. + return true; + } + + if (lhsType == lhsType.getOracle().getJavaLangObject()) { + // Done, any type can be assigned to object. + return true; + } + + /* + * Get the generic base type, if there is one, for the lhs type and convert + * it to a raw type if it is generic. + */ + if (lhsType.isGenericType() != null) { + lhsType = lhsType.isGenericType().getRawType(); + } + + if (rhsType.isGenericType() != null) { + // Treat the generic rhs type as a raw type. + rhsType = rhsType.isGenericType().getRawType(); + } + + // Check for JTypeParameters. + JTypeParameter lhsTypeParam = lhsType.isTypeParameter(); + JTypeParameter rhsTypeParam = rhsType.isTypeParameter(); + if (lhsTypeParam != null) { + JBound bounds = lhsTypeParam.getBounds(); + JClassType[] lhsTypeBounds = bounds.getBounds(); + for (JClassType lhsTypeBound : lhsTypeBounds) { + if (!areClassTypesAssignable(lhsTypeBound, rhsType)) { + // Done, the rhsType was not assignable to one of the bounds. + return false; + } + } + + // Done, the rhsType was assignable to all of the bounds. + return true; + } else if (rhsTypeParam != null) { + JClassType[] possibleSubtypeBounds = rhsTypeParam.getBounds().getBounds(); + for (JClassType possibleSubtypeBound : possibleSubtypeBounds) { + if (areClassTypesAssignable(lhsType, possibleSubtypeBound)) { + // Done, at least one bound is assignable to this type. + return true; + } + } + + return false; + } + + /* + * Check for JWildcards. We have not examined this part in great detail + * since there should not be top level wildcard types. + */ + JWildcardType lhsWildcard = lhsType.isWildcard(); + JWildcardType rhsWildcard = rhsType.isWildcard(); + if (lhsWildcard != null && rhsWildcard != null) { + // Both types are wildcards. + return areWildcardsAssignable(lhsWildcard, rhsWildcard); + } else if (lhsWildcard != null) { + // The lhs type is a wildcard but the rhs is not. + // ? extends T, U OR ? super T, U + JBound lhsBound = lhsWildcard.getBounds(); + if (lhsBound.isUpperBound() != null) { + return areClassTypesAssignable(lhsBound.getFirstBound(), rhsType); + } else { + // ? super T will reach object no matter what the rhs type is + return true; + } + } + + // Check for JArrayTypes. + JArrayType lhsArray = lhsType.isArray(); + JArrayType rhsArray = rhsType.isArray(); + if (lhsArray != null) { + if (rhsArray == null) { + return false; + } else { + return areArraysAssignable(lhsArray, rhsArray); + } + } else if (rhsArray != null) { + // Safe although perhaps not necessary + return false; + } + + // Check for JParameterizedTypes and JRawTypes. + JMaybeParameterizedType lhsMaybeParameterized = lhsType.isMaybeParameterizedType(); + JMaybeParameterizedType rhsMaybeParameterized = rhsType.isMaybeParameterizedType(); + if (lhsMaybeParameterized != null && rhsMaybeParameterized != null) { + if (lhsMaybeParameterized.getBaseType() == rhsMaybeParameterized.getBaseType()) { + if (lhsMaybeParameterized.isRawType() != null + || rhsMaybeParameterized.isRawType() != null) { + /* + * Any raw type can be assigned to or from any parameterization of its + * generic type. + */ + return true; + } + + assert (lhsMaybeParameterized.isRawType() == null && + rhsMaybeParameterized.isRawType() == null); + JParameterizedType lhsParameterized = lhsMaybeParameterized.isParameterized(); + JParameterizedType rhsParameterized = rhsMaybeParameterized.isParameterized(); + assert (lhsParameterized != null && rhsParameterized != null); + + return areTypeArgumentsAssignable(lhsParameterized, + rhsParameterized); + } + } + + // Default to not being assignable. + return false; + } + + /** + * Returns <code>true</code> if the type arguments of the rhs parameterized + * type are assignable to the type arguments of the lhs parameterized type. + */ + private static boolean areTypeArgumentsAssignable(JParameterizedType lhsType, + JParameterizedType rhsType) { + // areClassTypesAssignable should prevent us from getting here if the types + // are referentially equal. + assert (lhsType != rhsType); + assert (lhsType.getBaseType() == rhsType.getBaseType()); + + JClassType[] lhsTypeArgs = lhsType.getTypeArgs(); + JClassType[] rhsTypeArgs = rhsType.getTypeArgs(); + JGenericType lhsBaseType = lhsType.getBaseType(); + + // Compare at least as many formal type parameters as are declared on the + // generic base type. gwt.typeArgs could cause more types to be included. + + JTypeParameter[] lhsTypeParams = lhsBaseType.getTypeParameters(); + for (int i = 0; i < lhsTypeParams.length; ++i) { + if (!doesTypeArgumentContain(lhsTypeArgs[i], rhsTypeArgs[i])) { + return false; + } + } + + return true; + } + + /** + * Returns <code>true</code> if the rhsWildcard can be assigned to the + * lhsWildcard. This method does not consider supertypes of either + * lhs or rhs. + */ + private static boolean areWildcardsAssignable(JWildcardType lhsWildcard, + JWildcardType rhsWildcard) { + // areClassTypesAssignable should prevent us from getting here if the types + // are referentially equal. + assert (lhsWildcard != rhsWildcard); + assert (lhsWildcard != null && rhsWildcard != null); + + JBound lhsBound = lhsWildcard.getBounds(); + JBound rhsBound = rhsWildcard.getBounds(); + + if (lhsBound.isUpperBound() != null && rhsBound.isUpperBound() != null) { + // lhsType: ? extends T, rhsType: ? extends U + return areClassTypesAssignable(lhsBound.getFirstBound(), + rhsBound.getFirstBound()); + } else if (lhsBound.isLowerBound() != null + && rhsBound.isLowerBound() != null) { + // lhsType: ? super T, rhsType ? super U + return areClassTypesAssignable(rhsBound.getFirstBound(), + lhsBound.getFirstBound()); + } + + return false; + } + + /** + * A restricted version of areClassTypesAssignable that is used for comparing + * the type arguments of parameterized types, where the lhsTypeArg is the + * container. + */ + private static boolean doesTypeArgumentContain(JClassType lhsTypeArg, + JClassType rhsTypeArg) { + if (lhsTypeArg == rhsTypeArg) { + return true; + } + + // Check for wildcard types + JWildcardType lhsWildcard = lhsTypeArg.isWildcard(); + JWildcardType rhsWildcard = rhsTypeArg.isWildcard(); + + if (lhsWildcard != null) { + if (rhsWildcard != null) { + return areWildcardsAssignable(lhsWildcard, rhsWildcard); + } else { + // LHS is a wildcard but the RHS is not. + JBound lhsBound = lhsWildcard.getBounds(); + if (lhsBound.isLowerBound() == null) { + return areClassTypesAssignable(lhsBound.getFirstBound(), rhsTypeArg); + } else { + return areClassTypesAssignable(rhsTypeArg, lhsBound.getFirstBound()); + } + } + } + + /* + * At this point the arguments are not the same and they are not wildcards + * so, they cannot be assignable, Eh. + */ + return false; } private static void getFlattenedSuperTypeHierarchyRecursive(JClassType type, @@ -72,7 +323,7 @@ getFlattenedSuperTypeHierarchyRecursive(intf, typesSeen); } } - + public abstract void addImplementedInterface(JClassType intf); public abstract void addMetaData(String tagName, String[] values); @@ -171,9 +422,13 @@ public abstract boolean isAnnotationPresent( Class<? extends Annotation> annotationClass); - public abstract boolean isAssignableFrom(JClassType possibleSubtype); + public boolean isAssignableFrom(JClassType possibleSubtype) { + return areClassTypesAssignable(this, possibleSubtype); + } - public abstract boolean isAssignableTo(JClassType possibleSupertype); + public boolean isAssignableTo(JClassType possibleSupertype) { + return areClassTypesAssignable(possibleSupertype, this); + } /** * Determines if the class can be constructed using a simple <code>new</code> @@ -243,6 +498,10 @@ protected abstract void getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface( Map<String, JMethod> methodsBySignature); + protected JMaybeParameterizedType isMaybeParameterizedType() { + return null; + } + protected final String makeCompoundName(JClassType type) { if (type.getEnclosingType() == null) { return type.getSimpleSourceName();
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JDelegatingClassType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JDelegatingClassType.java index e421658..62ab6cd 100644 --- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JDelegatingClassType.java +++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JDelegatingClassType.java
@@ -1,5 +1,5 @@ /* - * Copyright 2007 Google Inc. + * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -253,16 +253,6 @@ } @Override - public boolean isAssignableFrom(JClassType possibleSubtype) { - return baseType.isAssignableFrom(possibleSubtype); - } - - @Override - public boolean isAssignableTo(JClassType possibleSupertype) { - return baseType.isAssignableTo(possibleSupertype); - } - - @Override public JClassType isClass() { if (baseType.isClass() != null) { return this;
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JGenericType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JGenericType.java index 50441dc..1297351 100644 --- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JGenericType.java +++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JGenericType.java
@@ -17,33 +17,11 @@ import java.util.ArrayList; import java.util.List; -import java.util.Set; /** - * + * Type declaration that has type parameters. */ public class JGenericType extends JRealClassType implements HasTypeParameters { - /** - * Returns <code>true</code> if lhsType is assignable to rhsType. - */ - private static boolean isAssignable(JClassType lhsType, JClassType rhsType) { - if (lhsType == rhsType) { - return true; - } - - Set<JClassType> supertypes = getFlattenedSuperTypeHierarchy(rhsType); - for (JClassType supertype : supertypes) { - if (supertype.isParameterized() == null) { - continue; - } - - if (supertype.isParameterized().getBaseType() == lhsType) { - return true; - } - } - - return false; - } private JRawType lazyRawType = null; @@ -107,20 +85,6 @@ } @Override - public boolean isAssignableFrom(JClassType otherType) { - otherType = maybeGetGenericBaseType(otherType); - - return isAssignable(this, otherType); - } - - @Override - public boolean isAssignableTo(JClassType otherType) { - otherType = maybeGetGenericBaseType(otherType); - - return isAssignable(otherType, this); - } - - @Override public JGenericType isGenericType() { return this; }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JMaybeParameterizedType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JMaybeParameterizedType.java new file mode 100644 index 0000000..ee130ef --- /dev/null +++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JMaybeParameterizedType.java
@@ -0,0 +1,38 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.core.ext.typeinfo; + +/** + * Super class for parameterized types or raw types. + */ +abstract class JMaybeParameterizedType extends JDelegatingClassType { + + public JMaybeParameterizedType() { + super(); + } + + @Override + public JGenericType getBaseType() { + JGenericType genericType = super.getBaseType().isGenericType(); + assert (genericType != null); + return genericType; + } + + @Override + protected JMaybeParameterizedType isMaybeParameterizedType() { + return this; + } +} \ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameterizedType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameterizedType.java index 3c27edf..ec7ae54 100644 --- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameterizedType.java +++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameterizedType.java
@@ -1,5 +1,5 @@ /* - * Copyright 2007 Google Inc. + * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -25,41 +25,7 @@ /** * Represents a parameterized type in a declaration. */ -public class JParameterizedType extends JDelegatingClassType { - private static boolean areTypeArgsAssignableFrom(JClassType[] myTypeArgs, - JClassType[] otherTypeArgs) { - assert (myTypeArgs.length <= otherTypeArgs.length); - - for (int i = 0; i < myTypeArgs.length; ++i) { - JClassType myTypeArg = myTypeArgs[i]; - JClassType otherTypeArg = otherTypeArgs[i]; - - if (myTypeArg.isTypeParameter() != null) { - /* - * If my type argument is a type parameter consider it's erased form. This - * avoids recursion sickness in the case where my type argument is of the - * form: - * - * T extends Serializable & Comparable<T> - * - * and otherTypeArg is something like Long, Short, etc. - */ - return myTypeArg.getErasedType().isAssignableFrom(otherTypeArg); - } - - if (myTypeArg.isWildcard() == null) { - // myTypeArg needs to be a wildcard or we cannot be assignable. - return false; - } - - if (!myTypeArg.isAssignableFrom(otherTypeArg)) { - return false; - } - } - - return true; - } - +public class JParameterizedType extends JMaybeParameterizedType { /** * Create a parameterized type along with any necessary enclosing * parameterized types. Enclosing parameterized types are necessary when the @@ -99,77 +65,6 @@ return parameterizedType; } - /** - * Returns <code>true</code> if the rhsType can be assigned to the lhsType. - */ - private static boolean isAssignable(JClassType lhsType, JClassType rhsType) { - if (lhsType == rhsType) { - return true; - } - - Set<JClassType> rhsSupertypes = getFlattenedSuperTypeHierarchy(rhsType); - if (rhsSupertypes.contains(lhsType)) { - // Done, appears explicitly in the supertype hierarchy. - return true; - } - - /* - * Get the generic base type for the lhsType if there is one. - */ - JGenericType lhsBaseType = null; - if (lhsType.isParameterized() != null) { - lhsBaseType = lhsType.isParameterized().getBaseType(); - } else if (lhsType.isRawType() != null) { - lhsBaseType = lhsType.isRawType().getBaseType(); - } - - /* - * Check the supertype hierarchy to see if we can find a parameterization - * or a raw type that would satisfy the assignment. - */ - for (JClassType rhsSupertype : rhsSupertypes) { - if (rhsSupertype.isGenericType() != null) { - /* - * A generic type will be treated as its raw type for assignment - * purposes. - */ - rhsSupertype = rhsSupertype.isGenericType().getRawType(); - } - - JParameterizedType rhsParameterized = rhsSupertype.isParameterized(); - if (rhsParameterized != null) { - if (rhsParameterized.getBaseType() == lhsBaseType) { - /* - * This supertype and the lhsType have the same base type, but they - * have different parameterizations so we test them. - */ - assert (rhsParameterized != lhsType); - - if (lhsType.isRawType() != null) { - // The lhsType is raw so we do not need to check the parameterization. - return true; - } else { - assert (lhsType.isParameterized() != null); - - return areTypeArgsAssignableFrom( - lhsType.isParameterized().getTypeArgs(), - rhsParameterized.getTypeArgs()); - } - } - } else if (rhsSupertype.isRawType() != null) { - if (rhsSupertype.isRawType().getBaseType() == lhsBaseType) { - /* - * The raw supertype has the same base type as the lhsType so the - * assignment is okay. - */ - return true; - } - } - } - - return false; - } - private final JClassType enclosingType; private List<JClassType> interfaces; @@ -229,11 +124,6 @@ } @Override - public JGenericType getBaseType() { - return (JGenericType) super.getBaseType(); - } - - @Override public JConstructor getConstructor(JType[] paramTypes) throws NotFoundException { return members.getConstructor(paramTypes); @@ -424,16 +314,6 @@ } @Override - public boolean isAssignableFrom(JClassType otherType) { - return isAssignable(this, otherType); - } - - @Override - public boolean isAssignableTo(JClassType otherType) { - return isAssignable(otherType, this); - } - - @Override public JGenericType isGenericType() { return null; }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRawType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRawType.java index 63ba139..b7a6017 100644 --- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRawType.java +++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRawType.java
@@ -1,5 +1,5 @@ /* - * Copyright 2007 Google Inc. + * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -21,7 +21,7 @@ /** * Represents a raw type; that is a generic type with no type arguments. */ -public class JRawType extends JDelegatingClassType { +public class JRawType extends JMaybeParameterizedType { private static final Substitution ERASURE_SUBSTITUTION = new Substitution() { public JType getSubstitution(JType type) { return type.getErasedType(); @@ -64,13 +64,6 @@ } @Override - public JGenericType getBaseType() { - JGenericType genericType = super.getBaseType().isGenericType(); - assert (genericType != null); - return genericType; - } - - @Override public JConstructor getConstructor(JType[] paramTypes) throws NotFoundException { return members.getConstructor(paramTypes); @@ -181,20 +174,6 @@ } @Override - public boolean isAssignableFrom(JClassType otherType) { - otherType = maybeGetGenericBaseType(otherType); - - return getBaseType().isAssignableFrom(otherType); - } - - @Override - public boolean isAssignableTo(JClassType otherType) { - otherType = maybeGetGenericBaseType(otherType); - - return getBaseType().isAssignableTo(otherType); - } - - @Override public JGenericType isGenericType() { return null; }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java index 2411d2c..78a0779 100644 --- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java +++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java
@@ -1,5 +1,5 @@ /* - * Copyright 2007 Google Inc. + * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -27,7 +27,7 @@ import java.util.Set; /** - * Type representing a Java class or interface type. + * Type representing a Java class or interface type that a user would declare. */ public class JRealClassType extends JClassType { @@ -325,51 +325,6 @@ } @Override - public boolean isAssignableFrom(JClassType otherType) { - if (otherType == this) { - return true; - } - - if (allSubtypes.contains(otherType)) { - // JGenericTypes should appear in the allSubtypes hierarchy - do nothing - return true; - } else if (this == getOracle().getJavaLangObject()) { - // This case handles the odd "every interface is an Object" - // but doesn't actually have Object as a superclass. - // - return true; - } else { - if (otherType.isTypeParameter() != null) { - return otherType.isAssignableTo(this); - } - - if (otherType.isWildcard() != null) { - return otherType.isAssignableTo(this); - } - - if (otherType.isGenericType() != null) { - return otherType.isAssignableTo(this); - } - - if (otherType.isRawType() != null) { - return otherType.isAssignableTo(this); - } - - if (otherType.isParameterized() != null) { - return otherType.isAssignableTo(this); - } - - // At this point we should only have JArrayTypes or JRealClassTypes from - // which we are not assignable. - return false; - } - } - - public boolean isAssignableTo(JClassType possibleSupertype) { - return possibleSupertype.isAssignableFrom(this); - } - - @Override public JClassType isClass() { return isInterface ? null : this; }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JTypeParameter.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JTypeParameter.java index 4262c0e..874e4c4 100644 --- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JTypeParameter.java +++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JTypeParameter.java
@@ -118,24 +118,6 @@ } @Override - public boolean isAssignableFrom(JClassType otherType) { - if (otherType == this) { - return true; - } - - return getBounds().isAssignableFrom(otherType); - } - - @Override - public boolean isAssignableTo(JClassType otherType) { - if (otherType == this) { - return true; - } - - return getBounds().isAssignableTo(otherType); - } - - @Override public JGenericType isGenericType() { return null; }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JWildcardType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JWildcardType.java index 20b8e53..a6d18dc 100644 --- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JWildcardType.java +++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JWildcardType.java
@@ -1,5 +1,5 @@ /* - * Copyright 2007 Google Inc. + * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -41,6 +41,17 @@ } @Override + public JClassType getErasedType() { + if (bounds.isLowerBound() != null) { + // ? super T erases to Object + return getOracle().getJavaLangObject(); + } + + // ? extends T erases to T + return getFirstBound(); + } + + @Override public JField getField(String name) { return getBaseType().getField(name); } @@ -74,30 +85,27 @@ public String getSimpleSourceName() { return "?" + bounds.getSimpleSourceName(); } - + @Override public JClassType[] getSubtypes() { + // We are not sure what the correct behavior should be for lower bound + // wildcards. ? super Number contains ? super T for all T extends Number, + // but it also includes T for Number extends T. For example, Object is a + // subtype. return bounds.getSubtypes(); } - + @Override - public boolean isAssignableFrom(JClassType otherType) { - if (otherType == this) { - return true; + public JClassType getSuperclass() { + if (bounds.isLowerBound() != null) { + // The only safe superclass for a ? super T is Object. + return getOracle().getJavaLangObject(); } - return getBounds().isAssignableFrom(otherType); + // The superclass of an upper bound is the upper bound. + return getFirstBound(); } - - @Override - public boolean isAssignableTo(JClassType otherType) { - if (otherType == this) { - return true; - } - - return getBounds().isAssignableTo(otherType); - } - + @Override public JGenericType isGenericType() { return null;
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JGenericTypeTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JGenericTypeTest.java index 5a443f1..d3e9ef3 100644 --- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JGenericTypeTest.java +++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JGenericTypeTest.java
@@ -184,9 +184,54 @@ JClassType[] bounds = bound.getBounds(); assertEquals(1, bounds.length); - assertEquals(moduleContext.getOracle().getJavaLangObject(), bounds[0]); + assertEquals(moduleContext.getOracle().getType(Serializable.class.getName()), + bounds[0]); + } + + /** + * Test method for {@link + * com.google.gwt.core.ext.typeinfo.JGenericType#isAssignableFrom(JClassType)}. + * + * @throws NotFoundException + */ + public void testIsAssignableFrom() throws NotFoundException { + JGenericType genericType = getTestType(); + + // Check that the generic type's superclass is assignable from the generic type + assertTrue(genericType.getSuperclass().isAssignableFrom(genericType)); + + // Check that each implemented interface is assignable from the generic type + JClassType[] implementedInterfaces = genericType.getImplementedInterfaces(); + for (JClassType implementedInterface : implementedInterfaces) { + assertTrue(implementedInterface.isAssignableFrom(genericType)); + assertTrue(implementedInterface.isAssignableFrom(genericType.getRawType())); + } + } + + /** + * Test method for {@link + * com.google.gwt.core.ext.typeinfo.JGenericType#isAssignableTo(JClassType)}. + * + * @throws NotFoundException + */ + public void testIsAssignableTo() throws NotFoundException { + JGenericType genericType = getTestType(); + + // Check that generic type is assignable to its superclass + assertTrue(genericType.isAssignableTo(genericType.getSuperclass())); + + // Check that the generic class is assignable to any implemented interface + JClassType[] implementedInterfaces = genericType.getImplementedInterfaces(); + for (JClassType implementedInterface : implementedInterfaces) { + assertTrue(genericType.isAssignableTo(implementedInterface)); + + if (implementedInterface.isParameterized() != null) { + assertTrue(genericType.isAssignableTo(implementedInterface.isParameterized().getRawType())); + } + } } + /** * Returns the generic version of {@link GenericClass}. */
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JParameterizedTypeTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JParameterizedTypeTest.java index ca91c61..0b23f6b 100644 --- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JParameterizedTypeTest.java +++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JParameterizedTypeTest.java
@@ -1,5 +1,5 @@ /* - * Copyright 2007 Google Inc. + * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -19,6 +19,7 @@ import com.google.gwt.core.ext.UnableToCompleteException; import com.google.gwt.core.ext.typeinfo.test.Base; import com.google.gwt.core.ext.typeinfo.test.Derived; +import com.google.gwt.core.ext.typeinfo.test.ExtendsRawGenericClass; import com.google.gwt.core.ext.typeinfo.test.GenericClass; import com.google.gwt.core.ext.typeinfo.test.MyCustomList; import com.google.gwt.core.ext.typeinfo.test.MyIntegerList; @@ -32,6 +33,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.Vector; /** * Test for {@link JParameterizedType}. @@ -228,33 +230,43 @@ TypeOracle oracle = moduleContext.getOracle(); JGenericType genericList = (JGenericType) oracle.getType(List.class.getName()); + // ? JWildcardType unboundWildcard = oracle.getWildcardType(new JUpperBound( oracle.getJavaLangObject())); + + // ? extends Number JWildcardType numUpperBoundWildcard = oracle.getWildcardType(new JUpperBound( oracle.getType(Number.class.getName()))); - // List<?> should be assignable from List<? extends Number> + // List<?> JParameterizedType unboundList = oracle.getParameterizedType(genericList, new JClassType[] {unboundWildcard}); - JParameterizedType numUpperBoundList = oracle.getParameterizedType( + + // List<? extends Number> + JParameterizedType listOfExtendsNumber = oracle.getParameterizedType( genericList, new JClassType[] {numUpperBoundWildcard}); - assertTrue(unboundList.isAssignableFrom(numUpperBoundList)); - assertFalse(unboundList.isAssignableTo(numUpperBoundList)); + + // List<?> should be assignable from List<? extends Number> + assertTrue(unboundList.isAssignableFrom(listOfExtendsNumber)); + assertFalse(unboundList.isAssignableTo(listOfExtendsNumber)); - assertFalse(numUpperBoundList.isAssignableFrom(unboundList)); - assertTrue(numUpperBoundList.isAssignableTo(unboundList)); + assertFalse(listOfExtendsNumber.isAssignableFrom(unboundList)); + assertTrue(listOfExtendsNumber.isAssignableTo(unboundList)); - // List<? extends Number> should be assignable from List<? extends Integer> + // ? extends Integer JWildcardType intUpperBoundWildcard = oracle.getWildcardType(new JUpperBound( integerType)); - JParameterizedType intUpperBoundList = oracle.getParameterizedType( + // List<? extends Integer> + JParameterizedType listOfExtendsInteger = oracle.getParameterizedType( genericList, new JClassType[] {intUpperBoundWildcard}); - assertTrue(numUpperBoundList.isAssignableFrom(intUpperBoundList)); - assertFalse(numUpperBoundList.isAssignableTo(intUpperBoundList)); - assertFalse(intUpperBoundList.isAssignableFrom(numUpperBoundList)); - assertTrue(intUpperBoundList.isAssignableTo(numUpperBoundList)); + // List<? extends Number> should be assignable from List<? extends Integer> + assertTrue(listOfExtendsNumber.isAssignableFrom(listOfExtendsInteger)); + assertFalse(listOfExtendsNumber.isAssignableTo(listOfExtendsInteger)); + + assertFalse(listOfExtendsInteger.isAssignableFrom(listOfExtendsNumber)); + assertTrue(listOfExtendsInteger.isAssignableTo(listOfExtendsNumber)); // List<? super Integer> should be assignable from List<? super Number> JWildcardType numLowerBoundWildcard = oracle.getWildcardType(new JLowerBound( @@ -262,15 +274,83 @@ JWildcardType intLowerBoundWildcard = oracle.getWildcardType(new JLowerBound( integerType)); - JParameterizedType numLowerBoundList = oracle.getParameterizedType( + // List<? super Number> + JParameterizedType listOfSuperNumber = oracle.getParameterizedType( genericList, new JClassType[] {numLowerBoundWildcard}); - JParameterizedType intLowerBoundList = oracle.getParameterizedType( + + // List<? super Interger> + JParameterizedType listOfSuperInteger = oracle.getParameterizedType( genericList, new JClassType[] {intLowerBoundWildcard}); - assertTrue(intLowerBoundList.isAssignableFrom(numLowerBoundList)); - assertFalse(intLowerBoundList.isAssignableTo(numLowerBoundList)); - assertFalse(numLowerBoundList.isAssignableFrom(intLowerBoundList)); - assertTrue(numLowerBoundList.isAssignableTo(intLowerBoundList)); + assertTrue(listOfSuperInteger.isAssignableFrom(listOfSuperNumber)); + assertFalse(listOfSuperInteger.isAssignableTo(listOfSuperNumber)); + assertFalse(listOfSuperNumber.isAssignableFrom(listOfSuperInteger)); + assertTrue(listOfSuperNumber.isAssignableTo(listOfSuperInteger)); + + JParameterizedType listOfObject = oracle.getParameterizedType(genericList, + new JClassType[] {oracle.getJavaLangObject()}); + + JClassType stringType = oracle.getType(String.class.getName()); + JParameterizedType listOfString = oracle.getParameterizedType(genericList, + new JClassType[] {stringType}); + + // List<Object> is not assignable from List<String> + assertFalse(listOfObject.isAssignableFrom(listOfString)); + + // List<String> is not assignable from List<Object> + assertFalse(listOfString.isAssignableFrom(listOfObject)); + + // List<List<String>> is not assignable from List<Vector<String>> + JParameterizedType listOfListOfString = oracle.getParameterizedType( + genericList, new JClassType[] {listOfString}); + + JGenericType genericVector = oracle.getType(Vector.class.getName()).isGenericType(); + JParameterizedType vectorOfString = oracle.getParameterizedType(genericVector, new JClassType[] {stringType}); + JParameterizedType listOfVectorOfString = oracle.getParameterizedType(genericList, new JClassType[] {vectorOfString}); + + assertFalse(listOfListOfString.isAssignableFrom(listOfVectorOfString)); + assertFalse(listOfVectorOfString.isAssignableFrom(listOfListOfString)); + + // List<List> is not assignable from List<List<String>> + JClassType listOfRawList = oracle.getParameterizedType(genericList, new JClassType[] {genericList.getRawType()}); + assertFalse(listOfRawList.isAssignableFrom(listOfListOfString)); + assertFalse(listOfListOfString.isAssignableFrom(listOfRawList)); + + JGenericType genericClass = oracle.getType(GenericClass.class.getName()).isGenericType(); + JParameterizedType parameterizedGenericClass = oracle.getParameterizedType(genericClass, new JClassType[] {stringType}); + JClassType extendsRawGenericClass = oracle.getType(ExtendsRawGenericClass.class.getName()); + + // GenericClass<String> is assignable from ExtendsRawGenericClass + assertTrue(parameterizedGenericClass.isAssignableFrom(extendsRawGenericClass)); + + // ExtendsRawGenericClass is not assignable from GenericClass<String> + assertFalse(extendsRawGenericClass.isAssignableFrom(parameterizedGenericClass)); + + // List<List<? extends Number>> + JClassType listOfListOfExtendsNumber = oracle.getParameterizedType(genericList, new JClassType[] {listOfExtendsNumber}); + + // List<List<? extends Integer>> + JClassType listOfListOfExtendsInteger = oracle.getParameterizedType(genericList, new JClassType[] {listOfExtendsInteger}); + + assertFalse(listOfListOfExtendsNumber.isAssignableFrom(listOfListOfExtendsInteger)); + + // List<Integer> + JClassType listOfInteger = oracle.getParameterizedType(genericList, new JClassType[] {integerType}); + + // List<? extends Number> is assignable from List<Integer> + assertTrue(listOfExtendsNumber.isAssignableFrom(listOfInteger)); + assertFalse(listOfExtendsNumber.isAssignableFrom(listOfObject)); + + // List<? super Number> is not assignable from List<Integer> + assertFalse(listOfSuperNumber.isAssignableFrom(listOfInteger)); + + // List<? super Number> is assignable from List<Object> + assertTrue(listOfSuperNumber.isAssignableFrom(listOfObject)); + } + + @Override + public void testIsAssignableTo() throws NotFoundException { + // This is covered as part of testIsAssignableFrom } public void testOverridableMethods_Base() throws NotFoundException { @@ -396,9 +476,4 @@ assertTrue(expectedMethods.isEmpty()); } - - @Override - public void testIsAssignableTo() throws NotFoundException { - // This is covered as part of testIsAssignableFrom - } }
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JTypeParameterTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JTypeParameterTest.java index 9066707..55d4724 100644 --- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JTypeParameterTest.java +++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JTypeParameterTest.java
@@ -23,11 +23,25 @@ import java.io.Serializable; import java.util.Arrays; +import java.util.Set; /** * Tests for {@link JTypeParameter}. */ public class JTypeParameterTest extends JDelegatingClassTypeTestBase { + private static JClassType findParameterizationOf(JClassType classType, + JGenericType genericType) { + Set<JClassType> supertypes = JClassType.getFlattenedSuperTypeHierarchy(classType); + for (JClassType supertype : supertypes) { + JMaybeParameterizedType maybeParameterizedType = supertype.isMaybeParameterizedType(); + if (maybeParameterizedType != null && maybeParameterizedType.getBaseType() == genericType) { + return supertype; + } + } + + return null; + } + private final boolean logToConsole = false; private final ModuleContext moduleContext = new ModuleContext(logToConsole ? new PrintWriterTreeLogger() : TreeLogger.NULL, @@ -80,13 +94,13 @@ } /* - * Checks that all non-local subtypes of the type parameter, - * T extends Serializable & Comparable<T> are actually assignable to - * Serializable and the properly parameterized version of Comparable<T>. + * Checks that all non-local subtypes of the type parameter, T extends + * Serializable & Comparable<T> are actually assignable to Serializable and + * the properly parameterized version of Comparable<T>. */ @Override public void testGetSubtypes() throws NotFoundException { - + TypeOracle oracle = moduleContext.getOracle(); JClassType testType = oracle.getType(MyCustomList.class.getName()); JGenericType genericType = testType.isGenericType(); @@ -96,29 +110,48 @@ JClassType serializableType = oracle.getType(Serializable.class.getCanonicalName()); JGenericType comparableType = (JGenericType) oracle.getType(Comparable.class.getCanonicalName()); JClassType[] computedSubtypes = typeParameter.getSubtypes(); - + for (JClassType computedSubtype : computedSubtypes) { - JParameterizedType parameterizedComparableType = oracle.getParameterizedType( - comparableType, new JClassType[] {computedSubtype}); if (computedSubtype.isLocalType()) { // Ignore local types. continue; } + // Find the parameterized version of the Comparable interface. + JClassType comparableIntf = findParameterizationOf(computedSubtype, + comparableType); + assertTrue(computedSubtype.isAssignableTo(serializableType)); - assertTrue(computedSubtype.isAssignableTo(parameterizedComparableType)); + assertTrue(computedSubtype.isAssignableTo(comparableIntf)); } } @Override public void testIsAssignableFrom() throws NotFoundException { JTypeParameter testType = getTestType(); - assertTrue(testType.isAssignableFrom(moduleContext.getOracle().getJavaLangObject())); + assertTrue(testType.isAssignableFrom(moduleContext.getOracle().getType( + Serializable.class.getName()))); + + // Check that the type parameter is assignable from each subtype + JClassType[] subtypes = testType.getSubtypes(); + for (JClassType subtype : subtypes) { + assertTrue(testType.isAssignableFrom(subtype)); + } } @Override public void testIsAssignableTo() throws NotFoundException { JTypeParameter testType = getTestType(); assertTrue(testType.isAssignableTo(moduleContext.getOracle().getJavaLangObject())); + + // Check that each bound is assignable to this type parameter. + JClassType[] typeBounds = testType.getBounds().getBounds(); + for (JClassType typeBound : typeBounds) { + // Test that the type parameter is assignable to the type bound. + assertTrue(testType.isAssignableTo(typeBound)); + + // Test that the type parameter is assignable from the type bound. + assertTrue(typeBound.isAssignableFrom(testType)); + } } @Override
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JWildcardTypeTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JWildcardTypeTest.java index 367a39d..fa6c004 100644 --- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JWildcardTypeTest.java +++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JWildcardTypeTest.java
@@ -1,5 +1,5 @@ /* - * Copyright 2007 Google Inc. + * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -24,6 +24,7 @@ import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -57,6 +58,20 @@ // Wildcard do not have nested types... } + @Override + public void testGetErasedType() throws NotFoundException { + TypeOracle oracle = moduleContext.getOracle(); + JClassType numberType = oracle.getType(Number.class.getCanonicalName()); + + // Tests that ? extends Number erases to number. + JWildcardType upperBoundWildcard = oracle.getWildcardType(new JUpperBound(numberType)); + assertEquals(numberType, upperBoundWildcard.getErasedType()); + + // Tests that ? super Number erases to Object + JWildcardType lowerBoundWildcard = oracle.getWildcardType(new JLowerBound(numberType)); + assertEquals(oracle.getJavaLangObject(), lowerBoundWildcard.getErasedType()); + } + public void testGetMethods() throws NotFoundException { super.testGetMethods(); } @@ -112,8 +127,46 @@ } @Override - public void testIsAssignableFrom() { + public void testIsAssignableFrom() throws NotFoundException { // Covered by the different testIsAssignableFrom*() variants below. + TypeOracle oracle = moduleContext.getOracle(); + + + JClassType integerType = oracle.getType(Integer.class.getName()); + JClassType numberType = oracle.getType(Number.class.getName()); + + // ? extends Number + JClassType extendsNumber = oracle.getWildcardType(new JUpperBound(numberType)); + + // ? extends Integer + JClassType extendsInteger = oracle.getWildcardType(new JUpperBound(integerType)); + + // Integer is not assignable from ? extends Number + assertFalse(integerType.isAssignableFrom(extendsNumber)); + + // Integer is assignable from ? extends Integer + assertTrue(integerType.isAssignableFrom(extendsInteger)); + + // Number is assignable from ? extends Integer + assertTrue(numberType.isAssignableFrom(extendsInteger)); + + // ? super Integer + JClassType superInteger = oracle.getWildcardType(new JLowerBound(integerType)); + + // Integer is assignable from ? super Integer + assertFalse(integerType.isAssignableFrom(superInteger)); + + // ? super Integer is assignable from Number + assertTrue(superInteger.isAssignableFrom(numberType)); + + JClassType superNumber = oracle.getWildcardType(new JLowerBound(numberType)); + + // ? super Number is assignable from Integer + assertTrue(superNumber.isAssignableFrom(integerType)); + + // ? super Number is assignable from Character + JClassType characterType = oracle.getType(Character.class.getName()); + assertTrue(superNumber.isAssignableFrom(characterType)); } /** @@ -137,8 +190,7 @@ } /** - * Tests that <? extends Number> is assignable from <? extends Integer> and - * that the reverse is not <code>true</code>. + * Tests that <? extends Object> is assignable to and from <? super Object>. */ public void testIsAssignableFrom_Extends_Object_From_Super_Object() { TypeOracle oracle = moduleContext.getOracle(); @@ -147,16 +199,21 @@ JLowerBound lowerBound = new JLowerBound(javaLangObject); JUpperBound upperBound = new JUpperBound(javaLangObject); + // ? super Object JWildcardType lowerWildcard = oracle.getWildcardType(lowerBound); + + // ? extends Object JWildcardType upperWildcard = oracle.getWildcardType(upperBound); + // ? extends Object assignable from ? super Object assertTrue(upperWildcard.isAssignableFrom(lowerWildcard)); - assertFalse(lowerWildcard.isAssignableFrom(upperWildcard)); + + // ? super Object assignable from ? extends Object + assertTrue(lowerWildcard.isAssignableFrom(upperWildcard)); } /** - * Tests that <? super Integer> is assignable from <? super Number> and that - * the reverse is not <code>true</code>. + * Tests that <? super Integer> is assignable to and from <? super Number>. */ public void testIsAssignableFrom_Super_Integer_From_Super_Number() throws NotFoundException { @@ -170,15 +227,14 @@ JWildcardType numberWildcard = oracle.getWildcardType(numberBound); JWildcardType integerWildcard = oracle.getWildcardType(integerBound); - assertFalse(numberWildcard.isAssignableFrom(integerWildcard)); + assertTrue(numberWildcard.isAssignableFrom(integerWildcard)); assertTrue(numberWildcard.isAssignableTo(integerWildcard)); assertTrue(integerWildcard.isAssignableFrom(numberWildcard)); - assertFalse(integerWildcard.isAssignableTo(numberWildcard)); + assertTrue(integerWildcard.isAssignableTo(numberWildcard)); } /** - * Tests that <? super Number> is assignable to <? super Integer> and that the - * reverse is not <code>true</code>. + * Tests that <? super Number> is assignable to and from <? super Integer>. */ public void testIsAssignableFrom_Super_Number_To_Super_Integer() throws NotFoundException { @@ -193,7 +249,7 @@ JWildcardType integerWildcard = oracle.getWildcardType(integerBound); assertTrue(numberWildcard.isAssignableTo(integerWildcard)); - assertFalse(integerWildcard.isAssignableTo(numberWildcard)); + assertTrue(integerWildcard.isAssignableTo(numberWildcard)); } @Override @@ -222,8 +278,7 @@ } /** - * Tests that <? super Number> is assignable to <? super Integer> and that - * the reverse is not <code>true</code>. + * Tests that <? super Number> is assignable to and from <? super Integer>. */ public void testIsAssignableTo_Super_Number_To_Super_Integer() throws NotFoundException { @@ -237,7 +292,7 @@ JWildcardType numberWildcard = oracle.getWildcardType(numberBound); JWildcardType integerWildcard = oracle.getWildcardType(integerBound); - assertFalse(integerWildcard.isAssignableTo(numberWildcard)); + assertTrue(integerWildcard.isAssignableTo(numberWildcard)); assertTrue(numberWildcard.isAssignableTo(integerWildcard)); }
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/ExtendsRawGenericClass.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/ExtendsRawGenericClass.java new file mode 100644 index 0000000..f6a6bd9 --- /dev/null +++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/ExtendsRawGenericClass.java
@@ -0,0 +1,23 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.core.ext.typeinfo.test; + +/** + * Class used to test assignment between a parameterized type and a subclass + * of the raw version. + */ +public class ExtendsRawGenericClass extends GenericClass { +}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClass.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClass.java index 047b3af..f328c00 100644 --- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClass.java +++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClass.java
@@ -1,5 +1,5 @@ /* - * Copyright 2007 Google Inc. + * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -29,7 +29,7 @@ * definition of GenericClass is as follows: class GenericClass<T extends * Serializable & Comparable<T>> implements Comparable<T> { ... } */ -public class GenericClass<T> implements Comparable<T> { +public class GenericClass<T extends Serializable> implements Comparable<T>, Serializable { /** * Non-static, generic inner class. * @@ -65,8 +65,6 @@ */ // GenericClass.NonGenericInnerClass rawNonGenericInnerClassField; - GenericClass<Integer>.Foo.Bar wtf; - Class rawClazzField; /**
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericSubclass.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericSubclass.java index 23187a6..5935087 100644 --- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericSubclass.java +++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericSubclass.java
@@ -1,5 +1,5 @@ /* - * Copyright 2007 Google Inc. + * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -15,10 +15,12 @@ */ package com.google.gwt.core.ext.typeinfo.test; +import java.io.Serializable; + /** * Test a generic class that extends a generic class. */ -public class GenericSubclass<U> extends GenericClass<U> { +public class GenericSubclass<U extends Serializable> extends GenericClass<U> { GenericClass<Integer> child; public GenericSubclass(U t) {