private boolean isSubtypeOfInterface(Type t, InterfaceType s) { // Special handling for union. if (t instanceof InterfaceTypeUnion) { InterfaceTypeUnion tUnion = (InterfaceTypeUnion) t; for (InterfaceType unionPart : tUnion.getTypes()) { if (isSubtype(unionPart, s)) { return true; } } return false; } // class "t" implements call() and "s" is Function if (TypeKind.of(t) == TypeKind.INTERFACE && typeProvider != null && s == typeProvider.getFunctionType()) { InterfaceType ti = (InterfaceType) t; if (ti.lookupMember("call") != null) { return true; } } // Try to cast "t" to "s". final Type sup = asInstanceOf(t, s.getElement()); if (TypeKind.of(sup) == TypeKind.INTERFACE) { InterfaceType ti = (InterfaceType) sup; assert ti.getElement().equals(s.getElement()); if (ti.isRaw() || s.isRaw()) { return true; } // Type arguments are covariant. return areSubtypes(ti.getArguments().iterator(), s.getArguments().iterator()); } return false; }
/** * Return an interface type representing the given interface, function or variable type. * * @return An interface type or null if the argument is neither an interface function or variable * type. */ public InterfaceType getInterfaceType(Type type) { switch (TypeKind.of(type)) { case VARIABLE: { TypeVariableElement element = ((TypeVariable) type).getTypeVariableElement(); if (element.getBound() == null) { return typeProvider.getObjectType(); } else { return getInterfaceType(element.getBound()); } } case FUNCTION: case FUNCTION_ALIAS: return typeProvider.getFunctionType(); case INTERFACE: return (InterfaceType) type; case DYNAMIC: case NONE: case VOID: default: return null; } }