From e4dd30599ec88525d19b80650e345b5f866c65c8 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 17 Aug 2015 22:18:19 +0300 Subject: [PATCH] Extraction Engine: Forbid extraction of non-singleton qualifiers #KT-8297 Fixed --- .../idea/codeInsight/CodeInsightUtils.java | 19 ++++++++++++++- .../extractFunction/basic/classQualifier.kt | 11 +++++++++ .../basic/classQualifier.kt.conflicts | 1 + .../extractFunction/basic/enumQualifier.kt | 7 ++++++ .../basic/enumQualifier.kt.conflicts | 1 + .../extractFunction/basic/objectQualifier.kt | 9 +++++++ .../basic/objectQualifier.kt.after | 11 +++++++++ .../extractFunction/basic/packageQualifier.kt | 9 +++++++ .../basic/packageQualifier.kt.conflicts | 1 + .../introduce/JetExtractionTestGenerated.java | 24 +++++++++++++++++++ 10 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 idea/testData/refactoring/extractFunction/basic/classQualifier.kt create mode 100644 idea/testData/refactoring/extractFunction/basic/classQualifier.kt.conflicts create mode 100644 idea/testData/refactoring/extractFunction/basic/enumQualifier.kt create mode 100644 idea/testData/refactoring/extractFunction/basic/enumQualifier.kt.conflicts create mode 100644 idea/testData/refactoring/extractFunction/basic/objectQualifier.kt create mode 100644 idea/testData/refactoring/extractFunction/basic/objectQualifier.kt.after create mode 100644 idea/testData/refactoring/extractFunction/basic/packageQualifier.kt create mode 100644 idea/testData/refactoring/extractFunction/basic/packageQualifier.kt.conflicts diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/CodeInsightUtils.java b/idea/src/org/jetbrains/kotlin/idea/codeInsight/CodeInsightUtils.java index 8e8f0d3ff94..de475df782a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/CodeInsightUtils.java +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/CodeInsightUtils.java @@ -27,8 +27,14 @@ import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.descriptors.ClassDescriptor; +import org.jetbrains.kotlin.descriptors.ClassKind; +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor; +import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage; import org.jetbrains.kotlin.lexer.JetTokens; import org.jetbrains.kotlin.psi.*; +import org.jetbrains.kotlin.resolve.BindingContext; +import org.jetbrains.kotlin.resolve.scopes.receivers.Qualifier; import org.jetbrains.kotlin.types.JetType; import java.util.ArrayList; @@ -65,7 +71,18 @@ public class CodeInsightUtils { } } } - return (JetExpression) element; + + JetExpression expression = (JetExpression) element; + + BindingContext context = ResolvePackage.analyze(expression); + + Qualifier qualifier = context.get(BindingContext.QUALIFIER, expression); + if (qualifier != null) { + ClassifierDescriptor classifier = qualifier.getClassifier(); + if (!(classifier instanceof ClassDescriptor) || ((ClassDescriptor) classifier).getKind() != ClassKind.OBJECT) return null; + } + + return expression; } @NotNull diff --git a/idea/testData/refactoring/extractFunction/basic/classQualifier.kt b/idea/testData/refactoring/extractFunction/basic/classQualifier.kt new file mode 100644 index 00000000000..10b9f850cb6 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/classQualifier.kt @@ -0,0 +1,11 @@ +class A { + companion object { + fun foo() { + + } + } +} + +fun bar() { + A.foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/classQualifier.kt.conflicts b/idea/testData/refactoring/extractFunction/basic/classQualifier.kt.conflicts new file mode 100644 index 00000000000..072400d731d --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/classQualifier.kt.conflicts @@ -0,0 +1 @@ +Cannot perform refactoring without an expression diff --git a/idea/testData/refactoring/extractFunction/basic/enumQualifier.kt b/idea/testData/refactoring/extractFunction/basic/enumQualifier.kt new file mode 100644 index 00000000000..e44d9e22d1c --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/enumQualifier.kt @@ -0,0 +1,7 @@ +enum class E { + A, B, C +} + +fun bar() { + val t = E.A +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/enumQualifier.kt.conflicts b/idea/testData/refactoring/extractFunction/basic/enumQualifier.kt.conflicts new file mode 100644 index 00000000000..072400d731d --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/enumQualifier.kt.conflicts @@ -0,0 +1 @@ +Cannot perform refactoring without an expression diff --git a/idea/testData/refactoring/extractFunction/basic/objectQualifier.kt b/idea/testData/refactoring/extractFunction/basic/objectQualifier.kt new file mode 100644 index 00000000000..7cb42b9d939 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/objectQualifier.kt @@ -0,0 +1,9 @@ +object A { + fun foo() { + + } +} + +fun bar() { + A.foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/objectQualifier.kt.after b/idea/testData/refactoring/extractFunction/basic/objectQualifier.kt.after new file mode 100644 index 00000000000..ec21b78fbb1 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/objectQualifier.kt.after @@ -0,0 +1,11 @@ +object A { + fun foo() { + + } +} + +fun bar() { + a().foo() +} + +private fun a() = A \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/packageQualifier.kt b/idea/testData/refactoring/extractFunction/basic/packageQualifier.kt new file mode 100644 index 00000000000..d2fdc3e89b6 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/packageQualifier.kt @@ -0,0 +1,9 @@ +package p + +fun foo() { + +} + +fun bar() { + p.foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/packageQualifier.kt.conflicts b/idea/testData/refactoring/extractFunction/basic/packageQualifier.kt.conflicts new file mode 100644 index 00000000000..072400d731d --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/packageQualifier.kt.conflicts @@ -0,0 +1 @@ +Cannot perform refactoring without an expression diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java index f5bc57fc919..4ffc948e35e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java @@ -456,6 +456,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("classQualifier.kt") + public void testClassQualifier() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/classQualifier.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("convertBinaryExpression.kt") public void testConvertBinaryExpression() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/convertBinaryExpression.kt"); @@ -480,6 +486,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("enumQualifier.kt") + public void testEnumQualifier() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/enumQualifier.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("extensionFunForArray.kt") public void testExtensionFunForArray() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/extensionFunForArray.kt"); @@ -630,6 +642,18 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("objectQualifier.kt") + public void testObjectQualifier() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/objectQualifier.kt"); + doExtractFunctionTest(fileName); + } + + @TestMetadata("packageQualifier.kt") + public void testPackageQualifier() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/packageQualifier.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("privateMemberInClassObject.kt") public void testPrivateMemberInClassObject() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/privateMemberInClassObject.kt");