11package org .terasology .gestalt .annotation .processing ;
22
3+ import com .google .common .collect .HashMultimap ;
4+ import com .google .common .collect .Multimap ;
35import com .google .common .collect .Queues ;
6+ import org .terasology .context .annotation .BindAnnotationFor ;
47import org .terasology .context .annotation .Index ;
58import org .terasology .context .annotation .IndexInherited ;
69
710import javax .annotation .processing .AbstractProcessor ;
811import javax .annotation .processing .Filer ;
912import javax .annotation .processing .ProcessingEnvironment ;
1013import javax .annotation .processing .RoundEnvironment ;
14+ import javax .lang .model .element .AnnotationValue ;
1115import javax .lang .model .element .Element ;
1216import javax .lang .model .element .ElementKind ;
1317import javax .lang .model .element .PackageElement ;
1923import javax .tools .StandardLocation ;
2024import java .io .IOException ;
2125import java .io .Writer ;
26+ import java .lang .annotation .Annotation ;
2227import java .util .Arrays ;
2328import java .util .Collections ;
29+ import java .util .Map ;
30+ import java .util .Optional ;
2431import java .util .Queue ;
2532import java .util .Set ;
2633
@@ -31,17 +38,34 @@ public class ClassIndexProcessor extends AbstractProcessor {
3138 private SubtypesTypeWriter subtypesTypeWriter ;
3239 private ElementUtility elementUtility ;
3340
41+ private Multimap <TypeMirror , Class <? extends Annotation >> boundAnnotations ;
42+
3443 @ Override
3544 public synchronized void init (ProcessingEnvironment processingEnv ) {
3645 super .init (processingEnv );
3746 filer = processingEnv .getFiler ();
3847 annotationTypeWriter = new AnnotationTypeWriter (filer );
3948 subtypesTypeWriter = new SubtypesTypeWriter (filer );
4049 elementUtility = new ElementUtility (processingEnv .getElementUtils (), processingEnv .getTypeUtils ());
50+ boundAnnotations = HashMultimap .create ();
4151 }
4252
4353 @ Override
4454 public boolean process (Set <? extends TypeElement > annotations , RoundEnvironment roundEnv ) {
55+ for (TypeElement annotation : annotations ) {
56+ if (annotation .asType ().toString ().equals (BindAnnotationFor .class .getName ())) {
57+ for (Element type : roundEnv .getElementsAnnotatedWith (annotation )) {
58+ TypeMirror foreighElement = getBindAnnotationFor (type );
59+ if (elementUtility .hasStereotype (type , Collections .singletonList (IndexInherited .class .getName ()))) {
60+ boundAnnotations .put (foreighElement , IndexInherited .class );
61+ }
62+ if (elementUtility .hasStereotype (type , Collections .singletonList (Index .class .getName ()))) {
63+ boundAnnotations .put (foreighElement , Index .class );
64+ }
65+ }
66+ }
67+ }
68+
4569 for (TypeElement annotation : annotations ) {
4670 // Annotation Index
4771 processAnnotationIndex (roundEnv , annotation );
@@ -71,7 +95,7 @@ private void processSubtypeIndexInReverseWay(Element type) {
7195 TypeMirror candidate = supers .poll ();
7296 if (candidate .getKind () != TypeKind .NONE ) {
7397 if (elementUtility .hasStereotype (elementUtility .getTypes ().asElement (candidate ),
74- Collections .singletonList (IndexInherited .class .getName ()))) {
98+ Collections .singletonList (IndexInherited .class .getName ())) || boundAnnotations . containsEntry ( candidate , IndexInherited . class )) {
7599 TypeElement candidateElement = (TypeElement ) elementUtility .getTypes ().asElement (elementUtility .getTypes ().erasure (candidate ));
76100 TypeElement erasedType = (TypeElement ) elementUtility .getTypes ().asElement (elementUtility .getTypes ().erasure (type .asType ()));
77101 subtypesTypeWriter .writeSubType (elementUtility .getElements ().getBinaryName (candidateElement ).toString (),
@@ -94,7 +118,7 @@ private void processSubtypeIndexByDirectMarked(RoundEnvironment roundEnv, TypeEl
94118 TypeMirror candidate = supers .poll ();
95119 if (candidate .getKind () != TypeKind .NONE ) {
96120 if (elementUtility .hasStereotype (elementUtility .getTypes ().asElement (candidate ),
97- Collections .singletonList (IndexInherited .class .getName ())))
121+ Collections .singletonList (IndexInherited .class .getName ())) || boundAnnotations . containsEntry ( candidate , IndexInherited . class ) )
98122 subtypesTypeWriter .writeSubType (elementUtility .getTypes ().erasure (candidate ).toString (), elementUtility .getTypes ().erasure (type .asType ()).toString ());
99123 supers .addAll (elementUtility .getTypes ().directSupertypes (candidate ));
100124 }
@@ -117,6 +141,27 @@ private void processAnnotationIndex(RoundEnvironment roundEnv, TypeElement annot
117141 }
118142 }
119143
144+ private TypeMirror getBindAnnotationFor (Element element ) {
145+ return (TypeMirror ) getAnnotationValue (element , BindAnnotationFor .class , "value" ).orElse (null );
146+ }
147+
148+ private Optional <Object > getAnnotationValue (Element element , Class <?> annotation , String fieldName ) {
149+ return element
150+ .getAnnotationMirrors ()
151+ .stream ()
152+ .filter (am -> am .getAnnotationType ().toString ().equals (annotation .getName ()))
153+ .map (am -> am .getElementValues ()
154+ .entrySet ()
155+ .stream ()
156+ .filter (kv -> kv .getKey ().getSimpleName ().toString ().equals (fieldName ))
157+ .map (Map .Entry ::getValue )
158+ .findFirst ())
159+ .filter (Optional ::isPresent )
160+ .map (Optional ::get )
161+ .map (AnnotationValue ::getValue )
162+ .findFirst ();
163+ }
164+
120165 private void writeIndexes () {
121166 try {
122167 annotationTypeWriter .finish ();
0 commit comments