diff --git a/ChangeLog.md b/ChangeLog.md index eb50655b63a..56a4db7deb0 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -114,6 +114,7 @@ These artifacts include extensions for the types available in the latter JDKs, s - [`KT-11483`](https://youtrack.jetbrains.com/issue/KT-11483) Move to Companion: Do not use qualified names as labels - [`KT-13874`](https://youtrack.jetbrains.com/issue/KT-13874) Move to Companion: Fix AssertionError on running refactoring from Conflicts View - [`KT-13883`](https://youtrack.jetbrains.com/issue/KT-13883) Move to Companion Object: Fix exception when applied to class +- [`KT-13876`](https://youtrack.jetbrains.com/issue/KT-13876) Move to Companion Object: Forbid for functions/properties referencing type parameters of the containing class ##### New features diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt index e9267d0efe3..767bac886ec 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt @@ -36,12 +36,10 @@ import com.intellij.util.containers.MultiMap import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor -import org.jetbrains.kotlin.idea.core.CollectingNameValidator -import org.jetbrains.kotlin.idea.core.KotlinNameSuggester -import org.jetbrains.kotlin.idea.core.getOrCreateCompanionObject -import org.jetbrains.kotlin.idea.core.replaced +import org.jetbrains.kotlin.idea.core.* import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively import org.jetbrains.kotlin.idea.refactoring.move.OuterInstanceReferenceUsageInfo import org.jetbrains.kotlin.idea.refactoring.move.collectOuterInstanceReferences @@ -53,7 +51,6 @@ import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest import org.jetbrains.kotlin.idea.search.declarationsSearch.searchOverriders import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers -import org.jetbrains.kotlin.idea.core.ShortenReferences import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -62,6 +59,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* +import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver @@ -237,6 +235,14 @@ class MoveMemberToCompanionObjectIntention : SelfTargetingRangeIntention { + val referencedDescriptor = it.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, it]?.constructor?.declarationDescriptor + referencedDescriptor is TypeParameterDescriptor && referencedDescriptor.containingDeclaration == containingClassDescriptor + }.isNotEmpty() + } + override fun startInWriteAction() = false override fun applyTo(element: KtNamedDeclaration, editor: Editor?) { @@ -259,10 +265,14 @@ class MoveMemberToCompanionObjectIntention : SelfTargetingRangeIntention() diff --git a/idea/testData/intentions/moveToCompanion/genericFunction.kt b/idea/testData/intentions/moveToCompanion/genericFunction.kt new file mode 100644 index 00000000000..5786d4df39e --- /dev/null +++ b/idea/testData/intentions/moveToCompanion/genericFunction.kt @@ -0,0 +1,4 @@ +// SHOULD_FAIL_WITH: Function genericFunT() references type parameters of the containing class +class Test6(val t: T) { + fun genericFunT(): T = t +} \ No newline at end of file diff --git a/idea/testData/intentions/moveToCompanion/genericProperty.kt b/idea/testData/intentions/moveToCompanion/genericProperty.kt new file mode 100644 index 00000000000..f13f768e7ea --- /dev/null +++ b/idea/testData/intentions/moveToCompanion/genericProperty.kt @@ -0,0 +1,4 @@ +// SHOULD_FAIL_WITH: Property genericValT references type parameters of the containing class +class Test6(val t: T) { + val genericValT: T get() = t +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 24d11735a68..20d30a0543f 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -9067,6 +9067,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("genericFunction.kt") + public void testGenericFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/moveToCompanion/genericFunction.kt"); + doTest(fileName); + } + + @TestMetadata("genericProperty.kt") + public void testGenericProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/moveToCompanion/genericProperty.kt"); + doTest(fileName); + } + @TestMetadata("implicitDispatchReceiver.kt") public void testImplicitDispatchReceiver() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/moveToCompanion/implicitDispatchReceiver.kt");