1 /*
2  * Copyright 2024 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.build.lint
18 
19 import com.android.tools.lint.client.api.UElementHandler
20 import com.android.tools.lint.detector.api.Category
21 import com.android.tools.lint.detector.api.Detector
22 import com.android.tools.lint.detector.api.Implementation
23 import com.android.tools.lint.detector.api.Incident
24 import com.android.tools.lint.detector.api.Issue
25 import com.android.tools.lint.detector.api.JavaContext
26 import com.android.tools.lint.detector.api.Scope
27 import com.android.tools.lint.detector.api.Severity
28 import org.jetbrains.uast.UAnnotation
29 
30 class BanNullMarked : Detector(), Detector.UastScanner {
31 
getApplicableUastTypesnull32     override fun getApplicableUastTypes() = listOf(UAnnotation::class.java)
33 
34     override fun createUastHandler(context: JavaContext): UElementHandler {
35         return AnnotationChecker(context)
36     }
37 
38     private inner class AnnotationChecker(val context: JavaContext) : UElementHandler() {
visitAnnotationnull39         override fun visitAnnotation(node: UAnnotation) {
40             if (node.qualifiedName != "org.jspecify.annotations.NullMarked") return
41 
42             val incident =
43                 Incident(context)
44                     .issue(ISSUE)
45                     .location(context.getLocation(node))
46                     .scope(node)
47                     .message("Should not use @NullMarked annotation")
48             context.report(incident)
49         }
50     }
51 
52     companion object {
53         val ISSUE =
54             Issue.create(
55                 "BanNullMarked",
56                 "Should not use @NullMarked annotation",
57                 "Usage of the @NullMarked annotation is not allowed because lint and metalava do not support it",
58                 Category.CORRECTNESS,
59                 5,
60                 Severity.ERROR,
61                 Implementation(BanNullMarked::class.java, Scope.JAVA_FILE_SCOPE)
62             )
63     }
64 }
65