Skip to content

Commit c806a96

Browse files
authored
Java ApiView: Add context to annotation id (#5426)
* Add context to annotation id * check for null * pr comment
1 parent 30dd44f commit c806a96

3 files changed

Lines changed: 69 additions & 20 deletions

File tree

src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/JavaASTAnalyser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ private void getAnnotations(final NodeWithAnnotations<?> nodeWithAnnotations,
10311031
addToken(makeWhitespace());
10321032
}
10331033

1034-
addToken(new Token(TYPE_NAME, "@" + annotation.getName().toString(), makeId(annotation)));
1034+
addToken(new Token(TYPE_NAME, "@" + annotation.getName().toString(), makeId(annotation, nodeWithAnnotations)));
10351035
if (showAnnotationProperties) {
10361036
if (annotation instanceof NormalAnnotationExpr) {
10371037
addToken(new Token(PUNCTUATION, "("));

src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/util/ASTUtils.java

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@
1010
import com.github.javaparser.ast.body.CallableDeclaration;
1111
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
1212
import com.github.javaparser.ast.body.ConstructorDeclaration;
13+
import com.github.javaparser.ast.body.EnumConstantDeclaration;
14+
import com.github.javaparser.ast.body.EnumDeclaration;
1315
import com.github.javaparser.ast.body.FieldDeclaration;
1416
import com.github.javaparser.ast.body.MethodDeclaration;
1517
import com.github.javaparser.ast.body.TypeDeclaration;
1618
import com.github.javaparser.ast.body.VariableDeclarator;
1719
import com.github.javaparser.ast.comments.Comment;
1820
import com.github.javaparser.ast.comments.JavadocComment;
1921
import com.github.javaparser.ast.expr.AnnotationExpr;
22+
import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
2023
import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc;
2124

2225
import java.util.Collections;
@@ -197,9 +200,43 @@ public static String makeId(String fullPath) {
197200
return MAKE_ID.matcher(fullPath).replaceAll("-");
198201
}
199202

200-
public static String makeId(AnnotationExpr annotation) {
201-
int line = annotation.getBegin().orElseThrow(RuntimeException::new).line;
202-
return makeId(getNodeFullyQualifiedName(annotation.getParentNode()) + "." + annotation.getNameAsString() + "-L" + line);
203+
public static String makeId(AnnotationExpr annotation, NodeWithAnnotations<?> nodeWithAnnotations) {
204+
String annotationContext = getAnnotationContext(nodeWithAnnotations);
205+
206+
String idSuffix;
207+
208+
if (annotationContext == null || annotationContext.isEmpty()) {
209+
idSuffix = "-L" + annotation.getBegin().orElseThrow(RuntimeException::new).line;
210+
} else {
211+
idSuffix = "-" + annotationContext;
212+
}
213+
return makeId(getNodeFullyQualifiedName(annotation.getParentNode()) + "." + annotation.getNameAsString() + idSuffix);
214+
}
215+
216+
private static String getAnnotationContext(NodeWithAnnotations<?> nodeWithAnnotations) {
217+
if (nodeWithAnnotations == null) {
218+
return "";
219+
}
220+
if (nodeWithAnnotations instanceof MethodDeclaration) {
221+
MethodDeclaration methodDeclaration = (MethodDeclaration) nodeWithAnnotations;
222+
// use the method declaration string instead of method name as there can be overloads
223+
return methodDeclaration.getDeclarationAsString(true, true, true);
224+
} else if (nodeWithAnnotations instanceof ClassOrInterfaceDeclaration) {
225+
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = (ClassOrInterfaceDeclaration) nodeWithAnnotations;
226+
return classOrInterfaceDeclaration.getNameAsString();
227+
} else if (nodeWithAnnotations instanceof EnumDeclaration) {
228+
EnumDeclaration enumDeclaration = (EnumDeclaration) nodeWithAnnotations;
229+
return enumDeclaration.getNameAsString();
230+
} else if (nodeWithAnnotations instanceof EnumConstantDeclaration) {
231+
EnumConstantDeclaration enumValueDeclaration = (EnumConstantDeclaration) nodeWithAnnotations;
232+
return enumValueDeclaration.getNameAsString();
233+
} else if (nodeWithAnnotations instanceof ConstructorDeclaration) {
234+
ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) nodeWithAnnotations;
235+
// use the constructor declaration string instead of the name as there can be overloads
236+
return constructorDeclaration.getDeclarationAsString(true, true, true);
237+
} else {
238+
return "";
239+
}
203240
}
204241

205242
/**

src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/BadAnnotationDiagnosticRule.java

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
import com.azure.tools.apiview.processor.model.Diagnostic;
66
import com.github.javaparser.ast.CompilationUnit;
77
import com.github.javaparser.ast.expr.AnnotationExpr;
8+
import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
89

910
import java.util.*;
10-
import java.util.function.Consumer;
1111

1212
import static com.azure.tools.apiview.processor.analysers.util.ASTUtils.*;
1313
import static com.azure.tools.apiview.processor.model.DiagnosticKind.WARNING;
@@ -18,32 +18,44 @@
1818
*/
1919
public class BadAnnotationDiagnosticRule implements DiagnosticRule {
2020

21-
private List<BadAnnotation> badAnnotations;
21+
private final List<BadAnnotation> badAnnotations;
2222

2323
public BadAnnotationDiagnosticRule(BadAnnotation... badAnnotations) {
2424
this.badAnnotations = Arrays.asList(badAnnotations);
2525
}
2626

2727
@Override
2828
public void scanIndividual(final CompilationUnit cu, final APIListing listing) {
29-
Consumer<AnnotationExpr> annotationConsumer = a -> {
30-
badAnnotations.forEach(badAnnotation -> {
31-
// check if the badAnnotation is the same as the found annotation
32-
if (badAnnotation.annotation.equals(a.getNameAsString())) {
33-
// we've got a match - file it as a diagnostic
34-
listing.addDiagnostic(new Diagnostic(WARNING, makeId(a), badAnnotation.errorMessage));
35-
}
36-
});
37-
};
3829

3930
getClasses(cu).forEach(typeDeclaration -> {
4031
// check annotations on the type itself
41-
typeDeclaration.getAnnotations().stream().forEach(annotationConsumer);
32+
typeDeclaration.getAnnotations()
33+
.forEach(annotation -> checkForBadAnnotations(listing, typeDeclaration, annotation));
4234

43-
// check annotations on fields, constructors, methods
44-
getPublicOrProtectedFields(typeDeclaration).flatMap(method -> method.getAnnotations().stream()).forEach(annotationConsumer);
45-
getPublicOrProtectedConstructors(typeDeclaration).flatMap(method -> method.getAnnotations().stream()).forEach(annotationConsumer);
46-
getPublicOrProtectedMethods(typeDeclaration).flatMap(method -> method.getAnnotations().stream()).forEach(annotationConsumer);
35+
// check annotations on fields
36+
getPublicOrProtectedFields(typeDeclaration)
37+
.forEach(field -> field.getAnnotations()
38+
.forEach(annotation -> checkForBadAnnotations(listing, field, annotation)));
39+
40+
// check annotations on constructors
41+
getPublicOrProtectedConstructors(typeDeclaration)
42+
.forEach(constructor -> constructor.getAnnotations()
43+
.forEach(annotation -> checkForBadAnnotations(listing, constructor, annotation)));
44+
// check annotations on methods
45+
getPublicOrProtectedMethods(typeDeclaration)
46+
.forEach(method -> method.getAnnotations()
47+
.forEach(annotation -> checkForBadAnnotations(listing, method, annotation)));
48+
});
49+
}
50+
51+
private void checkForBadAnnotations(APIListing listing, NodeWithAnnotations<?> nodeWithAnnotations, AnnotationExpr annotation) {
52+
badAnnotations.forEach(badAnnotation -> {
53+
// check if the badAnnotation is the same as the found annotation
54+
if (badAnnotation.annotation.equals(annotation.getNameAsString())) {
55+
// we've got a match - file it as a diagnostic
56+
listing.addDiagnostic(new Diagnostic(WARNING, makeId(annotation, nodeWithAnnotations),
57+
badAnnotation.errorMessage));
58+
}
4759
});
4860
}
4961

0 commit comments

Comments
 (0)