Member Info: Extended implementation (for Pull Up/Push Down)

This commit is contained in:
Alexey Sedunov
2015-07-07 18:43:09 +03:00
parent 3c36795984
commit e303a38f9e
7 changed files with 178 additions and 51 deletions
@@ -45,7 +45,8 @@ public fun JetType.nullability(): TypeNullability {
fun JetType.makeNullable() = TypeUtils.makeNullable(this)
fun JetType.makeNotNullable() = TypeUtils.makeNotNullable(this)
fun JetType.supertypes(): Set<JetType> = TypeUtils.getAllSupertypes(this)
fun JetType.immediateSupertypes(): Collection<JetType> = TypeUtils.getImmediateSupertypes(this)
fun JetType.supertypes(): Collection<JetType> = TypeUtils.getAllSupertypes(this)
fun JetType.isNothing(): Boolean = KotlinBuiltIns.isNothing(this)
fun JetType.isUnit(): Boolean = KotlinBuiltIns.isUnit(this)
@@ -14,10 +14,11 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.refactoring
package org.jetbrains.kotlin.idea.refactoring.memberInfo
import com.intellij.refactoring.classMembers.MemberInfoBase
import com.intellij.refactoring.classMembers.MemberInfoModel
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.psi.JetFile
@@ -25,7 +26,13 @@ import org.jetbrains.kotlin.psi.JetNamedDeclaration
public class KotlinMemberInfo(member: JetNamedDeclaration) : MemberInfoBase<JetNamedDeclaration>(member) {
init {
val memberDescriptor = member.resolveToDescriptor()
isStatic = member.getParent() is JetFile
displayName = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.render(member.resolveToDescriptor())
displayName = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.render(memberDescriptor)
val overriddenDescriptors = (memberDescriptor as? CallableMemberDescriptor)?.getOverriddenDescriptors() ?: emptySet()
if (overriddenDescriptors.isNotEmpty()) {
overrides = overriddenDescriptors.any { it.getModality() != Modality.ABSTRACT }
}
}
}
}
@@ -0,0 +1,79 @@
/*
* Copyright 2010-2015 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.refactoring.classMembers.AbstractMemberInfoStorage
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.psi.JetClassOrObject
import org.jetbrains.kotlin.psi.JetConstructor
import org.jetbrains.kotlin.psi.JetNamedDeclaration
import org.jetbrains.kotlin.psi.JetObjectDeclaration
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.OverloadUtil
import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
import java.util.ArrayList
public class KotlinMemberInfoStorage(
classOrObject: JetClassOrObject,
filter: (JetNamedDeclaration) -> Boolean = { true }
): AbstractMemberInfoStorage<JetNamedDeclaration, JetClassOrObject, KotlinMemberInfo>(classOrObject, filter) {
override fun memberConflict(member1: JetNamedDeclaration, member: JetNamedDeclaration): Boolean {
val descriptor1 = member1.resolveToDescriptor()
val descriptor = member.resolveToDescriptor()
if (descriptor1.getName() != descriptor.getName()) return false
return when {
descriptor1 is FunctionDescriptor && descriptor is FunctionDescriptor -> {
!OverloadUtil.isOverloadable(descriptor1, descriptor).isSuccess()
}
descriptor1 is PropertyDescriptor && descriptor is PropertyDescriptor,
descriptor1 is ClassDescriptor && descriptor is ClassDescriptor -> true
else -> false
}
}
override fun buildSubClassesMap(aClass: JetClassOrObject) {
val classDescriptor = aClass.resolveToDescriptor() as ClassDescriptor
val classType = classDescriptor.getDefaultType()
for (supertype in classType.immediateSupertypes()) {
val superClass = supertype.getConstructor().getDeclarationDescriptor()?.getSource()?.getPsi() as? JetClassOrObject
?: continue
getSubclasses(superClass).add(aClass)
buildSubClassesMap(superClass)
}
}
override fun isInheritor(baseClass: JetClassOrObject, aClass: JetClassOrObject): Boolean {
val baseDescriptor = baseClass.resolveToDescriptor() as ClassDescriptor
val currentDescriptor = aClass.resolveToDescriptor() as ClassDescriptor
return DescriptorUtils.isSubclass(currentDescriptor, baseDescriptor)
}
override fun extractClassMembers(aClass: JetClassOrObject, temp: ArrayList<KotlinMemberInfo>) {
aClass.getDeclarations()
.filter { it is JetNamedDeclaration
&& it !is JetConstructor<*>
&& !(it is JetObjectDeclaration && it.isCompanion())
&& myFilter.includeMember(it) }
.mapTo(temp) { KotlinMemberInfo(it as JetNamedDeclaration) }
}
}
@@ -14,12 +14,11 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.refactoring.ui
package org.jetbrains.kotlin.idea.refactoring.memberInfo
import com.intellij.refactoring.ui.AbstractMemberSelectionPanel
import com.intellij.ui.ScrollPaneFactory
import com.intellij.ui.SeparatorFactory
import org.jetbrains.kotlin.idea.refactoring.KotlinMemberInfo
import org.jetbrains.kotlin.psi.JetNamedDeclaration
import java.awt.BorderLayout
@@ -0,0 +1,82 @@
/*
* Copyright 2010-2015 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.icons.AllIcons
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiModifier
import com.intellij.refactoring.classMembers.MemberInfoModel
import com.intellij.refactoring.ui.AbstractMemberSelectionTable
import com.intellij.refactoring.ui.MemberSelectionTable
import com.intellij.ui.RowIcon
import org.jetbrains.kotlin.idea.JetIconProvider
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.JetNamedDeclaration
import org.jetbrains.kotlin.psi.JetNamedFunction
import org.jetbrains.kotlin.psi.JetProperty
import javax.swing.Icon
public class KotlinMemberSelectionTable(
memberInfos: List<KotlinMemberInfo>,
memberInfoModel: MemberInfoModel<JetNamedDeclaration, KotlinMemberInfo>?,
abstractColumnHeader: String?
) : AbstractMemberSelectionTable<JetNamedDeclaration, KotlinMemberInfo>(memberInfos, memberInfoModel, abstractColumnHeader) {
override fun getAbstractColumnValue(memberInfo: KotlinMemberInfo): Any? {
if (memberInfo.isStatic()) return null
val member = memberInfo.getMember()
if (member !is JetNamedFunction && member !is JetProperty) return null
if (member.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
myMemberInfoModel.isFixedAbstract(memberInfo)?.let { return it }
}
if (myMemberInfoModel.isAbstractEnabled(memberInfo)) return memberInfo.isToAbstract()
return myMemberInfoModel.isAbstractWhenDisabled(memberInfo)
}
override fun isAbstractColumnEditable(rowIndex: Int): Boolean {
val memberInfo = myMemberInfos.get(rowIndex)
if (memberInfo.isStatic()) return false
val member = memberInfo.getMember()
if (member !is JetNamedFunction && member !is JetProperty) return false
if (member.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
myMemberInfoModel.isFixedAbstract(memberInfo)?.let { return false }
}
return memberInfo.isChecked() && myMemberInfoModel.isAbstractEnabled(memberInfo)
}
override fun setVisibilityIcon(memberInfo: KotlinMemberInfo, icon: RowIcon) {
icon.setIcon(JetIconProvider.getVisibilityIcon(memberInfo.getMember().getModifierList()), 1);
}
override fun getOverrideIcon(memberInfo: KotlinMemberInfo): Icon? {
val defaultIcon = AbstractMemberSelectionTable.EMPTY_OVERRIDE_ICON
val member = memberInfo.getMember()
if (member !is JetNamedFunction && member !is JetProperty) return defaultIcon
return when (memberInfo.getOverrides()) {
true -> AllIcons.General.OverridingMethod
false -> AllIcons.General.ImplementingMethod
else -> defaultIcon
}
}
}
@@ -61,11 +61,11 @@ import org.jetbrains.kotlin.idea.JetFileType;
import org.jetbrains.kotlin.idea.core.CorePackage;
import org.jetbrains.kotlin.idea.core.refactoring.RefactoringPackage;
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle;
import org.jetbrains.kotlin.idea.refactoring.KotlinMemberInfo;
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo;
import org.jetbrains.kotlin.idea.refactoring.move.MovePackage;
import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.*;
import org.jetbrains.kotlin.idea.refactoring.ui.KotlinMemberSelectionPanel;
import org.jetbrains.kotlin.idea.refactoring.ui.KotlinMemberSelectionTable;
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionPanel;
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionTable;
import org.jetbrains.kotlin.idea.util.application.ApplicationPackage;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.JetFile;
@@ -1,41 +0,0 @@
/*
* Copyright 2010-2015 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.ui
import com.intellij.refactoring.classMembers.MemberInfoModel
import com.intellij.refactoring.ui.AbstractMemberSelectionTable
import com.intellij.ui.RowIcon
import com.intellij.util.IconUtil
import org.jetbrains.kotlin.idea.JetIconProvider
import org.jetbrains.kotlin.idea.refactoring.KotlinMemberInfo
import org.jetbrains.kotlin.psi.JetNamedDeclaration
public class KotlinMemberSelectionTable(
memberInfos: List<KotlinMemberInfo>,
memberInfoModel: MemberInfoModel<JetNamedDeclaration, KotlinMemberInfo>?,
abstractColumnHeader: String?
) : AbstractMemberSelectionTable<JetNamedDeclaration, KotlinMemberInfo>(memberInfos, memberInfoModel, abstractColumnHeader) {
override fun getAbstractColumnValue(memberInfo: KotlinMemberInfo) = null
override fun isAbstractColumnEditable(rowIndex: Int) = false
override fun setVisibilityIcon(memberInfo: KotlinMemberInfo, icon: RowIcon) {
icon.setIcon(JetIconProvider.getVisibilityIcon(memberInfo.getMember().getModifierList()), 1);
}
override fun getOverrideIcon(memberInfo: KotlinMemberInfo) = AbstractMemberSelectionTable.EMPTY_OVERRIDE_ICON
}