@Override void visitWildcardType(WildcardType t) { result.set(subtypeOfComponentType(t.getUpperBounds())); }
static Type getParameterUpperBound(int index, ParameterizedType type) { Type[] types = type.getActualTypeArguments(); if (index < 0 || index >= types.length) { throw new IllegalArgumentException( "Index " + index + " not in range [0," + types.length + ") for " + type); } Type paramType = types[index]; if (paramType instanceof WildcardType) { return ((WildcardType) paramType).getUpperBounds()[0]; } return paramType; }
/** * Determine whether the underlying type represents a wildcard * without specific bounds (i.e., equal to {@code ? extends Object}). */ private boolean isWildcardWithoutBounds() { if (this.type instanceof WildcardType) { WildcardType wt = (WildcardType) this.type; if (wt.getLowerBounds().length == 0) { Type[] upperBounds = wt.getUpperBounds(); if (upperBounds.length == 0 || (upperBounds.length == 1 && Object.class == upperBounds[0])) { return true; } } } return false; }
/** * @return The first bound, either a type or a reference to a TypeVariable */ public Type firstBound() { Type[] lowerBounds = wildcard.getLowerBounds(); Type[] upperBounds = wildcard.getUpperBounds(); return lowerBounds.length != 0 ? lowerBounds[0] : upperBounds[0]; }
@Override public boolean equals(Object obj) { if (obj instanceof WildcardType) { WildcardType that = (WildcardType) obj; return lowerBounds.equals(Arrays.asList(that.getLowerBounds())) && upperBounds.equals(Arrays.asList(that.getUpperBounds())); } return false; }
@Override void visitWildcardType(WildcardType fromWildcardType) { if (!(to instanceof WildcardType)) { return; // okay to say <?> is anything } WildcardType toWildcardType = (WildcardType) to; Type[] fromUpperBounds = fromWildcardType.getUpperBounds(); Type[] toUpperBounds = toWildcardType.getUpperBounds(); Type[] fromLowerBounds = fromWildcardType.getLowerBounds(); Type[] toLowerBounds = toWildcardType.getLowerBounds(); checkArgument( fromUpperBounds.length == toUpperBounds.length && fromLowerBounds.length == toLowerBounds.length, "Incompatible type: %s vs. %s", fromWildcardType, to); for (int i = 0; i < fromUpperBounds.length; i++) { populateTypeMappings(mappings, fromUpperBounds[i], toUpperBounds[i]); } for (int i = 0; i < fromLowerBounds.length; i++) { populateTypeMappings(mappings, fromLowerBounds[i], toLowerBounds[i]); } }
@Override void visitWildcardType(WildcardType t) { visit(t.getUpperBounds()); }
protected JavaType _fromWildcard(ClassStack context, WildcardType type, TypeBindings bindings) { /* Similar to challenges with TypeVariable, we may have multiple upper bounds. * But it is also possible that if upper bound defaults to Object, we might * want to consider lower bounds instead. * For now, we won't try anything more advanced; above is just for future reference. */ return _fromAny(context, type.getUpperBounds()[0], bindings); } }
protected JavaType _fromWildcard(ClassStack context, WildcardType type, TypeBindings bindings) { /* Similar to challenges with TypeVariable, we may have multiple upper bounds. * But it is also possible that if upper bound defaults to Object, we might * want to consider lower bounds instead. * For now, we won't try anything more advanced; above is just for future reference. */ return _fromAny(context, type.getUpperBounds()[0], bindings); } }
/** * {@inheritDoc} */ public TypeList.Generic getUpperBounds() { return new WildcardUpperBoundTypeList(wildcardType.getUpperBounds(), annotationReader); }
private static WildcardType canonicalizeWildcardType( TypeVariable<?> declaration, WildcardType type) { Type[] declared = declaration.getBounds(); List<Type> upperBounds = new ArrayList<>(); for (Type bound : type.getUpperBounds()) { if (!any(declared).isSubtypeOf(bound)) { upperBounds.add(canonicalizeWildcardsInType(bound)); } } return new Types.WildcardTypeImpl(type.getLowerBounds(), upperBounds.toArray(new Type[0])); }
@Override public boolean equals(Object obj) { if (obj instanceof WildcardType) { WildcardType that = (WildcardType) obj; return lowerBounds.equals(Arrays.asList(that.getLowerBounds())) && upperBounds.equals(Arrays.asList(that.getUpperBounds())); } return false; }
private WildcardType resolveWildcardType(WildcardType type) { Type[] lowerBounds = type.getLowerBounds(); Type[] upperBounds = type.getUpperBounds(); return new Types.WildcardTypeImpl(resolveTypes(lowerBounds), resolveTypes(upperBounds)); }
private void validateNoTypeParameterOnWildcardType(WildcardType wildcard, List<Throwable> errors) { for (Type each : wildcard.getUpperBounds()) { validateNoTypeParameterOnType(each, errors); } for (Type each : wildcard.getLowerBounds()) { validateNoTypeParameterOnType(each, errors); } }
private static WildcardType canonicalizeWildcardType( TypeVariable<?> declaration, WildcardType type) { Type[] declared = declaration.getBounds(); List<Type> upperBounds = new ArrayList<>(); for (Type bound : type.getUpperBounds()) { if (!any(declared).isSubtypeOf(bound)) { upperBounds.add(canonicalizeWildcardsInType(bound)); } } return new Types.WildcardTypeImpl(type.getLowerBounds(), upperBounds.toArray(new Type[0])); }
/** Returns the array type of {@code componentType}. */ static Type newArrayType(Type componentType) { if (componentType instanceof WildcardType) { WildcardType wildcard = (WildcardType) componentType; Type[] lowerBounds = wildcard.getLowerBounds(); checkArgument(lowerBounds.length <= 1, "Wildcard cannot have more than one lower bounds."); if (lowerBounds.length == 1) { return supertypeOf(newArrayType(lowerBounds[0])); } else { Type[] upperBounds = wildcard.getUpperBounds(); checkArgument(upperBounds.length == 1, "Wildcard should have only one upper bound."); return subtypeOf(newArrayType(upperBounds[0])); } } return JavaVersion.CURRENT.newArrayType(componentType); }
private WildcardType resolveWildcardType(WildcardType type) { Type[] lowerBounds = type.getLowerBounds(); Type[] upperBounds = type.getUpperBounds(); return new Types.WildcardTypeImpl(resolveTypes(lowerBounds), resolveTypes(upperBounds)); }
private static void assertEqualWildcardType(WildcardType expected, WildcardType actual) { assertEquals(expected.toString(), actual.toString()); assertEquals(actual.toString(), expected.hashCode(), actual.hashCode()); assertThat(actual.getLowerBounds()) .asList() .containsExactlyElementsIn(asList(expected.getLowerBounds())) .inOrder(); assertThat(actual.getUpperBounds()) .asList() .containsExactlyElementsIn(asList(expected.getUpperBounds())) .inOrder(); }
public void testWithGenericUpperBoundInWildcard() throws Exception { WildcardType wildcardType = (WildcardType) new WithGenericBound<String>() {}.getTargetType("withWildcardUpperBound"); assertEquals(String.class, wildcardType.getUpperBounds()[0]); }
@Test public void wildcardType() throws Exception { ParameterizedType typeSource = (ParameterizedType) SerializableTypeWrapper.forField(Fields.class.getField("wildcardType")); WildcardType type = (WildcardType) typeSource.getActualTypeArguments()[0]; assertThat(type.toString(), equalTo("? extends java.lang.CharSequence")); assertSerializable(type); assertSerializable(type.getLowerBounds()); assertSerializable(type.getUpperBounds()); }