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 package androidx.room.preconditions
18 
19 import androidx.room.ext.hasAnnotation
20 import androidx.room.log.RLog
21 import com.squareup.javapoet.ParameterizedTypeName
22 import com.squareup.javapoet.TypeName
23 import com.squareup.javapoet.TypeVariableName
24 import javax.lang.model.element.Element
25 import kotlin.reflect.KClass
26 
27 /**
28  * Similar to preconditions but element bound and just logs the error instead of throwing an
29  * exception.
30  * <p>
31  * It is important for processing to continue when some errors happen so that we can generate as
32  * much code as possible, leaving only the errors in javac output.
33  */
34 class Checks(private val logger: RLog) {
35 
checknull36     fun check(predicate: Boolean, element: Element, errorMsg: String, vararg args: Any): Boolean {
37         if (!predicate) {
38             logger.e(element, errorMsg, args)
39         }
40         return predicate
41     }
42 
hasAnnotationnull43     fun hasAnnotation(element: Element, annotation: KClass<out Annotation>, errorMsg: String,
44                       vararg args: Any): Boolean {
45         return if (!element.hasAnnotation(annotation)) {
46             logger.e(element, errorMsg, args)
47             false
48         } else {
49             true
50         }
51     }
52 
notUnboundnull53     fun notUnbound(typeName: TypeName, element: Element, errorMsg: String,
54                    vararg args: Any): Boolean {
55         // TODO support bounds cases like <T extends Foo> T bar()
56         val failed = check(typeName !is TypeVariableName, element, errorMsg, args)
57         if (typeName is ParameterizedTypeName) {
58             val nestedFailure = typeName.typeArguments
59                     .any { notUnbound(it, element, errorMsg, args) }
60             return !(failed || nestedFailure)
61         }
62         return !failed
63     }
64 
notBlanknull65     fun notBlank(value: String?, element: Element, msg: String, vararg args: Any): Boolean {
66         return check(value != null && value.isNotBlank(), element, msg, args)
67     }
68 }
69