Redundant companion reference: minor refactoring

This commit is contained in:
Mikhail Glukhikh
2018-06-19 11:30:07 +03:00
parent 5ad98a139d
commit b87dd07dd1
2 changed files with 11 additions and 9 deletions
@@ -480,6 +480,10 @@ fun KtClassOrObject.findPropertyByName(name: String): KtNamedDeclaration? {
?: primaryConstructorParameters.firstOrNull { it.hasValOrVar() && it.name == name } ?: primaryConstructorParameters.firstOrNull { it.hasValOrVar() && it.name == name }
} }
fun KtClassOrObject.findFunctionByName(name: String): KtNamedDeclaration? {
return declarations.firstOrNull { it is KtNamedFunction && it.name == name } as KtNamedDeclaration?
}
fun isTypeConstructorReference(e: PsiElement): Boolean { fun isTypeConstructorReference(e: PsiElement): Boolean {
val parent = e.parent val parent = e.parent
return parent is KtUserType && parent.referenceExpression == e return parent is KtUserType && parent.referenceExpression == e
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClass import org.jetbrains.kotlin.psi.psiUtil.containingClass
import org.jetbrains.kotlin.psi.psiUtil.findFunctionByName
import org.jetbrains.kotlin.psi.psiUtil.findPropertyByName import org.jetbrains.kotlin.psi.psiUtil.findPropertyByName
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
@@ -39,19 +40,20 @@ class RedundantCompanionReferenceInspection : AbstractKotlinInspection() {
if (expression.text != objectDeclaration.name) return if (expression.text != objectDeclaration.name) return
val containingClass = objectDeclaration.containingClass() ?: return val containingClass = objectDeclaration.containingClass() ?: return
val containingClassDescriptor = containingClass.descriptor as? ClassDescriptor ?: return
val selectorDescriptor = selectorExpression?.getCallableDescriptor() val selectorDescriptor = selectorExpression?.getCallableDescriptor()
when (selectorDescriptor) { when (selectorDescriptor) {
is PropertyDescriptor -> { is PropertyDescriptor -> {
val name = selectorDescriptor.name val name = selectorDescriptor.name
if (containingClass.findPropertyByName(name.asString()) != null) return if (containingClass.findPropertyByName(name.asString()) != null) return
val variable = expression.getResolutionScope().findVariable(name, NoLookupLocation.FROM_IDE) val variable = expression.getResolutionScope().findVariable(name, NoLookupLocation.FROM_IDE)
if (variable.isLocalOrExtension(containingClass)) return if (variable != null && variable.isLocalOrExtension(containingClassDescriptor)) return
} }
is FunctionDescriptor -> { is FunctionDescriptor -> {
val name = selectorDescriptor.name val name = selectorDescriptor.name
val function = containingClass.findFunctionByName(name.asString())?.descriptor val function = containingClass.findFunctionByName(name.asString())?.descriptor
?: expression.getResolutionScope().findFunction(name, NoLookupLocation.FROM_IDE)?.takeIf { ?: expression.getResolutionScope().findFunction(name, NoLookupLocation.FROM_IDE)?.takeIf {
it.isLocalOrExtension(containingClass) it.isLocalOrExtension(containingClassDescriptor)
} }
if (function is FunctionDescriptor) { if (function is FunctionDescriptor) {
val functionParams = function.valueParameters val functionParams = function.valueParameters
@@ -80,13 +82,9 @@ class RedundantCompanionReferenceInspection : AbstractKotlinInspection() {
} }
} }
private fun KtClass.findFunctionByName(name: String): KtDeclaration? { private fun CallableDescriptor.isLocalOrExtension(extensionClassDescriptor: ClassDescriptor): Boolean {
return declarations.firstOrNull { it is KtNamedFunction && it.name == name } return visibility == Visibilities.LOCAL ||
} extensionReceiverParameter?.type?.constructor?.declarationDescriptor == extensionClassDescriptor
private fun CallableDescriptor?.isLocalOrExtension(extensionClass: KtClass): Boolean {
return this?.visibility == Visibilities.LOCAL
|| this?.extensionReceiverParameter?.type?.constructor?.declarationDescriptor == extensionClass.descriptor
} }
private class RemoveRedundantCompanionReferenceFix : LocalQuickFix { private class RemoveRedundantCompanionReferenceFix : LocalQuickFix {