Skip to content

Commit

Permalink
Fixing issue whereby nested annotations weren't being handled because…
Browse files Browse the repository at this point in the history
… the derived class name was incorrect.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=297413484
  • Loading branch information
hagbard authored and cpovirk committed Feb 27, 2020
1 parent 73f065e commit 989bc53
Showing 1 changed file with 19 additions and 4 deletions.
23 changes: 19 additions & 4 deletions core/src/main/java/com/google/errorprone/refaster/UTemplater.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
import java.util.Map;
import javax.annotation.Nullable;
import javax.lang.model.element.Element;
import javax.lang.model.element.Name;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.MirroredTypeException;
Expand Down Expand Up @@ -919,11 +919,11 @@ public UForAll visitForAll(ForAll type, Void v) {
public static ImmutableClassToInstanceMap<Annotation> annotationMap(Symbol symbol) {
ImmutableClassToInstanceMap.Builder<Annotation> builder = ImmutableClassToInstanceMap.builder();
for (Compound compound : symbol.getAnnotationMirrors()) {
Name qualifiedAnnotationType =
((TypeElement) compound.getAnnotationType().asElement()).getQualifiedName();
String annotationClassName =
classNameFrom((TypeElement) compound.getAnnotationType().asElement());
try {
Class<? extends Annotation> annotationClazz =
Class.forName(qualifiedAnnotationType.toString()).asSubclass(Annotation.class);
Class.forName(annotationClassName).asSubclass(Annotation.class);
builder.put(
(Class) annotationClazz,
AnnotationProxyMaker.generateAnnotation(compound, annotationClazz));
Expand All @@ -933,4 +933,19 @@ public static ImmutableClassToInstanceMap<Annotation> annotationMap(Symbol symbo
}
return builder.build();
}

// Class.forName() needs nested classes as "foo.Bar$Baz$Quux", not "foo.Bar.Baz.Quux"
// (which is what getQualifiedName() returns).
private static String classNameFrom(TypeElement type) {
// Get the full type name (e.g. "foo.Bar.Baz.Quux") before walking up the hierarchy.
String typeName = type.getQualifiedName().toString();
// Find outermost enclosing type (e.g. "foo.Bar" in our example), possibly several levels up.
// Packages enclose types, so we cannot just wait until we hit null.
while (type.getEnclosingElement().getKind() == ElementKind.CLASS) {
type = (TypeElement) type.getEnclosingElement();
}
// Start with outermost class name and append remainder of full type name with '.' -> '$'
String className = type.getQualifiedName().toString();
return className + typeName.substring(className.length()).replace('.', '$');
}
}

0 comments on commit 989bc53

Please sign in to comment.