public TypeManifest(@Nullable TypeLiteral<T> nullableType) { this.typeToken = nullableType != null ? Types.toToken(nullableType) : new TypeToken<T>(getClass()){}; this.type = nullableType != null ? nullableType : Types.toLiteral(typeToken); Types.assertFullySpecified(this.type); this.typeParameter = new TypeParameter<T>(){}; this.typeArg = new TypeArgument<T>(this.type){}; TypeResolver resolver = new TypeResolver(); for(Class<?> cls = getClass(); cls != null; cls = cls.getSuperclass()) { if(cls.getTypeParameters().length > 0) { resolver = resolver.where(cls.getTypeParameters()[0], type.getType()); } } this.resolver = resolver; }
/** Returns a parameterized type with {@code raw} and {@code typeArgs}. */ // TODO: infer types and check that 'raw' can be parameterized by 'typeArgs'. public static ParameterizedType newParameterizedType( final Class<?> raw, Iterable<? extends Type> typeArgs) { TypeResolver resolver = new TypeResolver(); final List<TypeVariable<?>> vars = new ArrayList<TypeVariable<?>>(); for (Type arg : typeArgs) { TypeVariable<?> var = TypeVariableGenerator.freshTypeVariable("T" + vars.size()); vars.add(var); resolver = resolver.where(var, arg); } checkArgument(raw.getTypeParameters().length == vars.size(), "%s expected %s type parameters, while %s are provied", raw, raw.getTypeParameters().length, typeArgs); return (ParameterizedType) resolver.resolveType(new ParameterizedType() { @Override public Class<?> getRawType() { return raw; } @Override public Type getOwnerType() { return null; } @Override public Type[] getActualTypeArguments() { return vars.toArray(new Type[0]); } }); }
/** * Returns a canonical form of {@code initialType} by replacing all {@link TypeVariable} by {@link Class} * instances. * <p> * <p> * Such a canonical form allows to compare {@link ParameterizedType}s, {@link WildcardType}(s), * {@link GenericArrayType}(s), {@link TypeVariable}(s). * </p> */ public static Type canonize(Type initialType) { if (doesNotNeedCanonization(initialType)) { return initialType; } ReplacementClassSupplier replacementClassSupplier = new ReplacementClassSupplier(); TypeResolver typeResolver = new TypeResolver(); for (TypeVariable<?> typeVariable : findAllTypeVariables(initialType)) { // Once we have all TypeVariable we need to resolve them with actual classes so the typeResolver can resolve // them properly typeResolver = typeResolver.where(typeVariable, replacementClassSupplier.get()); } return typeResolver.resolveType(initialType); }
/** Returns a wildcard type that's subtype of {@code bound}. */ public static WildcardType subtypeOf(Type bound) { final TypeVariable<?> var = TypeVariableGenerator.freshTypeVariable("B"); return (WildcardType) new TypeResolver().where(var, bound).resolveType(new WildcardType() { @Override public Type[] getUpperBounds() { return new Type[] {var}; } @Override public Type[] getLowerBounds() { return new Type[0]; } }); }
/** Returns a wildcard type that's supertype of {@code bound}. */ public static WildcardType supertypeOf(Type bound) { final TypeVariable<?> var = TypeVariableGenerator.freshTypeVariable("SUB"); return (WildcardType) new TypeResolver().where(var, bound).resolveType(new WildcardType() { @Override public Type[] getUpperBounds() { return new Type[] {Object.class}; } @Override public Type[] getLowerBounds() { return new Type[] {var}; } }); }
/** Returns a new array type with {@code componentType}. */ public static Type newArrayType(Type componentType) { if (componentType instanceof Class<?>) { return newArrayType((Class<?>) componentType); } final TypeVariable<?> var = TypeVariableGenerator.freshTypeVariable("E"); return new TypeResolver().where(var, componentType).resolveType(new GenericArrayType() { @Override public Type getGenericComponentType() { return var; } }); }
public TypeLiteral<T> where(TypeVariable<?> typeVariable, TypeLiteral<?> type) { final TypeResolver resolver = new TypeResolver().where(typeVariable, type.getType()); return (TypeLiteral<T>) TypeLiteral.get(resolver.resolveType(getType())); }
public TypeLiteral<T> where(TypeVariable<?> typeVariable, TypeToken<?> type) { final TypeResolver resolver = new TypeResolver().where(typeVariable, type.getType()); return (TypeLiteral<T>) TypeLiteral.get(resolver.resolveType(getType())); }
/** * A more general form of {@link #where(TypeParameter, TypeDescriptor)} that returns a new {@code * TypeDescriptor} by matching {@code formal} against {@code actual} to resolve type variables in * the current {@link TypeDescriptor}. */ @SuppressWarnings("unchecked") public TypeDescriptor<T> where(Type formal, Type actual) { TypeResolver resolver = new TypeResolver().where(formal, actual); return (TypeDescriptor<T>) TypeDescriptor.of(resolver.resolveType(token.getType())); }
@SuppressWarnings("unchecked") public <I> Builder<T> where(Parameter<I> parameter, ModelType<I> type) { TypeResolver resolver = new TypeResolver().where(parameter.typeVariable, type.typeToken.getType()); typeToken = (TypeToken<T>) TypeToken.of(resolver.resolveType(typeToken.getType())); return this; }