Reformat: unused symbol inspection

This commit is contained in:
Mikhail Glukhikh
2018-04-27 18:16:44 +03:00
parent 78ed39856e
commit 59c019cb00
@@ -84,8 +84,8 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
val descriptor = declaration.descriptor ?: return false val descriptor = declaration.descriptor ?: return false
val entryPointsManager = EntryPointsManager.getInstance(declaration.project) as EntryPointsManagerBase val entryPointsManager = EntryPointsManager.getInstance(declaration.project) as EntryPointsManagerBase
return checkAnnotatedUsingPatterns( return checkAnnotatedUsingPatterns(
descriptor, descriptor,
entryPointsManager.additionalAnnotations + entryPointsManager.ADDITIONAL_ANNOTATIONS entryPointsManager.additionalAnnotations + entryPointsManager.ADDITIONAL_ANNOTATIONS
) )
} }
else -> return false else -> return false
@@ -103,7 +103,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
} }
private fun KtNamedFunction.isSerializationImplicitlyUsedMethod(): Boolean = private fun KtNamedFunction.isSerializationImplicitlyUsedMethod(): Boolean =
toLightMethods().any { JavaHighlightUtil.isSerializationRelatedMethod(it, it.containingClass) } toLightMethods().any { JavaHighlightUtil.isSerializationRelatedMethod(it, it.containingClass) }
// variation of IDEA's AnnotationUtil.checkAnnotatedUsingPatterns() // variation of IDEA's AnnotationUtil.checkAnnotatedUsingPatterns()
fun checkAnnotatedUsingPatterns(annotated: Annotated, annotationPatterns: Collection<String>): Boolean { fun checkAnnotatedUsingPatterns(annotated: Annotated, annotationPatterns: Collection<String>): Boolean {
@@ -113,8 +113,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
for (pattern in annotationPatterns) { for (pattern in annotationPatterns) {
val hasAnnotation = if (pattern.endsWith(".*")) { val hasAnnotation = if (pattern.endsWith(".*")) {
annotationsPresent.any { it.startsWith(pattern.dropLast(1)) } annotationsPresent.any { it.startsWith(pattern.dropLast(1)) }
} } else {
else {
pattern in annotationsPresent pattern in annotationsPresent
} }
if (hasAnnotation) return true if (hasAnnotation) return true
@@ -155,12 +154,12 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
val psiElement = declaration.nameIdentifier ?: (declaration as? KtConstructor<*>)?.getConstructorKeyword() ?: return val psiElement = declaration.nameIdentifier ?: (declaration as? KtConstructor<*>)?.getConstructorKeyword() ?: return
val problemDescriptor = holder.manager.createProblemDescriptor( val problemDescriptor = holder.manager.createProblemDescriptor(
psiElement, psiElement,
null, null,
message, message,
ProblemHighlightType.LIKE_UNUSED_SYMBOL, ProblemHighlightType.LIKE_UNUSED_SYMBOL,
true, true,
*createQuickFixes(declaration).toTypedArray() *createQuickFixes(declaration).toTypedArray()
) )
holder.registerProblem(problemDescriptor) holder.registerProblem(problemDescriptor)
@@ -176,9 +175,9 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
if (classOrObject.useScope is GlobalSearchScope) { if (classOrObject.useScope is GlobalSearchScope) {
val findClassUsagesHandler = KotlinFindClassUsagesHandler(classOrObject, KotlinFindUsagesHandlerFactory(classOrObject.project)) val findClassUsagesHandler = KotlinFindClassUsagesHandler(classOrObject, KotlinFindUsagesHandlerFactory(classOrObject.project))
findClassUsagesHandler.processUsagesInText( findClassUsagesHandler.processUsagesInText(
classOrObject, classOrObject,
{ hasTextUsages = true; false }, { hasTextUsages = true; false },
GlobalSearchScope.projectScope(classOrObject.project) GlobalSearchScope.projectScope(classOrObject.project)
) )
} }
@@ -195,7 +194,8 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
for (name in listOf(declaration.name) + declaration.getAccessorNames() + listOfNotNull(declaration.getClassNameForCompanionObject())) { for (name in listOf(declaration.name) + declaration.getAccessorNames() + listOfNotNull(declaration.getClassNameForCompanionObject())) {
if (name == null) continue if (name == null) continue
when (psiSearchHelper.isCheapEnoughToSearchConsideringOperators(name, useScope, null, null)) { when (psiSearchHelper.isCheapEnoughToSearchConsideringOperators(name, useScope, null, null)) {
ZERO_OCCURRENCES -> {} // go on, check other names ZERO_OCCURRENCES -> {
} // go on, check other names
FEW_OCCURRENCES -> zeroOccurrences = false FEW_OCCURRENCES -> zeroOccurrences = false
TOO_MANY_OCCURRENCES -> return true // searching usages is too expensive; behave like it is used TOO_MANY_OCCURRENCES -> return true // searching usages is too expensive; behave like it is used
} }
@@ -204,28 +204,26 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
if (zeroOccurrences) { if (zeroOccurrences) {
if (declaration is KtObjectDeclaration && declaration.isCompanion()) { if (declaration is KtObjectDeclaration && declaration.isCompanion()) {
// go on: companion object can be used only in containing class // go on: companion object can be used only in containing class
} } else {
else {
return false return false
} }
} }
KotlinSourceFilterScope.projectSources(useScope, declaration.project) KotlinSourceFilterScope.projectSources(useScope, declaration.project)
} } else useScope
else useScope
return (declaration is KtObjectDeclaration && declaration.isCompanion() && return (declaration is KtObjectDeclaration && declaration.isCompanion() &&
declaration.getBody()?.declarations?.isNotEmpty() == true) || declaration.getBody()?.declarations?.isNotEmpty() == true) ||
hasReferences(declaration, descriptor, restrictedScope) || hasReferences(declaration, descriptor, restrictedScope) ||
hasOverrides(declaration, restrictedScope) || hasOverrides(declaration, restrictedScope) ||
hasFakeOverrides(declaration, restrictedScope) || hasFakeOverrides(declaration, restrictedScope) ||
isPlatformImplementation(declaration) || isPlatformImplementation(declaration) ||
hasPlatformImplementations(declaration, descriptor) hasPlatformImplementations(declaration, descriptor)
} }
private fun hasReferences( private fun hasReferences(
declaration: KtNamedDeclaration, declaration: KtNamedDeclaration,
descriptor: DeclarationDescriptor?, descriptor: DeclarationDescriptor?,
useScope: SearchScope useScope: SearchScope
): Boolean { ): Boolean {
fun checkReference(ref: PsiReference): Boolean { fun checkReference(ref: PsiReference): Boolean {
@@ -242,17 +240,17 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
if (declaration is KtClassOrObject) { if (declaration is KtClassOrObject) {
if (import.isAllUnder) { if (import.isAllUnder) {
val importedFrom = import.importedReference?.getQualifiedElementSelector()?.mainReference?.resolve() val importedFrom = import.importedReference?.getQualifiedElementSelector()?.mainReference?.resolve()
as? KtClassOrObject ?: return true as? KtClassOrObject ?: return true
return importedFrom.declarations.none { it is KtNamedDeclaration && hasNonTrivialUsages(it) } return importedFrom.declarations.none { it is KtNamedDeclaration && hasNonTrivialUsages(it) }
} } else {
else {
if (import.importedFqName != declaration.fqName) { if (import.importedFqName != declaration.fqName) {
val importedDeclaration = val importedDeclaration =
import.importedReference?.getQualifiedElementSelector()?.mainReference?.resolve() as? KtNamedDeclaration import.importedReference?.getQualifiedElementSelector()?.mainReference?.resolve() as? KtNamedDeclaration
?: return true ?: return true
if (declaration is KtObjectDeclaration || if (declaration is KtObjectDeclaration ||
(declaration is KtClass && declaration.isEnum()) || (declaration is KtClass && declaration.isEnum()) ||
importedDeclaration.containingClassOrObject is KtObjectDeclaration) { importedDeclaration.containingClassOrObject is KtObjectDeclaration
) {
return declaration !in importedDeclaration.parentsWithSelf && !hasNonTrivialUsages(importedDeclaration) return declaration !in importedDeclaration.parentsWithSelf && !hasNonTrivialUsages(importedDeclaration)
} }
} }
@@ -267,7 +265,8 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
val referenceUsed: Boolean by lazy { !ReferencesSearch.search(declaration, useScope).forEach(::checkReference) } val referenceUsed: Boolean by lazy { !ReferencesSearch.search(declaration, useScope).forEach(::checkReference) }
if (descriptor is FunctionDescriptor && if (descriptor is FunctionDescriptor &&
DescriptorUtils.getAnnotationByFqName(descriptor.annotations, JvmFileClassUtil.JVM_NAME) != null) { DescriptorUtils.getAnnotationByFqName(descriptor.annotations, JvmFileClassUtil.JVM_NAME) != null
) {
if (referenceUsed) return true if (referenceUsed) return true
} }
@@ -284,7 +283,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
} }
private fun hasOverrides(declaration: KtNamedDeclaration, useScope: SearchScope): Boolean = private fun hasOverrides(declaration: KtNamedDeclaration, useScope: SearchScope): Boolean =
DefinitionsScopedSearch.search(declaration, useScope).findFirst() != null DefinitionsScopedSearch.search(declaration, useScope).findFirst() != null
private fun hasFakeOverrides(declaration: KtNamedDeclaration, useScope: SearchScope): Boolean { private fun hasFakeOverrides(declaration: KtNamedDeclaration, useScope: SearchScope): Boolean {
val ownerClass = declaration.containingClassOrObject as? KtClass ?: return false val ownerClass = declaration.containingClassOrObject as? KtClass ?: return false
@@ -292,24 +291,22 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
val descriptor = declaration.toDescriptor() as? CallableMemberDescriptor ?: return false val descriptor = declaration.toDescriptor() as? CallableMemberDescriptor ?: return false
if (descriptor.modality == Modality.ABSTRACT) return false if (descriptor.modality == Modality.ABSTRACT) return false
val lightMethods = declaration.toLightMethods() val lightMethods = declaration.toLightMethods()
return DefinitionsScopedSearch.search(ownerClass, useScope).any { return DefinitionsScopedSearch.search(ownerClass, useScope).any { element: PsiElement ->
element: PsiElement ->
when (element) { when (element) {
is KtLightClass -> { is KtLightClass -> {
val memberBySignature = val memberBySignature =
(element.kotlinOrigin?.toDescriptor() as? ClassDescriptor)?.findCallableMemberBySignature(descriptor) (element.kotlinOrigin?.toDescriptor() as? ClassDescriptor)?.findCallableMemberBySignature(descriptor)
memberBySignature != null && memberBySignature != null &&
!memberBySignature.kind.isReal && !memberBySignature.kind.isReal &&
memberBySignature.overriddenDescriptors.any { it != descriptor } memberBySignature.overriddenDescriptors.any { it != descriptor }
} }
is PsiClass -> is PsiClass ->
lightMethods.any { lightMethods.any { lightMethod ->
lightMethod ->
val sameMethods = element.findMethodsBySignature(lightMethod, true) val sameMethods = element.findMethodsBySignature(lightMethod, true)
sameMethods.all { it.containingClass != element } && sameMethods.all { it.containingClass != element } &&
sameMethods.any { it.containingClass != lightMethod.containingClass } sameMethods.any { it.containingClass != lightMethod.containingClass }
} }
else -> else ->
false false
@@ -318,7 +315,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
} }
private fun isPlatformImplementation(declaration: KtNamedDeclaration) = private fun isPlatformImplementation(declaration: KtNamedDeclaration) =
declaration.hasActualModifier() declaration.hasActualModifier()
private fun hasPlatformImplementations(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor?): Boolean { private fun hasPlatformImplementations(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor?): Boolean {
if (!declaration.hasExpectModifier()) return false if (!declaration.hasExpectModifier()) return false
@@ -327,14 +324,14 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
return commonModuleDescriptor.implementingDescriptors.any { it.hasActualsFor(descriptor) } || return commonModuleDescriptor.implementingDescriptors.any { it.hasActualsFor(descriptor) } ||
commonModuleDescriptor.hasActualsFor(descriptor) commonModuleDescriptor.hasActualsFor(descriptor)
} }
override fun createOptionsPanel(): JComponent? { override fun createOptionsPanel(): JComponent? {
val panel = JPanel(GridBagLayout()) val panel = JPanel(GridBagLayout())
panel.add( panel.add(
EntryPointsManagerImpl.createConfigureAnnotationsButton(), EntryPointsManagerImpl.createConfigureAnnotationsButton(),
GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, Insets(0, 0, 0, 0), 0, 0) GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, Insets(0, 0, 0, 0), 0, 0)
) )
return panel return panel
} }
@@ -353,10 +350,12 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
if (fqName.startsWith("kotlin.") if (fqName.startsWith("kotlin.")
|| fqName.startsWith("java.") || fqName.startsWith("java.")
|| fqName.startsWith("javax.") || fqName.startsWith("javax.")
|| fqName.startsWith("org.jetbrains.") && AnnotationUtil.isJetbrainsAnnotation(StringUtil.getShortName(fqName))) || fqName.startsWith("org.jetbrains.") && AnnotationUtil.isJetbrainsAnnotation(StringUtil.getShortName(fqName))
)
continue continue
val intentionAction = QuickFixFactory.getInstance().createAddToDependencyInjectionAnnotationsFix(declaration.project, fqName, "declarations") val intentionAction =
QuickFixFactory.getInstance().createAddToDependencyInjectionAnnotationsFix(declaration.project, fqName, "declarations")
list.add(IntentionWrapper(intentionAction, declaration.containingFile)) list.add(IntentionWrapper(intentionAction, declaration.containingFile))
} }
@@ -366,8 +365,8 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
class SafeDeleteFix(declaration: KtDeclaration) : LocalQuickFix { class SafeDeleteFix(declaration: KtDeclaration) : LocalQuickFix {
private val name: String = private val name: String =
if (declaration is KtConstructor<*>) "Safe delete constructor" if (declaration is KtConstructor<*>) "Safe delete constructor"
else QuickFixBundle.message("safe.delete.text", declaration.name) else QuickFixBundle.message("safe.delete.text", declaration.name)
override fun getName() = name override fun getName() = name
@@ -380,11 +379,10 @@ class SafeDeleteFix(declaration: KtDeclaration) : LocalQuickFix {
if (!FileModificationService.getInstance().prepareFileForWrite(declaration.containingFile)) return if (!FileModificationService.getInstance().prepareFileForWrite(declaration.containingFile)) return
if (declaration is KtParameter && declaration.parent is KtParameterList && declaration.parent?.parent is KtFunction) { if (declaration is KtParameter && declaration.parent is KtParameterList && declaration.parent?.parent is KtFunction) {
RemoveUnusedFunctionParameterFix(declaration).invoke(project, declaration.findExistingEditor(), declaration.containingKtFile) RemoveUnusedFunctionParameterFix(declaration).invoke(project, declaration.findExistingEditor(), declaration.containingKtFile)
} } else {
else {
ApplicationManager.getApplication().invokeLater( ApplicationManager.getApplication().invokeLater(
{ SafeDeleteHandler.invoke(project, arrayOf(declaration), false) }, { SafeDeleteHandler.invoke(project, arrayOf(declaration), false) },
ModalityState.NON_MODAL ModalityState.NON_MODAL
) )
} }
} }