diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/JavaResolveExtension.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/JavaResolveExtension.kt index 84819d079e9..b8d960782aa 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/JavaResolveExtension.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/JavaResolveExtension.kt @@ -150,4 +150,4 @@ private fun Collection.findByJavaElemen false } } -} +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt index 214e5e71d51..18879baeec5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt @@ -80,6 +80,7 @@ import org.jetbrains.kotlin.idea.intentions.RemoveCurlyBracesFromTemplateIntenti import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar import org.jetbrains.kotlin.idea.refactoring.changeSignature.toValVar +import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.idea.util.string.collapseSpaces @@ -714,7 +715,12 @@ fun FqNameUnsafe.hasIdentifiersOnly(): Boolean = pathSegments().all { KotlinName fun FqName.hasIdentifiersOnly(): Boolean = pathSegments().all { KotlinNameSuggester.isIdentifier(it.asString().quoteIfNeeded()) } -fun PsiNamedElement.isInterfaceClass(): Boolean = this is KtClass && isInterface() || this is PsiClass && isInterface +fun PsiNamedElement.isInterfaceClass(): Boolean = when (this) { + is KtClass -> isInterface() + is PsiClass -> isInterface + is KtPsiClassWrapper -> psiClass.isInterface + else -> false +} fun replaceListPsiAndKeepDelimiters( originalList: ListType, diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/KotlinMemberInfo.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/KotlinMemberInfo.kt index 53632df3fd8..992b84bf057 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/KotlinMemberInfo.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/KotlinMemberInfo.kt @@ -30,7 +30,7 @@ import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.MemberDescriptor import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor +import org.jetbrains.kotlin.idea.refactoring.isInterfaceClass import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.renderer.DescriptorRendererModifier @@ -49,11 +49,11 @@ class KotlinMemberInfo @JvmOverloads constructor( } init { - val memberDescriptor = member.resolveToDescriptor() + val memberDescriptor = member.resolveToDescriptorWrapperAware() isStatic = member.parent is KtFile - if (member is KtClass && isSuperClass) { - if (member.isInterface()) { + if ((member is KtClass || member is KtPsiClassWrapper) && isSuperClass) { + if (member.isInterfaceClass()) { displayName = RefactoringBundle.message("member.info.implements.0", member.name) overrides = false } @@ -86,6 +86,7 @@ fun lightElementForMemberInfo(declaration: KtNamedDeclaration?): PsiMember? { it.firstIsInstanceOrNull() ?: it.firstIsInstanceOrNull() } as PsiMember? is KtClassOrObject -> declaration.toLightClass() + is KtPsiClassWrapper -> declaration.psiClass else -> null } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/KotlinMemberInfoStorage.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/KotlinMemberInfoStorage.kt index f186160c5bb..221a55603aa 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/KotlinMemberInfoStorage.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/KotlinMemberInfoStorage.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade -import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor +import org.jetbrains.kotlin.idea.refactoring.isInterfaceClass import org.jetbrains.kotlin.idea.resolve.frontendService import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingContext @@ -40,8 +40,8 @@ class KotlinMemberInfoStorage( filter: (KtNamedDeclaration) -> Boolean = { true } ): AbstractMemberInfoStorage(classOrObject, filter) { override fun memberConflict(member1: KtNamedDeclaration, member: KtNamedDeclaration): Boolean { - val descriptor1 = member1.resolveToDescriptor() - val descriptor = member.resolveToDescriptor() + val descriptor1 = member1.resolveToDescriptorWrapperAware() + val descriptor = member.resolveToDescriptorWrapperAware() if (descriptor1.name != descriptor.name) return false return when { @@ -111,9 +111,14 @@ fun extractClassMembers( val typeReference = it.typeReference ?: return@mapNotNull null val type = typeReference.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, typeReference] val classDescriptor = type?.constructor?.declarationDescriptor as? ClassDescriptor - classDescriptor?.source?.getPsi() as? KtClass + val classPsi = classDescriptor?.source?.getPsi() + when (classPsi) { + is KtClass -> classPsi + is PsiClass -> KtPsiClassWrapper(classPsi) + else -> null + } } - .filter { it.isInterface() } + .filter { it.isInterfaceClass() } .mapTo(result) { KotlinMemberInfo(it, true) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/KtPsiClassWrapper.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/KtPsiClassWrapper.kt new file mode 100644 index 00000000000..bb83c6a8cf4 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/KtPsiClassWrapper.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.refactoring.memberInfo + +import com.intellij.psi.PsiClass +import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.KtPsiFactory + +interface KtPsiClassWrapper : KtNamedDeclaration { + val psiClass: PsiClass +} + +fun KtPsiClassWrapper(psiClass: PsiClass): KtPsiClassWrapper { + val dummyKtClass = KtPsiFactory(psiClass.project).createClass("class ${psiClass.name}") + return object : KtPsiClassWrapper, KtNamedDeclaration by dummyKtClass { + override fun equals(other: Any?) = psiClass == (other as? KtPsiClassWrapper)?.psiClass + + override fun hashCode() = psiClass.hashCode() + + override val psiClass: PsiClass + get() = psiClass + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/memberInfoUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/memberInfoUtils.kt index bd4020ea53a..c569170fb98 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/memberInfoUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/memberInfo/memberInfoUtils.kt @@ -18,8 +18,12 @@ package org.jetbrains.kotlin.idea.refactoring.memberInfo import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMember import com.intellij.psi.PsiNamedElement +import org.jetbrains.kotlin.asJava.classes.KtLightClass +import org.jetbrains.kotlin.asJava.namedUnwrappedElement import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.idea.caches.resolve.getJavaClassDescriptor import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade @@ -59,4 +63,14 @@ fun KotlinMemberInfo.getChildrenToAnalyze(): List { } } return childrenToCheck +} + +internal fun KtNamedDeclaration.resolveToDescriptorWrapperAware(resolutionFacade: ResolutionFacade? = null): DeclarationDescriptor { + if (this is KtPsiClassWrapper) return psiClass.getJavaClassDescriptor(resolutionFacade)!! + return (resolutionFacade ?: getResolutionFacade()).resolveToDescriptor(this) +} + +internal fun PsiMember.toKtDeclarationWrapperAware(): KtNamedDeclaration? { + if (this is PsiClass && this !is KtLightClass) return KtPsiClassWrapper(this) + return namedUnwrappedElement as? KtNamedDeclaration } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpData.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpData.kt index f47186ced36..29d7afa3a47 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpData.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpData.kt @@ -20,7 +20,9 @@ import com.intellij.psi.PsiNamedElement import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.getJavaClassDescriptor import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade +import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper import org.jetbrains.kotlin.idea.refactoring.memberInfo.getClassDescriptorIfAny import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.psi.KtClassOrObject @@ -45,11 +47,10 @@ class KotlinPullUpData(val sourceClass: KtClassOrObject, val sourceClassDescriptor = sourceClassContext[BindingContext.DECLARATION_TO_DESCRIPTOR, sourceClass] as ClassDescriptor val memberDescriptors = membersToMove.keysToMap { - if (it is KtParameter) { - sourceClassContext[BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, it]!! - } - else { - sourceClassContext[BindingContext.DECLARATION_TO_DESCRIPTOR, it]!! + when (it) { + is KtPsiClassWrapper -> it.psiClass.getJavaClassDescriptor(resolutionFacade)!! + is KtParameter -> sourceClassContext[BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, it]!! + else -> sourceClassContext[BindingContext.DECLARATION_TO_DESCRIPTOR, it]!! } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpDialog.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpDialog.kt index 1d041f8c26d..34023ee270f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpDialog.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpDialog.kt @@ -29,10 +29,7 @@ import com.intellij.refactoring.util.DocCommentPolicy import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.idea.refactoring.isCompanionMemberOf import org.jetbrains.kotlin.idea.refactoring.isInterfaceClass -import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo -import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfoStorage -import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionTable -import org.jetbrains.kotlin.idea.refactoring.memberInfo.toJavaMemberInfo +import org.jetbrains.kotlin.idea.refactoring.memberInfo.* import org.jetbrains.kotlin.psi.* class KotlinPullUpDialog( diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelper.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelper.kt index ccf4505baf4..d06ca2a13ac 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelper.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelper.kt @@ -40,6 +40,8 @@ import org.jetbrains.kotlin.idea.intentions.setType import org.jetbrains.kotlin.idea.refactoring.createJavaField import org.jetbrains.kotlin.idea.refactoring.dropOverrideKeywordIfNecessary import org.jetbrains.kotlin.idea.refactoring.isCompanionMemberOf +import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper +import org.jetbrains.kotlin.idea.refactoring.memberInfo.toKtDeclarationWrapperAware import org.jetbrains.kotlin.idea.refactoring.safeDelete.removeOverrideModifier import org.jetbrains.kotlin.idea.util.anonymousObjectSuperTypeOrNull import org.jetbrains.kotlin.idea.util.psi.patternMatching.KotlinPsiUnifier @@ -325,7 +327,8 @@ class KotlinPullUpHelper( return clashingSuperDescriptor.source.getPsi() as? KtCallableDeclaration } - private fun moveSuperInterface(member: KtClass, substitutor: PsiSubstitutor) { + private fun moveSuperInterface(member: PsiNamedElement, substitutor: PsiSubstitutor) { + val realMemberPsi = if (member is KtPsiClassWrapper) member.psiClass else member val classDescriptor = data.memberDescriptors[member] as? ClassDescriptor ?: return val currentSpecifier = data.sourceClass.getSuperTypeEntryByDescriptor(classDescriptor, data.sourceClassContext) ?: return when (data.targetClass) { @@ -340,7 +343,7 @@ class KotlinPullUpHelper( val sourcePsiClass = data.sourceClass.toLightClass() ?: return val superRef = sourcePsiClass.implementsList ?.referenceElements - ?.firstOrNull { it.resolve()?.unwrapped == member } + ?.firstOrNull { it.resolve()?.unwrapped == realMemberPsi } ?: return val superTypeForTarget = substitutor.substitute(elementFactory.createType(superRef)) @@ -426,9 +429,9 @@ class KotlinPullUpHelper( } override fun move(info: MemberInfoBase, substitutor: PsiSubstitutor) { - val member = info.member.namedUnwrappedElement as? KtNamedDeclaration ?: return + val member = info.member.toKtDeclarationWrapperAware() ?: return - if (member is KtClass && info.overrides != null) { + if ((member is KtClass || member is KtPsiClassWrapper) && info.overrides != null) { moveSuperInterface(member, substitutor) return } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelperFactory.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelperFactory.kt index cd254469c60..fe8c327cf92 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelperFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelperFactory.kt @@ -23,13 +23,13 @@ import com.intellij.refactoring.memberPullUp.JavaPullUpHelper import com.intellij.refactoring.memberPullUp.PullUpData import com.intellij.refactoring.memberPullUp.PullUpHelper import com.intellij.refactoring.memberPullUp.PullUpHelperFactory -import org.jetbrains.kotlin.asJava.namedUnwrappedElement +import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.refactoring.createJavaClass +import org.jetbrains.kotlin.idea.refactoring.memberInfo.toKtDeclarationWrapperAware import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.psiUtil.parents import org.jetbrains.kotlin.psi.psiUtil.startOffset @@ -38,7 +38,7 @@ class KotlinPullUpHelperFactory : PullUpHelperFactory { val sourceClass = sourceClass.unwrapped as? KtClassOrObject ?: return null val targetClass = targetClass.unwrapped as? PsiNamedElement ?: return null val membersToMove = membersToMove - .mapNotNull { it.namedUnwrappedElement as? KtNamedDeclaration } + .mapNotNull { it.toKtDeclarationWrapperAware() } .sortedBy { it.startOffset } return KotlinPullUpData(sourceClass, targetClass, membersToMove) } @@ -56,7 +56,7 @@ class KotlinPullUpHelperFactory : PullUpHelperFactory { } class JavaToKotlinPullUpHelperFactory : PullUpHelperFactory { - private fun createJavaToKotlinPullUpHelper(data: PullUpData): JavaToKotlinPreconversionPullUpHelper? { + private fun createJavaToKotlinPullUpHelper(data: PullUpData): PullUpHelper<*>? { if (!data.sourceClass.isInheritor(data.targetClass, true)) return null val dummyTargetClass = createDummyTargetClass(data) ?: return null val dataForDelegate = object : PullUpData by data { @@ -96,6 +96,8 @@ class JavaToKotlinPullUpHelperFactory : PullUpHelperFactory { } override fun createPullUpHelper(data: PullUpData): PullUpHelper<*> { + if (data.sourceClass is KtLightClass) return KotlinPullUpHelperFactory().createPullUpHelper(data) + createJavaToKotlinPullUpHelper(data)?.let { return it } return PullUpHelper.INSTANCE diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/pullUpConflictsUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/pullUpConflictsUtils.kt index ca87e878bdf..f585321037a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/pullUpConflictsUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/pullUpConflictsUtils.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo import org.jetbrains.kotlin.idea.refactoring.memberInfo.getChildrenToAnalyze +import org.jetbrains.kotlin.idea.refactoring.memberInfo.resolveToDescriptorWrapperAware import org.jetbrains.kotlin.idea.references.KtReference import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors @@ -57,7 +58,7 @@ fun checkConflicts(project: Project, with(pullUpData) { for (memberInfo in memberInfos) { val member = memberInfo.member - val memberDescriptor = resolutionFacade.resolveToDescriptor(member) + val memberDescriptor = member.resolveToDescriptorWrapperAware(resolutionFacade) checkClashWithSuperDeclaration(member, memberDescriptor, conflicts) checkAccidentalOverrides(member, memberDescriptor, conflicts) @@ -131,7 +132,7 @@ private fun KotlinPullUpData.checkAccidentalOverrides( .filterNot { it.isSourceOrTarget(this) } .mapNotNull { it.unwrapped as? KtClassOrObject } .forEach { - val subClassDescriptor = resolutionFacade.resolveToDescriptor(it) as ClassDescriptor + val subClassDescriptor = it.resolveToDescriptorWrapperAware(resolutionFacade) as ClassDescriptor val substitutor = getTypeSubstitutor(targetClassDescriptor.defaultType, subClassDescriptor.defaultType) ?: TypeSubstitutor.EMPTY val memberDescriptorInSubClass = @@ -142,7 +143,7 @@ private fun KotlinPullUpData.checkAccidentalOverrides( val message = memberDescriptor.renderForConflicts() + " in super class would clash with existing member of " + - resolutionFacade.resolveToDescriptor(it).renderForConflicts() + it.resolveToDescriptorWrapperAware(resolutionFacade).renderForConflicts() conflicts.putValue(clashingMember, message.capitalize()) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/pushDown/KotlinPushDownProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/pushDown/KotlinPushDownProcessor.kt index a6558fa630c..a9bb5f15459 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/pushDown/KotlinPushDownProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/pushDown/KotlinPushDownProcessor.kt @@ -31,10 +31,12 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.idea.caches.resolve.getJavaClassDescriptor import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet import org.jetbrains.kotlin.idea.refactoring.runSynchronouslyWithProgress import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo +import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper import org.jetbrains.kotlin.idea.refactoring.pullUp.* import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors @@ -62,7 +64,12 @@ class KotlinPushDownContext( val memberDescriptors = membersToMove .map { it.member } - .keysToMap { sourceClassContext[BindingContext.DECLARATION_TO_DESCRIPTOR, it]!! } + .keysToMap { + when (it) { + is KtPsiClassWrapper -> it.psiClass.getJavaClassDescriptor(resolutionFacade)!! + else -> sourceClassContext[BindingContext.DECLARATION_TO_DESCRIPTOR, it]!! + } + } } class KotlinPushDownProcessor( @@ -161,7 +168,7 @@ class KotlinPushDownProcessor( } } - is KtClassOrObject -> { + is KtClassOrObject, is KtPsiClassWrapper -> { if (memberInfo.overrides != null) { context.sourceClass.getSuperTypeEntryByDescriptor( memberDescriptor as ClassDescriptor, @@ -202,7 +209,7 @@ class KotlinPushDownProcessor( member.delete() } } - is KtClassOrObject -> { + is KtClassOrObject, is KtPsiClassWrapper -> { if (memberInfo.overrides != null) { context.sourceClass.getSuperTypeEntryByDescriptor( memberDescriptor as ClassDescriptor, diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/pushDown/pushDownConflictsUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/pushDown/pushDownConflictsUtils.kt index 043106cb0f9..87932d9705b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/pushDown/pushDownConflictsUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/pushDown/pushDownConflictsUtils.kt @@ -24,6 +24,7 @@ import com.intellij.usageView.UsageInfo import com.intellij.util.containers.MultiMap import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper import org.jetbrains.kotlin.idea.refactoring.pullUp.renderForConflicts import org.jetbrains.kotlin.idea.references.KtReference import org.jetbrains.kotlin.idea.references.mainReference @@ -50,7 +51,7 @@ fun analyzePushDownConflicts(context: KotlinPushDownContext, val membersToKeepAbstract = ArrayList() for (info in context.membersToMove) { val member = info.member - if (!info.isChecked || (member is KtClassOrObject && info.overrides != null)) continue + if (!info.isChecked || ((member is KtClassOrObject || member is KtPsiClassWrapper) && info.overrides != null)) continue membersToPush += member if ((member is KtNamedFunction || member is KtProperty) diff --git a/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToClass.1.java b/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToClass.1.java index 085f6131db3..7d76c0f49f2 100644 --- a/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToClass.1.java +++ b/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToClass.1.java @@ -1,3 +1,8 @@ class A implements Z { +} + +// INFO: {"checked": "true"} +interface J { + } \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToClass.1.java.after b/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToClass.1.java.after index cfc6c5665c3..20b575a7314 100644 --- a/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToClass.1.java.after +++ b/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToClass.1.java.after @@ -1,3 +1,8 @@ -class A implements Z, X { +class A implements Z, X, J { + +} + +// INFO: {"checked": "true"} +interface J { } \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToClass.kt b/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToClass.kt index 4aa7c600229..1651753eb59 100644 --- a/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToClass.kt +++ b/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToClass.kt @@ -7,4 +7,4 @@ interface Y // INFO: {"checked": "true"} interface Z -class B: A(), X, Y, Z \ No newline at end of file +class B: A(), X, Y, Z, J \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToInterface.1.java b/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToInterface.1.java index c4cda5ced3f..87ba058c19c 100644 --- a/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToInterface.1.java +++ b/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToInterface.1.java @@ -1,3 +1,8 @@ interface I extends Z { +} + +// INFO: {"checked": "true"} +interface J { + } \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToInterface.1.java.after b/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToInterface.1.java.after index acf6e0d4b69..daa5fcf23c7 100644 --- a/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToInterface.1.java.after +++ b/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToInterface.1.java.after @@ -1,3 +1,8 @@ -interface I extends Z, X { +interface I extends Z, X, J { + +} + +// INFO: {"checked": "true"} +interface J { } \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToInterface.kt b/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToInterface.kt index 8410146ba90..837a539065e 100644 --- a/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToInterface.kt +++ b/idea/testData/refactoring/pullUp/k2j/moveSuperInterfacesToInterface.kt @@ -7,4 +7,4 @@ interface Y // INFO: {"checked": "true"} interface Z -class B: I, X, Y, Z \ No newline at end of file +class B: I, X, Y, Z, J \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.1.java b/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.1.java new file mode 100644 index 00000000000..7225760e96c --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.1.java @@ -0,0 +1,4 @@ +// INFO: {"checked": "true"} +interface J { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.1.java.after b/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.1.java.after new file mode 100644 index 00000000000..d05ab4b11f5 --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.1.java.after @@ -0,0 +1,4 @@ +// INFO: {"checked": "true"} +interface J { + +} diff --git a/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.kt b/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.kt index 695d863feda..d4451b2d536 100644 --- a/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.kt +++ b/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.kt @@ -11,4 +11,4 @@ interface Y // INFO: {"checked": "true"} interface Z -class B: A(), X, Y, Z \ No newline at end of file +class B: A(), X, Y, Z, J \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.kt.after b/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.kt.after index 66f893a7d24..907cc8de579 100644 --- a/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.kt.after +++ b/idea/testData/refactoring/pullUp/k2k/moveAllSuperInterfaces.kt.after @@ -1,4 +1,4 @@ -open class A: Z, X, Y { +open class A: Z, X, Y, J { } diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/AbstractMemberPullPushTest.kt b/idea/tests/org/jetbrains/kotlin/idea/refactoring/AbstractMemberPullPushTest.kt index 098fb04c3d2..7b54c4764eb 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/AbstractMemberPullPushTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/AbstractMemberPullPushTest.kt @@ -25,6 +25,7 @@ import com.intellij.refactoring.BaseRefactoringProcessor import com.intellij.refactoring.classMembers.MemberInfoBase import com.intellij.refactoring.util.CommonRefactoringUtil import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture +import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor @@ -64,6 +65,7 @@ abstract class AbstractMemberPullPushTest : KotlinLightCodeInsightFixtureTestCas try { markMembersInfo(file) + extraFilesToPsi.keys.forEach(::markMembersInfo) action(file) @@ -105,7 +107,8 @@ internal var PsiElement.elementInfo: ElementInfo by NotNullableUserDataProperty( internal fun > chooseMembers(members: List): List { members.forEach { - val info = it.member.elementInfo + val memberPsi = it.member.let { if (it is KtPsiClassWrapper) it.psiClass else it } + val info = memberPsi.elementInfo it.isChecked = info.checked it.isToAbstract = info.toAbstract }