1 /*
2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  *   - Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  *
11  *   - Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  *   - Neither the name of Oracle nor the names of its
16  *     contributors may be used to endorse or promote products derived
17  *     from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 import java.lang.annotation.Annotation;
33 import javax.annotation.processing.SupportedSourceVersion;
34 import javax.lang.model.element.*;
35 import javax.lang.model.element.Modifier;
36 import javax.lang.model.type.*;
37 import javax.lang.model.util.*;
38 import java.lang.reflect.*;
39 import java.io.Writer;
40 import java.util.*;
41 
42 import static javax.lang.model.SourceVersion.RELEASE_8;
43 import static java.util.Objects.*;
44 
45 /**
46  * This class provides a proof-of-concept implementation of the {@code
47  * javax.lang.model.*} API backed by core reflection. That is, rather
48  * than having a source file or compile-time class file as the
49  * originator of the information about an element or type, as done
50  * during standard annotation processing, runtime core reflection
51  * objects serve that purpose instead.
52  *
53  * With this kind of implementation, the same logic can be used for
54  * both compile-time and runtime processing of annotations.
55  *
56  * The nested types in this class define a specialization of {@code
57  * javax.lang.model.*} to provide some additional functionality and
58  * type information. The original {@code javax.lang.model.*} API was
59  * designed to accommodate such a specialization by using wildcards in
60  * the return types of methods.
61  *
62  * It would be technically possible for further specializations of the
63  * API implemented in this class to define alternative semantics of
64  * annotation look-up. For example to allow one annotation to have the
65  * effect of macro-expanding into a set of other annotations.
66  *
67  * Some aspects of the implementation are left as "exercises for the
68  * reader" to complete if interested.
69  *
70  * When passed null pointers, the methods defined in this type will
71  * generally throw null pointer exceptions.
72  *
73  * To get started, first compile this file with a command line like:
74  *
75  * <pre>
76  * $JDK/bin/javac -parameters -Xdoclint:all/public -Xlint:all -d $OUTPUT_DIR CoreReflectionFactory.java
77  * </pre>
78  *
79  * and then run the main method of {@code CoreReflectionFactory},
80  * which will print out a representation of {@code
81  * CoreReflectionFactory}. To use the printing logic defined in {@code
82  * javac}, put {@code tools.jar} on the classpath as in:
83  *
84  * <pre>
85  * $JDK/bin/java -cp $OUTPUT_DIR:$JDK_ROOT/lib/tools.jar CoreReflectionFactory
86  * </pre>
87  *
88  * @author Joseph D. Darcy (darcy)
89  * @author Joel Borggren-Franck (jfranck)
90  */
91 public class CoreReflectionFactory {
CoreReflectionFactory()92     private CoreReflectionFactory() {
93         throw new AssertionError("No instances of CoreReflectionFactory for you!");
94     }
95 
96     /**
97      * Returns a reflection type element mirroring a {@code Class} object.
98      * @return a reflection type element mirroring a {@code Class} object
99      * @param clazz the {@code Class} to mirror
100      */
createMirror(Class<?> clazz)101     public static ReflectionTypeElement createMirror(Class<?> clazz) {
102         return new CoreReflTypeElement(Objects.requireNonNull(clazz));
103     }
104 
105     /**
106      * Returns a reflection package element mirroring a {@code Package} object.
107      * @return a reflection package element mirroring a {@code Package} object
108      * @param pkg the {@code Package} to mirror
109      */
createMirror(Package pkg)110     public static ReflectionPackageElement createMirror(Package pkg) {
111         // Treat a null pkg to mean an unnamed package.
112         return new CoreReflPackageElement(pkg);
113     }
114 
115     /**
116      * Returns a reflection variable element mirroring a {@code Field} object.
117      * @return a reflection variable element mirroring a {@code Field} object
118      * @param field the {@code Field} to mirror
119      */
createMirror(Field field)120     public static ReflectionVariableElement createMirror(Field field) {
121         return new CoreReflFieldVariableElement(Objects.requireNonNull(field));
122     }
123 
124     /**
125      * Returns a reflection executable element mirroring a {@code Method} object.
126      * @return a reflection executable element mirroring a {@code Method} object
127      * @param method the {@code Method} to mirror
128      */
createMirror(Method method)129     public static ReflectionExecutableElement createMirror(Method method)  {
130         return new CoreReflMethodExecutableElement(Objects.requireNonNull(method));
131     }
132 
133     /**
134      * Returns a reflection executable element mirroring a {@code Constructor} object.
135      * @return a reflection executable element mirroring a {@code Constructor} object
136      * @param constructor the {@code Constructor} to mirror
137      */
createMirror(Constructor<?> constructor)138     public static ReflectionExecutableElement createMirror(Constructor<?> constructor)  {
139         return new CoreReflConstructorExecutableElement(Objects.requireNonNull(constructor));
140     }
141 
142     /**
143      * Returns a type parameter element mirroring a {@code TypeVariable} object.
144      * @return a type parameter element mirroring a {@code TypeVariable} object
145      * @param tv the {@code TypeVariable} to mirror
146      */
createMirror(java.lang.reflect.TypeVariable<?> tv)147     public static TypeParameterElement createMirror(java.lang.reflect.TypeVariable<?> tv) {
148         return new CoreReflTypeParameterElement(Objects.requireNonNull(tv));
149     }
150 
151     /**
152      * Returns a variable element mirroring a {@code Parameter} object.
153      * @return a variable element mirroring a {@code Parameter} object
154      * @param p the {Parameter} to mirror
155      */
createMirror(java.lang.reflect.Parameter p)156     public static VariableElement createMirror(java.lang.reflect.Parameter p) {
157         return new CoreReflParameterVariableElement(Objects.requireNonNull(p));
158     }
159 
160     /**
161      * Returns an annotation mirror mirroring an annotation object.
162      * @return an annotation mirror mirroring an annotation object
163      * @param annotation the annotation to mirror
164      */
createMirror(Annotation annotation)165     public static AnnotationMirror createMirror(Annotation annotation)  {
166         return new CoreReflAnnotationMirror(Objects.requireNonNull(annotation));
167     }
168 
169     /**
170      * Returns a {@code Types} utility object for type objects backed by core reflection.
171      * @return a {@code Types} utility object for type objects backed by core reflection
172      */
getTypes()173     public static Types getTypes() {
174         return CoreReflTypes.instance();
175     }
176 
177     /**
178      * Returns an {@code Elements} utility object for type objects backed by core reflection.
179      * @return an {@code Elements} utility object for type objects backed by core reflection
180      */
getElements()181     public static Elements getElements() {
182         return CoreReflElements.instance();
183     }
184 
185     // Helper
createTypeMirror(Class<?> c)186     private static TypeMirror createTypeMirror(Class<?> c) {
187         return TypeFactory.instance(Objects.requireNonNull(c));
188     }
189 
190     /**
191      * Main method; prints out a representation of this class.
192      * @param args command-line arguments, currently ignored
193      */
main(String... args)194     public static void main(String... args) {
195         getElements().printElements(new java.io.PrintWriter(System.out),
196                                     createMirror(CoreReflectionFactory.class));
197     }
198 
199     /**
200      * A specialization of {@code javax.lang.model.element.Element} that is
201      * backed by core reflection.
202      */
203     public static interface ReflectionElement
204         extends Element, AnnotatedElement {
205 
206         /**
207          * {@inheritDoc}
208          */
209         @Override
getEnclosingElement()210         ReflectionElement getEnclosingElement();
211 
212         /**
213          * {@inheritDoc}
214          */
215         @Override
getEnclosedElements()216         List<ReflectionElement> getEnclosedElements();
217 
218         /**
219          * Applies a visitor to this element.
220          *
221          * @param v the visitor operating on this element
222          * @param p additional parameter to the visitor
223          * @param <R> the return type of the visitor's methods
224          * @param <P> the type of the additional parameter to the visitor's methods
225          * @return a visitor-specified result
226          */
accept(ReflectionElementVisitor<R,P> v, P p)227         <R,P> R accept(ReflectionElementVisitor<R,P> v, P p);
228 
229         // Functionality specific to the specialization
230         /**
231          * Returns the underlying core reflection source object, if applicable.
232          * @return the underlying core reflection source object, if applicable
233          */
getSource()234         AnnotatedElement getSource();
235 
236         // Functionality from javax.lang.model.util.Elements
237         /**
238          * Returns the package of an element. The package of a package
239          * is itself.
240          * @return the package of an element
241          */
getPackage()242         ReflectionPackageElement getPackage();
243 
244     }
245 
246     /**
247      * A logical specialization of {@code
248      * javax.lang.model.element.ElementVisitor} being backed by core
249      * reflection.
250      *
251      * @param <R> the return type of this visitor's methods.
252      * @param <P> the type of the additional parameter to this visitor's
253      *            methods.
254      */
255     public static interface ReflectionElementVisitor<R, P> {
256         /**
257          * Visits an element.
258          * @param e  the element to visit
259          * @param p  a visitor-specified parameter
260          * @return a visitor-specified result
261          */
visit(ReflectionElement e, P p)262         R visit(ReflectionElement e, P p);
263 
264         /**
265          * A convenience method equivalent to {@code v.visit(e, null)}.
266          * @param e  the element to visit
267          * @return a visitor-specified result
268          */
visit(ReflectionElement e)269         R visit(ReflectionElement e);
270 
271         /**
272          * Visits a package element.
273          * @param e  the element to visit
274          * @param p  a visitor-specified parameter
275          * @return a visitor-specified result
276          */
visitPackage(ReflectionPackageElement e, P p)277         R visitPackage(ReflectionPackageElement e, P p);
278 
279         /**
280          * Visits a type element.
281          * @param e  the element to visit
282          * @param p  a visitor-specified parameter
283          * @return a visitor-specified result
284          */
visitType(ReflectionTypeElement e, P p)285         R visitType(ReflectionTypeElement e, P p);
286 
287         /**
288          * Visits a variable element.
289          * @param e  the element to visit
290          * @param p  a visitor-specified parameter
291          * @return a visitor-specified result
292          */
visitVariable(ReflectionVariableElement e, P p)293         R visitVariable(ReflectionVariableElement e, P p);
294 
295         /**
296          * Visits an executable element.
297          * @param e  the element to visit
298          * @param p  a visitor-specified parameter
299          * @return a visitor-specified result
300          */
visitExecutable(ReflectionExecutableElement e, P p)301         R visitExecutable(ReflectionExecutableElement e, P p);
302 
303         /**
304          * Visits a type parameter element.
305          * @param e  the element to visit
306          * @param p  a visitor-specified parameter
307          * @return a visitor-specified result
308          */
visitTypeParameter(ReflectionTypeParameterElement e, P p)309         R visitTypeParameter(ReflectionTypeParameterElement e, P p);
310 
311         /**
312          * Visits an unknown kind of element.
313          * This can occur if the language evolves and new kinds
314          * of elements are added to the {@code Element} hierarchy.
315          *
316          * @param e  the element to visit
317          * @param p  a visitor-specified parameter
318          * @return a visitor-specified result
319          * @throws UnknownElementException
320          * a visitor implementation may optionally throw this exception
321          */
visitUnknown(ReflectionElement e, P p)322         R visitUnknown(ReflectionElement e, P p);
323     }
324 
325     /**
326      * A specialization of {@code javax.lang.model.element.ExecutableElement} that is
327      * backed by core reflection.
328      */
329     public static interface ReflectionExecutableElement
330         extends ReflectionElement, ExecutableElement, ReflectionParameterizable {
331 
332         /**
333          * {@inheritDoc}
334          */
335         @Override
getTypeParameters()336         List<ReflectionTypeParameterElement> getTypeParameters();
337 
338         /**
339          * {@inheritDoc}
340          */
341         @Override
getParameters()342         List<ReflectionVariableElement> getParameters();
343 
344         // Functionality specific to the specialization
345         /**
346          * Returns all parameters, including synthetic ones.
347          * @return all parameters, including synthetic ones
348          */
getAllParameters()349         List<ReflectionVariableElement> getAllParameters();
350 
351         /**
352          * {@inheritDoc}
353          */
354         @Override
getSource()355         Executable getSource();
356 
357         /**
358          * Returns true if this executable is a synthetic construct; returns false otherwise.
359          * @return true if this executable is a synthetic construct; returns false otherwise
360          */
isSynthetic()361         boolean isSynthetic();
362 
363         /**
364          * Returns true if this executable is a bridge method; returns false otherwise.
365          * @return true if this executable is a bridge method; returns false otherwise
366          */
isBridge()367         boolean isBridge();
368     }
369 
370     /**
371      * A specialization of {@code javax.lang.model.element.PackageElement} being
372      * backed by core reflection.
373      */
374     public static interface ReflectionPackageElement
375         extends ReflectionElement, PackageElement {
376 
377         // Functionality specific to the specialization
378         /**
379          * {@inheritDoc}
380          */
381         @Override
getSource()382         Package getSource();
383     }
384 
385     /**
386      * A specialization of {@code javax.lang.model.element.TypeElement} that is
387      * backed by core reflection.
388      */
389     public static interface ReflectionTypeElement
390         extends ReflectionElement, TypeElement, ReflectionParameterizable {
391 
392         /**
393          * {@inheritDoc}
394          */
395         @Override
getTypeParameters()396         List<ReflectionTypeParameterElement> getTypeParameters();
397 
398         /**
399          * {@inheritDoc}
400          */
401         @Override
getEnclosedElements()402         List<ReflectionElement> getEnclosedElements();
403 
404         // Methods specific to the specialization, but functionality
405         // also present in javax.lang.model.util.Elements.
406         /**
407          * Returns all members of a type element, whether inherited or
408          * declared directly. For a class the result also includes its
409          * constructors, but not local or anonymous classes.
410          * @return all members of the type
411          */
getAllMembers()412         List<ReflectionElement> getAllMembers();
413 
414         /**
415          * Returns the binary name of a type element.
416          * @return the binary name of a type element
417          */
getBinaryName()418         Name getBinaryName();
419 
420         // Functionality specific to the specialization
421         /**
422          * {@inheritDoc}
423          */
424         @Override
getSource()425         Class<?> getSource();
426     }
427 
428     /**
429      * A specialization of {@code javax.lang.model.element.TypeParameterElement} being
430      * backed by core reflection.
431      */
432     public static interface ReflectionTypeParameterElement
433         extends ReflectionElement, TypeParameterElement {
434 
435         /**
436          * {@inheritDoc}
437          */
438         @Override
getGenericElement()439         ReflectionElement getGenericElement();
440 
441         // Functionality specific to the specialization
442         /**
443          * {@inheritDoc}
444          */
445         @Override
getSource()446         java.lang.reflect.TypeVariable<?> getSource();
447     }
448 
449     /**
450      * A specialization of {@code javax.lang.model.element.VariableElement} that is
451      * backed by core reflection.
452      */
453     public static interface ReflectionVariableElement
454         extends ReflectionElement, VariableElement {
455 
456         // Functionality specific to the specialization
457         /**
458          * Returns true if this variable is a synthetic construct; returns false otherwise.
459          * @return true if this variable is a synthetic construct; returns false otherwise
460          */
isSynthetic()461         boolean isSynthetic();
462 
463         /**
464          * Returns true if this variable is implicitly declared in source code; returns false otherwise.
465          * @return true if this variable is implicitly declared in source code; returns false otherwise
466          */
isImplicit()467         boolean isImplicit();
468 
469         // The VariableElement concept covers fields, variables, and
470         // method and constructor parameters. Therefore, this
471         // interface cannot define a more precise override of
472         // getSource since those three concept have different core
473         // reflection types with no supertype more precise than
474         // AnnotatedElement.
475     }
476 
477     /**
478      * A specialization of {@code javax.lang.model.element.Parameterizable} being
479      * backed by core reflection.
480      */
481     public static interface ReflectionParameterizable
482         extends ReflectionElement, Parameterizable {
483         @Override
getTypeParameters()484         List<ReflectionTypeParameterElement> getTypeParameters();
485     }
486 
487     /**
488      * Base class for concrete visitors of elements backed by core reflection.
489      */
490     public static abstract class AbstractReflectionElementVisitor8<R, P>
491         extends AbstractElementVisitor8<R, P>
492         implements ReflectionElementVisitor<R, P> {
AbstractReflectionElementVisitor8()493         protected AbstractReflectionElementVisitor8() {
494             super();
495         }
496     }
497 
498     /**
499      * Base class for simple visitors of elements that are backed by core reflection.
500      */
501     @SupportedSourceVersion(value=RELEASE_8)
502     public static abstract class SimpleReflectionElementVisitor8<R, P>
503         extends SimpleElementVisitor8<R, P>
504         implements ReflectionElementVisitor<R, P> {
505 
SimpleReflectionElementVisitor8()506         protected SimpleReflectionElementVisitor8(){
507             super();
508         }
509 
SimpleReflectionElementVisitor8(R defaultValue)510         protected SimpleReflectionElementVisitor8(R defaultValue) {
511             super(defaultValue);
512         }
513 
514         // Create manual "bridge methods" for now.
515 
516         @Override
visitPackage(PackageElement e, P p)517         public final R visitPackage(PackageElement e, P p) {
518             return visitPackage((ReflectionPackageElement) e , p);
519         }
520 
521         @Override
visitType(TypeElement e, P p)522         public final R visitType(TypeElement e, P p) {
523             return visitType((ReflectionTypeElement) e , p);
524         }
525 
526         @Override
visitVariable(VariableElement e, P p)527         public final R visitVariable(VariableElement e, P p) {
528             return visitVariable((ReflectionVariableElement) e , p);
529         }
530 
531         @Override
visitExecutable(ExecutableElement e, P p)532         public final R visitExecutable(ExecutableElement e, P p) {
533             return visitExecutable((ReflectionExecutableElement) e , p);
534         }
535 
536         @Override
visitTypeParameter(TypeParameterElement e, P p)537         public final R visitTypeParameter(TypeParameterElement e, P p) {
538             return visitTypeParameter((ReflectionTypeParameterElement) e , p);
539         }
540     }
541 
542     /**
543      * {@inheritDoc}
544      */
545     public static interface ReflectionElements  extends Elements {
546         /**
547          * Returns the innermost enclosing {@link ReflectionTypeElement}
548          * of the {@link ReflectionElement} or {@code null} if the
549          * supplied ReflectionElement is toplevel or represents a
550          * Package.
551          *
552          * @param e the {@link ReflectionElement} whose innermost
553          * enclosing {@link ReflectionTypeElement} is sought
554          * @return the innermost enclosing {@link
555          * ReflectionTypeElement} or @{code null} if the parameter
556          * {@code e} is a toplevel element or a package
557          */
getEnclosingTypeElement(ReflectionElement e)558         ReflectionTypeElement getEnclosingTypeElement(ReflectionElement e);
559 
560         /**
561          * {@inheritDoc}
562          */
563         @Override
getAllMembers(TypeElement type)564         List<? extends ReflectionElement> getAllMembers(TypeElement type);
565 
566         /**
567          * {@inheritDoc}
568          */
569         @Override
getPackageElement(CharSequence name)570         ReflectionPackageElement getPackageElement(CharSequence name);
571 
572         /**
573          * {@inheritDoc}
574          */
575         @Override
getPackageOf(Element type)576         ReflectionPackageElement getPackageOf(Element type);
577 
578         /**
579          * {@inheritDoc}
580          */
581         @Override
getTypeElement(CharSequence name)582         ReflectionTypeElement getTypeElement(CharSequence name);
583     }
584 
585     // ------------------------- Implementation classes ------------------------
586 
587     // Exercise for the reader: review the CoreReflElement class
588     // hierarchy below with an eye toward exposing it as an extensible
589     // API that could be subclassed to provide customized behavior,
590     // such as alternate annotation lookup semantics.
591 
592     private static abstract class CoreReflElement
593         implements ReflectionElement, AnnotatedElement {
getSource()594         public abstract AnnotatedElement getSource();
595 
CoreReflElement()596         protected CoreReflElement() {
597             super();
598         }
599 
600         // ReflectionElement methods
601         @Override
getPackage()602         public ReflectionPackageElement getPackage() {
603             throw new UnsupportedOperationException();
604         }
605 
606         @Override
asType()607         public TypeMirror asType() {
608             throw new UnsupportedOperationException(getClass().toString());
609         }
610 
611         @Override
getAnnotationMirrors()612         public List<? extends AnnotationMirror> getAnnotationMirrors() {
613             Annotation[] annotations = getSource().getDeclaredAnnotations();
614             int len = annotations.length;
615 
616             if (len > 0) {
617                 List<AnnotationMirror> res = new ArrayList<>(len);
618                 for (Annotation a : annotations) {
619                     res.add(createMirror(a));
620                 }
621                 return Collections.unmodifiableList(res);
622             } else {
623                 return Collections.emptyList();
624             }
625         }
626 
627         @Override
getModifiers()628         public Set<Modifier> getModifiers() {
629             return ModifierUtil.instance(0, false);
630         }
631 
632         @Override
getSimpleName()633         public abstract Name getSimpleName();
634 
635         @Override
getEnclosingElement()636         public abstract ReflectionElement getEnclosingElement();
637 
638         @Override
getEnclosedElements()639         public abstract List<ReflectionElement> getEnclosedElements();
640 
641         //AnnotatedElement methods
642         @Override
getAnnotation(Class<T> annotationClass)643         public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
644             return getSource().getAnnotation(annotationClass);
645         }
646 
647         @Override
getAnnotationsByType(Class<T> annotationClass)648         public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
649             return getSource().getAnnotationsByType(annotationClass);
650         }
651 
652         @Override
getAnnotations()653         public Annotation[] getAnnotations() {
654             return getSource().getAnnotations();
655         }
656 
657         @Override
getDeclaredAnnotation(Class<T> annotationClass)658         public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
659             return getSource().getDeclaredAnnotation(annotationClass);
660         }
661 
662         @Override
getDeclaredAnnotationsByType(Class<T> annotationClass)663         public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
664             return getSource().getDeclaredAnnotationsByType(annotationClass);
665         }
666 
667         @Override
getDeclaredAnnotations()668         public Annotation[] getDeclaredAnnotations() {
669             return getSource().getDeclaredAnnotations();
670         }
671 
672         // java.lang.Object methods
673         @Override
equals(Object obj)674         public boolean equals(Object obj) {
675             if (obj instanceof CoreReflElement) {
676                 CoreReflElement other = (CoreReflElement)obj;
677                 return Objects.equals(other.getSource(), this.getSource());
678             }
679             return false;
680         }
681 
682         @Override
hashCode()683         public int hashCode() {
684             return Objects.hashCode(getSource());
685         }
686 
687         @Override
toString()688         public String toString() {
689             return getKind().toString() + " " + getSimpleName().toString();
690         }
691     }
692 
693     // Type
694     private static class CoreReflTypeElement extends CoreReflElement
695         implements ReflectionTypeElement {
696         private final Class<?> source;
697 
CoreReflTypeElement(Class<?> source)698         protected CoreReflTypeElement(Class<?> source) {
699             Objects.requireNonNull(source);
700             if (source.isPrimitive() ||
701                 source.isArray()) {
702                 throw new IllegalArgumentException("Cannot create a ReflectionTypeElement based on class: " + source);
703             }
704 
705             this.source = source;
706         }
707 
708         @Override
asType()709         public TypeMirror asType() {
710             return createTypeMirror(source);
711         }
712 
713         @Override
getSource()714         public Class<?> getSource() {
715             return source;
716         }
717 
718         @Override
equals(Object o)719         public boolean equals(Object o) {
720             if (o instanceof CoreReflTypeElement) {
721                 return source.equals(((CoreReflTypeElement)o).getSource());
722             } else {
723                 return false;
724             }
725         }
726 
727         @Override
accept(ElementVisitor<R,P> v, P p)728         public <R,P> R accept(ElementVisitor<R,P> v, P p) {
729             return v.visitType(this, p);
730         }
731 
732         @Override
accept(ReflectionElementVisitor<R,P> v, P p)733         public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
734             return v.visitType(this, p);
735         }
736 
737         @Override
getModifiers()738         public Set<Modifier> getModifiers() {
739             return ModifierUtil.instance(source.getModifiers() &
740                                          (source.isInterface() ?
741                                           java.lang.reflect.Modifier.interfaceModifiers() :
742                                           java.lang.reflect.Modifier.classModifiers()),
743                                          false);
744         }
745 
746         @Override
getEnclosedElements()747         public List<ReflectionElement> getEnclosedElements() {
748             List<ReflectionElement> enclosedElements = new ArrayList<>();
749 
750             for (Class<?> declaredClass : source.getDeclaredClasses()) {
751                 enclosedElements.add(createMirror(declaredClass));
752             }
753 
754             // Add elements in the conventional ordering: fields, then
755             // constructors, then methods.
756             for (Field f : source.getDeclaredFields()) {
757                 enclosedElements.add(createMirror(f));
758             }
759 
760             for (Constructor<?> c : source.getDeclaredConstructors()) {
761                 enclosedElements.add(createMirror(c));
762             }
763 
764             for (Method m : source.getDeclaredMethods()) {
765                 enclosedElements.add(createMirror(m));
766             }
767 
768             return (enclosedElements.isEmpty() ?
769                     Collections.emptyList():
770                     Collections.unmodifiableList(enclosedElements));
771         }
772 
773         // Review for default method handling.
774         @Override
getAllMembers()775         public List<ReflectionElement> getAllMembers() {
776             List<ReflectionElement> allMembers = new ArrayList<>();
777 
778             // If I only had a MultiMap ...
779             List<ReflectionElement> fields = new ArrayList<>();
780             List<ReflectionExecutableElement> methods = new ArrayList<>();
781             List<ReflectionElement> classes = new ArrayList<>();
782 
783             // Add all fields for this class
784             for (Field f : source.getDeclaredFields()) {
785                 fields.add(createMirror(f));
786             }
787 
788             // Add all methods for this class
789             for (Method m : source.getDeclaredMethods()) {
790                 methods.add(createMirror(m));
791             }
792 
793             // Add all classes for this class, except anonymous/local as per Elements.getAllMembers doc
794             for (Class<?> c : source.getDeclaredClasses()) {
795                 if (c.isLocalClass() || c.isAnonymousClass())
796                     continue;
797                 classes.add(createMirror(c));
798             }
799 
800             Class<?> cls = source;
801             if (cls.isInterface()) {
802                 cls = null;
803             }
804             do {
805                 // Walk up superclasses adding non-private elements.
806                 // If source is an interface, just add Object's
807                 // elements.
808 
809                 if (cls == null) {
810                     cls = java.lang.Object.class;
811                 } else {
812                     cls = cls.getSuperclass();
813                 }
814 
815                 addMembers(cls, fields, methods, classes);
816 
817             } while (cls != java.lang.Object.class);
818 
819             // add members on (super)interface(s)
820             Set<Class<?>> seenInterfaces = new HashSet<>();
821             Queue<Class<?>> interfaces = new LinkedList<>();
822             if (source.isInterface()) {
823                 seenInterfaces.add(source);
824                 interfaces.add(source);
825             } else {
826                 Class<?>[] ifaces = source.getInterfaces();
827                 for (Class<?> iface : ifaces) {
828                     seenInterfaces.add(iface);
829                     interfaces.add(iface);
830                 }
831             }
832 
833             while (interfaces.peek() != null) {
834                 Class<?> head = interfaces.remove();
835                 addMembers(head, fields, methods, classes);
836 
837                 Class<?>[] ifaces = head.getInterfaces();
838                 for (Class<?> iface : ifaces) {
839                     if (!seenInterfaces.contains(iface)) {
840                         seenInterfaces.add(iface);
841                         interfaces.add(iface);
842                     }
843                 }
844             }
845 
846             // Add constructors
847             for (Constructor<?> c : source.getDeclaredConstructors()) {
848                 allMembers.add(createMirror(c));
849             }
850 
851             // Add all unique methods
852             allMembers.addAll(methods);
853 
854             // Add all unique fields
855             allMembers.addAll(fields);
856 
857             // Add all unique classes
858             allMembers.addAll(classes);
859 
860             return Collections.unmodifiableList(allMembers);
861         }
862 
addMembers(Class<?> cls, List<ReflectionElement> fields, List<ReflectionExecutableElement> methods, List<ReflectionElement> classes)863         private void addMembers(Class<?> cls,
864                                 List<ReflectionElement> fields,
865                                 List<ReflectionExecutableElement> methods,
866                                 List<ReflectionElement> classes) {
867             Elements elements = getElements();
868 
869             for (Field f : cls.getDeclaredFields()) {
870                 if (java.lang.reflect.Modifier.isPrivate(f.getModifiers())) { continue; }
871                 ReflectionElement tmp = createMirror(f);
872                 boolean add = true;
873                 for (ReflectionElement e : fields) {
874                     if (elements.hides(e, tmp)) {
875                         add = false;
876                         break;
877                     }
878                 }
879                 if (add) {
880                     fields.add(tmp);
881                 }
882             }
883 
884             for (Method m : cls.getDeclaredMethods()) {
885                 if (java.lang.reflect.Modifier.isPrivate(m.getModifiers()))
886                     continue;
887 
888                 ReflectionExecutableElement tmp = createMirror(m);
889                 boolean add = true;
890                 for (ReflectionExecutableElement e : methods) {
891                     if (elements.hides(e, tmp)) {
892                         add = false;
893                         break;
894                     } else if (elements.overrides(e, tmp, this)) {
895                         add = false;
896                         break;
897                     }
898                 }
899                 if (add) {
900                     methods.add(tmp);
901                 }
902             }
903 
904             for (Class<?> c : cls.getDeclaredClasses()) {
905                 if (java.lang.reflect.Modifier.isPrivate(c.getModifiers()) ||
906                     c.isLocalClass() ||
907                     c.isAnonymousClass())
908                     continue;
909 
910                 ReflectionElement tmp = createMirror(c);
911                 boolean add = true;
912                 for (ReflectionElement e : classes) {
913                     if (elements.hides(e, tmp)) {
914                         add = false;
915                         break;
916                     }
917                 }
918                 if (add) {
919                     classes.add(tmp);
920                 }
921             }
922         }
923 
924         @Override
getKind()925         public ElementKind getKind() {
926             if (source.isInterface()) {
927                 if (source.isAnnotation())
928                     return ElementKind.ANNOTATION_TYPE;
929                 else
930                     return ElementKind.INTERFACE;
931             } else if (source.isEnum()) {
932                 return ElementKind.ENUM;
933             } else
934                 return ElementKind.CLASS;
935         }
936 
937         @Override
getNestingKind()938         public NestingKind getNestingKind() {
939             if (source.isAnonymousClass())
940                 return NestingKind.ANONYMOUS;
941             else if (source.isLocalClass())
942                 return NestingKind.LOCAL;
943             else if (source.isMemberClass())
944                 return NestingKind.MEMBER;
945             else return
946                 NestingKind.TOP_LEVEL;
947         }
948 
949         @Override
getQualifiedName()950         public Name getQualifiedName() {
951             String name = source.getCanonicalName(); // TODO, this should be a FQN for
952                                                      // the current element
953             if (name == null)
954                 name = "";
955             return StringName.instance(name);
956         }
957 
958         @Override
getSimpleName()959         public Name getSimpleName() {
960             return StringName.instance(source.getSimpleName());
961         }
962 
963         @Override
getSuperclass()964         public TypeMirror getSuperclass() {
965             if (source.equals(java.lang.Object.class)) {
966                 return NoType.getNoneInstance();
967             } else {
968                 return createTypeMirror(source.getSuperclass());
969             }
970         }
971 
972         @Override
getInterfaces()973         public List<? extends TypeMirror> getInterfaces() {
974             Class[] interfaces = source.getInterfaces();
975             int len = interfaces.length;
976             List<TypeMirror> res = new ArrayList<>(len);
977 
978             if (len > 0) {
979                 for (Class<?> c : interfaces) {
980                     res.add(createTypeMirror(c));
981                 }
982             } else {
983                 return Collections.emptyList();
984             }
985             return Collections.unmodifiableList(res);
986         }
987 
988         @Override
getTypeParameters()989         public List<ReflectionTypeParameterElement> getTypeParameters() {
990             return createTypeParameterList(source);
991         }
992 
993         @Override
getEnclosingElement()994         public ReflectionElement getEnclosingElement() {
995             // Returns the package of a top-level type and returns the
996             // immediately lexically enclosing element for a nested type.
997 
998             switch(getNestingKind()) {
999             case TOP_LEVEL:
1000                 return createMirror(source.getPackage());
1001             case MEMBER:
1002                 return createMirror(source.getEnclosingClass());
1003             default:
1004                 if (source.getEnclosingConstructor() != null) {
1005                     return createMirror(source.getEnclosingConstructor());
1006                 } else if (source.getEnclosingMethod() != null) {
1007                     return createMirror(source.getEnclosingMethod());
1008                 } else {
1009                     return createMirror(source.getEnclosingClass());
1010                 }
1011             }
1012         }
1013 
1014         @Override
getBinaryName()1015         public Name getBinaryName() {
1016             return StringName.instance(getSource().getName());
1017         }
1018     }
1019 
1020     private static abstract class CoreReflExecutableElement extends CoreReflElement
1021         implements ReflectionExecutableElement {
1022 
1023         protected Executable source = null;
1024         protected final List<CoreReflParameterVariableElement> parameters;
1025 
CoreReflExecutableElement(Executable source, List<CoreReflParameterVariableElement> parameters)1026         protected CoreReflExecutableElement(Executable source,
1027                                             List<CoreReflParameterVariableElement> parameters) {
1028             this.source = Objects.requireNonNull(source);
1029             this.parameters = Objects.requireNonNull(parameters);
1030         }
1031 
1032         @Override
accept(ElementVisitor<R,P> v, P p)1033         public <R,P> R accept(ElementVisitor<R,P> v, P p) {
1034             return v.visitExecutable(this, p);
1035         }
1036 
1037         @Override
accept(ReflectionElementVisitor<R,P> v, P p)1038         public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
1039             return v.visitExecutable(this, p);
1040         }
1041 
1042         @Override
asType()1043         public abstract ExecutableType asType();
1044 
1045         // Only Types and Packages enclose elements; see Element.getEnclosedElements()
1046         @Override
getEnclosedElements()1047         public List<ReflectionElement> getEnclosedElements() {
1048             return Collections.emptyList();
1049         }
1050 
1051         @Override
getParameters()1052         public List<ReflectionVariableElement> getParameters() {
1053             List<ReflectionVariableElement> tmp = new ArrayList<>();
1054             for (ReflectionVariableElement parameter : parameters) {
1055                 if (!parameter.isSynthetic())
1056                     tmp.add(parameter);
1057             }
1058             return tmp;
1059         }
1060 
1061         @Override
getAllParameters()1062         public List<ReflectionVariableElement> getAllParameters() {
1063             // Could "fix" this if the return type included wildcards
1064             @SuppressWarnings("unchecked")
1065             List<ReflectionVariableElement> tmp = (List<ReflectionVariableElement>)(List)parameters;
1066             return tmp;
1067         }
1068 
1069         @Override
getThrownTypes()1070         public List<? extends TypeMirror> getThrownTypes() {
1071             Class<?>[] thrown = source.getExceptionTypes();
1072             int len = thrown.length;
1073             List<TypeMirror> res = new ArrayList<>(len);
1074 
1075             if (len > 0) {
1076                 for (Class<?> c : thrown) {
1077                     res.add(createTypeMirror(c));
1078                 }
1079             } else {
1080                 return Collections.emptyList();
1081             }
1082             return Collections.unmodifiableList(res);
1083         }
1084 
1085         @Override
isVarArgs()1086         public boolean isVarArgs() {
1087             return source.isVarArgs();
1088         }
1089 
1090         @Override
isSynthetic()1091         public boolean isSynthetic() {
1092             return source.isSynthetic();
1093         }
1094 
1095         @Override
isBridge()1096         public boolean isBridge() {
1097             return false;
1098         }
1099 
1100         @Override
getTypeParameters()1101         public List<ReflectionTypeParameterElement> getTypeParameters() {
1102             return createTypeParameterList(source);
1103         }
1104 
getDefaultValue()1105         public abstract AnnotationValue getDefaultValue();
1106 
1107         @Override
getReceiverType()1108         public TypeMirror getReceiverType() {
1109             // New in JDK 8
1110             throw new UnsupportedOperationException(this.toString());
1111         }
1112     }
1113 
1114     private static class CoreReflConstructorExecutableElement
1115         extends CoreReflExecutableElement {
1116 
CoreReflConstructorExecutableElement(Constructor<?> source)1117         protected CoreReflConstructorExecutableElement(Constructor<?> source) {
1118             super(Objects.requireNonNull(source),
1119                   createParameterList(source));
1120         }
1121 
1122         @Override
getSource()1123         public  Constructor<?> getSource() {
1124             return (Constructor<?>)source;
1125         }
1126 
1127         @Override
getReturnType()1128         public TypeMirror getReturnType() {
1129             return NoType.getVoidInstance();
1130         }
1131 
1132         @Override
asType()1133         public ExecutableType asType() {
1134             throw new UnsupportedOperationException(getClass().toString());
1135         }
1136 
1137         @Override
equals(Object o)1138         public boolean equals(Object o) {
1139             if (o instanceof CoreReflConstructorExecutableElement) {
1140                 return source.equals(((CoreReflConstructorExecutableElement)o).getSource());
1141             } else {
1142                 return false;
1143             }
1144         }
1145 
1146         @Override
getKind()1147         public ElementKind getKind() {
1148             return ElementKind.CONSTRUCTOR;
1149         }
1150 
1151         @Override
getModifiers()1152         public Set<Modifier> getModifiers() {
1153             return ModifierUtil.instance(source.getModifiers() &
1154                                          java.lang.reflect.Modifier.constructorModifiers(), false);
1155         }
1156 
1157         @Override
getEnclosingElement()1158         public ReflectionElement getEnclosingElement() {
1159             return createMirror(source.getDeclaringClass());
1160         }
1161 
1162         @Override
getSimpleName()1163         public Name getSimpleName() {
1164             return StringName.instance("<init>");
1165         }
1166 
1167         @Override
getDefaultValue()1168         public AnnotationValue getDefaultValue() {
1169             // a constructor is never an annotation element
1170             return null;
1171         }
1172 
1173         @Override
isDefault()1174         public boolean isDefault() {
1175             return false; // A constructor cannot be a default method
1176         }
1177     }
1178 
1179     private static class CoreReflMethodExecutableElement
1180         extends CoreReflExecutableElement {
1181 
CoreReflMethodExecutableElement(Method source)1182         protected CoreReflMethodExecutableElement(Method source) {
1183             super(Objects.requireNonNull(source),
1184                   createParameterList(source));
1185             this.source = source;
1186         }
1187 
1188         @Override
getSource()1189         public Method getSource() {
1190             return (Method)source;
1191         }
1192 
1193         @Override
getReturnType()1194         public TypeMirror getReturnType() {
1195             return TypeFactory.instance(getSource().getReturnType());
1196         }
1197 
1198         @Override
equals(Object o)1199         public boolean equals(Object o) {
1200             if (o instanceof CoreReflMethodExecutableElement) {
1201                 return source.equals( ((CoreReflMethodExecutableElement)o).getSource());
1202             } else {
1203                 return false;
1204             }
1205         }
1206 
1207         @Override
getKind()1208         public ElementKind getKind() {
1209             return ElementKind.METHOD;
1210         }
1211 
1212         @Override
getModifiers()1213         public Set<Modifier> getModifiers() {
1214             return ModifierUtil.instance(source.getModifiers() &
1215                                          java.lang.reflect.Modifier.methodModifiers(),
1216                                          isDefault());
1217         }
1218 
1219         @Override
getEnclosingElement()1220         public ReflectionElement getEnclosingElement() {
1221             return createMirror(source.getDeclaringClass());
1222         }
1223 
1224         @Override
getSimpleName()1225         public Name getSimpleName() {
1226             return StringName.instance(source.getName());
1227         }
1228 
1229         @Override
getDefaultValue()1230         public AnnotationValue getDefaultValue() {
1231             Object value = getSource().getDefaultValue();
1232             if (null == value) {
1233                 return null;
1234             } else {
1235                 return new CoreReflAnnotationValue(value);
1236             }
1237         }
1238 
1239         @Override
isDefault()1240         public boolean isDefault() {
1241             return getSource().isDefault();
1242         }
1243 
1244         @Override
isBridge()1245         public boolean isBridge() {
1246             return getSource().isBridge();
1247         }
1248 
1249         @Override
asType()1250         public ExecutableType asType() {
1251             return TypeFactory.instance(getSource());
1252         }
1253     }
1254 
createParameterList(Executable source)1255     private static List<CoreReflParameterVariableElement> createParameterList(Executable source) {
1256         Parameter[] parameters = source.getParameters();
1257         int length = parameters.length;
1258         if (length == 0)
1259             return Collections.emptyList();
1260         else {
1261             List<CoreReflParameterVariableElement> tmp = new ArrayList<>(length);
1262             for (Parameter parameter : parameters) {
1263                 tmp.add(new CoreReflParameterVariableElement(parameter));
1264             }
1265             return Collections.unmodifiableList(tmp);
1266         }
1267     }
1268 
createTypeParameterList(GenericDeclaration source)1269     private static List<ReflectionTypeParameterElement> createTypeParameterList(GenericDeclaration source) {
1270         java.lang.reflect.TypeVariable<?>[] typeParams = source.getTypeParameters();
1271         int length = typeParams.length;
1272         if (length == 0)
1273             return Collections.emptyList();
1274         else {
1275             List<ReflectionTypeParameterElement> tmp = new ArrayList<>(length);
1276             for (java.lang.reflect.TypeVariable<?> typeVar : typeParams)
1277                 tmp.add(new CoreReflTypeParameterElement(typeVar));
1278             return Collections.unmodifiableList(tmp);
1279         }
1280     }
1281 
1282     private static class CoreReflTypeParameterElement
1283         extends CoreReflElement
1284         implements ReflectionTypeParameterElement {
1285 
1286         private final GenericDeclaration source;
1287         private final java.lang.reflect.TypeVariable<?> sourceTypeVar;
1288 
CoreReflTypeParameterElement(java.lang.reflect.TypeVariable<?> sourceTypeVar)1289         protected CoreReflTypeParameterElement(java.lang.reflect.TypeVariable<?> sourceTypeVar) {
1290             this.sourceTypeVar = Objects.requireNonNull(sourceTypeVar);
1291             this.source = Objects.requireNonNull(sourceTypeVar.getGenericDeclaration());
1292         }
1293 
1294         @Override
getSource()1295         public java.lang.reflect.TypeVariable<?> getSource() {
1296             return sourceTypeVar;
1297         }
1298 
getSourceTypeVar()1299         protected java.lang.reflect.TypeVariable<?> getSourceTypeVar() {
1300             return sourceTypeVar;
1301         }
1302 
1303         @Override
equals(Object o)1304         public boolean equals(Object o) {
1305             if (o instanceof CoreReflTypeParameterElement) {
1306                 return sourceTypeVar.equals(((CoreReflTypeParameterElement)o).sourceTypeVar);
1307             } else {
1308                 return false;
1309             }
1310         }
1311 
1312         @Override
accept(ElementVisitor<R,P> v, P p)1313         public <R,P> R accept(ElementVisitor<R,P> v, P p) {
1314             return v.visitTypeParameter(this, p);
1315         }
1316 
1317         @Override
accept(ReflectionElementVisitor<R,P> v, P p)1318         public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
1319             return v.visitTypeParameter(this, p);
1320         }
1321 
1322         @Override
getEnclosedElements()1323         public List<ReflectionElement> getEnclosedElements() {
1324             return Collections.emptyList();
1325         }
1326 
1327         @Override
getEnclosingElement()1328         public ReflectionElement getEnclosingElement() {
1329             if (source instanceof Class)
1330                 return createMirror((Class<?>)source);
1331             else if (source instanceof Method)
1332                 return createMirror((Method)source);
1333             else if (source instanceof Constructor)
1334                 return createMirror((Constructor<?>)source);
1335             else
1336                 throw new AssertionError("Unexpected enclosing element: " + source);
1337         }
1338 
1339         @Override
getKind()1340         public ElementKind getKind() {
1341             return ElementKind.TYPE_PARAMETER;
1342         }
1343 
1344         @Override
getSimpleName()1345         public Name getSimpleName() {
1346             return StringName.instance(sourceTypeVar.getName());
1347         }
1348 
1349         // TypeParameterElement methods
1350         @Override
getGenericElement()1351         public ReflectionElement getGenericElement() {
1352             return getEnclosingElement(); // As per the doc,
1353                                           // getEnclosingElement and
1354                                           // getGenericElement return
1355                                           // the same information.
1356         }
1357 
1358         @Override
getBounds()1359         public List<? extends TypeMirror> getBounds() {
1360             Type[] types = getSourceTypeVar().getBounds();
1361             int len = types.length;
1362 
1363             if (len > 0) {
1364                 List<TypeMirror> res = new ArrayList<>(len);
1365                 for (Type t : types) {
1366                     res.add(TypeFactory.instance(t));
1367                 }
1368                 return Collections.unmodifiableList(res);
1369             } else {
1370                 return Collections.emptyList();
1371             }
1372         }
1373     }
1374 
1375     private abstract static class CoreReflVariableElement extends CoreReflElement
1376         implements ReflectionVariableElement {
1377 
CoreReflVariableElement()1378         protected CoreReflVariableElement() {}
1379 
1380         // Element visitor
1381         @Override
accept(ElementVisitor<R,P>v, P p)1382         public <R,P> R accept(ElementVisitor<R,P>v, P p) {
1383             return v.visitVariable(this, p);
1384         }
1385 
1386         // ReflectElement visitor
1387         @Override
accept(ReflectionElementVisitor<R,P> v, P p)1388         public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
1389             return v.visitVariable(this, p);
1390         }
1391 
1392         @Override
getEnclosedElements()1393         public List<ReflectionElement> getEnclosedElements() {
1394             return Collections.emptyList();
1395         }
1396 
1397         @Override
getEnclosingElement()1398         public ReflectionElement getEnclosingElement() {
1399             return null;
1400         }
1401 
1402         @Override
isSynthetic()1403         public boolean isSynthetic() {
1404             return false;
1405         }
1406 
1407         @Override
isImplicit()1408         public boolean isImplicit() {
1409             return false;
1410         }
1411     }
1412 
1413     private static class CoreReflFieldVariableElement extends CoreReflVariableElement {
1414         private final Field source;
1415 
CoreReflFieldVariableElement(Field source)1416         protected CoreReflFieldVariableElement(Field source) {
1417             this.source = Objects.requireNonNull(source);
1418         }
1419 
1420         @Override
getSource()1421         public Field getSource() {
1422             return source;
1423         }
1424 
1425         @Override
asType()1426         public TypeMirror asType() {
1427             return createTypeMirror(getSource().getType());
1428         }
1429 
1430         @Override
getKind()1431         public ElementKind getKind() {
1432             if (source.isEnumConstant())
1433                 return ElementKind.ENUM_CONSTANT;
1434             else
1435                 return ElementKind.FIELD;
1436         }
1437 
1438         @Override
getModifiers()1439         public Set<Modifier> getModifiers() {
1440             return ModifierUtil.instance(source.getModifiers() &
1441                                          java.lang.reflect.Modifier.fieldModifiers(), false);
1442         }
1443 
1444         @Override
getSimpleName()1445         public Name getSimpleName() {
1446             return StringName.instance(source.getName());
1447         }
1448 
1449         @Override
getEnclosingElement()1450         public ReflectionElement getEnclosingElement() {
1451             return createMirror(source.getDeclaringClass());
1452         }
1453 
1454         @Override
equals(Object o)1455         public boolean equals(Object o) {
1456             if (o instanceof CoreReflFieldVariableElement) {
1457                 return Objects.equals(source,
1458                                       ((CoreReflFieldVariableElement)o).getSource());
1459             } else {
1460                 return false;
1461             }
1462         }
1463 
1464         @Override
getConstantValue()1465         public Object getConstantValue() {
1466             Field target = source;
1467 
1468             // The api says only Strings and primitives may be compile time constants.
1469             // Ensure field is that, and final.
1470             //
1471             // Also, we don't have an instance so restrict to static Fields
1472             //
1473             if (!(source.getType().equals(java.lang.String.class)
1474                   || source.getType().isPrimitive())) {
1475                 return null;
1476             }
1477             final int modifiers = target.getModifiers();
1478             if (!( java.lang.reflect.Modifier.isFinal(modifiers) &&
1479                    java.lang.reflect.Modifier.isStatic(modifiers))) {
1480                 return null;
1481             }
1482 
1483             try {
1484                 return target.get(null);
1485             } catch (IllegalAccessException e) {
1486                 try {
1487                     target.setAccessible(true);
1488                     return target.get(null);
1489                 } catch (IllegalAccessException i) {
1490                     throw new SecurityException(i);
1491                 }
1492             }
1493         }
1494     }
1495 
1496     private static class CoreReflParameterVariableElement
1497         extends CoreReflVariableElement {
1498         private final Parameter source;
1499 
CoreReflParameterVariableElement(Parameter source)1500         protected CoreReflParameterVariableElement(Parameter source) {
1501             this.source = Objects.requireNonNull(source);
1502         }
1503 
1504         @Override
getSource()1505         public Parameter getSource() {
1506             return source;
1507         }
1508 
1509         @Override
getModifiers()1510         public Set<Modifier> getModifiers() {
1511             return ModifierUtil.instance(source.getModifiers() &
1512                                          java.lang.reflect.Modifier.parameterModifiers(), false);
1513         }
1514 
1515         @Override
asType()1516         public TypeMirror asType() {
1517             // TODO : switch to parameterized type
1518             return createTypeMirror(source.getType());
1519         }
1520 
1521         @Override
getKind()1522         public ElementKind getKind() {
1523             return ElementKind.PARAMETER;
1524         }
1525 
1526         @Override
getSimpleName()1527         public Name getSimpleName() {
1528             return StringName.instance(source.getName());
1529         }
1530 
1531         @Override
getEnclosingElement()1532         public ReflectionElement getEnclosingElement() {
1533             Executable enclosing = source.getDeclaringExecutable();
1534             if (enclosing instanceof Method)
1535                 return createMirror((Method)enclosing);
1536             else if (enclosing instanceof Constructor)
1537                 return createMirror((Constructor<?>)enclosing);
1538             else
1539                 throw new AssertionError("Bad enclosing value.");
1540         }
1541 
1542         @Override
equals(Object o)1543         public boolean equals(Object o) {
1544             if (o instanceof CoreReflParameterVariableElement) {
1545                 return source.equals(((CoreReflParameterVariableElement) o).getSource());
1546             } else
1547                 return false;
1548         }
1549 
1550         // VariableElement methods
1551         @Override
getConstantValue()1552         public Object getConstantValue() {
1553             return null;
1554         }
1555 
1556         @Override
isSynthetic()1557         public boolean isSynthetic() {
1558             return source.isSynthetic();
1559         }
1560 
1561         @Override
isImplicit()1562         public boolean isImplicit() {
1563             return source.isImplicit();
1564         }
1565     }
1566 
1567     private static class CoreReflPackageElement extends CoreReflElement
1568         implements ReflectionPackageElement {
1569 
1570         private final Package source;
1571 
CoreReflPackageElement(Package source)1572         protected CoreReflPackageElement(Package source) {
1573             this.source = source;
1574         }
1575 
1576         @Override
getSource()1577         public Package getSource() {
1578             return source;
1579         }
1580 
1581         @Override
accept(ElementVisitor<R,P> v, P p)1582         public <R,P> R accept(ElementVisitor<R,P> v, P p) {
1583             return v.visitPackage(this, p);
1584         }
1585 
1586         @Override
accept(ReflectionElementVisitor<R,P> v, P p)1587         public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
1588             return v.visitPackage(this, p);
1589         }
1590 
1591         @Override
equals(Object o)1592         public boolean equals(Object o) {
1593             if (o instanceof CoreReflPackageElement) {
1594                 return Objects.equals(source,
1595                                       ((CoreReflPackageElement)o).getSource());
1596             } else {
1597                 return false;
1598             }
1599         }
1600 
1601         @Override
getKind()1602         public ElementKind getKind() {
1603             return ElementKind.PACKAGE;
1604         }
1605 
1606         @Override
getEnclosingElement()1607         public ReflectionElement getEnclosingElement() {
1608             return null;
1609         }
1610 
1611         @Override
getEnclosedElements()1612         public List<ReflectionElement> getEnclosedElements() {
1613             throw new UnsupportedOperationException();
1614         }
1615 
1616         @Override
getQualifiedName()1617         public Name getQualifiedName() {
1618             return StringName.instance((source != null) ?
1619                                        source.getName() :
1620                                        "" );
1621         }
1622 
1623         @Override
getSimpleName()1624         public Name getSimpleName() {
1625             String n = ((source != null) ?
1626                         source.getName() :
1627                         "");
1628             int index = n.lastIndexOf('.');
1629             if (index > 0) {
1630                 return StringName.instance(n.substring(index + 1, n.length()));
1631             } else {
1632                 return StringName.instance(n);
1633             }
1634         }
1635 
1636         @Override
isUnnamed()1637         public boolean isUnnamed() {
1638             if (source != null) {
1639                 String name = source.getName();
1640                 return(name == null || name.isEmpty());
1641             } else
1642                 return true;
1643         }
1644     }
1645 
1646     private static class CoreReflAnnotationMirror
1647         implements javax.lang.model.element.AnnotationMirror {
1648         private final Annotation annotation;
1649 
CoreReflAnnotationMirror(Annotation annotation)1650         protected CoreReflAnnotationMirror(Annotation annotation) {
1651             this.annotation = Objects.requireNonNull(annotation);
1652         }
1653 
1654         @Override
getAnnotationType()1655         public DeclaredType getAnnotationType() {
1656             return (DeclaredType)TypeFactory.instance(annotation.annotationType());
1657         }
1658 
1659         @Override
getElementValues()1660         public Map<? extends ReflectionExecutableElement, ? extends AnnotationValue> getElementValues() {
1661             // This differs from the javac implementation in that it returns default values
1662 
1663             Method[] elems = annotation.annotationType().getDeclaredMethods();
1664             int len = elems.length;
1665 
1666             if (len > 0) {
1667                 Map<ReflectionExecutableElement, AnnotationValue> res = new HashMap<>();
1668                 for (Method m : elems) {
1669                     AnnotationValue v;
1670                     try {
1671                         v = new CoreReflAnnotationValue(m.invoke(annotation));
1672                     } catch (IllegalAccessException e) {
1673                         try {
1674                             m.setAccessible(true);
1675                             v = new CoreReflAnnotationValue(m.invoke(annotation));
1676                         } catch (IllegalAccessException i) {
1677                             throw new SecurityException(i);
1678                         } catch (InvocationTargetException ee) {
1679                             throw new RuntimeException(ee);
1680                         }
1681                     } catch (InvocationTargetException ee) {
1682                         throw new RuntimeException(ee);
1683                     }
1684                     ReflectionExecutableElement e = createMirror(m);
1685                     res.put(e, v);
1686                 }
1687 
1688                 return Collections.unmodifiableMap(res);
1689             } else {
1690                 return Collections.emptyMap();
1691             }
1692         }
1693 
1694         @Override
equals(Object other)1695         public boolean equals(Object other) {
1696             if (other instanceof CoreReflAnnotationMirror) {
1697                 return annotation.equals(((CoreReflAnnotationMirror)other).annotation);
1698             } else {
1699                 return false;
1700             }
1701         }
1702 
1703         @Override
hashCode()1704         public int hashCode() {
1705             return Objects.hashCode(annotation);
1706         }
1707 
1708         @Override
toString()1709         public String toString() {
1710             return annotation.toString();
1711         }
1712     }
1713 
1714     private static class CoreReflAnnotationValue
1715         implements javax.lang.model.element.AnnotationValue {
1716         private Object value = null;
1717 
CoreReflAnnotationValue(Object value)1718         protected CoreReflAnnotationValue(Object value) {
1719             // Is this constraint really necessary?
1720             Objects.requireNonNull(value);
1721             this.value = value;
1722         }
1723 
1724         @Override
getValue()1725         public Object getValue() {
1726             return value;
1727         }
1728 
1729         @Override
toString()1730         public String toString() {
1731             return value.toString();
1732         }
1733 
1734         @Override
accept(AnnotationValueVisitor<R,P> v, P p)1735         public <R,P> R accept(AnnotationValueVisitor<R,P> v, P p) {
1736             return v.visit(this, p);
1737         }
1738     }
1739 
1740     // Helper utility classes
1741 
1742     private static class StringName implements Name {
1743         private String name;
1744 
StringName(String name)1745         private StringName(String name) {
1746             this.name = Objects.requireNonNull(name);
1747         }
1748 
instance(String name)1749         public static StringName instance(String name) {
1750             return new StringName(name);
1751         }
1752 
1753         @Override
length()1754         public int length() {
1755             return name.length();
1756         }
1757 
1758         @Override
charAt(int index)1759         public char charAt(int index) {
1760             return name.charAt(index);
1761         }
1762 
1763         @Override
subSequence(int start, int end)1764         public CharSequence subSequence(int start, int end) {
1765             return name.subSequence(start, end);
1766         }
1767 
1768         @Override
toString()1769         public String toString() {
1770             return name;
1771         }
1772 
1773         @Override
equals(Object other)1774         public boolean equals(Object other) {
1775             if (other instanceof StringName) {
1776                 return name.equals(((StringName) other).name);
1777             } else {
1778                 return false;
1779             }
1780         }
1781 
1782         @Override
hashCode()1783         public int hashCode() {
1784             return name.hashCode();
1785         }
1786 
1787         @Override
contentEquals(CharSequence cs)1788         public boolean contentEquals(CharSequence cs) {
1789             return name.contentEquals(cs);
1790         }
1791     }
1792 
1793     /*
1794      * Given an {@code int} value of modifiers, return a proper immutable set
1795      * of {@code Modifier}s as a result.
1796      */
1797     private static class ModifierUtil {
ModifierUtil()1798         private ModifierUtil() {
1799             throw new AssertionError("No instances for you.");
1800         }
1801 
1802         // Exercise for the reader: explore if caching of sets of
1803         // Modifiers would be helpful.
1804 
instance(int modifiers, boolean isDefault)1805         public static Set<Modifier> instance(int modifiers, boolean isDefault) {
1806             Set<Modifier> modSet = EnumSet.noneOf(Modifier.class);
1807 
1808             if (java.lang.reflect.Modifier.isAbstract(modifiers))
1809                 modSet.add(Modifier.ABSTRACT);
1810 
1811             if (java.lang.reflect.Modifier.isFinal(modifiers))
1812                 modSet.add(Modifier.FINAL);
1813 
1814             if (java.lang.reflect.Modifier.isNative(modifiers))
1815                 modSet.add(Modifier.NATIVE);
1816 
1817             if (java.lang.reflect.Modifier.isPrivate(modifiers))
1818                 modSet.add(Modifier.PRIVATE);
1819 
1820             if (java.lang.reflect.Modifier.isProtected(modifiers))
1821                 modSet.add(Modifier.PROTECTED);
1822 
1823             if (java.lang.reflect.Modifier.isPublic(modifiers))
1824                 modSet.add(Modifier.PUBLIC);
1825 
1826             if (java.lang.reflect.Modifier.isStatic(modifiers))
1827                 modSet.add(Modifier.STATIC);
1828 
1829             if (java.lang.reflect.Modifier.isStrict(modifiers))
1830                 modSet.add(Modifier.STRICTFP);
1831 
1832             if (java.lang.reflect.Modifier.isSynchronized(modifiers))
1833                 modSet.add(Modifier.SYNCHRONIZED);
1834 
1835             if (java.lang.reflect.Modifier.isTransient(modifiers))
1836                 modSet.add(Modifier.TRANSIENT);
1837 
1838             if (java.lang.reflect.Modifier.isVolatile(modifiers))
1839                 modSet.add(Modifier.VOLATILE);
1840 
1841             if (isDefault)
1842                 modSet.add(Modifier.DEFAULT);
1843 
1844             return Collections.unmodifiableSet(modSet);
1845         }
1846     }
1847 
1848     private abstract static class AbstractTypeMirror implements TypeMirror {
1849         private final TypeKind kind;
1850 
AbstractTypeMirror(TypeKind kind)1851         protected AbstractTypeMirror(TypeKind kind) {
1852             this.kind = Objects.requireNonNull(kind);
1853         }
1854 
1855         @Override
getKind()1856         public TypeKind getKind() {
1857             return kind;
1858         }
1859 
1860         @Override
accept(TypeVisitor<R,P> v, P p)1861         public <R,P> R accept(TypeVisitor<R,P> v, P p) {
1862             return v.visit(this, p);
1863         }
1864 
1865         //Types methods
directSuperTypes()1866         abstract List<? extends TypeMirror> directSuperTypes();
1867 
capture()1868         TypeMirror capture() {
1869             // Exercise for the reader: make this abstract and implement in subtypes
1870             throw new UnsupportedOperationException();
1871         }
1872 
erasure()1873         TypeMirror erasure() {
1874             // Exercise for the reader: make this abstract and implement in subtypes
1875             throw new UnsupportedOperationException();
1876         }
1877 
1878         // Exercise for the reader: implement the AnnotatedConstruct methods
1879         @Override
getAnnotationMirrors()1880         public List<? extends AnnotationMirror> getAnnotationMirrors() {
1881             throw new UnsupportedOperationException();
1882         }
1883 
1884         @Override
getAnnotation(Class<T> annotationClass)1885         public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
1886             throw new UnsupportedOperationException();
1887         }
1888 
1889         @Override
getAnnotationsByType(Class<T> annotationClass)1890         public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
1891             throw new UnsupportedOperationException();
1892         }
1893     }
1894 
1895     private static class CoreReflArrayType extends AbstractTypeMirror
1896         implements javax.lang.model.type.ArrayType,
1897                    Reifiable {
1898         private Class<?> source = null;
1899         private Class<?> component = null;
1900         private TypeMirror eagerComponent = null;
1901 
CoreReflArrayType(Class<?> source)1902         protected CoreReflArrayType(Class<?> source) {
1903             super(TypeKind.ARRAY);
1904             this.source = source;
1905             this.component = source.getComponentType();
1906             this.eagerComponent = TypeFactory.instance(component);
1907         }
1908 
getComponentType()1909         public TypeMirror getComponentType() {
1910             return eagerComponent;
1911         }
1912 
1913         @Override
getSource()1914         public Class<?> getSource() {
1915             return source;
1916         }
1917 
1918         @Override
directSuperTypes()1919         List<? extends TypeMirror> directSuperTypes() {
1920             final TypeMirror componentType = getComponentType();
1921             final TypeMirror[] directSupers;
1922 
1923             // JLS v4 4.10.3
1924             if (componentType.getKind().isPrimitive() ||
1925                 component.equals(java.lang.Object.class)) {
1926                 directSupers = new TypeMirror[3];
1927                 directSupers[0] = TypeFactory.instance(java.lang.Object.class);
1928                 directSupers[1] = TypeFactory.instance(java.lang.Cloneable.class);
1929                 directSupers[2] = TypeFactory.instance(java.io.Serializable.class);
1930             } else if (componentType.getKind() == TypeKind.ARRAY) {
1931                 List<? extends TypeMirror> componentDirectSupertypes = CoreReflTypes.instance().directSupertypes(componentType);
1932                 directSupers = new TypeMirror[componentDirectSupertypes.size()];
1933                 for (int i = 0; i < directSupers.length; i++) {
1934                     directSupers[i] = new CoreReflArrayType(Array.newInstance(((Reifiable)componentDirectSupertypes.get(i)).getSource(), 0).getClass());
1935                 }
1936             } else {
1937                 Class<?> superClass = component.getSuperclass();
1938                 Class<?>[] interfaces = component.getInterfaces();
1939                 directSupers = new TypeMirror[1 + interfaces.length];
1940 
1941                 directSupers[0] = TypeFactory.instance(Array.newInstance(superClass, 0).getClass());
1942 
1943                 for (int i = 0; i < interfaces.length; i++) {
1944                     directSupers[i + 1] = TypeFactory.instance(Array.newInstance(interfaces[i],0).getClass());
1945                 }
1946             }
1947 
1948             return Collections.unmodifiableList(Arrays.asList(directSupers));
1949         }
1950 
1951         @Override
toString()1952         public String toString() {
1953             return getKind() + " of " + getComponentType().toString();
1954         }
1955     }
1956 
1957     private static class CaptureTypeVariable extends AbstractTypeMirror implements javax.lang.model.type.TypeVariable {
1958         private TypeMirror source = null;
1959         private TypeMirror upperBound = null;
1960         private TypeMirror lowerBound = null;
1961 
CaptureTypeVariable(TypeMirror source, TypeMirror upperBound, TypeMirror lowerBound)1962         CaptureTypeVariable(TypeMirror source,
1963                             TypeMirror upperBound,
1964                             TypeMirror lowerBound) {
1965             super(TypeKind.TYPEVAR);
1966 
1967             this.source = Objects.requireNonNull(source);
1968             this.upperBound = (upperBound == null ? CoreReflTypes.instance().getNullType() : upperBound);
1969             this.lowerBound = (lowerBound == null ? CoreReflTypes.instance().getNullType() : lowerBound);
1970         }
1971 
getSource()1972         protected Class<?> getSource() {
1973             if (source instanceof CoreReflDeclaredType) {
1974                 return ((CoreReflDeclaredType)source).getSource();
1975             } else {
1976                 return null;
1977             }
1978         }
1979 
1980         @Override
getUpperBound()1981         public TypeMirror getUpperBound() {
1982             return upperBound;
1983         }
1984 
1985         @Override
getLowerBound()1986         public TypeMirror getLowerBound() {
1987             return lowerBound;
1988         }
1989 
1990         @Override
asElement()1991         public Element asElement() {
1992             if (null == getSource()) {
1993                 return null;
1994             }
1995             return CoreReflectionFactory.createMirror(getSource());
1996         }
1997 
1998         @Override
directSuperTypes()1999         List<? extends TypeMirror> directSuperTypes() {
2000             throw new UnsupportedOperationException();
2001 
2002         }
2003 
2004         @Override
toString()2005         public String toString() {
2006             return getKind() + " CAPTURE of: " + source.toString();
2007         }
2008     }
2009 
2010     private static class CoreReflElements implements ReflectionElements {
CoreReflElements()2011         private CoreReflElements() {} // mostly one instance for you
2012 
2013         private static CoreReflElements instance = new CoreReflElements();
2014 
instance()2015         static CoreReflElements instance() {
2016             return instance;
2017         }
2018 
2019         /**
2020          * {@inheritDoc}
2021          */
2022         @Override
getPackageElement(CharSequence name)2023         public ReflectionPackageElement getPackageElement(CharSequence name) {
2024             return createMirror(Package.getPackage(name.toString()));
2025         }
2026 
2027         /**
2028          * {@inheritDoc}
2029          */
2030         @Override
getTypeElement(CharSequence name)2031         public ReflectionTypeElement getTypeElement(CharSequence name) {
2032             // where name is a Canonical Name jls 6.7
2033             // but this method will probably accept an equivalent FQN
2034             // depending on Class.forName(String)
2035 
2036             ReflectionTypeElement tmp = null;
2037 
2038             // Filter out arrays
2039             String n = name.toString();
2040             if (n.contains("[")) return null;
2041             if (n.equals("")) return null;
2042 
2043             // The intention of this loop is to handle nested
2044             // elements.  If finding the element using Class.forName
2045             // fails, an attempt is made to find the element as an
2046             // enclosed element by trying fo find a prefix of the name
2047             // (dropping a trailing ".xyz") and looking for "xyz" as
2048             // an enclosed element.
2049 
2050             Deque<String> parts = new ArrayDeque<>();
2051             boolean again;
2052             do {
2053                 again = false;
2054                 try {
2055                     tmp = createMirror(Class.forName(n));
2056                 } catch (ClassNotFoundException e) {
2057                     tmp = null;
2058                 }
2059 
2060                 if (tmp != null) {
2061                     if (parts.isEmpty()) {
2062                         return tmp;
2063                     }
2064 
2065                     tmp = findInner(tmp, parts);
2066                     if (tmp != null) {
2067                         return tmp;
2068                     }
2069                 }
2070 
2071                 int indx = n.lastIndexOf('.');
2072                 if (indx > -1) {
2073                     parts.addFirst(n.substring(indx + 1));
2074                     n = n.substring(0, indx);
2075                     again = true;
2076                 }
2077             } while (again);
2078 
2079             return null;
2080         }
2081 
2082         // Recursively finds enclosed type elements named as part.top() popping part and repeating
findInner(ReflectionTypeElement e, Deque<String> parts)2083         private ReflectionTypeElement findInner(ReflectionTypeElement e, Deque<String> parts) {
2084             if (parts.isEmpty()) {
2085                 return e;
2086             }
2087 
2088             String part = parts.removeFirst();
2089             List<ReflectionElement> enclosed = e.getEnclosedElements();
2090             for (ReflectionElement elm : enclosed) {
2091                 if ((elm.getKind() == ElementKind.CLASS ||
2092                      elm.getKind() == ElementKind.INTERFACE ||
2093                      elm.getKind() == ElementKind.ENUM ||
2094                      elm.getKind() == ElementKind.ANNOTATION_TYPE)
2095                     && elm.getSimpleName().toString().equals(part)) {
2096                     ReflectionTypeElement t = findInner((ReflectionTypeElement)elm, parts);
2097                     if (t != null) {
2098                         return t;
2099                     }
2100                 }
2101             }
2102             return null;
2103         }
2104 
2105         /**
2106          * {@inheritDoc}
2107          */
2108         @Override
2109         public Map<? extends ReflectionExecutableElement, ? extends AnnotationValue>
getElementValuesWithDefaults(AnnotationMirror a)2110             getElementValuesWithDefaults(AnnotationMirror a) {
2111             if (a instanceof CoreReflAnnotationMirror) {
2112                 return ((CoreReflAnnotationMirror)a).getElementValues();
2113             } else {
2114                 throw new IllegalArgumentException();
2115             }
2116         }
2117 
2118         /**
2119          * {@inheritDoc}
2120          */
2121         @Override
getDocComment(Element e)2122         public String getDocComment(Element e) {
2123             checkElement(e);
2124             return null; // As per the doc
2125         }
2126 
2127         /**
2128          * {@inheritDoc}
2129          */
2130         @Override
isDeprecated(Element e)2131         public boolean isDeprecated(Element e) {
2132             checkElement(e);
2133             return ((CoreReflElement)e).getSource().isAnnotationPresent(java.lang.Deprecated.class);
2134         }
2135 
2136         /**
2137          * {@inheritDoc}
2138          */
2139         @Override
getBinaryName(TypeElement type)2140         public Name getBinaryName(TypeElement type) {
2141             checkElement(type);
2142             return StringName.instance(((CoreReflTypeElement)type)
2143                                        .getSource()
2144                                        .getName());
2145         }
2146 
2147         /**
2148          * {@inheritDoc}
2149          */
2150         @Override
getPackageOf(Element type)2151         public ReflectionPackageElement getPackageOf(Element type) {
2152             checkElement(type);
2153             if (type instanceof ReflectionPackageElement) {
2154                 return (ReflectionPackageElement)type;
2155             }
2156 
2157             Package p;
2158             if (type instanceof CoreReflTypeElement) {
2159                 p = ((CoreReflTypeElement)type).getSource().getPackage();
2160             } else {
2161                 CoreReflTypeElement enclosingTypeElement = (CoreReflTypeElement)getEnclosingTypeElement((ReflectionElement)type);
2162                 p = enclosingTypeElement.getSource().getPackage();
2163             }
2164 
2165             return createMirror(p);
2166         }
2167 
2168         /**
2169          * {@inheritDoc}
2170          */
2171         @Override
getAllMembers(TypeElement type)2172         public List<? extends ReflectionElement> getAllMembers(TypeElement type) {
2173             checkElement(type);
2174             return getAllMembers((ReflectionTypeElement)type);
2175         }
2176 
2177         // Exercise for the reader: should this method, and similar
2178         // ones that specialize on the more specific argument types,
2179         // be addd to the public ReflectionElements API?
getAllMembers(ReflectionTypeElement type)2180         public List<? extends ReflectionElement> getAllMembers(ReflectionTypeElement type) {
2181             return type.getAllMembers();
2182         }
2183 
2184         /**
2185          * {@inheritDoc}
2186          */
2187         @Override
getAllAnnotationMirrors(Element e)2188         public List<? extends AnnotationMirror> getAllAnnotationMirrors(Element e) {
2189             checkElement(e);
2190             AnnotatedElement ae = CoreReflElement.class.cast(e).getSource();
2191             Annotation[] annotations = ae.getAnnotations();
2192             int len = annotations.length;
2193 
2194             if (len > 0) {
2195                 List<AnnotationMirror> res = new ArrayList<>(len);
2196                 for (Annotation a : annotations) {
2197                     res.add(createMirror(a));
2198                 }
2199                 return Collections.unmodifiableList(res);
2200             } else {
2201                 List<AnnotationMirror> ret = Collections.emptyList();
2202                 return ret;
2203             }
2204         }
2205 
2206         /**
2207          * {@inheritDoc}
2208          */
2209         @Override
hides(Element hider, Element hidden)2210         public boolean hides(Element hider, Element hidden) {
2211             checkElement(hider);
2212             checkElement(hidden);
2213 
2214             // Names must be equal
2215             if (!hider.getSimpleName().equals(hidden.getSimpleName())) {
2216                 return false;
2217             }
2218 
2219             // Hides isn't reflexive
2220             if (hider.equals(hidden)) {
2221                 return false;
2222             }
2223 
2224             // Hider and hidden needs to be field, method or type
2225             // and fields hide fields, types hide types, methods hide methods
2226             // IE a Field doesn't hide a Methods etc
2227             ElementKind hiderKind = hider.getKind();
2228             ElementKind hiddenKind = hidden.getKind();
2229             if (hiderKind.isField() && !hiddenKind.isField()) {
2230                 return false;
2231             } else if (hiderKind.isClass() &&
2232                        !(hiddenKind.isClass() || hiddenKind.isInterface())) {
2233                 return false;
2234             } else if (hiderKind.isInterface() &&
2235                        !(hiddenKind.isClass() || hiddenKind.isInterface())) {
2236                 return false;
2237             } else if (hiderKind == ElementKind.METHOD && hiddenKind != ElementKind.METHOD) {
2238                 return false;
2239             } else if (!(hiderKind.isClass() ||
2240                          hiderKind.isInterface() ||
2241                          hiderKind.isField() ||
2242                          hiderKind == ElementKind.METHOD)) {
2243                 return false;
2244             }
2245 
2246             Set<Modifier> hm = hidden.getModifiers();
2247             // jls 8.4.8.2 only static methods can hide methods
2248             if (hider.getKind() == ElementKind.METHOD) {
2249                 if (!hider.getModifiers().contains(Modifier.STATIC)) {
2250                     return false; // hider not static
2251                 } else if (!hm.contains(Modifier.STATIC)) { // we know it's a method
2252                     return false; // hidden not static
2253                 }
2254 
2255                 // For methods we also need to check parameter types
2256                 Class<?>[] h1 = ((CoreReflMethodExecutableElement)hider).getSource().getParameterTypes();
2257                 Class<?>[] h2 = ((CoreReflMethodExecutableElement)hidden).getSource().getParameterTypes();
2258                 if (h1.length != h2.length) {
2259                     return false;
2260                 }
2261                 for (int i = 0; i < h1.length; i++) {
2262                     if (h1[i] != h2[i]) {
2263                         return false;
2264                     }
2265                 }
2266             }
2267 
2268             // You can only hide visible elements
2269             if (hm.contains(Modifier.PRIVATE)) {
2270                 return false; // hidden private, can't be hidden
2271             } else if ((!(hm.contains(Modifier.PUBLIC) || hm.contains(Modifier.PROTECTED))) && // not private, not (public or protected) IE package private
2272                        (!getPackageOf(hider).equals(getPackageOf(hidden)))) {
2273                 return false; // hidden package private, and different packages, IE not visible
2274             }
2275 
2276             // Ok so now hider actually hides hidden if hider is
2277             // declared on a subtype of hidden.
2278             //
2279             // TODO: should this be a proper subtype or is that taken
2280             // care of by the reflexive check in the beginning?
2281             //
2282             TypeMirror hiderType = getEnclosingTypeElement((ReflectionElement)hider).asType();
2283             TypeMirror hiddenType = getEnclosingTypeElement((ReflectionElement)hidden).asType();
2284 
2285             return getTypes().isSubtype(hiderType, hiddenType);
2286         }
2287 
2288         /**
2289          * {@inheritDoc}
2290          */
2291         @Override
getEnclosingTypeElement(ReflectionElement e)2292         public ReflectionTypeElement getEnclosingTypeElement(ReflectionElement e) {
2293             if (e.getKind() == ElementKind.PACKAGE) {
2294                 return null;
2295             }
2296 
2297             if(e instanceof CoreReflTypeParameterElement) {
2298                 ReflectionElement encElem = ((CoreReflTypeParameterElement)e).getEnclosingElement();
2299                 if (encElem instanceof ReflectionTypeElement) {
2300                     return (ReflectionTypeElement)encElem;
2301                 } else  {
2302                     return getEnclosingTypeElement(encElem);
2303                 }
2304             }
2305 
2306             Class<?> encl = null;
2307             if (e instanceof CoreReflTypeElement) {
2308                 encl = ((CoreReflTypeElement)e).getSource().getDeclaringClass();
2309             } else if (e instanceof CoreReflExecutableElement) {
2310                 encl = (((CoreReflExecutableElement)e).getSource()).getDeclaringClass();
2311             } else if (e instanceof CoreReflFieldVariableElement) {
2312                 encl = ((CoreReflFieldVariableElement)e).getSource().getDeclaringClass();
2313             } else if (e instanceof CoreReflParameterVariableElement) {
2314                 encl = ((CoreReflParameterVariableElement)e).getSource().getDeclaringExecutable().getDeclaringClass();
2315             }
2316 
2317             return encl == null ? null : createMirror(encl);
2318         }
2319 
2320         /**
2321          *{@inheritDoc}
2322          *
2323          * Note that this implementation does not handle the situation
2324          * where A overrides B and B overrides C but A does not
2325          * directly override C. In this case, this implementation will
2326          * erroneously return false.
2327          */
2328         @Override
overrides(ExecutableElement overrider, ExecutableElement overridden, TypeElement type)2329         public boolean overrides(ExecutableElement overrider, ExecutableElement overridden,
2330                                  TypeElement type) {
2331             checkElement(overrider);
2332             checkElement(overridden);
2333             checkElement(type);
2334 
2335             // TODO handle transitive overrides
2336             return overridesDirect(overrider, overridden, type);
2337         }
2338 
overridesDirect(ExecutableElement overrider, ExecutableElement overridden, TypeElement type)2339         private boolean overridesDirect(ExecutableElement overrider, ExecutableElement overridden,
2340                                          TypeElement type) {
2341             // Should we check that at least one of the types
2342             // overrider has is in fact a supertype of the TypeElement
2343             // 'type' supplied?
2344 
2345             CoreReflExecutableElement rider = (CoreReflExecutableElement)overrider;
2346             CoreReflExecutableElement ridden = (CoreReflExecutableElement)overridden;
2347             CoreReflTypeElement riderType = (CoreReflTypeElement)type;
2348 
2349             // Names must match, redundant - see subsignature below
2350             if (!rider.getSimpleName().equals(ridden.getSimpleName())) {
2351                 return false;
2352             }
2353 
2354             // Constructors don't override
2355             // TODO: verify this fact
2356             if (rider.getKind() == ElementKind.CONSTRUCTOR ||
2357                 ridden.getKind() == ElementKind.CONSTRUCTOR) {
2358                 return false;
2359             }
2360 
2361             // Overridden must be visible to be overridden
2362             // TODO Fix transitive visibility/override
2363             Set<Modifier> rm = ridden.getModifiers();
2364             if (rm.contains(Modifier.PRIVATE)) {
2365                 return false; // overridden private, can't be overridden
2366             } else if ((!(rm.contains(Modifier.PUBLIC) || rm.contains(Modifier.PROTECTED))) && // not private, not (public or protected) IE package private
2367                        (!getPackageOf(rider).equals(getPackageOf(ridden)))) {
2368                 return false; // ridden package private, and different packages, IE not visible
2369             }
2370 
2371             // Static methods doesn't override
2372             if (rm.contains(Modifier.STATIC) ||
2373                 rider.getModifiers().contains(Modifier.STATIC)) {
2374                 return false;
2375             }
2376 
2377             // Declaring class of overrider must be a subclass of declaring class of overridden
2378             // except we use the parameter type as declaring class of overrider
2379             if (!getTypes().isSubtype(riderType.asType(), getEnclosingTypeElement(ridden).asType())) {
2380                 return false;
2381             }
2382 
2383             // Now overrider overrides overridden if the signature of rider is a subsignature of ridden
2384             return getTypes().isSubsignature(rider.asType(), ridden.asType());
2385         }
2386 
2387         /**
2388          *{@inheritDoc}
2389          */
2390         @Override
getConstantExpression(Object value)2391         public String getConstantExpression(Object value) {
2392             return Constants.format(value);
2393         }
2394 
2395         // If CoreReflectionFactory were a proper part of the JDK, the
2396         // analogous functionality in javac could be reused.
2397         private static class Constants {
2398             /**
2399              * Returns a string representation of a constant value (given in
2400              * standard wrapped representation), quoted and formatted as in
2401              * Java source.
2402              */
format(Object value)2403             public static String format(Object value) {
2404                 if (value instanceof Byte)      return formatByte((Byte) value);
2405                 if (value instanceof Short)     return formatShort((Short) value);
2406                 if (value instanceof Long)      return formatLong((Long) value);
2407                 if (value instanceof Float)     return formatFloat((Float) value);
2408                 if (value instanceof Double)    return formatDouble((Double) value);
2409                 if (value instanceof Character) return formatChar((Character) value);
2410                 if (value instanceof String)    return formatString((String) value);
2411                 if (value instanceof Integer ||
2412                     value instanceof Boolean)   return value.toString();
2413                 else
2414                     throw new IllegalArgumentException("Argument is not a primitive type or a string; it " +
2415                                                        ((value == null) ?
2416                                                         "is a null value." :
2417                                                         "has class " +
2418                                                         value.getClass().getName()) + "." );
2419             }
2420 
formatByte(byte b)2421             private static String formatByte(byte b) {
2422                 return String.format("(byte)0x%02x", b);
2423             }
2424 
formatShort(short s)2425             private static String formatShort(short s) {
2426                 return String.format("(short)%d", s);
2427             }
2428 
formatLong(long lng)2429             private static String formatLong(long lng) {
2430                 return lng + "L";
2431             }
2432 
formatFloat(float f)2433             private static String formatFloat(float f) {
2434                 if (Float.isNaN(f))
2435                     return "0.0f/0.0f";
2436                 else if (Float.isInfinite(f))
2437                     return (f < 0) ? "-1.0f/0.0f" : "1.0f/0.0f";
2438                 else
2439                     return f + "f";
2440             }
2441 
formatDouble(double d)2442             private static String formatDouble(double d) {
2443                 if (Double.isNaN(d))
2444                     return "0.0/0.0";
2445                 else if (Double.isInfinite(d))
2446                     return (d < 0) ? "-1.0/0.0" : "1.0/0.0";
2447                 else
2448                     return d + "";
2449             }
2450 
formatChar(char c)2451             private static String formatChar(char c) {
2452                 return '\'' + quote(c) + '\'';
2453             }
2454 
formatString(String s)2455             private static String formatString(String s) {
2456                 return '"' + quote(s) + '"';
2457             }
2458 
2459             /**
2460              * Escapes each character in a string that has an escape sequence or
2461              * is non-printable ASCII.  Leaves non-ASCII characters alone.
2462              */
quote(String s)2463             private static String quote(String s) {
2464                 StringBuilder buf = new StringBuilder();
2465                 for (int i = 0; i < s.length(); i++) {
2466                     buf.append(quote(s.charAt(i)));
2467                 }
2468                 return buf.toString();
2469             }
2470 
2471             /**
2472              * Escapes a character if it has an escape sequence or is
2473              * non-printable ASCII.  Leaves ASCII characters alone.
2474              */
quote(char ch)2475             private static String quote(char ch) {
2476                 switch (ch) {
2477                 case '\b':  return "\\b";
2478                 case '\f':  return "\\f";
2479                 case '\n':  return "\\n";
2480                 case '\r':  return "\\r";
2481                 case '\t':  return "\\t";
2482                 case '\'':  return "\\'";
2483                 case '\"':  return "\\\"";
2484                 case '\\':  return "\\\\";
2485                 default:
2486                     return (isPrintableAscii(ch))
2487                         ? String.valueOf(ch)
2488                         : String.format("\\u%04x", (int) ch);
2489                 }
2490             }
2491 
2492             /**
2493              * Is a character printable ASCII?
2494              */
isPrintableAscii(char ch)2495             private static boolean isPrintableAscii(char ch) {
2496                 return ch >= ' ' && ch <= '~';
2497             }
2498         }
2499 
2500         /**
2501          * {@inheritDoc}
2502          */
2503         @Override
printElements(Writer w, Element... elements)2504         public void printElements(Writer w, Element... elements) {
2505             ElementVisitor<?, ?> printer = getPrinter(w);
2506             try {
2507                 for (Element e : elements) {
2508                     checkElement(e);
2509                     printer.visit(e);
2510                 }
2511             } finally {
2512                 try {
2513                     w.flush();
2514                 } catch (java.io.IOException e) { /* Ignore */;}
2515             }
2516         }
2517 
getPrinter(Writer w)2518         private ElementVisitor<?, ?> getPrinter(Writer w) {
2519             // First try a reflective call into javac and if that
2520             // fails, fallback to a very simple toString-based
2521             // scanner.
2522             try {
2523                 //reflective form of
2524                 // return new com.sun.tools.javac.processing.PrintingProcessor.PrintingElementVisitor(w, getElements());
2525                 Class<?> printProcClass =
2526                     ClassLoader.getSystemClassLoader().loadClass("com.sun.tools.javac.processing.PrintingProcessor$PrintingElementVisitor");
2527                 Constructor<?> printProcCtor = printProcClass.getConstructor(Writer.class, Elements.class);
2528                 return (ElementVisitor) printProcCtor.newInstance(w, getElements());
2529             } catch (ReflectiveOperationException | SecurityException e) {
2530                 return new ElementScanner8<Writer, Void>(w){
2531                     @Override
2532                     public Writer scan(Element e, Void v) {
2533                         try {
2534                             DEFAULT_VALUE.append(e.toString());
2535                             DEFAULT_VALUE.append("\n");
2536                         } catch (java.io.IOException ioe) {
2537                             throw new RuntimeException(ioe);
2538                         }
2539                         return DEFAULT_VALUE;
2540                     }
2541                 };
2542             }
2543         }
2544 
2545         /**
2546          * {@inheritDoc}
2547          */
2548         @Override
getName(CharSequence cs)2549         public Name getName(CharSequence cs) {
2550             return StringName.instance(cs.toString());
2551         }
2552 
checkElement(Element e)2553         private void checkElement(Element e) {
2554             if(!(e instanceof CoreReflElement)) {
2555                 throw new IllegalArgumentException();
2556             }
2557         }
2558 
2559         @Override
isFunctionalInterface(TypeElement e)2560         public boolean isFunctionalInterface(TypeElement e) {
2561             throw new UnsupportedOperationException();
2562             // Update once this functionality is in core reflection
2563         }
2564     }
2565 
2566     private static class CoreReflTypes implements javax.lang.model.util.Types {
2567         private static Types instance = new CoreReflTypes();
2568 
instance()2569         public static Types instance() {
2570             return instance;
2571         }
2572 
2573         // Private to suppress instantiation
CoreReflTypes()2574         private CoreReflTypes() {}
2575 
2576         // Types methods
2577         @Override
asElement(TypeMirror t)2578         public Element asElement(TypeMirror t) {
2579             checkType(t);
2580             if (t instanceof javax.lang.model.type.TypeVariable) {
2581                 ((javax.lang.model.type.TypeVariable)t).asElement();
2582             } else if (t instanceof DeclaredType) {
2583                 return ((DeclaredType)t).asElement();
2584             }
2585             return null;
2586         }
2587 
2588         @Override
isSameType(TypeMirror t1, TypeMirror t2)2589         public boolean isSameType(TypeMirror t1, TypeMirror t2) {
2590             if (t1.getKind() != t2.getKind()) {
2591                 return false;
2592             }
2593 
2594             if (t1.getKind() == TypeKind.WILDCARD ||
2595                 t2.getKind() == TypeKind.WILDCARD) {
2596                 // Wildcards are not equal to any type
2597                 return false;
2598             }
2599 
2600             if (t1 instanceof CoreReflDeclaredType &&
2601                 t2 instanceof CoreReflDeclaredType) {
2602                 return ((CoreReflDeclaredType)t1).isSameType((CoreReflDeclaredType)t2);
2603             } else if (t1 instanceof PrimitiveType &&
2604                        t2 instanceof PrimitiveType) {
2605                 return t1.getKind() == t2.getKind();
2606             } else if (t1 instanceof NoType &&
2607                        t2 instanceof NoType) {
2608                 return true;
2609             } else if (t1 instanceof NullType &&
2610                        t2 instanceof NullType) {
2611                 return true;
2612             } else if (t1 instanceof ArrayType &&
2613                        t2 instanceof ArrayType) {
2614                 return isSameType(((ArrayType)t1).getComponentType(), ((ArrayType)t2).getComponentType());
2615             }
2616 
2617             return false;
2618         }
2619 
2620         @Override
isSubtype(TypeMirror t1, TypeMirror t2)2621         public boolean isSubtype(TypeMirror t1, TypeMirror t2) {
2622             checkType(t1);
2623             checkType(t2);
2624 
2625             if (isSameType(t1, t2)) {
2626                 return true;
2627             } else if(t1.getKind() == TypeKind.NULL) {
2628                 return true;
2629             }
2630 
2631             // This depth first traversal should terminate due to the ban on circular inheritance
2632             List<? extends TypeMirror> directSupertypes = directSupertypes(t1);
2633             if (directSupertypes.isEmpty()) {
2634                 return false;
2635             }
2636             for (TypeMirror ti : directSupertypes) {
2637                 if (isSameType(ti, t2) || isSubtype(ti, t2)) {
2638                     return true;
2639                 }
2640             }
2641             return false;
2642         }
2643 
2644         @Override
isAssignable(TypeMirror t1, TypeMirror t2)2645         public boolean isAssignable(TypeMirror t1, TypeMirror t2) {
2646             throw new UnsupportedOperationException();
2647         }
2648 
2649         @Override
contains(TypeMirror t1, TypeMirror t2)2650         public boolean contains(TypeMirror t1, TypeMirror t2) {
2651             throw new UnsupportedOperationException();
2652         }
2653 
2654         @Override
isSubsignature(ExecutableType m1, ExecutableType m2)2655         public boolean isSubsignature(ExecutableType m1, ExecutableType m2) {
2656             checkType(m1);
2657             checkType(m2);
2658 
2659             ExecutableMethodType m0 = (ExecutableMethodType)m1;
2660 
2661             return m0.sameSignature((ExecutableMethodType)m2) || m0.sameSignature((ExecutableMethodType)erasure(m2));
2662         }
2663 
2664         @Override
directSupertypes(TypeMirror t)2665         public List<? extends TypeMirror> directSupertypes(TypeMirror t) {
2666             checkType(t);
2667             if (t instanceof ExecutableType ||
2668                 t.getKind() == TypeKind.PACKAGE) {
2669                 throw new IllegalArgumentException("You can't ask for direct supertypes for type: " + t);
2670             }
2671             return ((AbstractTypeMirror)t).directSuperTypes();
2672         }
2673 
2674         @Override
erasure(TypeMirror t)2675         public TypeMirror erasure(TypeMirror t) {
2676             checkType(t);
2677             return ((AbstractTypeMirror)t).erasure();
2678         }
2679 
2680         @Override
boxedClass(javax.lang.model.type.PrimitiveType p)2681         public TypeElement boxedClass(javax.lang.model.type.PrimitiveType p) {
2682             throw new UnsupportedOperationException();
2683         }
2684 
2685         @Override
unboxedType(TypeMirror t)2686         public PrimitiveType unboxedType(TypeMirror t) {
2687             throw new UnsupportedOperationException();
2688         }
2689 
2690         @Override
capture(TypeMirror t)2691         public TypeMirror capture(TypeMirror t) {
2692             checkType(t);
2693             return ((AbstractTypeMirror)t).capture();
2694         }
2695 
2696         @Override
getPrimitiveType(TypeKind kind)2697         public PrimitiveType getPrimitiveType(TypeKind kind) {
2698             return PrimitiveType.instance(kind);
2699         }
2700 
2701         @Override
getNullType()2702         public NullType getNullType() {
2703             return CoreReflNullType.getInstance();
2704         }
2705 
2706         @Override
getNoType(TypeKind kind)2707         public javax.lang.model.type.NoType getNoType(TypeKind kind) {
2708             if (kind == TypeKind.NONE) {
2709                 return NoType.getNoneInstance();
2710             } else if (kind == TypeKind.VOID) {
2711                 return NoType.getVoidInstance();
2712             } else {
2713                 throw new IllegalArgumentException("No NoType of kind: " + kind);
2714             }
2715         }
2716 
2717         @Override
getArrayType(TypeMirror componentType)2718         public ArrayType getArrayType(TypeMirror componentType) {
2719             throw new UnsupportedOperationException();
2720         }
2721 
2722         @Override
getWildcardType(TypeMirror extendsBound, TypeMirror superBound)2723         public javax.lang.model.type.WildcardType getWildcardType(TypeMirror extendsBound,
2724                                                                   TypeMirror superBound) {
2725             throw new UnsupportedOperationException();
2726         }
2727 
2728         @Override
getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs)2729         public DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) {
2730             throw new UnsupportedOperationException();
2731         }
2732 
2733         @Override
getDeclaredType(javax.lang.model.type.DeclaredType containing, TypeElement typeElem, TypeMirror... typeArgs)2734         public javax.lang.model.type.DeclaredType getDeclaredType(javax.lang.model.type.DeclaredType containing,
2735                                                                   TypeElement typeElem,
2736                                                                   TypeMirror... typeArgs) {
2737             throw new UnsupportedOperationException();
2738         }
2739 
2740         @Override
asMemberOf(javax.lang.model.type.DeclaredType containing, Element element)2741         public TypeMirror asMemberOf(javax.lang.model.type.DeclaredType containing, Element element) {
2742             throw new UnsupportedOperationException();
2743         }
2744 
checkType(TypeMirror t)2745         private void checkType(TypeMirror t) {
2746             if (!(t instanceof AbstractTypeMirror)) {
2747                 throw new IllegalArgumentException("This Types implementation can only operate on CoreReflectionFactory type classes");
2748             }
2749         }
2750     }
2751 
2752     private abstract static class CoreReflDeclaredType extends AbstractTypeMirror
2753         implements javax.lang.model.type.DeclaredType {
2754         private Class<?> source = null;
2755 
CoreReflDeclaredType(Class<?> source)2756         private CoreReflDeclaredType(Class<?> source) {
2757             super(TypeKind.DECLARED);
2758             this.source = source;
2759         }
2760 
instance(Class<?> source, Type genericSource)2761         static DeclaredType instance(Class<?> source, Type genericSource) {
2762             if (genericSource instanceof ParameterizedType) {
2763                 return new ParameterizedDeclaredType(source, (ParameterizedType)genericSource);
2764             } else if (genericSource instanceof Class) { // This happens when a field has a raw type
2765                 if (!source.equals(genericSource)) {
2766                     throw new IllegalArgumentException("Don't know how to handle this");
2767                 }
2768                 return instance(source);
2769             }
2770             throw new IllegalArgumentException("Don't know how to create a declared type from: " +
2771                                                source +
2772                                                " and genericSource " +
2773                                                genericSource);
2774         }
2775 
instance(Class<?> source)2776         static DeclaredType instance(Class<?> source) {
2777             return new RawDeclaredType(source);
2778         }
2779 
getSource()2780         protected Class<?> getSource() {
2781             return source;
2782         }
2783 
2784         @Override
asElement()2785         public Element asElement() {
2786             return CoreReflectionFactory.createMirror(getSource());
2787         }
2788 
isSameType(DeclaredType other)2789         abstract boolean isSameType(DeclaredType other);
2790 
2791         @Override
capture()2792         TypeMirror capture() {
2793             return new CaptureDeclaredType(this);
2794         }
2795 
2796         private static class CaptureDeclaredType extends CoreReflDeclaredType {
2797             CoreReflDeclaredType cap;
CaptureDeclaredType(CoreReflDeclaredType t)2798             CaptureDeclaredType(CoreReflDeclaredType t) {
2799                 super(t.source);
2800                 this.cap = t;
2801             }
2802 
2803             @Override
getTypeArguments()2804             public List<? extends TypeMirror> getTypeArguments() {
2805                 List<? extends TypeMirror> wrapped = cap.getTypeArguments();
2806                 ArrayList<TypeMirror> res = new ArrayList<>(wrapped.size());
2807                 res.ensureCapacity(wrapped.size());
2808 
2809                 for (int i = 0; i < wrapped.size(); i++) {
2810                     TypeMirror t = wrapped.get(i);
2811 
2812                     if (t instanceof javax.lang.model.type.WildcardType) {
2813                         res.add(i, convert(t));
2814                     } else {
2815                         res.add(i, t);
2816                     }
2817                 }
2818                 return Collections.unmodifiableList(res);
2819             }
2820 
convert(TypeMirror t)2821             private TypeMirror convert(TypeMirror t) {
2822                 if (!(t instanceof javax.lang.model.type.WildcardType)) {
2823                     throw new IllegalArgumentException();
2824                 } else {
2825                     javax.lang.model.type.WildcardType w = (javax.lang.model.type.WildcardType)t;
2826                     return TypeFactory.typeVariableInstance(w, w.getExtendsBound(), w.getSuperBound());
2827                 }
2828             }
2829 
2830             @Override
getEnclosingType()2831             public TypeMirror getEnclosingType() {
2832                 return cap.getEnclosingType();
2833             }
2834 
2835             @Override
directSuperTypes()2836             List<? extends TypeMirror> directSuperTypes() {
2837                 return cap.directSuperTypes();
2838             }
2839 
2840             @Override
isSameType(DeclaredType other)2841             boolean isSameType(DeclaredType other) {
2842                 return other == this;
2843             }
2844 
2845             @Override
toString()2846             public String toString() {
2847                 return " CAPTURE of: " + cap.toString();
2848             }
2849         }
2850 
2851         private static class RawDeclaredType extends CoreReflDeclaredType
2852             implements Reifiable {
RawDeclaredType(Class<?> source)2853             private RawDeclaredType(Class<?> source) {
2854                 super(source);
2855             }
2856 
2857             @Override
getSource()2858             public Class<?> getSource() {
2859                 return super.getSource();
2860             }
2861 
2862             @Override
getEnclosingType()2863             public TypeMirror getEnclosingType() {
2864                 Class<?> enclosing = getSource().getEnclosingClass();
2865                 if (null == enclosing) {
2866                     return NoType.getNoneInstance();
2867                 } else {
2868                     return TypeFactory.instance(enclosing);
2869                 }
2870             }
2871 
2872             @Override
getTypeArguments()2873             public List<? extends TypeMirror> getTypeArguments() {
2874                 return Collections.emptyList();
2875             }
2876 
2877             @Override
directSuperTypes()2878             List<? extends TypeMirror> directSuperTypes() {
2879                 if (getSource().isEnum()) {
2880                     return enumSuper();
2881                 }
2882 
2883                 if (getSource() == java.lang.Object.class) {
2884                     return Collections.emptyList();
2885                 }
2886                 List<TypeMirror> res = new ArrayList<>();
2887                 Type[] superInterfaces = getSource().getInterfaces();
2888                 if (!getSource().isInterface()) {
2889                     res.add(TypeFactory.instance(getSource().getSuperclass()));
2890                 } else if (superInterfaces.length == 0) {
2891                     // Interfaces that don't extend another interface
2892                     // have java.lang.Object as a direct supertype.
2893                     return Collections.unmodifiableList(Arrays.asList(TypeFactory.instance(java.lang.Object.class)));
2894                 }
2895 
2896                 for (Type t : superInterfaces) {
2897                     res.add(TypeFactory.instance(t));
2898                 }
2899                 return Collections.unmodifiableList(res);
2900             }
2901 
enumSuper()2902             private List<? extends TypeMirror> enumSuper() {
2903                 Class<?> rawSuper = getSource().getSuperclass();
2904                 Type[] actualArgs = ((ParameterizedTypeImpl)getSource().getGenericSuperclass()).getActualTypeArguments();
2905 
2906                 // Reconsider this : assume the problem is making
2907                 // Enum<MyEnum> rather than just a raw enum.
2908                 return Collections.unmodifiableList(Arrays.asList(TypeFactory.instance(ParameterizedTypeImpl.make(rawSuper,
2909                                                                                                                   Arrays.copyOf(actualArgs,
2910                                                                                                                                 actualArgs.length),
2911                                                                                                                   null))));
2912             }
2913 
2914             @Override
isSameType(DeclaredType other)2915             boolean isSameType(DeclaredType other) {
2916                 if (other instanceof RawDeclaredType) {
2917                     return Objects.equals(getSource(), ((RawDeclaredType)other).getSource());
2918                 } else {
2919                     return false;
2920                 }
2921             }
2922 
2923             @Override
toString()2924             public String toString() {
2925                 return getSource().toString();
2926             }
2927         }
2928 
2929         private static class ParameterizedDeclaredType extends CoreReflDeclaredType {
2930             private ParameterizedType genericSource = null;
ParameterizedDeclaredType(Class<?> source, ParameterizedType genericSource)2931             private ParameterizedDeclaredType(Class<?> source, ParameterizedType genericSource) {
2932                 super(source);
2933                 this.genericSource = genericSource;
2934             }
2935 
2936             @Override
getEnclosingType()2937             public TypeMirror getEnclosingType() {
2938                 Type me = genericSource;
2939                 Type owner = GenericTypes.getEnclosingType(me);
2940                 if (owner == null) {
2941                     return NoType.getNoneInstance();
2942                 }
2943                 return TypeFactory.instance(owner);
2944             }
2945 
2946             @Override
getTypeArguments()2947             public List<? extends TypeMirror> getTypeArguments() {
2948                 Type[] typeArgs = genericSource.getActualTypeArguments();
2949 
2950                 int length = typeArgs.length;
2951                 if (length == 0)
2952                     return Collections.emptyList();
2953                 else {
2954                     List<TypeMirror> tmp = new ArrayList<>(length);
2955                     for (Type t : typeArgs) {
2956                         tmp.add(TypeFactory.instance(t));
2957                     }
2958                     return Collections.unmodifiableList(tmp);
2959                 }
2960             }
2961 
2962             @Override
directSuperTypes()2963             List<? extends TypeMirror> directSuperTypes() {
2964                 if (getSource() == java.lang.Object.class) {
2965                     return Collections.emptyList();
2966                 }
2967 
2968                 List<TypeMirror> res = new ArrayList<>();
2969                 Type[] superInterfaces = getSource().getGenericInterfaces();
2970                 if (!getSource().isInterface()) {
2971                     // Replace actual type arguments with our type arguments
2972                     res.add(TypeFactory.instance(substituteTypeArgs(getSource().getGenericSuperclass())));
2973                 } else if (superInterfaces.length == 0) {
2974                     // Interfaces that don't extend another interface
2975                     // have java.lang.Object as a direct supertype, plus
2976                     // possibly the interface's raw type
2977                     res.add(TypeFactory.instance(java.lang.Object.class));
2978                 }
2979 
2980                 for (Type t : superInterfaces) {
2981                     res.add(TypeFactory.instance(substituteTypeArgs(t)));
2982                 }
2983 
2984                 res.add(TypeFactory.instance(getSource())); // Add raw type
2985                 return Collections.unmodifiableList(res);
2986             }
2987 
substituteTypeArgs(Type type)2988             private Type substituteTypeArgs(Type type) {
2989                 if (!(type instanceof ParameterizedType)) {
2990                     return type;
2991                 }
2992 
2993                 ParameterizedType target = (ParameterizedType)type;
2994                 // Cast to get a Class instead of a plain type.
2995                 Class<?> raw = ((ParameterizedTypeImpl)target).getRawType();
2996                 Type[] actualArgs = genericSource.getActualTypeArguments();
2997 
2998                 return  ParameterizedTypeImpl.make(raw, Arrays.copyOf(actualArgs, actualArgs.length), null);
2999             }
3000 
3001             @Override
isSameType(DeclaredType other)3002             boolean isSameType(DeclaredType other) {
3003                 if (other instanceof ParameterizedDeclaredType) {
3004                     return GenericTypes.isSameGenericType(genericSource,
3005                                                           ((ParameterizedDeclaredType)other).genericSource);
3006                 } else {
3007                     return false;
3008                 }
3009             }
3010 
3011             @Override
toString()3012             public String toString() {
3013                 return getKind().toString() + " " + genericSource.toString();
3014             }
3015         }
3016 
3017         /**
3018          * Implementing class for ParameterizedType interface.
3019          * Derived from sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
3020          */
3021 
3022         private static class ParameterizedTypeImpl implements ParameterizedType {
3023             private Type[] actualTypeArguments;
3024             private Class<?>  rawType;
3025             private Type   ownerType;
3026 
ParameterizedTypeImpl(Class<?> rawType, Type[] actualTypeArguments, Type ownerType)3027             private ParameterizedTypeImpl(Class<?> rawType,
3028                                           Type[] actualTypeArguments,
3029                                           Type ownerType) {
3030                 this.actualTypeArguments = actualTypeArguments;
3031                 this.rawType             = rawType;
3032                 if (ownerType != null) {
3033                     this.ownerType = ownerType;
3034                 } else {
3035                     this.ownerType = rawType.getDeclaringClass();
3036                 }
3037                 validateConstructorArguments();
3038             }
3039 
validateConstructorArguments()3040             private void validateConstructorArguments() {
3041                 java.lang.reflect.TypeVariable/*<?>*/[] formals = rawType.getTypeParameters();
3042                 // check correct arity of actual type args
3043                 if (formals.length != actualTypeArguments.length){
3044                     throw new MalformedParameterizedTypeException();
3045                 }
3046             }
3047 
3048             /**
3049              * Static factory. Given a (generic) class, actual type arguments
3050              * and an owner type, creates a parameterized type.
3051              * This class can be instantiated with a a raw type that does not
3052              * represent a generic type, provided the list of actual type
3053              * arguments is empty.
3054              * If the ownerType argument is null, the declaring class of the
3055              * raw type is used as the owner type.
3056              * <p> This method throws a MalformedParameterizedTypeException
3057              * under the following circumstances:
3058              * If the number of actual type arguments (i.e., the size of the
3059              * array {@code typeArgs}) does not correspond to the number of
3060              * formal type arguments.
3061              * If any of the actual type arguments is not an instance of the
3062              * bounds on the corresponding formal.
3063              * @param rawType the Class representing the generic type declaration being
3064              * instantiated
3065              * @param actualTypeArguments - a (possibly empty) array of types
3066              * representing the actual type arguments to the parameterized type
3067              * @param ownerType - the enclosing type, if known.
3068              * @return An instance of {@code ParameterizedType}
3069              * @throws MalformedParameterizedTypeException - if the instantiation
3070              * is invalid
3071              */
make(Class<?> rawType, Type[] actualTypeArguments, Type ownerType)3072             public static ParameterizedTypeImpl make(Class<?> rawType,
3073                                                      Type[] actualTypeArguments,
3074                                                      Type ownerType) {
3075                 return new ParameterizedTypeImpl(rawType, actualTypeArguments,
3076                                                  ownerType);
3077             }
3078 
3079 
3080             /**
3081              * Returns an array of {@code Type} objects representing the actual type
3082              * arguments to this type.
3083              *
3084              * <p>Note that in some cases, the returned array be empty. This can occur
3085              * if this type represents a non-parameterized type nested within
3086              * a parameterized type.
3087              *
3088              * @return an array of {@code Type} objects representing the actual type
3089              *     arguments to this type
3090              * @throws {@code TypeNotPresentException} if any of the
3091              *     actual type arguments refers to a non-existent type declaration
3092              * @throws {@code MalformedParameterizedTypeException} if any of the
3093              *     actual type parameters refer to a parameterized type that cannot
3094              *     be instantiated for any reason
3095              * @since 1.5
3096              */
getActualTypeArguments()3097             public Type[] getActualTypeArguments() {
3098                 return actualTypeArguments.clone();
3099             }
3100 
3101             /**
3102              * Returns the {@code Type} object representing the class or interface
3103              * that declared this type.
3104              *
3105              * @return the {@code Type} object representing the class or interface
3106              *     that declared this type
3107              */
getRawType()3108             public Class<?> getRawType() {
3109                 return rawType;
3110             }
3111 
3112 
3113             /**
3114              * Returns a {@code Type} object representing the type that this type
3115              * is a member of.  For example, if this type is {@code O<T>.I<S>},
3116              * return a representation of {@code O<T>}.
3117              *
3118              * <p>If this type is a top-level type, {@code null} is returned.
3119              *
3120              * @return a {@code Type} object representing the type that
3121              *     this type is a member of. If this type is a top-level type,
3122              *     {@code null} is returned
3123              */
getOwnerType()3124             public Type getOwnerType() {
3125                 return ownerType;
3126             }
3127 
3128             /*
3129              * From the JavaDoc for java.lang.reflect.ParameterizedType
3130              * "Instances of classes that implement this interface must
3131              * implement an equals() method that equates any two instances
3132              * that share the same generic type declaration and have equal
3133              * type parameters."
3134              */
3135             @Override
equals(Object o)3136             public boolean equals(Object o) {
3137                 if (o instanceof ParameterizedType) {
3138                     // Check that information is equivalent
3139                     ParameterizedType that = (ParameterizedType) o;
3140 
3141                     if (this == that)
3142                         return true;
3143 
3144                     Type thatOwner   = that.getOwnerType();
3145                     Type thatRawType = that.getRawType();
3146 
3147                     return Objects.equals(ownerType, thatOwner) &&
3148                         Objects.equals(rawType, thatRawType) &&
3149                         Arrays.equals(actualTypeArguments, // avoid clone
3150                                       that.getActualTypeArguments());
3151                 } else
3152                     return false;
3153             }
3154 
3155             @Override
hashCode()3156             public int hashCode() {
3157                 return
3158                     Arrays.hashCode(actualTypeArguments) ^
3159                     Objects.hashCode(ownerType) ^
3160                     Objects.hashCode(rawType);
3161             }
3162 
toString()3163             public String toString() {
3164                 StringBuilder sb = new StringBuilder();
3165 
3166                 if (ownerType != null) {
3167                     if (ownerType instanceof Class)
3168                         sb.append(((Class)ownerType).getName());
3169                     else
3170                         sb.append(ownerType.toString());
3171 
3172                     sb.append(".");
3173 
3174                     if (ownerType instanceof ParameterizedTypeImpl) {
3175                         // Find simple name of nested type by removing the
3176                         // shared prefix with owner.
3177                         sb.append(rawType.getName().replace( ((ParameterizedTypeImpl)ownerType).rawType.getName() + "$",
3178                                                              ""));
3179                     } else
3180                         sb.append(rawType.getName());
3181                 } else
3182                     sb.append(rawType.getName());
3183 
3184                 if (actualTypeArguments != null &&
3185                     actualTypeArguments.length > 0) {
3186                     sb.append("<");
3187                     boolean first = true;
3188                     for (Type t: actualTypeArguments) {
3189                         if (!first)
3190                             sb.append(", ");
3191                         if (t instanceof Class)
3192                             sb.append(((Class)t).getName());
3193                         else
3194                             sb.append(t.toString());
3195                         first = false;
3196                     }
3197                     sb.append(">");
3198                 }
3199 
3200                 return sb.toString();
3201             }
3202         }
3203 
3204     }
3205 
3206     private static class ErasedMethodType extends ExecutableMethodType implements javax.lang.model.type.ExecutableType {
3207         private final Method m;
3208 
ErasedMethodType(Method m)3209         ErasedMethodType(Method m) {
3210             super(m);
3211             this.m = Objects.requireNonNull(m);
3212         }
3213 
3214         @Override
getTypeVariables()3215         public List<javax.lang.model.type.TypeVariable> getTypeVariables() {
3216             return Collections.emptyList();
3217         }
3218 
3219         @Override
getThrownTypes()3220         public List<? extends TypeMirror> getThrownTypes() {
3221             Class<?>[] exceptions = m.getExceptionTypes();
3222             int len = exceptions.length;
3223 
3224             if (len > 0) {
3225                 List<TypeMirror> res = new ArrayList<TypeMirror>(len);
3226                 for (Class<?> t : exceptions) {
3227                     res.add(TypeFactory.instance(t));
3228                 }
3229                 return Collections.unmodifiableList(res);
3230             } else {
3231                 List<TypeMirror> ret = Collections.emptyList();
3232                 return ret;
3233             }
3234         }
3235 
3236         @Override
getParameterTypes()3237         public List<? extends TypeMirror> getParameterTypes() {
3238             Class<?>[] params = m.getParameterTypes();
3239             int len = params.length;
3240 
3241             if (len > 0) {
3242                 List<TypeMirror> res = new ArrayList<TypeMirror>(len);
3243                 for (Class<?> t : params) {
3244                     res.add(TypeFactory.instance(t));
3245                 }
3246                 return Collections.unmodifiableList(res);
3247             } else {
3248                 List<TypeMirror> ret = Collections.emptyList();
3249                 return ret;
3250             }
3251         }
3252 
3253         @Override
getReturnType()3254         public TypeMirror getReturnType() {
3255             return TypeFactory.instance(m.getReturnType());
3256         }
3257 
3258         @Override
erasure()3259         TypeMirror erasure() {
3260             return this;
3261         }
3262     }
3263 
3264     private static class ErrorType extends AbstractTypeMirror implements javax.lang.model.type.ErrorType {
3265         private static ErrorType errorType = new ErrorType();
3266 
getErrorInstance()3267         public static ErrorType getErrorInstance() {
3268             return errorType;
3269         }
3270 
ErrorType()3271         private ErrorType() {
3272             super(TypeKind.ERROR);
3273         }
3274 
3275         @Override
getTypeArguments()3276         public List<? extends TypeMirror> getTypeArguments() {
3277             throw new UnsupportedOperationException();
3278         }
3279 
3280         @Override
getEnclosingType()3281         public TypeMirror getEnclosingType() {
3282             throw new UnsupportedOperationException();
3283         }
3284 
3285         @Override
asElement()3286         public Element asElement() {
3287             throw new UnsupportedOperationException();
3288         }
3289 
3290         @Override
directSuperTypes()3291         List<? extends TypeMirror> directSuperTypes() {
3292             throw new UnsupportedOperationException();
3293         }
3294     }
3295 
3296     private static class ExecutableMethodType extends AbstractTypeMirror
3297         implements javax.lang.model.type.ExecutableType {
3298         private final Method m;
3299 
ExecutableMethodType(Method m)3300         ExecutableMethodType(Method m) {
3301             super(TypeKind.EXECUTABLE);
3302             this.m = Objects.requireNonNull(m);
3303         }
3304 
3305         @Override
getThrownTypes()3306         public List<? extends TypeMirror> getThrownTypes() {
3307             Type[] exceptions = m.getGenericExceptionTypes();
3308             int len = exceptions.length;
3309 
3310             if (len > 0) {
3311                 List<TypeMirror> res = new ArrayList<TypeMirror>(len);
3312                 for (Type t : exceptions) {
3313                     res.add(TypeFactory.instance(t));
3314                 }
3315                 return Collections.unmodifiableList(res);
3316             } else {
3317                 List<TypeMirror> ret = Collections.emptyList();
3318                 return ret;
3319             }
3320         }
3321 
3322         @Override
getTypeVariables()3323         public List<javax.lang.model.type.TypeVariable> getTypeVariables() {
3324             java.lang.reflect.TypeVariable[] variables = m.getTypeParameters();
3325             int len = variables.length;
3326 
3327             if (len > 0) {
3328                 List<javax.lang.model.type.TypeVariable> res = new ArrayList<>(len);
3329                 for (java.lang.reflect.TypeVariable<?> t : variables) {
3330                     res.add(TypeFactory.typeVariableInstance(t));
3331                 }
3332                 return Collections.unmodifiableList(res);
3333             } else {
3334                 return Collections.emptyList();
3335             }
3336         }
3337 
3338         @Override
getReturnType()3339         public TypeMirror getReturnType() {
3340             return TypeFactory.instance(m.getGenericReturnType());
3341         }
3342 
3343         @Override
getParameterTypes()3344         public List<? extends TypeMirror> getParameterTypes() {
3345             Type[] params = m.getGenericParameterTypes();
3346             int len = params.length;
3347 
3348             if (len > 0) {
3349                 List<TypeMirror> res = new ArrayList<TypeMirror>(len);
3350                 for (Type t : params) {
3351                     res.add(TypeFactory.instance(t));
3352                 }
3353                 return Collections.unmodifiableList(res);
3354             } else {
3355                 return Collections.emptyList();
3356             }
3357         }
3358 
3359         @Override
directSuperTypes()3360         List<? extends TypeMirror> directSuperTypes() {
3361             // Spec says we don't need this
3362             throw new UnsupportedOperationException();
3363         }
3364 
3365         @Override
erasure()3366         TypeMirror erasure() {
3367             return new ErasedMethodType(m);
3368         }
3369 
3370         @Override
getReceiverType()3371         public TypeMirror getReceiverType() {
3372             throw new UnsupportedOperationException();
3373         }
3374 
sameSignature(ExecutableMethodType other)3375         boolean sameSignature(ExecutableMethodType other){
3376             if (!m.getName().equals(other.m.getName())) {
3377                 return false;
3378             }
3379 
3380             List<? extends TypeMirror> thisParams = getParameterTypes();
3381             List<? extends TypeMirror> otherParams = other.getParameterTypes();
3382             if (thisParams.size() != otherParams.size()) {
3383                 return false;
3384             }
3385             for (int i = 0; i < thisParams.size(); i++) {
3386                 if (!CoreReflTypes.instance().isSameType(thisParams.get(i), otherParams.get(i))) {
3387                     return false;
3388                 }
3389             }
3390             return true;
3391         }
3392     }
3393 
3394     private static class GenericTypes {
isSameGenericType(Type t1, Type t2)3395         public static boolean isSameGenericType(Type t1, Type t2) {
3396             if (t1 instanceof Class) {
3397                 return ((Class)t1).equals(t2);
3398             } else if (t1 instanceof ParameterizedType) {
3399                 return ((ParameterizedType)t1).equals(t2);
3400             }
3401             throw new UnsupportedOperationException();
3402         }
3403 
getEnclosingType(Type t1)3404         public static Type getEnclosingType(Type t1) {
3405             if (t1 instanceof Class) {
3406                 return ((Class)t1).getEnclosingClass();
3407             } else if (t1 instanceof ParameterizedType) {
3408                 return ((ParameterizedType)t1).getOwnerType();
3409             }
3410             throw new UnsupportedOperationException();
3411         }
3412     }
3413 
3414     private static class IntersectionDeclaredType extends AbstractTypeMirror
3415         implements javax.lang.model.type.DeclaredType {
3416         private Type[] sources = null;
3417 
IntersectionDeclaredType(Type[] sources)3418         IntersectionDeclaredType(Type[] sources) {
3419             super(TypeKind.DECLARED);
3420             this.sources = Arrays.copyOf(Objects.requireNonNull(sources),
3421                                          sources.length);
3422         }
3423 
3424         @Override
getEnclosingType()3425         public TypeMirror getEnclosingType() {
3426             return NoType.getNoneInstance();
3427         }
3428 
3429         @Override
asElement()3430         public  Element asElement() {
3431             throw new UnsupportedOperationException();
3432         }
3433 
3434         @Override
getTypeArguments()3435         public List<? extends TypeMirror> getTypeArguments() {
3436             throw new UnsupportedOperationException();
3437         }
3438 
3439         @Override
directSuperTypes()3440         List<? extends TypeMirror> directSuperTypes() {
3441             int len = sources.length;
3442 
3443             if (len > 0) {
3444                 List<TypeMirror> res = new ArrayList<TypeMirror>(len);
3445                 for (Type c : sources) {
3446                     res.add(TypeFactory.instance(c));
3447                 }
3448                 return Collections.unmodifiableList(res);
3449             } else {
3450                 return Collections.emptyList();
3451             }
3452         }
3453     }
3454 
3455     private static class ModelWildcardType extends AbstractTypeMirror
3456         implements javax.lang.model.type.WildcardType {
3457         private java.lang.reflect.WildcardType genericSource;
3458 
ModelWildcardType(java.lang.reflect.WildcardType genericSource)3459         ModelWildcardType(java.lang.reflect.WildcardType genericSource) {
3460             super(TypeKind.WILDCARD);
3461             this.genericSource = Objects.requireNonNull(genericSource);
3462         }
3463 
3464         @Override
directSuperTypes()3465         List<? extends TypeMirror> directSuperTypes() {
3466             // TODO Add support for this operation
3467             throw new UnsupportedOperationException();
3468         }
3469 
3470         @Override
getExtendsBound()3471         public TypeMirror getExtendsBound() {
3472             Type[] t = genericSource.getUpperBounds();
3473 
3474             if (t.length == 1) {
3475                 if (t[0].equals(Object.class) && getSuperBound() != null) { // can't have both lower and upper explicit
3476                     return null;
3477                 }
3478                 return TypeFactory.instance(t[0]);
3479             }
3480             throw new UnsupportedOperationException(); // TODO: intersection type?
3481         }
3482 
3483         @Override
getSuperBound()3484         public TypeMirror getSuperBound() {
3485             Type[] t = genericSource.getLowerBounds();
3486 
3487             if (t.length == 0) { // bound is null
3488                 return null;
3489             } else if (t.length == 1) {
3490                 return TypeFactory.instance(t[0]);
3491             }
3492             throw new UnsupportedOperationException(); // TODO: intersection type?
3493         }
3494 
3495         @Override
toString()3496         public String toString() {
3497             return getKind() + " " + genericSource.toString();
3498         }
3499     }
3500 
3501     private static class NoType extends AbstractTypeMirror
3502         implements javax.lang.model.type.NoType {
3503         private static NoType noneType = new NoType(TypeKind.NONE, "none");
3504         private static NoType packageType = new NoType(TypeKind.PACKAGE, "package");
3505         private static NoType voidType = new NoType(TypeKind.VOID, "void");
3506 
3507         private String str;
3508 
getNoneInstance()3509         public static NoType getNoneInstance() {
3510             return noneType;
3511         }
3512 
getPackageInstance()3513         public static NoType getPackageInstance() {
3514             return packageType;
3515         }
3516 
getVoidInstance()3517         public static NoType getVoidInstance() {
3518             return voidType;
3519         }
3520 
NoType(TypeKind k, String str)3521         private NoType(TypeKind k, String str) {
3522             super(k);
3523             this.str = str;
3524         }
3525 
3526         @Override
directSuperTypes()3527         List<? extends TypeMirror> directSuperTypes() {
3528             // TODO We don't need this for the Package instance, how about the others?
3529             throw new UnsupportedOperationException();
3530         }
3531 
3532         @Override
toString()3533         public String toString() {
3534             return str;
3535         }
3536     }
3537 
3538     private static class CoreReflNullType extends AbstractTypeMirror
3539         implements javax.lang.model.type.NullType {
3540         private static CoreReflNullType nullType = new CoreReflNullType();
3541 
getInstance()3542         public static NullType getInstance() {
3543             return nullType;
3544         }
3545 
CoreReflNullType()3546         private CoreReflNullType() {
3547             super(TypeKind.NULL);
3548         }
3549 
3550         @Override
directSuperTypes()3551         List<? extends TypeMirror> directSuperTypes() {
3552             // JLS 4.10.2 says:
3553             // "The direct supertypes of the null type are all reference types other than the null type itself."
3554             // TODO return null? an empty list? the error type? anyhow fix this
3555             throw new UnsupportedOperationException();
3556         }
3557     }
3558 
3559     private static interface Reifiable {
getSource()3560         Class<?> getSource();
3561     }
3562 
3563     private static class PrimitiveType extends AbstractTypeMirror
3564         implements javax.lang.model.type.PrimitiveType,
3565                    Reifiable {
3566         private Class<?> source;
3567 
3568         private static PrimitiveType booleanInstance = new PrimitiveType(TypeKind.BOOLEAN, boolean.class);
3569         private static PrimitiveType byteInstance =    new PrimitiveType(TypeKind.BYTE, byte.class);
3570         private static PrimitiveType charInstance =    new PrimitiveType(TypeKind.CHAR, char.class);
3571         private static PrimitiveType shortInstance =   new PrimitiveType(TypeKind.SHORT, short.class);
3572         private static PrimitiveType intInstance =     new PrimitiveType(TypeKind.INT, int.class);
3573         private static PrimitiveType longInstance =    new PrimitiveType(TypeKind.LONG, long.class);
3574         private static PrimitiveType floatInstance =   new PrimitiveType(TypeKind.FLOAT, float.class);
3575         private static PrimitiveType doubleInstance =  new PrimitiveType(TypeKind.DOUBLE, double.class);
3576 
PrimitiveType(TypeKind kind, Class<?> source)3577         private PrimitiveType(TypeKind kind, Class<?> source) {
3578             super(kind);
3579             this.source = source;
3580         }
3581 
3582         @Override
getSource()3583         public Class<?> getSource() {
3584             return source;
3585         }
3586 
instance(Class<?> c)3587         static PrimitiveType instance(Class<?> c) {
3588             switch(c.getName()) {
3589             case "boolean":
3590                 return booleanInstance;
3591             case "byte":
3592                 return byteInstance;
3593             case "char":
3594                 return charInstance;
3595             case "short":
3596                 return shortInstance;
3597             case "int":
3598                 return intInstance;
3599             case "long":
3600                 return longInstance;
3601             case "float":
3602                 return floatInstance;
3603             case "double":
3604                 return doubleInstance;
3605             default:
3606                 throw new IllegalArgumentException();
3607             }
3608         }
3609 
instance(TypeKind k)3610         static PrimitiveType instance(TypeKind k) {
3611             switch(k) {
3612             case BOOLEAN:
3613                 return booleanInstance;
3614             case BYTE:
3615                 return byteInstance;
3616             case CHAR:
3617                 return charInstance;
3618             case SHORT:
3619                 return shortInstance;
3620             case INT:
3621                 return intInstance;
3622             case LONG:
3623                 return longInstance;
3624             case FLOAT:
3625                 return floatInstance;
3626             case DOUBLE:
3627                 return doubleInstance;
3628             default:
3629                 throw new IllegalArgumentException();
3630             }
3631         }
3632 
3633         @Override
toString()3634         public String toString() {
3635             return source.getName();
3636         }
3637 
3638         //Types methods
3639         @Override
directSuperTypes()3640         List<? extends TypeMirror> directSuperTypes() {
3641             switch (getKind()) {
3642             case DOUBLE:
3643                 return Collections.emptyList();
3644             case FLOAT:
3645                 return Arrays.asList(doubleInstance);
3646             case LONG:
3647                 return Arrays.asList(floatInstance);
3648             case INT:
3649                 return Arrays.asList(longInstance);
3650             case CHAR:
3651                 return Arrays.asList(intInstance);
3652             case SHORT:
3653                 return Arrays.asList(intInstance);
3654             case BYTE:
3655                 return Arrays.asList(shortInstance);
3656             default:
3657                 return Collections.emptyList();
3658             }
3659         }
3660     }
3661 
3662     private static class TypeFactory {
TypeFactory()3663         private TypeFactory() { }// no instances for you
3664 
instance(Class<?> c)3665         public static TypeMirror instance(Class<?> c) {
3666             if (c.isPrimitive()) {
3667                 if (c.getName().equals("void")) {
3668                     return NoType.getVoidInstance();
3669                 } else {
3670                     return PrimitiveType.instance(c);
3671                 }
3672             } else if (c.isArray()) {
3673                 return new CoreReflArrayType(c);
3674             } else if (c.isAnonymousClass() ||
3675                        c.isLocalClass() ||
3676                        c.isMemberClass() ||
3677                        c.isInterface() || // covers annotations
3678                        c.isEnum()) {
3679                 return CoreReflDeclaredType.instance(c);
3680             } else { // plain old class ??
3681                 return CoreReflDeclaredType.instance(c);
3682             }
3683         }
3684 
instance(Type t)3685         public static TypeMirror instance(Type t) {
3686             if (t instanceof Class) {
3687                 return instance((Class)t);
3688             } else if (t instanceof ParameterizedType) {
3689                 ParameterizedType tmp = (ParameterizedType)t;
3690                 Type raw = tmp.getRawType();
3691                 if (!(raw instanceof Class)) {
3692                     throw new IllegalArgumentException(t + " " + raw );
3693                 }
3694                 return CoreReflDeclaredType.instance((Class)raw, tmp);
3695             } else if (t instanceof java.lang.reflect.WildcardType) {
3696                 return new ModelWildcardType((java.lang.reflect.WildcardType)t);
3697             } else if (t instanceof java.lang.reflect.TypeVariable) {
3698             return new CoreReflTypeVariable((java.lang.reflect.TypeVariable)t);
3699             }
3700             throw new IllegalArgumentException("Don't know how to make instance from: " + t.getClass());
3701         }
3702 
instance(Field f)3703         public static TypeMirror instance(Field f) {
3704             return CoreReflDeclaredType.instance(f.getType(), f.getGenericType());
3705         }
3706 
instance(Method m)3707         public static ExecutableType instance(Method m) {
3708             return new ExecutableMethodType(m);
3709         }
3710 
typeVariableInstance(java.lang.reflect.TypeVariable<?> v)3711         public static javax.lang.model.type.TypeVariable typeVariableInstance(java.lang.reflect.TypeVariable<?> v) {
3712             return new CoreReflTypeVariable(v);
3713         }
3714 
typeVariableInstance(TypeMirror source, TypeMirror upperBound, TypeMirror lowerBound)3715         public static javax.lang.model.type.TypeVariable typeVariableInstance(TypeMirror source,
3716                                                         TypeMirror upperBound,
3717                                                         TypeMirror lowerBound) {
3718             return new CaptureTypeVariable(source, upperBound, lowerBound);
3719         }
3720     }
3721 
3722     private static class CoreReflTypeVariable extends AbstractTypeMirror
3723         implements javax.lang.model.type.TypeVariable {
3724         private final java.lang.reflect.TypeVariable<?> source;
3725         private boolean isCapture = false;
3726 
CoreReflTypeVariable(java.lang.reflect.TypeVariable<?> source)3727         protected CoreReflTypeVariable(java.lang.reflect.TypeVariable<?> source) {
3728             super(TypeKind.TYPEVAR);
3729             Objects.requireNonNull(source);
3730             this.source = source;
3731         }
3732 
3733         @Override
getUpperBound()3734         public TypeMirror getUpperBound() {
3735             return new IntersectionDeclaredType(source.getBounds());
3736         }
3737 
3738         @Override
getLowerBound()3739         public TypeMirror getLowerBound() {
3740             return CoreReflTypes.instance().getNullType();
3741         }
3742 
3743         @Override
asElement()3744         public Element asElement() {
3745             return CoreReflectionFactory.createMirror(source);
3746         }
3747 
3748         @Override
directSuperTypes()3749         List<? extends TypeMirror> directSuperTypes() {
3750             return ((AbstractTypeMirror)getUpperBound()).directSuperTypes();
3751         }
3752 
3753         @Override
hashCode()3754         public int hashCode() {
3755             return source.hashCode();
3756         }
3757 
3758         @Override
equals(Object other)3759         public boolean equals(Object other) {
3760             if (other instanceof CoreReflTypeVariable) {
3761                 return this.source.equals(((CoreReflTypeVariable)other).source);
3762             } else {
3763                 return false;
3764             }
3765         }
3766     }
3767 }
3768