Redundant companion reference: simplify name conflict checking code
Before this commit, function with same name but different signature wasn't counted as name conflict, now it is - just because that exact check in this place could be too complex and error-prone Enhancement for KT-27539
This commit is contained in:
+17
-30
@@ -47,25 +47,15 @@ class RedundantCompanionReferenceInspection : AbstractKotlinInspection() {
|
|||||||
when (selectorDescriptor) {
|
when (selectorDescriptor) {
|
||||||
is PropertyDescriptor -> {
|
is PropertyDescriptor -> {
|
||||||
val name = selectorDescriptor.name
|
val name = selectorDescriptor.name
|
||||||
if (containingClassDescriptor.findMemberVariable(name.asString()) != null) return
|
if (containingClassDescriptor.findMemberVariable(name) != null) return
|
||||||
val variable = expression.getResolutionScope().findVariable(name, NoLookupLocation.FROM_IDE)
|
val variable = expression.getResolutionScope().findVariable(name, NoLookupLocation.FROM_IDE)
|
||||||
if (variable != null && variable.isLocalOrExtension(containingClassDescriptor)) return
|
if (variable != null && variable.isLocalOrExtension(containingClassDescriptor)) return
|
||||||
}
|
}
|
||||||
is FunctionDescriptor -> {
|
is FunctionDescriptor -> {
|
||||||
val name = selectorDescriptor.name
|
val name = selectorDescriptor.name
|
||||||
val functions = containingClassDescriptor.collectMemberFunction(name.asString()) + listOfNotNull(
|
if (containingClassDescriptor.findMemberFunction(name) != null) return
|
||||||
expression.getResolutionScope().findFunction(name, NoLookupLocation.FROM_IDE)?.takeIf {
|
val function = expression.getResolutionScope().findFunction(name, NoLookupLocation.FROM_IDE)
|
||||||
it.isLocalOrExtension(containingClassDescriptor)
|
if (function != null && function.isLocalOrExtension(containingClassDescriptor)) return
|
||||||
}
|
|
||||||
)
|
|
||||||
if (functions.any {
|
|
||||||
val functionParams = it.valueParameters
|
|
||||||
val calleeParams = (selectorExpression as? KtCallExpression)?.calleeExpression?.getCallableDescriptor()
|
|
||||||
?.valueParameters.orEmpty()
|
|
||||||
functionParams.size == calleeParams.size && functionParams.zip(calleeParams).all { param ->
|
|
||||||
param.first.type == param.second.type
|
|
||||||
}
|
|
||||||
}) return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,30 +75,27 @@ class RedundantCompanionReferenceInspection : AbstractKotlinInspection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ClassDescriptor.findMemberVariable(name: String): PropertyDescriptor? {
|
private fun <D : MemberDescriptor> ClassDescriptor.findMemberByName(name: Name, find: ClassDescriptor.(Name) -> D?): D? {
|
||||||
val variable = unsubstitutedMemberScope.getContributedVariables(Name.identifier(name), NoLookupLocation.FROM_IDE).firstOrNull()
|
val member = find(name)
|
||||||
if (variable != null) return variable
|
if (member != null) return member
|
||||||
|
|
||||||
val variableInSuperClass = getSuperClassNotAny()?.findMemberVariable(name)
|
val memberInSuperClass = getSuperClassNotAny()?.findMemberByName(name, find)
|
||||||
if (variableInSuperClass != null) return variableInSuperClass
|
if (memberInSuperClass != null) return memberInSuperClass
|
||||||
|
|
||||||
getSuperInterfaces().forEach {
|
getSuperInterfaces().forEach {
|
||||||
val variableInInterface = it.findMemberVariable(name)
|
val memberInInterface = it.findMemberByName(name, find)
|
||||||
if (variableInInterface != null) return variableInInterface
|
if (memberInInterface != null) return memberInInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ClassDescriptor.collectMemberFunction(name: String): MutableList<FunctionDescriptor> {
|
private fun ClassDescriptor.findMemberVariable(name: Name): PropertyDescriptor? = findMemberByName(name) {
|
||||||
val functions = mutableListOf<FunctionDescriptor>()
|
unsubstitutedMemberScope.getContributedVariables(it, NoLookupLocation.FROM_IDE).firstOrNull()
|
||||||
fun collect(descriptor: ClassDescriptor) {
|
}
|
||||||
functions.addAll(descriptor.unsubstitutedMemberScope.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_IDE))
|
|
||||||
descriptor.getSuperClassNotAny()?.let { collect(it) }
|
private fun ClassDescriptor.findMemberFunction(name: Name): FunctionDescriptor? = findMemberByName(name) {
|
||||||
descriptor.getSuperInterfaces().forEach { collect(it) }
|
unsubstitutedMemberScope.getContributedFunctions(it, NoLookupLocation.FROM_IDE).firstOrNull()
|
||||||
}
|
|
||||||
collect(this)
|
|
||||||
return functions
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CallableDescriptor.isLocalOrExtension(extensionClassDescriptor: ClassDescriptor): Boolean {
|
private fun CallableDescriptor.isLocalOrExtension(extensionClassDescriptor: ClassDescriptor): Boolean {
|
||||||
|
|||||||
Vendored
+2
@@ -1,3 +1,5 @@
|
|||||||
|
// PROBLEM: none
|
||||||
|
|
||||||
class Test {
|
class Test {
|
||||||
companion object {
|
companion object {
|
||||||
fun f(x: Int, y: Int) = 1
|
fun f(x: Int, y: Int) = 1
|
||||||
|
|||||||
Vendored
-11
@@ -1,11 +0,0 @@
|
|||||||
class Test {
|
|
||||||
companion object {
|
|
||||||
fun f(x: Int, y: Int) = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
fun f(x: Int, y: String) = 2
|
|
||||||
|
|
||||||
fun test() {
|
|
||||||
f(1, 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user