From 17869abfafe55becd5ed30f2b562038967d9ad3f Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 18 May 2017 19:52:07 +0300 Subject: [PATCH] Don't suggest making interface member final (which was possible in leaking this inspection) So #KT-14443 Fixed --- .../idea/inspections/LeakingThisInspection.kt | 2 ++ .../inspectionsLocal/leakingThis/.inspection | 1 + .../leakingThis/noOpenForInterface.kt | 14 ++++++++++++++ .../leakingThis/noOpenForInterface.kt.after | 14 ++++++++++++++ .../inspections/LocalInspectionTestGenerated.java | 15 +++++++++++++++ 5 files changed, 46 insertions(+) create mode 100644 idea/testData/inspectionsLocal/leakingThis/.inspection create mode 100644 idea/testData/inspectionsLocal/leakingThis/noOpenForInterface.kt create mode 100644 idea/testData/inspectionsLocal/leakingThis/noOpenForInterface.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/LeakingThisInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/LeakingThisInspection.kt index e3db313e724..4c361a4a228 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/LeakingThisInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/LeakingThisInspection.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully import org.jetbrains.kotlin.idea.quickfix.AddModifierFix import org.jetbrains.kotlin.lexer.KtTokens 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.DescriptorToSourceUtils @@ -88,6 +89,7 @@ class LeakingThisInspection : AbstractKotlinInspection() { declaration ?: return null val useScope = declaration.useScope 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) } } diff --git a/idea/testData/inspectionsLocal/leakingThis/.inspection b/idea/testData/inspectionsLocal/leakingThis/.inspection new file mode 100644 index 00000000000..e43b9d522f2 --- /dev/null +++ b/idea/testData/inspectionsLocal/leakingThis/.inspection @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.inspections.LeakingThisInspection diff --git a/idea/testData/inspectionsLocal/leakingThis/noOpenForInterface.kt b/idea/testData/inspectionsLocal/leakingThis/noOpenForInterface.kt new file mode 100644 index 00000000000..c2a8602a673 --- /dev/null +++ b/idea/testData/inspectionsLocal/leakingThis/noOpenForInterface.kt @@ -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 + foo() + } +} diff --git a/idea/testData/inspectionsLocal/leakingThis/noOpenForInterface.kt.after b/idea/testData/inspectionsLocal/leakingThis/noOpenForInterface.kt.after new file mode 100644 index 00000000000..e32b1132cbd --- /dev/null +++ b/idea/testData/inspectionsLocal/leakingThis/noOpenForInterface.kt.after @@ -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 + foo() + } +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index a346f1504c1..911dfc468dd 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -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") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)