1 /* <lambda>null2 * Copyright 2019 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("UnstableApiUsage") 18 19 package androidx.work.lint 20 21 import com.android.tools.lint.detector.api.Category 22 import com.android.tools.lint.detector.api.Detector 23 import com.android.tools.lint.detector.api.Implementation 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 com.android.tools.lint.detector.api.SourceCodeScanner 29 import com.intellij.psi.PsiMethod 30 import org.jetbrains.uast.UCallExpression 31 32 class PeriodicEnqueueIssueDetector : Detector(), SourceCodeScanner { 33 companion object { 34 val ISSUE = 35 Issue.create( 36 id = "BadPeriodicWorkRequestEnqueue", 37 briefDescription = "Use `enqueueUniquePeriodicWork()` instead of `enqueue()`", 38 explanation = 39 """ 40 When using `enqueue()` for `PeriodicWorkRequest`s, you might end up enqueuing 41 duplicate requests unintentionally. You should be using 42 `enqueueUniquePeriodicWork` with an `ExistingPeriodicWorkPolicy.KEEP` instead. 43 """, 44 androidSpecific = true, 45 category = Category.CORRECTNESS, 46 severity = Severity.WARNING, 47 implementation = 48 Implementation(PeriodicEnqueueIssueDetector::class.java, Scope.JAVA_FILE_SCOPE) 49 ) 50 } 51 52 override fun getApplicableMethodNames(): List<String>? = listOf("enqueue") 53 54 override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) { 55 if (context.evaluator.isMemberInClass(method, "androidx.work.WorkManager")) { 56 val periodic = 57 node.valueArguments.filter { argument -> 58 val type = argument.getExpressionType()?.canonicalText 59 type == "androidx.work.PeriodicWorkRequest" || 60 type == "java.util.List<? extends androidx.work.PeriodicWorkRequest>" || 61 type == "java.util.List<? extends androidx.work.WorkRequest>" 62 } 63 if (periodic.isNotEmpty()) { 64 context.report( 65 ISSUE, 66 context.getLocation(method), 67 message = "Use `enqueueUniquePeriodicWork()` instead of `enqueue()`" 68 ) 69 } 70 } 71 } 72 } 73