• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 @file:Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
18 
19 package android.arch.persistence.room.ext
20 
21 import com.google.auto.common.AnnotationMirrors
22 import com.google.auto.common.MoreElements
23 import com.google.auto.common.MoreTypes
24 import javax.annotation.processing.ProcessingEnvironment
25 import javax.lang.model.element.AnnotationValue
26 import javax.lang.model.element.Element
27 import javax.lang.model.element.ElementKind
28 import javax.lang.model.element.Modifier
29 import javax.lang.model.element.TypeElement
30 import javax.lang.model.element.VariableElement
31 import javax.lang.model.type.TypeKind
32 import javax.lang.model.type.TypeMirror
33 import javax.lang.model.util.SimpleAnnotationValueVisitor6
34 import kotlin.reflect.KClass
35 
hasAnyOfnull36 fun Element.hasAnyOf(vararg modifiers: Modifier): Boolean {
37     return this.modifiers.any { modifiers.contains(it) }
38 }
39 
hasAnnotationnull40 fun Element.hasAnnotation(klass: KClass<out Annotation>): Boolean {
41     return MoreElements.isAnnotationPresent(this, klass.java)
42 }
43 
isNonNullnull44 fun Element.isNonNull() =
45         asType().kind.isPrimitive
46                 || hasAnnotation(android.support.annotation.NonNull::class)
47                 || hasAnnotation(org.jetbrains.annotations.NotNull::class)
48 
49 /**
50  * gets all members including super privates. does not handle duplicate field names!!!
51  */
52 // TODO handle conflicts with super: b/35568142
53 fun TypeElement.getAllFieldsIncludingPrivateSupers(processingEnvironment: ProcessingEnvironment):
54         Set<VariableElement> {
55     val myMembers = processingEnvironment.elementUtils.getAllMembers(this)
56             .filter { it.kind == ElementKind.FIELD }
57             .filter { it is VariableElement }
58             .map { it as VariableElement }
59             .toSet()
60     if (superclass.kind != TypeKind.NONE) {
61         return myMembers + MoreTypes.asTypeElement(superclass)
62                 .getAllFieldsIncludingPrivateSupers(processingEnvironment)
63     } else {
64         return myMembers
65     }
66 }
67 
68 // code below taken from dagger2
69 // compiler/src/main/java/dagger/internal/codegen/ConfigurationAnnotations.java
70 private val TO_LIST_OF_TYPES = object
71     : SimpleAnnotationValueVisitor6<List<TypeMirror>, Void?>() {
visitArraynull72     override fun visitArray(values: MutableList<out AnnotationValue>?, p: Void?)
73             : List<TypeMirror> {
74         return values?.map {
75             val tmp = TO_TYPE.visit(it)
76             tmp
77         }?.filterNotNull() ?: emptyList()
78     }
79 
80 
defaultActionnull81     override fun defaultAction(o: Any?, p: Void?): List<TypeMirror>? {
82         return emptyList()
83     }
84 }
85 
86 private val TO_TYPE = object : SimpleAnnotationValueVisitor6<TypeMirror, Void>() {
87 
visitTypenull88     override fun visitType(t: TypeMirror, p: Void?): TypeMirror {
89         return t
90     }
91 
defaultActionnull92     override fun defaultAction(o: Any?, p: Void?): TypeMirror {
93         throw TypeNotPresentException(o!!.toString(), null)
94     }
95 }
96 
AnnotationValuenull97 fun AnnotationValue.toListOfClassTypes(): List<TypeMirror> {
98     return TO_LIST_OF_TYPES.visit(this)
99 }
100 
toTypenull101 fun AnnotationValue.toType(): TypeMirror {
102     return TO_TYPE.visit(this)
103 }
104 
toClassTypenull105 fun AnnotationValue.toClassType(): TypeMirror? {
106     return TO_TYPE.visit(this)
107 }
108 
TypeMirrornull109 fun TypeMirror.isCollection(): Boolean {
110     return MoreTypes.isType(this)
111             && (MoreTypes.isTypeOf(java.util.List::class.java, this)
112             || MoreTypes.isTypeOf(java.util.Set::class.java, this))
113 }
114 
getAnnotationValuenull115 fun Element.getAnnotationValue(annotation: Class<out Annotation>, fieldName: String): Any? {
116     return MoreElements.getAnnotationMirror(this, annotation)
117             .orNull()?.let {
118         AnnotationMirrors.getAnnotationValue(it, fieldName)?.value
119     }
120 }
121 
122 private val ANNOTATION_VALUE_TO_INT_VISITOR = object : SimpleAnnotationValueVisitor6<Int?, Void>() {
visitIntnull123     override fun visitInt(i: Int, p: Void?): Int? {
124         return i
125     }
126 }
127 
128 private val ANNOTATION_VALUE_TO_BOOLEAN_VISITOR = object
129     : SimpleAnnotationValueVisitor6<Boolean?, Void>() {
visitBooleannull130     override fun visitBoolean(b: Boolean, p: Void?): Boolean? {
131         return b
132     }
133 }
134 
135 private val ANNOTATION_VALUE_TO_STRING_VISITOR = object
136     : SimpleAnnotationValueVisitor6<String?, Void>() {
visitStringnull137     override fun visitString(s: String?, p: Void?): String? {
138         return s
139     }
140 }
141 
142 private val ANNOTATION_VALUE_STRING_ARR_VISITOR = object
143     : SimpleAnnotationValueVisitor6<List<String>, Void>() {
visitArraynull144     override fun visitArray(vals: MutableList<out AnnotationValue>?, p: Void?): List<String> {
145         return vals?.map {
146             ANNOTATION_VALUE_TO_STRING_VISITOR.visit(it)
147         }?.filterNotNull() ?: emptyList()
148     }
149 }
150 
AnnotationValuenull151 fun AnnotationValue.getAsInt(def: Int? = null): Int? {
152     return ANNOTATION_VALUE_TO_INT_VISITOR.visit(this) ?: def
153 }
154 
AnnotationValuenull155 fun AnnotationValue.getAsString(def: String? = null): String? {
156     return ANNOTATION_VALUE_TO_STRING_VISITOR.visit(this) ?: def
157 }
158 
getAsBooleannull159 fun AnnotationValue.getAsBoolean(def: Boolean): Boolean {
160     return ANNOTATION_VALUE_TO_BOOLEAN_VISITOR.visit(this) ?: def
161 }
162 
AnnotationValuenull163 fun AnnotationValue.getAsStringList(): List<String> {
164     return ANNOTATION_VALUE_STRING_ARR_VISITOR.visit(this)
165 }
166