diff options
author | Jon Brandvein <brandjon@google.com> | 2016-10-11 17:51:06 +0000 |
---|---|---|
committer | Yue Gan <yueg@google.com> | 2016-10-12 08:55:43 +0000 |
commit | 1171a7fb55ae9928cd976d4c3963f4874d58f60c (patch) | |
tree | a6a49c86b189798c7d28b6729583fd989daa3186 /src/main/java/com/google/devtools/build/lib/skylarkinterface | |
parent | 7bbf70ba0029c9480d61633973d8c293157e9407 (diff) |
Make EvalUtils.getDataTypeNameFromClass() look for @SkylarkModules in parent classes
This is needed to let subclasses of @SkylarkModules have the same type() string as their superclass, without requiring a second annotation for the subclass.
--
MOS_MIGRATED_REVID=135814343
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skylarkinterface')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkInterfaceUtils.java | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkInterfaceUtils.java b/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkInterfaceUtils.java index 95d4f4fcf5..348a9ccef4 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkInterfaceUtils.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkInterfaceUtils.java @@ -23,40 +23,59 @@ import javax.annotation.Nullable; public class SkylarkInterfaceUtils { /** + * Returns the {@link SkylarkModule} annotation for the given class, if it exists, and + * null otherwise. The first annotation found will be returned, starting with {@code classObj} + * and following its base classes and interfaces recursively. + */ + @Nullable + public static SkylarkModule getSkylarkModule(Class<?> classObj) { + if (classObj.isAnnotationPresent(SkylarkModule.class)) { + return classObj.getAnnotation(SkylarkModule.class); + } + Class<?> superclass = classObj.getSuperclass(); + if (superclass != null) { + SkylarkModule annotation = getSkylarkModule(superclass); + if (annotation != null) { + return annotation; + } + } + for (Class<?> interfaceObj : classObj.getInterfaces()) { + SkylarkModule annotation = getSkylarkModule(interfaceObj); + if (annotation != null) { + return annotation; + } + } + return null; + } + + /** * Returns the {@link SkylarkCallable} annotation for the given method, if it exists, and - * null otherwise. The method must be declared in {@code classObj} or one of its base classes - * or interfaces. The first annotation of an overridden version of the method that is found + * null otherwise. The first annotation of an overridden version of the method that is found * will be returned, starting with {@code classObj} and following its base classes and - * interfaces recursively. + * interfaces recursively, skipping any annotation inside a class not marked + * {@link SkylarkModule}. */ @Nullable public static SkylarkCallable getSkylarkCallable(Class<?> classObj, Method method) { - boolean keepLooking = false; try { Method superMethod = classObj.getMethod(method.getName(), method.getParameterTypes()); if (classObj.isAnnotationPresent(SkylarkModule.class) && superMethod.isAnnotationPresent(SkylarkCallable.class)) { return superMethod.getAnnotation(SkylarkCallable.class); - } else { - keepLooking = true; } } catch (NoSuchMethodException e) { - // The class might not have the specified method, so an exceptions is OK. - keepLooking = true; + // The class might not have the specified method, so an exception is OK. } - if (keepLooking) { - if (classObj.getSuperclass() != null) { - SkylarkCallable annotation = - getSkylarkCallable(classObj.getSuperclass(), method); - if (annotation != null) { - return annotation; - } + if (classObj.getSuperclass() != null) { + SkylarkCallable annotation = getSkylarkCallable(classObj.getSuperclass(), method); + if (annotation != null) { + return annotation; } - for (Class<?> interfaceObj : classObj.getInterfaces()) { - SkylarkCallable annotation = getSkylarkCallable(interfaceObj, method); - if (annotation != null) { - return annotation; - } + } + for (Class<?> interfaceObj : classObj.getInterfaces()) { + SkylarkCallable annotation = getSkylarkCallable(interfaceObj, method); + if (annotation != null) { + return annotation; } } return null; |