private boolean isIntrospectable(TreeLogger logger, JType type) { if (type == null) { return false; } JClassType ct = type.isClassOrInterface(); if (ct != null) { if (ct.getAnnotation(Introspectable.class) != null) { return true; } for (JClassType iface : ct.getImplementedInterfaces()) { if (isIntrospectable(logger, iface)) { return true; } } if (isIntrospectable(logger, ct.getSuperclass())) { return true; } } return false; }
@Override public MetaField getDeclaredField(final String name) { JClassType type = getEnclosedMetaObject().isClassOrInterface(); if (type == null) { if ("length".equals(name) && getEnclosedMetaObject().isArray() != null) { return new MetaField.ArrayLengthMetaField(this); } return null; } JField field = type.findField(name); while (field == null && (type = type.getSuperclass()) != null && !type.getQualifiedSourceName().equals("java.lang.Object")) { JField superTypeField = type.findField(name); if (!superTypeField.isPrivate()) { field = superTypeField; } for (final JClassType interfaceType : type.getImplementedInterfaces()) { field = interfaceType.findField(name); } } if (field == null) { throw new RuntimeException("no such field: " + name + " in class: " + this); } return new GWTField(oracle, field); }
@Override public MetaMethod[] getMethods() { final Set<MetaMethod> meths = new LinkedHashSet<MetaMethod>(); meths.addAll(getSpecialTypeMethods()); JClassType type = getEnclosedMetaObject().isClassOrInterface(); if (type == null) { return null; } do { for (final JMethod jMethod : type.getMethods()) { if (!jMethod.isPrivate()) { meths.add(new GWTMethod(oracle, jMethod)); } } for (final JClassType interfaceType : type.getImplementedInterfaces()) { meths.addAll(Arrays.asList(GWTClass.newInstance(oracle, interfaceType).getMethods())); } } while ((type = type.getSuperclass()) != null && !type.getQualifiedSourceName().equals("java.lang.Object")); meths.addAll(overrideMethods); return meths.toArray(new MetaMethod[meths.size()]); }
@Override public MetaClass[] getInterfaces() { final JClassType jClassType = getEnclosedMetaObject().isClassOrInterface(); if (jClassType == null) return new MetaClass[0]; final List<MetaClass> metaClassList = new ArrayList<MetaClass>(); for (final JClassType type : jClassType.getImplementedInterfaces()) { metaClassList.add(new GWTClass(oracle, type, false)); } return metaClassList.toArray(new MetaClass[metaClassList.size()]); }
private static void getFlattenedSuperTypeHierarchyRecursive( JClassType type, Set<JClassType> typesSeen) { if (typesSeen.contains(type)) { return; } typesSeen.add(type); // Check the interfaces JClassType[] intfs = type.getImplementedInterfaces(); for (JClassType intf : intfs) { typesSeen.addAll(getFlattenedSuperTypeHierarchy(intf)); } // Superclass JClassType superclass = type.getSuperclass(); if (superclass != null) { typesSeen.addAll(getFlattenedSuperTypeHierarchy(superclass)); } }
public static JMethod findInheritedMethod(JClassType type, String methodName, JType... params) { JClassType currentType = type; while (currentType != null) { JMethod method = currentType.findMethod(methodName, params); if (method != null) { return method; } currentType = currentType.getSuperclass(); } JClassType[] interfaces = type.getImplementedInterfaces(); for (JClassType iface : interfaces) { JMethod method = iface.findMethod(methodName, params); if (method != null) { return method; } } return null; }
/** * Find an annotation on a type or on one of its superclasses or superinterfaces. * * <p>This provides semantics similar to that of {@link java.lang.annotation.Inherited} except * that it checks all types to which this type is assignable. {@code @Inherited} only works on * superclasses, not superinterfaces. * * <p>Annotations present on the superclass chain will be returned preferentially over those found * in the superinterface hierarchy. Note that the annotation does not need to be tagged with * {@code @Inherited} in order to be returned from the superclass chain. * * @param annotationType the type of the annotation to look for * @return the desired annotation or <code>null</code> if the annotation is not present in the * type's type hierarchy */ public <T extends Annotation> T findAnnotationInTypeHierarchy(Class<T> annotationType) { // Remember what we've seen to avoid loops Set<JClassType> seen = new HashSet<JClassType>(); // Work queue List<JClassType> searchTypes = new LinkedList<JClassType>(); searchTypes.add(this); T toReturn = null; while (!searchTypes.isEmpty()) { JClassType current = searchTypes.remove(0); if (!seen.add(current)) { continue; } toReturn = current.getAnnotation(annotationType); if (toReturn != null) { /* * First one wins. It might be desirable at some point to have a * variation that can return more than one instance of the annotation if * it is present on multiple supertypes. */ break; } if (current.getSuperclass() != null) { // Add the superclass at the front of the list searchTypes.add(0, current.getSuperclass()); } // Superinterfaces Collections.addAll(searchTypes, current.getImplementedInterfaces()); } return toReturn; }