From de69962e9d6c0b0a2c12f427dddf918d7afa262d Mon Sep 17 00:00:00 2001 From: Vladimir Ilmov Date: Fri, 15 May 2020 14:51:16 +0200 Subject: [PATCH] (UnusedSymbolInspection) alternative accessor names for searching references relates to #KT-38653 --- .../inspections/UnusedSymbolInspection.kt | 58 ++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt index f1c512975ef..b364664eb33 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.idea.inspections import com.intellij.codeInsight.FileModificationService import com.intellij.codeInsight.daemon.QuickFixBundle -import com.intellij.codeInsight.daemon.impl.HighlightInfoType import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil import com.intellij.codeInspection.* @@ -17,6 +16,7 @@ import com.intellij.codeInspection.ex.EntryPointsManagerBase import com.intellij.codeInspection.ex.EntryPointsManagerImpl import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ModalityState +import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.Project import com.intellij.psi.PsiClass @@ -68,9 +68,11 @@ import org.jetbrains.kotlin.idea.search.usagesSearch.getAccessorNames import org.jetbrains.kotlin.idea.search.usagesSearch.getClassNameForCompanionObject import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope import org.jetbrains.kotlin.idea.util.ProjectRootsUtil +import org.jetbrains.kotlin.idea.util.application.isUnitTestMode import org.jetbrains.kotlin.idea.util.hasActualsFor import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* @@ -90,6 +92,10 @@ import javax.swing.JPanel class UnusedSymbolInspection : AbstractKotlinInspection() { companion object { + private val log = Logger.getInstance( + UnusedSymbolInspection::class.java + ) + private val javaInspection = UnusedDeclarationInspection() private val KOTLIN_ADDITIONAL_ANNOTATIONS = listOf("kotlin.test.*") @@ -149,7 +155,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() { val useScope = psiSearchHelper.getUseScope(declaration) if (useScope is GlobalSearchScope) { var zeroOccurrences = true - for (name in listOf(declaration.name) + declaration.getAccessorNames() + listOfNotNull(declaration.getClassNameForCompanionObject())) { + for (name in listOf(declaration.name) + declarationAccessorNames(declaration) + listOfNotNull(declaration.getClassNameForCompanionObject())) { if (name == null) continue when (psiSearchHelper.isCheapEnoughToSearchConsideringOperators(name, useScope, null, null)) { ZERO_OCCURRENCES -> { @@ -164,6 +170,54 @@ class UnusedSymbolInspection : AbstractKotlinInspection() { return FEW_OCCURRENCES } + fun declarationAccessorNames(declaration: KtNamedDeclaration): List { + val accessors = + when (declaration) { + is KtProperty -> listOfPropertyAccessorNames(declaration) + is KtParameter -> listOfParameterAccessorNames(declaration) + else -> emptyList() + } + if (log.isDebugEnabled && !isUnitTestMode()) { + val resolverAccessors = declaration.getAccessorNames() + if (accessors != resolverAccessors) + log.error( + "Accessor names for declaration ${declaration.text} differs: " + + "$accessors vs $resolverAccessors in ${declaration.containingFile.name}" + ) + } + return accessors + } + + fun listOfParameterAccessorNames(parameter: KtParameter): List { + val accessors = mutableListOf() + if (parameter.hasValOrVar()) { + parameter.name?.let { + accessors.add(JvmAbi.getterName(it)) + if (parameter.isVarArg) + accessors.add(JvmAbi.setterName(it)) + } + } + return accessors + } + + fun listOfPropertyAccessorNames(property: KtProperty): List { + val accessors = mutableListOf() + val propertyName = property.name ?: return accessors + accessors.add(property.getter?.let { getCustomAccessorName(it) } ?: JvmAbi.getterName(propertyName)) + if (property.isVar) + accessors.add(property.setter?.let { getCustomAccessorName(it) } ?: JvmAbi.setterName(propertyName)) + return accessors + } + + /* + If the property has 'JvmName' annotation at accessor it should be used instead + */ + private fun getCustomAccessorName(method: KtPropertyAccessor?): String? { + val customJvmNameAnnotation = + method?.annotationEntries?.firstOrNull { it.shortName?.asString() == "JvmName" } ?: return null + return customJvmNameAnnotation.findDescendantOfType()?.text + } + private fun KtProperty.isSerializationImplicitlyUsedField(): Boolean { val ownerObject = getNonStrictParentOfType() if (ownerObject is KtObjectDeclaration && ownerObject.isCompanion()) {