55import static javax .lang .model .element .Modifier .STATIC ;
66
77import com .google .common .base .Splitter ;
8- import com .google .common .collect .ImmutableMap ;
98import com .google .common .collect .ImmutableSet ;
10- import com .google .common .collect .ImmutableSortedSet ;
119import com .google .common .collect .Lists ;
1210import com .sun .source .tree .AnnotationTree ;
1311import com .sun .source .tree .ArrayTypeTree ;
3129import java .util .HashMap ;
3230import java .util .List ;
3331import java .util .Map ;
32+ import java .util .Objects ;
3433import java .util .Set ;
34+ import java .util .SortedMap ;
3535import java .util .SortedSet ;
3636import java .util .TreeMap ;
3737import java .util .TreeSet ;
@@ -57,7 +57,7 @@ public class ClasspathParser {
5757
5858 // Mapping from fully-qualified class-name to class-names of annotations on that class.
5959 // 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 <>();
6161
6262 // get the system java compiler instance
6363 private static final JavaCompiler compiler = ToolProvider .getSystemJavaCompiler ();
@@ -67,6 +67,46 @@ public ClasspathParser() {
6767 // Doesn't need to do anything currently
6868 }
6969
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+
70110 public ImmutableSet <String > getUsedTypes () {
71111 return ImmutableSet .copyOf (usedTypes );
72112 }
@@ -87,15 +127,6 @@ public ImmutableSet<String> getMainClasses() {
87127 return ImmutableSet .copyOf (mainClasses );
88128 }
89129
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-
99130 public void parseClasses (Path directory , List <String > files ) throws IOException {
100131 StandardJavaFileManager fileManager = compiler .getStandardFileManager (null , null , null );
101132 List <? extends JavaFileObject > objectFiles =
@@ -245,6 +276,20 @@ public Void visitMethod(com.sun.source.tree.MethodTree m, Void v) {
245276 checkFullyQualifiedType (param .getType ());
246277 handleAnnotations (param .getModifiers ().getAnnotations ());
247278 }
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+
248293 return super .visitMethod (m , v );
249294 }
250295
@@ -333,10 +378,27 @@ private Set<String> checkFullyQualifiedType(Tree identifier) {
333378
334379 private void noteAnnotatedClass (
335380 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 <>());
338400 }
339- annotatedClasses . get (annotatedFullyQualifiedClassName ).add (annotationFullyQualifiedClassName );
401+ data . perMethodAnnotations . get (methodName ).add (annotationFullyQualifiedClassName );
340402 }
341403
342404 private String fullyQualify (String packageName , String className ) {
0 commit comments