@Test public void canAssignStaticMethodResult() { TypeElement immutableMap = elementUtils.getTypeElement(ImmutableMap.class.getCanonicalName()); TypeElement string = elementUtils.getTypeElement(String.class.getCanonicalName()); TypeElement integer = elementUtils.getTypeElement(Integer.class.getCanonicalName()); TypeElement number = elementUtils.getTypeElement(Number.class.getCanonicalName()); TypeMirror immutableMapStringNumber = typeUtils.getDeclaredType(immutableMap, string.asType(), number.asType()); TypeMirror immutableMapStringInteger = typeUtils.getDeclaredType(immutableMap, string.asType(), integer.asType()); TypeElement map = elementUtils.getTypeElement(Map.class.getCanonicalName()); TypeMirror erasedMap = typeUtils.erasure(map.asType()); List<ExecutableElement> immutableMapMethods = ElementFilter.methodsIn(immutableMap.getEnclosedElements()); ExecutableElement copyOf = methodNamed(immutableMapMethods, "copyOf", erasedMap); expect.that( TypeVariables.canAssignStaticMethodResult( copyOf, immutableMapStringInteger, immutableMapStringNumber, typeUtils)) .isTrue(); expect.that( TypeVariables.canAssignStaticMethodResult( copyOf, immutableMapStringNumber, immutableMapStringInteger, typeUtils)) .isFalse(); }
static boolean canAssignStaticMethodResult( ExecutableElement method, TypeMirror actualParameterType, TypeMirror targetType, Types typeUtils) { if (!targetType.getKind().equals(TypeKind.DECLARED) || !method.getModifiers().contains(Modifier.STATIC) || method.getParameters().size() != 1) { return false; } List<? extends TypeParameterElement> typeParameters = method.getTypeParameters(); List<? extends TypeMirror> targetTypeArguments = MoreTypes.asDeclared(targetType).getTypeArguments(); if (typeParameters.size() != targetTypeArguments.size()) { return false; } Map<Equivalence.Wrapper<TypeVariable>, TypeMirror> typeVariables = new LinkedHashMap<>(); for (int i = 0; i < typeParameters.size(); i++) { TypeVariable v = MoreTypes.asTypeVariable(typeParameters.get(i).asType()); typeVariables.put(MoreTypes.equivalence().wrap(v), targetTypeArguments.get(i)); } TypeMirror formalParameterType = method.getParameters().get(0).asType(); SubstitutionVisitor substitutionVisitor = new SubstitutionVisitor(typeVariables, typeUtils); TypeMirror substitutedParameterType = substitutionVisitor.visit(formalParameterType, null); if (substitutedParameterType.getKind().equals(TypeKind.WILDCARD)) { WildcardType wildcard = MoreTypes.asWildcard(substitutedParameterType); if (wildcard.getExtendsBound() != null) { substitutedParameterType = wildcard.getExtendsBound(); } } return typeUtils.isAssignable(actualParameterType, substitutedParameterType); }
TypeVariables { static boolean canAssignStaticMethodResult( ExecutableElement method, TypeMirror actualParameterType, TypeMirror targetType, Types typeUtils) { if (!targetType.getKind().equals(TypeKind.DECLARED) || !method.getModifiers().contains(Modifier.STATIC) || method.getParameters().size() != 1) { return false; } List<? extends TypeParameterElement> typeParameters = method.getTypeParameters(); List<? extends TypeMirror> targetTypeArguments = MoreTypes.asDeclared(targetType).getTypeArguments(); if (typeParameters.size() != targetTypeArguments.size()) { return false; } Map<Equivalence.Wrapper<TypeVariable>, TypeMirror> typeVariables = new LinkedHashMap<>(); for (int i = 0; i < typeParameters.size(); i++) { TypeVariable v = MoreTypes.asTypeVariable(typeParameters.get(i).asType()); typeVariables.put(MoreTypes.equivalence().wrap(v), targetTypeArguments.get(i)); } TypeMirror formalParameterType = method.getParameters().get(0).asType(); SubstitutionVisitor substitutionVisitor = new SubstitutionVisitor(typeVariables, typeUtils); TypeMirror substitutedParameterType = substitutionVisitor.visit(formalParameterType, null); if (substitutedParameterType.getKind().equals(TypeKind.WILDCARD)) { WildcardType wildcard = MoreTypes.asWildcard(substitutedParameterType); if (wildcard.getExtendsBound() != null) { substitutedParameterType = wildcard.getExtendsBound(); } } return typeUtils.isAssignable(actualParameterType, substitutedParameterType); } }
TypeVariables { static boolean canAssignStaticMethodResult( ExecutableElement method, TypeMirror actualParameterType, TypeMirror targetType, Types typeUtils) { if (!targetType.getKind().equals(TypeKind.DECLARED) || !method.getModifiers().contains(Modifier.STATIC) || method.getParameters().size() != 1) { return false; } List<? extends TypeParameterElement> typeParameters = method.getTypeParameters(); List<? extends TypeMirror> targetTypeArguments = MoreTypes.asDeclared(targetType).getTypeArguments(); if (typeParameters.size() != targetTypeArguments.size()) { return false; } Map<Equivalence.Wrapper<TypeVariable>, TypeMirror> typeVariables = new LinkedHashMap<>(); for (int i = 0; i < typeParameters.size(); i++) { TypeVariable v = MoreTypes.asTypeVariable(typeParameters.get(i).asType()); typeVariables.put(MoreTypes.equivalence().wrap(v), targetTypeArguments.get(i)); } TypeMirror formalParameterType = method.getParameters().get(0).asType(); SubstitutionVisitor substitutionVisitor = new SubstitutionVisitor(typeVariables, typeUtils); TypeMirror substitutedParameterType = substitutionVisitor.visit(formalParameterType, null); if (substitutedParameterType.getKind().equals(TypeKind.WILDCARD)) { WildcardType wildcard = MoreTypes.asWildcard(substitutedParameterType); if (wildcard.getExtendsBound() != null) { substitutedParameterType = wildcard.getExtendsBound(); } } return typeUtils.isAssignable(actualParameterType, substitutedParameterType); } private  TypeVariables(); }
TypeVariables { static boolean canAssignStaticMethodResult( ExecutableElement method, TypeMirror actualParameterType, TypeMirror targetType, Types typeUtils) { if (!targetType.getKind().equals(TypeKind.DECLARED) || !method.getModifiers().contains(Modifier.STATIC) || method.getParameters().size() != 1) { return false; } List<? extends TypeParameterElement> typeParameters = method.getTypeParameters(); List<? extends TypeMirror> targetTypeArguments = MoreTypes.asDeclared(targetType).getTypeArguments(); if (typeParameters.size() != targetTypeArguments.size()) { return false; } Map<Equivalence.Wrapper<TypeVariable>, TypeMirror> typeVariables = new LinkedHashMap<>(); for (int i = 0; i < typeParameters.size(); i++) { TypeVariable v = MoreTypes.asTypeVariable(typeParameters.get(i).asType()); typeVariables.put(MoreTypes.equivalence().wrap(v), targetTypeArguments.get(i)); } TypeMirror formalParameterType = method.getParameters().get(0).asType(); SubstitutionVisitor substitutionVisitor = new SubstitutionVisitor(typeVariables, typeUtils); TypeMirror substitutedParameterType = substitutionVisitor.visit(formalParameterType, null); if (substitutedParameterType.getKind().equals(TypeKind.WILDCARD)) { WildcardType wildcard = MoreTypes.asWildcard(substitutedParameterType); if (wildcard.getExtendsBound() != null) { substitutedParameterType = wildcard.getExtendsBound(); } } return typeUtils.isAssignable(actualParameterType, substitutedParameterType); } private  TypeVariables();  }
TypeVariables { static boolean canAssignStaticMethodResult( ExecutableElement method, TypeMirror actualParameterType, TypeMirror targetType, Types typeUtils) { if (!targetType.getKind().equals(TypeKind.DECLARED) || !method.getModifiers().contains(Modifier.STATIC) || method.getParameters().size() != 1) { return false; } List<? extends TypeParameterElement> typeParameters = method.getTypeParameters(); List<? extends TypeMirror> targetTypeArguments = MoreTypes.asDeclared(targetType).getTypeArguments(); if (typeParameters.size() != targetTypeArguments.size()) { return false; } Map<Equivalence.Wrapper<TypeVariable>, TypeMirror> typeVariables = new LinkedHashMap<>(); for (int i = 0; i < typeParameters.size(); i++) { TypeVariable v = MoreTypes.asTypeVariable(typeParameters.get(i).asType()); typeVariables.put(MoreTypes.equivalence().wrap(v), targetTypeArguments.get(i)); } TypeMirror formalParameterType = method.getParameters().get(0).asType(); SubstitutionVisitor substitutionVisitor = new SubstitutionVisitor(typeVariables, typeUtils); TypeMirror substitutedParameterType = substitutionVisitor.visit(formalParameterType, null); if (substitutedParameterType.getKind().equals(TypeKind.WILDCARD)) { WildcardType wildcard = MoreTypes.asWildcard(substitutedParameterType); if (wildcard.getExtendsBound() != null) { substitutedParameterType = wildcard.getExtendsBound(); } } return typeUtils.isAssignable(actualParameterType, substitutedParameterType); } private  TypeVariables();   }