5
5
import static javax .lang .model .element .Modifier .STATIC ;
6
6
7
7
import com .google .common .base .Splitter ;
8
- import com .google .common .collect .ImmutableMap ;
9
8
import com .google .common .collect .ImmutableSet ;
10
- import com .google .common .collect .ImmutableSortedSet ;
11
9
import com .google .common .collect .Lists ;
12
10
import com .sun .source .tree .AnnotationTree ;
13
11
import com .sun .source .tree .ArrayTypeTree ;
31
29
import java .util .HashMap ;
32
30
import java .util .List ;
33
31
import java .util .Map ;
32
+ import java .util .Objects ;
34
33
import java .util .Set ;
34
+ import java .util .SortedMap ;
35
35
import java .util .SortedSet ;
36
36
import java .util .TreeMap ;
37
37
import java .util .TreeSet ;
@@ -57,7 +57,7 @@ public class ClasspathParser {
57
57
58
58
// Mapping from fully-qualified class-name to class-names of annotations on that class.
59
59
// Annotations will be fully-qualified where that's known, and not where not known.
60
- private final Map <String , SortedSet < String >> annotatedClasses = new TreeMap <>();
60
+ final Map <String , PerClassData > perClassData = new TreeMap <>();
61
61
62
62
// get the system java compiler instance
63
63
private static final JavaCompiler compiler = ToolProvider .getSystemJavaCompiler ();
@@ -67,6 +67,46 @@ public ClasspathParser() {
67
67
// Doesn't need to do anything currently
68
68
}
69
69
70
+ static class PerClassData {
71
+ public PerClassData () {
72
+ this (new TreeSet <>(), new TreeMap <>());
73
+ }
74
+
75
+ @ Override
76
+ public String toString () {
77
+ return "PerClassData{"
78
+ + "annotations="
79
+ + annotations
80
+ + ", perMethodAnnotations="
81
+ + perMethodAnnotations
82
+ + '}' ;
83
+ }
84
+
85
+ public PerClassData (
86
+ SortedSet <String > annotations , SortedMap <String , SortedSet <String >> perMethodAnnotations ) {
87
+ this .annotations = annotations ;
88
+ this .perMethodAnnotations = perMethodAnnotations ;
89
+ }
90
+
91
+ final SortedSet <String > annotations ;
92
+
93
+ final SortedMap <String , SortedSet <String >> perMethodAnnotations ;
94
+
95
+ @ Override
96
+ public boolean equals (Object o ) {
97
+ if (this == o ) return true ;
98
+ if (o == null || getClass () != o .getClass ()) return false ;
99
+ PerClassData that = (PerClassData ) o ;
100
+ return Objects .equals (annotations , that .annotations )
101
+ && Objects .equals (perMethodAnnotations , that .perMethodAnnotations );
102
+ }
103
+
104
+ @ Override
105
+ public int hashCode () {
106
+ return Objects .hash (annotations , perMethodAnnotations );
107
+ }
108
+ }
109
+
70
110
public ImmutableSet <String > getUsedTypes () {
71
111
return ImmutableSet .copyOf (usedTypes );
72
112
}
@@ -87,15 +127,6 @@ public ImmutableSet<String> getMainClasses() {
87
127
return ImmutableSet .copyOf (mainClasses );
88
128
}
89
129
90
- public ImmutableMap <String , ImmutableSortedSet <String >> getAnnotatedClasses () {
91
- ImmutableMap .Builder <String , ImmutableSortedSet <String >> builder =
92
- ImmutableMap .builderWithExpectedSize (annotatedClasses .size ());
93
- for (Map .Entry <String , SortedSet <String >> entry : annotatedClasses .entrySet ()) {
94
- builder .put (entry .getKey (), ImmutableSortedSet .copyOf (entry .getValue ()));
95
- }
96
- return builder .build ();
97
- }
98
-
99
130
public void parseClasses (Path directory , List <String > files ) throws IOException {
100
131
StandardJavaFileManager fileManager = compiler .getStandardFileManager (null , null , null );
101
132
List <? extends JavaFileObject > objectFiles =
@@ -245,6 +276,20 @@ public Void visitMethod(com.sun.source.tree.MethodTree m, Void v) {
245
276
checkFullyQualifiedType (param .getType ());
246
277
handleAnnotations (param .getModifiers ().getAnnotations ());
247
278
}
279
+
280
+ for (AnnotationTree annotation : m .getModifiers ().getAnnotations ()) {
281
+ String annotationClassName = annotation .getAnnotationType ().toString ();
282
+ String importedFullyQualified = currentFileImports .get (annotationClassName );
283
+ String currentFullyQualifiedClass = fullyQualify (currentPackage , currentClassName );
284
+ if (importedFullyQualified != null ) {
285
+ noteAnnotatedMethod (
286
+ currentFullyQualifiedClass , m .getName ().toString (), importedFullyQualified );
287
+ } else {
288
+ noteAnnotatedMethod (
289
+ currentFullyQualifiedClass , m .getName ().toString (), annotationClassName );
290
+ }
291
+ }
292
+
248
293
return super .visitMethod (m , v );
249
294
}
250
295
@@ -333,10 +378,27 @@ private Set<String> checkFullyQualifiedType(Tree identifier) {
333
378
334
379
private void noteAnnotatedClass (
335
380
String annotatedFullyQualifiedClassName , String annotationFullyQualifiedClassName ) {
336
- if (!annotatedClasses .containsKey (annotatedFullyQualifiedClassName )) {
337
- annotatedClasses .put (annotatedFullyQualifiedClassName , new TreeSet <>());
381
+ if (!perClassData .containsKey (annotatedFullyQualifiedClassName )) {
382
+ perClassData .put (annotatedFullyQualifiedClassName , new PerClassData ());
383
+ }
384
+ perClassData
385
+ .get (annotatedFullyQualifiedClassName )
386
+ .annotations
387
+ .add (annotationFullyQualifiedClassName );
388
+ }
389
+
390
+ private void noteAnnotatedMethod (
391
+ String annotatedFullyQualifiedClassName ,
392
+ String methodName ,
393
+ String annotationFullyQualifiedClassName ) {
394
+ if (!perClassData .containsKey (annotatedFullyQualifiedClassName )) {
395
+ perClassData .put (annotatedFullyQualifiedClassName , new PerClassData ());
396
+ }
397
+ PerClassData data = perClassData .get (annotatedFullyQualifiedClassName );
398
+ if (!data .perMethodAnnotations .containsKey (methodName )) {
399
+ data .perMethodAnnotations .put (methodName , new TreeSet <>());
338
400
}
339
- annotatedClasses . get (annotatedFullyQualifiedClassName ).add (annotationFullyQualifiedClassName );
401
+ data . perMethodAnnotations . get (methodName ).add (annotationFullyQualifiedClassName );
340
402
}
341
403
342
404
private String fullyQualify (String packageName , String className ) {
0 commit comments