"Redundant overriding method" inspection: do not report when overriding package private method

#KT-33153 Fixed
This commit is contained in:
Toshiaki Kameyama
2019-09-06 09:31:18 +09:00
committed by Dmitry Gridin
parent 25799447a6
commit 92dcb54207
4 changed files with 24 additions and 7 deletions
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.psiUtil.*
@@ -59,7 +60,9 @@ class KotlinRedundantOverrideInspection : AbstractKotlinInspection(), CleanupLoc
val context = function.analyze() val context = function.analyze()
val functionDescriptor = context[BindingContext.FUNCTION, function] val functionDescriptor = context[BindingContext.FUNCTION, function]
if (function.hasDerivedProperty(functionDescriptor, context)) return if (function.hasDerivedProperty(functionDescriptor, context)) return
if (function.isAmbiguouslyDerived(functionDescriptor, context)) return val overriddenDescriptors = functionDescriptor?.original?.overriddenDescriptors
if (overriddenDescriptors?.any { it is JavaMethodDescriptor && it.visibility == JavaVisibilities.PACKAGE_VISIBILITY } == true) return
if (function.isAmbiguouslyDerived(overriddenDescriptors, context)) return
val descriptor = holder.manager.createProblemDescriptor( val descriptor = holder.manager.createProblemDescriptor(
function, function,
@@ -85,7 +88,7 @@ class KotlinRedundantOverrideInspection : AbstractKotlinInspection(), CleanupLoc
val superCallMethodName = superSelectorExpression.getCallNameExpression()?.text ?: return false val superCallMethodName = superSelectorExpression.getCallNameExpression()?.text ?: return false
return function.name == superCallMethodName return function.name == superCallMethodName
} }
private fun KtNamedFunction.hasDerivedProperty(functionDescriptor: FunctionDescriptor?, context: BindingContext): Boolean { private fun KtNamedFunction.hasDerivedProperty(functionDescriptor: FunctionDescriptor?, context: BindingContext): Boolean {
if (functionDescriptor == null) return false if (functionDescriptor == null) return false
val functionName = nameAsName ?: return false val functionName = nameAsName ?: return false
@@ -95,7 +98,7 @@ class KotlinRedundantOverrideInspection : AbstractKotlinInspection(), CleanupLoc
val valueParameters = valueParameters val valueParameters = valueParameters
val singleValueParameter = valueParameters.singleOrNull() val singleValueParameter = valueParameters.singleOrNull()
if (isSetter && singleValueParameter == null || !isSetter && valueParameters.isNotEmpty()) return false if (isSetter && singleValueParameter == null || !isSetter && valueParameters.isNotEmpty()) return false
val propertyType = val propertyType =
(if (isSetter) context[BindingContext.VALUE_PARAMETER, singleValueParameter]?.type else functionType)?.makeNotNullable() (if (isSetter) context[BindingContext.VALUE_PARAMETER, singleValueParameter]?.type else functionType)?.makeNotNullable()
return SyntheticJavaPropertyDescriptor.propertyNamesByAccessorName(functionName).any { return SyntheticJavaPropertyDescriptor.propertyNamesByAccessorName(functionName).any {
val propertyName = it.asString() val propertyName = it.asString()
@@ -119,10 +122,8 @@ class KotlinRedundantOverrideInspection : AbstractKotlinInspection(), CleanupLoc
} }
} }
private fun KtNamedFunction.isAmbiguouslyDerived(functionDescriptor: FunctionDescriptor?, context: BindingContext): Boolean { private fun KtNamedFunction.isAmbiguouslyDerived(overriddenDescriptors: Collection<FunctionDescriptor>?, context: BindingContext): Boolean {
val original = functionDescriptor?.original if (overriddenDescriptors == null || overriddenDescriptors.size < 2) return false
val overriddenDescriptors = original?.overriddenDescriptors ?: return false
if (overriddenDescriptors.size < 2) return false
// Two+ functions // Two+ functions
// At least one default in interface or abstract in class, or just something from Java // At least one default in interface or abstract in class, or just something from Java
if (overriddenDescriptors.any { overriddenFunction -> if (overriddenDescriptors.any { overriddenFunction ->
@@ -0,0 +1,5 @@
public class Foo {
void foo() {
// nothing
}
}
@@ -0,0 +1,6 @@
// PROBLEM: none
class Bar : Foo() {
<caret>override fun foo() {
super.foo()
}
}
@@ -7255,6 +7255,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
runTest("idea/testData/inspectionsLocal/redundantOverride/getterWithDerivedProperty4.kt"); runTest("idea/testData/inspectionsLocal/redundantOverride/getterWithDerivedProperty4.kt");
} }
@TestMetadata("javaPackagePrivate.kt")
public void testJavaPackagePrivate() throws Exception {
runTest("idea/testData/inspectionsLocal/redundantOverride/javaPackagePrivate.kt");
}
@TestMetadata("notCallSuper.kt") @TestMetadata("notCallSuper.kt")
public void testNotCallSuper() throws Exception { public void testNotCallSuper() throws Exception {
runTest("idea/testData/inspectionsLocal/redundantOverride/notCallSuper.kt"); runTest("idea/testData/inspectionsLocal/redundantOverride/notCallSuper.kt");