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