Don't suggest making interface member final
(which was possible in leaking this inspection) So #KT-14443 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
a73cf0e1fe
commit
17869abfaf
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
|
|||||||
import org.jetbrains.kotlin.idea.quickfix.AddModifierFix
|
import org.jetbrains.kotlin.idea.quickfix.AddModifierFix
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext.LEAKING_THIS
|
import org.jetbrains.kotlin.resolve.BindingContext.LEAKING_THIS
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
|
|
||||||
@@ -88,6 +89,7 @@ class LeakingThisInspection : AbstractKotlinInspection() {
|
|||||||
declaration ?: return null
|
declaration ?: return null
|
||||||
val useScope = declaration.useScope
|
val useScope = declaration.useScope
|
||||||
if (DefinitionsScopedSearch.search(declaration, useScope).findFirst() != null) return null
|
if (DefinitionsScopedSearch.search(declaration, useScope).findFirst() != null) return null
|
||||||
|
if ((declaration.containingClassOrObject as? KtClass)?.isInterface() ?: false) return null
|
||||||
return IntentionWrapper(AddModifierFix(declaration, KtTokens.FINAL_KEYWORD), declaration.containingFile)
|
return IntentionWrapper(AddModifierFix(declaration, KtTokens.FINAL_KEYWORD), declaration.containingFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
org.jetbrains.kotlin.idea.inspections.LeakingThisInspection
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// PROBLEM: Calling non-final function foo in constructor
|
||||||
|
|
||||||
|
interface My {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class Your : My {
|
||||||
|
|
||||||
|
init {
|
||||||
|
// exactly one fix action should be here (make 'Your' final)
|
||||||
|
// making 'foo' final will provoke an error
|
||||||
|
<caret>foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// PROBLEM: Calling non-final function foo in constructor
|
||||||
|
|
||||||
|
interface My {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Your : My {
|
||||||
|
|
||||||
|
init {
|
||||||
|
// exactly one fix action should be here (make 'Your' final)
|
||||||
|
// making 'foo' final will provoke an error
|
||||||
|
<caret>foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -63,6 +63,21 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/inspectionsLocal/leakingThis")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class LeakingThis extends AbstractLocalInspectionTest {
|
||||||
|
public void testAllFilesPresentInLeakingThis() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/leakingThis"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("noOpenForInterface.kt")
|
||||||
|
public void testNoOpenForInterface() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/leakingThis/noOpenForInterface.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/inspectionsLocal/moveSuspiciousCallableReferenceIntoParentheses")
|
@TestMetadata("idea/testData/inspectionsLocal/moveSuspiciousCallableReferenceIntoParentheses")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user