Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java @ 10597:79041ab43660
Truffle-DSL: API-change: Renamed truffle.api.codegen to truffle.api.dsl for all projects and packages.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 01 Jul 2013 20:58:32 +0200 |
parents | |
children | efe58aa92f86 |
comparison
equal
deleted
inserted
replaced
10596:f43eb2f1bbbc | 10597:79041ab43660 |
---|---|
1 /* | |
2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.oracle.truffle.dsl.processor; | |
24 | |
25 import java.io.*; | |
26 import java.lang.annotation.*; | |
27 import java.util.*; | |
28 | |
29 import javax.annotation.processing.*; | |
30 import javax.lang.model.element.*; | |
31 import javax.lang.model.type.*; | |
32 import javax.lang.model.util.*; | |
33 | |
34 import com.oracle.truffle.dsl.processor.ast.*; | |
35 import com.oracle.truffle.dsl.processor.ast.CodeTypeMirror.*; | |
36 import com.oracle.truffle.dsl.processor.compiler.*; | |
37 | |
38 /** | |
39 * THIS IS NOT PUBLIC API. | |
40 */ | |
41 public class Utils { | |
42 | |
43 public static ExecutableElement findExecutableElement(DeclaredType type, String name) { | |
44 List<? extends ExecutableElement> elements = ElementFilter.methodsIn(type.asElement().getEnclosedElements()); | |
45 for (ExecutableElement executableElement : elements) { | |
46 if (executableElement.getSimpleName().toString().equals(name)) { | |
47 return executableElement; | |
48 } | |
49 } | |
50 return null; | |
51 } | |
52 | |
53 public static VariableElement findVariableElement(DeclaredType type, String name) { | |
54 List<? extends VariableElement> elements = ElementFilter.fieldsIn(type.asElement().getEnclosedElements()); | |
55 for (VariableElement variableElement : elements) { | |
56 if (variableElement.getSimpleName().toString().equals(name)) { | |
57 return variableElement; | |
58 } | |
59 } | |
60 return null; | |
61 } | |
62 | |
63 public static String getMethodBody(ProcessingEnvironment env, ExecutableElement method) { | |
64 if (method instanceof CodeExecutableElement) { | |
65 return ((CodeExecutableElement) method).getBody(); | |
66 } else { | |
67 return CompilerFactory.getCompiler(method).getMethodBody(env, method); | |
68 } | |
69 } | |
70 | |
71 public static TypeMirror boxType(ProcessorContext context, TypeMirror primitiveType) { | |
72 TypeMirror boxedType = primitiveType; | |
73 if (boxedType.getKind().isPrimitive()) { | |
74 boxedType = context.getEnvironment().getTypeUtils().boxedClass((PrimitiveType) boxedType).asType(); | |
75 } | |
76 return boxedType; | |
77 } | |
78 | |
79 public static List<TypeMirror> asTypeMirrors(List<? extends Element> elements) { | |
80 List<TypeMirror> types = new ArrayList<>(elements.size()); | |
81 for (Element element : elements) { | |
82 types.add(element.asType()); | |
83 } | |
84 return types; | |
85 } | |
86 | |
87 public static DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) { | |
88 return new DeclaredCodeTypeMirror(typeElem, Arrays.asList(typeArgs)); | |
89 } | |
90 | |
91 public static List<AnnotationMirror> collectAnnotations(ProcessorContext context, AnnotationMirror markerAnnotation, String elementName, Element element, | |
92 Class<? extends Annotation> annotationClass) { | |
93 List<AnnotationMirror> result = new ArrayList<>(); | |
94 if (markerAnnotation != null) { | |
95 result.addAll(Utils.getAnnotationValueList(AnnotationMirror.class, markerAnnotation, elementName)); | |
96 } | |
97 AnnotationMirror explicit = Utils.findAnnotationMirror(context.getEnvironment(), element, annotationClass); | |
98 if (explicit != null) { | |
99 result.add(explicit); | |
100 } | |
101 return result; | |
102 } | |
103 | |
104 public static TypeMirror getCommonSuperType(ProcessorContext context, TypeMirror[] types) { | |
105 if (types.length == 0) { | |
106 return context.getType(Object.class); | |
107 } | |
108 TypeMirror prev = types[0]; | |
109 for (int i = 1; i < types.length; i++) { | |
110 prev = getCommonSuperType(context, prev, types[i]); | |
111 } | |
112 return prev; | |
113 } | |
114 | |
115 public static TypeMirror getCommonSuperType(ProcessorContext context, TypeMirror type1, TypeMirror type2) { | |
116 if (typeEquals(type1, type2)) { | |
117 return type1; | |
118 } | |
119 TypeElement element1 = fromTypeMirror(type1); | |
120 TypeElement element2 = fromTypeMirror(type2); | |
121 if (element1 == null || element2 == null) { | |
122 return context.getType(Object.class); | |
123 } | |
124 | |
125 List<TypeElement> element1Types = getDirectSuperTypes(element1); | |
126 element1Types.add(0, element1); | |
127 List<TypeElement> element2Types = getDirectSuperTypes(element2); | |
128 element2Types.add(0, element2); | |
129 | |
130 for (TypeElement superType1 : element1Types) { | |
131 for (TypeElement superType2 : element2Types) { | |
132 if (typeEquals(superType1.asType(), superType2.asType())) { | |
133 return superType2.asType(); | |
134 } | |
135 } | |
136 } | |
137 return context.getType(Object.class); | |
138 } | |
139 | |
140 public static String getReadableSignature(ExecutableElement method) { | |
141 // TODO toString does not guarantee a good signature | |
142 return method.toString(); | |
143 } | |
144 | |
145 public static boolean hasError(TypeMirror mirror) { | |
146 switch (mirror.getKind()) { | |
147 case BOOLEAN: | |
148 case BYTE: | |
149 case CHAR: | |
150 case DOUBLE: | |
151 case FLOAT: | |
152 case INT: | |
153 case SHORT: | |
154 case LONG: | |
155 case DECLARED: | |
156 case VOID: | |
157 case TYPEVAR: | |
158 return false; | |
159 case ARRAY: | |
160 return hasError(((ArrayType) mirror).getComponentType()); | |
161 case ERROR: | |
162 return true; | |
163 default: | |
164 throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror); | |
165 } | |
166 } | |
167 | |
168 public static boolean isAssignable(ProcessorContext context, TypeMirror from, TypeMirror to) { | |
169 if (!(from instanceof CodeTypeMirror) && !(to instanceof CodeTypeMirror)) { | |
170 return context.getEnvironment().getTypeUtils().isAssignable(context.reloadType(from), context.reloadType(to)); | |
171 } else { | |
172 return isAssignableImpl(context, from, to); | |
173 } | |
174 } | |
175 | |
176 private static boolean isAssignableImpl(ProcessorContext context, TypeMirror from, TypeMirror to) { | |
177 // JLS 5.1.1 identity conversion | |
178 if (Utils.typeEquals(from, to)) { | |
179 return true; | |
180 } | |
181 | |
182 // JLS 5.1.2 widening primitives | |
183 if (Utils.isPrimitive(from) && Utils.isPrimitive(to)) { | |
184 TypeKind fromKind = from.getKind(); | |
185 TypeKind toKind = to.getKind(); | |
186 switch (fromKind) { | |
187 case BYTE: | |
188 switch (toKind) { | |
189 case SHORT: | |
190 case INT: | |
191 case LONG: | |
192 case FLOAT: | |
193 case DOUBLE: | |
194 return true; | |
195 } | |
196 break; | |
197 case SHORT: | |
198 switch (toKind) { | |
199 case INT: | |
200 case LONG: | |
201 case FLOAT: | |
202 case DOUBLE: | |
203 return true; | |
204 } | |
205 break; | |
206 case CHAR: | |
207 switch (toKind) { | |
208 case INT: | |
209 case LONG: | |
210 case FLOAT: | |
211 case DOUBLE: | |
212 return true; | |
213 } | |
214 break; | |
215 case INT: | |
216 switch (toKind) { | |
217 case LONG: | |
218 case FLOAT: | |
219 case DOUBLE: | |
220 return true; | |
221 } | |
222 break; | |
223 case LONG: | |
224 switch (toKind) { | |
225 case FLOAT: | |
226 case DOUBLE: | |
227 return true; | |
228 } | |
229 break; | |
230 case FLOAT: | |
231 switch (toKind) { | |
232 case DOUBLE: | |
233 return true; | |
234 } | |
235 break; | |
236 | |
237 } | |
238 return false; | |
239 } else if (Utils.isPrimitive(from) || Utils.isPrimitive(to)) { | |
240 return false; | |
241 } | |
242 | |
243 if (from instanceof ArrayType && to instanceof ArrayType) { | |
244 return isAssignable(context, ((ArrayType) from).getComponentType(), ((ArrayType) to).getComponentType()); | |
245 } | |
246 | |
247 TypeElement fromType = Utils.fromTypeMirror(from); | |
248 TypeElement toType = Utils.fromTypeMirror(to); | |
249 if (fromType == null || toType == null) { | |
250 return false; | |
251 } | |
252 // JLS 5.1.6 narrowing reference conversion | |
253 | |
254 List<TypeElement> superTypes = Utils.getSuperTypes(fromType); | |
255 for (TypeElement superType : superTypes) { | |
256 if (Utils.typeEquals(superType.asType(), to)) { | |
257 return true; | |
258 } | |
259 } | |
260 | |
261 // TODO more spec | |
262 return false; | |
263 } | |
264 | |
265 public static Set<Modifier> modifiers(Modifier... modifier) { | |
266 return new LinkedHashSet<>(Arrays.asList(modifier)); | |
267 } | |
268 | |
269 public static String getTypeId(TypeMirror mirror) { | |
270 switch (mirror.getKind()) { | |
271 case BOOLEAN: | |
272 return "Boolean"; | |
273 case BYTE: | |
274 return "Byte"; | |
275 case CHAR: | |
276 return "Char"; | |
277 case DOUBLE: | |
278 return "Double"; | |
279 case FLOAT: | |
280 return "Float"; | |
281 case SHORT: | |
282 return "Short"; | |
283 case INT: | |
284 return "Int"; | |
285 case LONG: | |
286 return "Long"; | |
287 case DECLARED: | |
288 return ((DeclaredType) mirror).asElement().getSimpleName().toString(); | |
289 case ARRAY: | |
290 return getTypeId(((ArrayType) mirror).getComponentType()) + "Array"; | |
291 case VOID: | |
292 return "Void"; | |
293 case WILDCARD: | |
294 StringBuilder b = new StringBuilder(); | |
295 WildcardType type = (WildcardType) mirror; | |
296 if (type.getExtendsBound() != null) { | |
297 b.append("Extends").append(getTypeId(type.getExtendsBound())); | |
298 } else if (type.getSuperBound() != null) { | |
299 b.append("Super").append(getTypeId(type.getExtendsBound())); | |
300 } | |
301 return b.toString(); | |
302 case TYPEVAR: | |
303 return "Any"; | |
304 case ERROR: | |
305 throw new CompileErrorException("Type error " + mirror); | |
306 default: | |
307 throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror); | |
308 } | |
309 } | |
310 | |
311 public static String getSimpleName(TypeElement element) { | |
312 return getSimpleName(element.asType()); | |
313 } | |
314 | |
315 public static String getSimpleName(TypeMirror mirror) { | |
316 switch (mirror.getKind()) { | |
317 case BOOLEAN: | |
318 return "boolean"; | |
319 case BYTE: | |
320 return "byte"; | |
321 case CHAR: | |
322 return "char"; | |
323 case DOUBLE: | |
324 return "double"; | |
325 case FLOAT: | |
326 return "float"; | |
327 case SHORT: | |
328 return "short"; | |
329 case INT: | |
330 return "int"; | |
331 case LONG: | |
332 return "long"; | |
333 case DECLARED: | |
334 return getDeclaredName((DeclaredType) mirror); | |
335 case ARRAY: | |
336 return getSimpleName(((ArrayType) mirror).getComponentType()) + "[]"; | |
337 case VOID: | |
338 return "void"; | |
339 case WILDCARD: | |
340 return getWildcardName((WildcardType) mirror); | |
341 case TYPEVAR: | |
342 return "?"; | |
343 case ERROR: | |
344 throw new CompileErrorException("Type error " + mirror); | |
345 default: | |
346 throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror); | |
347 } | |
348 } | |
349 | |
350 private static String getWildcardName(WildcardType type) { | |
351 StringBuilder b = new StringBuilder(); | |
352 if (type.getExtendsBound() != null) { | |
353 b.append("? extends ").append(getSimpleName(type.getExtendsBound())); | |
354 } else if (type.getSuperBound() != null) { | |
355 b.append("? super ").append(getSimpleName(type.getExtendsBound())); | |
356 } | |
357 return b.toString(); | |
358 } | |
359 | |
360 private static String getDeclaredName(DeclaredType element) { | |
361 String simpleName = element.asElement().getSimpleName().toString(); | |
362 | |
363 if (element.getTypeArguments().size() == 0) { | |
364 return simpleName; | |
365 } | |
366 | |
367 StringBuilder b = new StringBuilder(simpleName); | |
368 b.append("<"); | |
369 if (element.getTypeArguments().size() > 0) { | |
370 for (int i = 0; i < element.getTypeArguments().size(); i++) { | |
371 b.append(getSimpleName(element.getTypeArguments().get(i))); | |
372 if (i < element.getTypeArguments().size() - 1) { | |
373 b.append(", "); | |
374 } | |
375 } | |
376 } | |
377 b.append(">"); | |
378 return b.toString(); | |
379 } | |
380 | |
381 public static String getQualifiedName(TypeElement element) { | |
382 return element.getQualifiedName().toString(); | |
383 } | |
384 | |
385 public static String getQualifiedName(TypeMirror mirror) { | |
386 switch (mirror.getKind()) { | |
387 case BOOLEAN: | |
388 return "boolean"; | |
389 case BYTE: | |
390 return "byte"; | |
391 case CHAR: | |
392 return "char"; | |
393 case DOUBLE: | |
394 return "double"; | |
395 case SHORT: | |
396 return "short"; | |
397 case FLOAT: | |
398 return "float"; | |
399 case INT: | |
400 return "int"; | |
401 case LONG: | |
402 return "long"; | |
403 case DECLARED: | |
404 return getQualifiedName(fromTypeMirror(mirror)); | |
405 case ARRAY: | |
406 return getQualifiedName(((ArrayType) mirror).getComponentType()); | |
407 case VOID: | |
408 return "void"; | |
409 case TYPEVAR: | |
410 return getSimpleName(mirror); | |
411 case ERROR: | |
412 throw new CompileErrorException("Type error " + mirror); | |
413 case NONE: | |
414 return "$none"; | |
415 default: | |
416 throw new RuntimeException("Unknown type specified " + mirror + " mirror: " + mirror); | |
417 } | |
418 } | |
419 | |
420 public static boolean isVoid(TypeMirror mirror) { | |
421 return mirror.getKind() == TypeKind.VOID; | |
422 } | |
423 | |
424 public static boolean isPrimitive(TypeMirror mirror) { | |
425 return mirror.getKind().isPrimitive(); | |
426 } | |
427 | |
428 public static boolean isPrimitiveOrVoid(TypeMirror mirror) { | |
429 return isPrimitive(mirror) || isVoid(mirror); | |
430 } | |
431 | |
432 public static List<String> getQualifiedSuperTypeNames(TypeElement element) { | |
433 List<TypeElement> types = getSuperTypes(element); | |
434 List<String> qualifiedNames = new ArrayList<>(); | |
435 for (TypeElement type : types) { | |
436 qualifiedNames.add(getQualifiedName(type)); | |
437 } | |
438 return qualifiedNames; | |
439 } | |
440 | |
441 public static List<TypeElement> getDeclaredTypes(TypeElement element) { | |
442 return ElementFilter.typesIn(element.getEnclosedElements()); | |
443 } | |
444 | |
445 public static VariableElement findDeclaredField(TypeMirror type, String singletonName) { | |
446 List<VariableElement> elements = ElementFilter.fieldsIn(fromTypeMirror(type).getEnclosedElements()); | |
447 for (VariableElement var : elements) { | |
448 if (var.getSimpleName().toString().equals(singletonName)) { | |
449 return var; | |
450 } | |
451 } | |
452 return null; | |
453 } | |
454 | |
455 public static TypeElement findRootEnclosingType(Element element) { | |
456 List<Element> elements = getElementHierarchy(element); | |
457 | |
458 for (int i = elements.size() - 1; i >= 0; i--) { | |
459 if (elements.get(i).getKind().isClass()) { | |
460 return (TypeElement) elements.get(i); | |
461 } | |
462 } | |
463 | |
464 return null; | |
465 } | |
466 | |
467 public static List<Element> getElementHierarchy(Element e) { | |
468 List<Element> elements = new ArrayList<>(); | |
469 elements.add(e); | |
470 | |
471 Element enclosing = e.getEnclosingElement(); | |
472 while (enclosing != null && enclosing.getKind() != ElementKind.PACKAGE) { | |
473 elements.add(enclosing); | |
474 enclosing = enclosing.getEnclosingElement(); | |
475 } | |
476 if (enclosing != null) { | |
477 elements.add(enclosing); | |
478 } | |
479 return elements; | |
480 } | |
481 | |
482 public static TypeElement findNearestEnclosingType(Element element) { | |
483 List<Element> elements = getElementHierarchy(element); | |
484 for (Element e : elements) { | |
485 if (e.getKind().isClass()) { | |
486 return (TypeElement) e; | |
487 } | |
488 } | |
489 return null; | |
490 } | |
491 | |
492 public static List<TypeElement> getDirectSuperTypes(TypeElement element) { | |
493 List<TypeElement> types = new ArrayList<>(); | |
494 if (element.getSuperclass() != null) { | |
495 TypeElement superElement = fromTypeMirror(element.getSuperclass()); | |
496 if (superElement != null) { | |
497 types.add(superElement); | |
498 types.addAll(getDirectSuperTypes(superElement)); | |
499 } | |
500 } | |
501 | |
502 return types; | |
503 } | |
504 | |
505 public static List<TypeElement> getSuperTypes(TypeElement element) { | |
506 List<TypeElement> types = new ArrayList<>(); | |
507 List<TypeElement> superTypes = null; | |
508 List<TypeElement> superInterfaces = null; | |
509 if (element.getSuperclass() != null) { | |
510 TypeElement superElement = fromTypeMirror(element.getSuperclass()); | |
511 if (superElement != null) { | |
512 types.add(superElement); | |
513 superTypes = getSuperTypes(superElement); | |
514 } | |
515 } | |
516 for (TypeMirror interfaceMirror : element.getInterfaces()) { | |
517 TypeElement interfaceElement = fromTypeMirror(interfaceMirror); | |
518 if (interfaceElement != null) { | |
519 types.add(interfaceElement); | |
520 superInterfaces = getSuperTypes(interfaceElement); | |
521 } | |
522 } | |
523 | |
524 if (superTypes != null) { | |
525 types.addAll(superTypes); | |
526 } | |
527 | |
528 if (superInterfaces != null) { | |
529 types.addAll(superInterfaces); | |
530 } | |
531 | |
532 return types; | |
533 } | |
534 | |
535 public static String getPackageName(TypeElement element) { | |
536 return findPackageElement(element).getQualifiedName().toString(); | |
537 } | |
538 | |
539 public static String getPackageName(TypeMirror mirror) { | |
540 switch (mirror.getKind()) { | |
541 case BOOLEAN: | |
542 case BYTE: | |
543 case CHAR: | |
544 case DOUBLE: | |
545 case FLOAT: | |
546 case SHORT: | |
547 case INT: | |
548 case LONG: | |
549 case VOID: | |
550 case TYPEVAR: | |
551 return null; | |
552 case DECLARED: | |
553 PackageElement pack = findPackageElement(fromTypeMirror(mirror)); | |
554 if (pack == null) { | |
555 throw new IllegalArgumentException("No package element found for declared type " + getSimpleName(mirror)); | |
556 } | |
557 return pack.getQualifiedName().toString(); | |
558 case ARRAY: | |
559 return getSimpleName(((ArrayType) mirror).getComponentType()); | |
560 default: | |
561 throw new RuntimeException("Unknown type specified " + mirror.getKind()); | |
562 } | |
563 } | |
564 | |
565 public static String createConstantName(String simpleName) { | |
566 // TODO use camel case to produce underscores. | |
567 return simpleName.toString().toUpperCase(); | |
568 } | |
569 | |
570 public static TypeElement fromTypeMirror(TypeMirror mirror) { | |
571 switch (mirror.getKind()) { | |
572 case DECLARED: | |
573 return (TypeElement) ((DeclaredType) mirror).asElement(); | |
574 case ARRAY: | |
575 return fromTypeMirror(((ArrayType) mirror).getComponentType()); | |
576 default: | |
577 return null; | |
578 } | |
579 } | |
580 | |
581 @SuppressWarnings("unchecked") | |
582 public static <T> List<T> getAnnotationValueList(Class<T> expectedListType, AnnotationMirror mirror, String name) { | |
583 List<? extends AnnotationValue> values = getAnnotationValue(List.class, mirror, name); | |
584 List<T> result = new ArrayList<>(); | |
585 | |
586 if (values != null) { | |
587 for (AnnotationValue value : values) { | |
588 T annotationValue = resolveAnnotationValue(expectedListType, value); | |
589 if (annotationValue != null) { | |
590 result.add(annotationValue); | |
591 } | |
592 } | |
593 } | |
594 return result; | |
595 } | |
596 | |
597 public static <T> T getAnnotationValue(Class<T> expectedType, AnnotationMirror mirror, String name) { | |
598 return resolveAnnotationValue(expectedType, getAnnotationValue(mirror, name)); | |
599 } | |
600 | |
601 @SuppressWarnings({"unchecked"}) | |
602 private static <T> T resolveAnnotationValue(Class<T> expectedType, AnnotationValue value) { | |
603 if (value == null) { | |
604 return null; | |
605 } | |
606 | |
607 Object unboxedValue = value.accept(new AnnotationValueVisitorImpl(), null); | |
608 if (unboxedValue != null) { | |
609 if (expectedType == TypeMirror.class && unboxedValue instanceof String) { | |
610 return null; | |
611 } | |
612 if (!expectedType.isAssignableFrom(unboxedValue.getClass())) { | |
613 throw new ClassCastException(unboxedValue.getClass().getName() + " not assignable from " + expectedType.getName()); | |
614 } | |
615 } | |
616 return (T) unboxedValue; | |
617 } | |
618 | |
619 public static AnnotationValue getAnnotationValue(AnnotationMirror mirror, String name) { | |
620 ExecutableElement valueMethod = null; | |
621 for (ExecutableElement method : ElementFilter.methodsIn(mirror.getAnnotationType().asElement().getEnclosedElements())) { | |
622 if (method.getSimpleName().toString().equals(name)) { | |
623 valueMethod = method; | |
624 break; | |
625 } | |
626 } | |
627 | |
628 if (valueMethod == null) { | |
629 return null; | |
630 } | |
631 | |
632 AnnotationValue value = mirror.getElementValues().get(valueMethod); | |
633 if (value == null) { | |
634 value = valueMethod.getDefaultValue(); | |
635 } | |
636 | |
637 return value; | |
638 } | |
639 | |
640 private static class AnnotationValueVisitorImpl extends AbstractAnnotationValueVisitor7<Object, Void> { | |
641 | |
642 @Override | |
643 public Object visitBoolean(boolean b, Void p) { | |
644 return Boolean.valueOf(b); | |
645 } | |
646 | |
647 @Override | |
648 public Object visitByte(byte b, Void p) { | |
649 return Byte.valueOf(b); | |
650 } | |
651 | |
652 @Override | |
653 public Object visitChar(char c, Void p) { | |
654 return c; | |
655 } | |
656 | |
657 @Override | |
658 public Object visitDouble(double d, Void p) { | |
659 return d; | |
660 } | |
661 | |
662 @Override | |
663 public Object visitFloat(float f, Void p) { | |
664 return f; | |
665 } | |
666 | |
667 @Override | |
668 public Object visitInt(int i, Void p) { | |
669 return i; | |
670 } | |
671 | |
672 @Override | |
673 public Object visitLong(long i, Void p) { | |
674 return i; | |
675 } | |
676 | |
677 @Override | |
678 public Object visitShort(short s, Void p) { | |
679 return s; | |
680 } | |
681 | |
682 @Override | |
683 public Object visitString(String s, Void p) { | |
684 return s; | |
685 } | |
686 | |
687 @Override | |
688 public Object visitType(TypeMirror t, Void p) { | |
689 return t; | |
690 } | |
691 | |
692 @Override | |
693 public Object visitEnumConstant(VariableElement c, Void p) { | |
694 return c; | |
695 } | |
696 | |
697 @Override | |
698 public Object visitAnnotation(AnnotationMirror a, Void p) { | |
699 return a; | |
700 } | |
701 | |
702 @Override | |
703 public Object visitArray(List<? extends AnnotationValue> vals, Void p) { | |
704 return vals; | |
705 } | |
706 | |
707 } | |
708 | |
709 public static boolean getAnnotationValueBoolean(AnnotationMirror mirror, String name) { | |
710 return (Boolean) getAnnotationValue(mirror, name).getValue(); | |
711 } | |
712 | |
713 public static String printException(Throwable e) { | |
714 StringWriter string = new StringWriter(); | |
715 PrintWriter writer = new PrintWriter(string); | |
716 e.printStackTrace(writer); | |
717 writer.flush(); | |
718 return e.getMessage() + "\r\n" + string.toString(); | |
719 } | |
720 | |
721 public static AnnotationMirror findAnnotationMirror(ProcessingEnvironment processingEnv, Element element, Class<?> annotationClass) { | |
722 return findAnnotationMirror(processingEnv, element.getAnnotationMirrors(), annotationClass); | |
723 } | |
724 | |
725 public static AnnotationMirror findAnnotationMirror(ProcessingEnvironment processingEnv, List<? extends AnnotationMirror> mirrors, Class<?> annotationClass) { | |
726 TypeElement expectedAnnotationType = processingEnv.getElementUtils().getTypeElement(annotationClass.getCanonicalName()); | |
727 for (AnnotationMirror mirror : mirrors) { | |
728 DeclaredType annotationType = mirror.getAnnotationType(); | |
729 TypeElement actualAnnotationType = (TypeElement) annotationType.asElement(); | |
730 if (actualAnnotationType.equals(expectedAnnotationType)) { | |
731 return mirror; | |
732 } | |
733 } | |
734 return null; | |
735 } | |
736 | |
737 private static PackageElement findPackageElement(Element type) { | |
738 List<Element> hierarchy = getElementHierarchy(type); | |
739 for (Element element : hierarchy) { | |
740 if (element.getKind() == ElementKind.PACKAGE) { | |
741 return (PackageElement) element; | |
742 } | |
743 } | |
744 return null; | |
745 } | |
746 | |
747 public static String firstLetterUpperCase(String name) { | |
748 if (name == null || name.isEmpty()) { | |
749 return name; | |
750 } | |
751 return Character.toUpperCase(name.charAt(0)) + name.substring(1, name.length()); | |
752 } | |
753 | |
754 public static String firstLetterLowerCase(String name) { | |
755 if (name == null || name.isEmpty()) { | |
756 return name; | |
757 } | |
758 return Character.toLowerCase(name.charAt(0)) + name.substring(1, name.length()); | |
759 } | |
760 | |
761 private static ExecutableElement getDeclaredMethod(TypeElement element, String name, TypeMirror[] params) { | |
762 List<ExecutableElement> methods = ElementFilter.methodsIn(element.getEnclosedElements()); | |
763 method: for (ExecutableElement method : methods) { | |
764 if (!method.getSimpleName().toString().equals(name)) { | |
765 continue; | |
766 } | |
767 if (method.getParameters().size() != params.length) { | |
768 continue; | |
769 } | |
770 for (int i = 0; i < params.length; i++) { | |
771 TypeMirror param1 = params[i]; | |
772 TypeMirror param2 = method.getParameters().get(i).asType(); | |
773 if (param1.getKind() != TypeKind.TYPEVAR && param2.getKind() != TypeKind.TYPEVAR) { | |
774 if (!getQualifiedName(param1).equals(getQualifiedName(param2))) { | |
775 continue method; | |
776 } | |
777 } | |
778 } | |
779 return method; | |
780 } | |
781 return null; | |
782 } | |
783 | |
784 private static boolean isDeclaredMethod(TypeElement element, String name, TypeMirror[] params) { | |
785 return getDeclaredMethod(element, name, params) != null; | |
786 } | |
787 | |
788 public static boolean isDeclaredMethodInSuperType(TypeElement element, String name, TypeMirror[] params) { | |
789 List<TypeElement> superElements = getSuperTypes(element); | |
790 | |
791 for (TypeElement typeElement : superElements) { | |
792 if (isDeclaredMethod(typeElement, name, params)) { | |
793 return true; | |
794 } | |
795 } | |
796 return false; | |
797 } | |
798 | |
799 private static ExecutableElement getDeclaredMethodInSuperType(TypeElement element, String name, TypeMirror[] params) { | |
800 List<TypeElement> superElements = getSuperTypes(element); | |
801 | |
802 for (TypeElement typeElement : superElements) { | |
803 ExecutableElement declared = getDeclaredMethod(typeElement, name, params); | |
804 if (declared != null) { | |
805 return declared; | |
806 } | |
807 } | |
808 return null; | |
809 } | |
810 | |
811 public static ExecutableElement getDeclaredMethodRecursive(TypeElement element, String name, TypeMirror[] params) { | |
812 ExecutableElement declared = getDeclaredMethod(element, name, params); | |
813 if (declared != null) { | |
814 return declared; | |
815 } | |
816 return getDeclaredMethodInSuperType(element, name, params); | |
817 } | |
818 | |
819 public static boolean typeEquals(TypeMirror type1, TypeMirror type2) { | |
820 if (type1 == null && type2 == null) { | |
821 return true; | |
822 } else if (type1 == null || type2 == null) { | |
823 return false; | |
824 } | |
825 String qualified1 = getQualifiedName(type1); | |
826 String qualified2 = getQualifiedName(type2); | |
827 | |
828 if (type1.getKind() == TypeKind.ARRAY || type2.getKind() == TypeKind.ARRAY) { | |
829 if (type1.getKind() == TypeKind.ARRAY && type2.getKind() == TypeKind.ARRAY) { | |
830 return typeEquals(((ArrayType) type1).getComponentType(), ((ArrayType) type2).getComponentType()); | |
831 } else { | |
832 return false; | |
833 } | |
834 } | |
835 return qualified1.equals(qualified2); | |
836 } | |
837 | |
838 public static int compareByTypeHierarchy(TypeMirror t1, TypeMirror t2) { | |
839 if (typeEquals(t1, t2)) { | |
840 return 0; | |
841 } | |
842 Set<String> t1SuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(t1))); | |
843 if (t1SuperSet.contains(getQualifiedName(t2))) { | |
844 return -1; | |
845 } | |
846 | |
847 Set<String> t2SuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(t2))); | |
848 if (t2SuperSet.contains(getQualifiedName(t1))) { | |
849 return 1; | |
850 } | |
851 return 0; | |
852 } | |
853 | |
854 public static boolean canThrowType(List<? extends TypeMirror> thrownTypes, TypeMirror exceptionType) { | |
855 if (Utils.containsType(thrownTypes, exceptionType)) { | |
856 return true; | |
857 } | |
858 | |
859 if (isRuntimeException(exceptionType)) { | |
860 return true; | |
861 } | |
862 | |
863 // search for any super types | |
864 TypeElement exceptionTypeElement = fromTypeMirror(exceptionType); | |
865 List<TypeElement> superTypes = getSuperTypes(exceptionTypeElement); | |
866 for (TypeElement typeElement : superTypes) { | |
867 if (Utils.containsType(thrownTypes, typeElement.asType())) { | |
868 return true; | |
869 } | |
870 } | |
871 | |
872 return false; | |
873 } | |
874 | |
875 public static Modifier getVisibility(Set<Modifier> modifier) { | |
876 for (Modifier mod : modifier) { | |
877 if (mod == Modifier.PUBLIC || mod == Modifier.PRIVATE || mod == Modifier.PROTECTED) { | |
878 return mod; | |
879 } | |
880 } | |
881 return null; | |
882 } | |
883 | |
884 private static boolean isRuntimeException(TypeMirror type) { | |
885 Set<String> typeSuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(type))); | |
886 String typeName = getQualifiedName(type); | |
887 if (!typeSuperSet.contains(Throwable.class.getCanonicalName()) && !typeName.equals(Throwable.class.getCanonicalName())) { | |
888 throw new IllegalArgumentException("Given type does not extend Throwable."); | |
889 } | |
890 return typeSuperSet.contains(RuntimeException.class.getCanonicalName()) || typeName.equals(RuntimeException.class.getCanonicalName()); | |
891 } | |
892 | |
893 private static boolean containsType(Collection<? extends TypeMirror> collection, TypeMirror type) { | |
894 for (TypeMirror otherTypeMirror : collection) { | |
895 if (typeEquals(otherTypeMirror, type)) { | |
896 return true; | |
897 } | |
898 } | |
899 return false; | |
900 } | |
901 | |
902 public static boolean isTopLevelClass(TypeMirror importType) { | |
903 TypeElement type = fromTypeMirror(importType); | |
904 if (type != null && type.getEnclosingElement() != null) { | |
905 return !type.getEnclosingElement().getKind().isClass(); | |
906 } | |
907 return true; | |
908 } | |
909 | |
910 public static boolean isObject(TypeMirror actualType) { | |
911 return getQualifiedName(actualType).equals("java.lang.Object"); | |
912 } | |
913 | |
914 public static boolean isFieldAccessible(Element element, VariableElement variable) { | |
915 TypeElement type = Utils.findNearestEnclosingType(element); | |
916 TypeElement varType = Utils.findNearestEnclosingType(variable); | |
917 | |
918 while (type != null) { | |
919 if (typeEquals(type.asType(), varType.asType())) { | |
920 return true; | |
921 } | |
922 if (type.getSuperclass() != null) { | |
923 type = Utils.fromTypeMirror(type.getSuperclass()); | |
924 } else { | |
925 type = null; | |
926 } | |
927 } | |
928 return false; | |
929 } | |
930 } |