public EnumSet<DispatchType> getDispatchType(JReferenceType type) { if (!typeOracle.isInstantiatedType(type)) { return EnumSet.noneOf(DispatchType.class); } // Object methods can be dispatched to all four possible classes. if (type == getTypeJavaLangObject()) { return EnumSet.allOf(DispatchType.class); } EnumSet<DispatchType> dispatchSet = EnumSet.noneOf(DispatchType.class); DispatchType dispatchType = getRepresentedAsNativeTypesDispatchMap().get(type); if (dispatchType != null) { dispatchSet = EnumSet.of(dispatchType); } else if (typeOracle.isDualJsoInterface(type)) { // If it is an interface implemented both by JSOs and regular Java Objects; dispatchSet = EnumSet.of(DispatchType.HAS_JAVA_VIRTUAL_DISPATCH, DispatchType.JSO); } else if (typeOracle.isSingleJsoImpl(type) || type.isJsoType()) { // If it is either an interface implemented by JSOs or JavaScriptObject or one of its // subclasses. dispatchSet = EnumSet.of(DispatchType.JSO); } for (JDeclaredType potentialNativeDispatchType : getRepresentedAsNativeTypes()) { if (potentialNativeDispatchType == type) { continue; } if (typeOracle.isInstantiatedType(potentialNativeDispatchType) && typeOracle.isSuperClassOrInterface(potentialNativeDispatchType, type)) { dispatchSet.add(getRepresentedAsNativeTypesDispatchMap().get(potentialNativeDispatchType)); dispatchSet.add(DispatchType.HAS_JAVA_VIRTUAL_DISPATCH); } } return dispatchSet; }