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 19package android.arch.persistence.room.ext 20 21import com.google.auto.common.AnnotationMirrors 22import com.google.auto.common.MoreElements 23import com.google.auto.common.MoreTypes 24import javax.annotation.processing.ProcessingEnvironment 25import javax.lang.model.element.AnnotationValue 26import javax.lang.model.element.Element 27import javax.lang.model.element.ElementKind 28import javax.lang.model.element.Modifier 29import javax.lang.model.element.TypeElement 30import javax.lang.model.element.VariableElement 31import javax.lang.model.type.TypeKind 32import javax.lang.model.type.TypeMirror 33import javax.lang.model.util.SimpleAnnotationValueVisitor6 34import kotlin.reflect.KClass 35 36fun Element.hasAnyOf(vararg modifiers: Modifier): Boolean { 37 return this.modifiers.any { modifiers.contains(it) } 38} 39 40fun Element.hasAnnotation(klass: KClass<out Annotation>): Boolean { 41 return MoreElements.isAnnotationPresent(this, klass.java) 42} 43 44fun 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 53fun 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 70private val TO_LIST_OF_TYPES = object 71 : SimpleAnnotationValueVisitor6<List<TypeMirror>, Void?>() { 72 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 81 override fun defaultAction(o: Any?, p: Void?): List<TypeMirror>? { 82 return emptyList() 83 } 84} 85 86private val TO_TYPE = object : SimpleAnnotationValueVisitor6<TypeMirror, Void>() { 87 88 override fun visitType(t: TypeMirror, p: Void?): TypeMirror { 89 return t 90 } 91 92 override fun defaultAction(o: Any?, p: Void?): TypeMirror { 93 throw TypeNotPresentException(o!!.toString(), null) 94 } 95} 96 97fun AnnotationValue.toListOfClassTypes(): List<TypeMirror> { 98 return TO_LIST_OF_TYPES.visit(this) 99} 100 101fun AnnotationValue.toType(): TypeMirror { 102 return TO_TYPE.visit(this) 103} 104 105fun AnnotationValue.toClassType(): TypeMirror? { 106 return TO_TYPE.visit(this) 107} 108 109fun 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 115fun 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 122private val ANNOTATION_VALUE_TO_INT_VISITOR = object : SimpleAnnotationValueVisitor6<Int?, Void>() { 123 override fun visitInt(i: Int, p: Void?): Int? { 124 return i 125 } 126} 127 128private val ANNOTATION_VALUE_TO_BOOLEAN_VISITOR = object 129 : SimpleAnnotationValueVisitor6<Boolean?, Void>() { 130 override fun visitBoolean(b: Boolean, p: Void?): Boolean? { 131 return b 132 } 133} 134 135private val ANNOTATION_VALUE_TO_STRING_VISITOR = object 136 : SimpleAnnotationValueVisitor6<String?, Void>() { 137 override fun visitString(s: String?, p: Void?): String? { 138 return s 139 } 140} 141 142private val ANNOTATION_VALUE_STRING_ARR_VISITOR = object 143 : SimpleAnnotationValueVisitor6<List<String>, Void>() { 144 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 151fun AnnotationValue.getAsInt(def: Int? = null): Int? { 152 return ANNOTATION_VALUE_TO_INT_VISITOR.visit(this) ?: def 153} 154 155fun AnnotationValue.getAsString(def: String? = null): String? { 156 return ANNOTATION_VALUE_TO_STRING_VISITOR.visit(this) ?: def 157} 158 159fun AnnotationValue.getAsBoolean(def: Boolean): Boolean { 160 return ANNOTATION_VALUE_TO_BOOLEAN_VISITOR.visit(this) ?: def 161} 162 163fun AnnotationValue.getAsStringList(): List<String> { 164 return ANNOTATION_VALUE_STRING_ARR_VISITOR.visit(this) 165} 166