Minor: refactoring 'refactoring' package

This commit is contained in:
Dmitry Gridin
2019-05-13 18:08:10 +07:00
parent 98a4c4588e
commit 379152303c
11 changed files with 197 additions and 187 deletions
@@ -25,12 +25,12 @@ abstract class AbstractIntroduceAction : BasePlatformRefactoringAction() {
setInjectedContext(true)
}
override final fun setInjectedContext(worksInInjected: Boolean) {
final override fun setInjectedContext(worksInInjected: Boolean) {
super.setInjectedContext(worksInInjected)
}
override fun isAvailableInEditorOnly(): Boolean = true
override fun isEnabledOnElements(elements: Array<out PsiElement>): Boolean =
elements.all { it is KtElement }
elements.all { it is KtElement }
}
@@ -33,14 +33,14 @@ import org.jetbrains.kotlin.psi.psiUtil.isIdentifier
import org.jetbrains.kotlin.psi.psiUtil.quoteIfNeeded
import java.awt.BorderLayout
abstract class AbstractKotlinInplaceIntroducer<D: KtNamedDeclaration>(
localVariable: D?,
expression: KtExpression?,
occurrences: Array<KtExpression>,
title: String,
project: Project,
editor: Editor
): AbstractInplaceIntroducer<D, KtExpression>(project, editor, expression, localVariable, occurrences, title, KotlinFileType.INSTANCE) {
abstract class AbstractKotlinInplaceIntroducer<D : KtNamedDeclaration>(
localVariable: D?,
expression: KtExpression?,
occurrences: Array<KtExpression>,
title: String,
project: Project,
editor: Editor
) : AbstractInplaceIntroducer<D, KtExpression>(project, editor, expression, localVariable, occurrences, title, KotlinFileType.INSTANCE) {
protected fun initFormComponents(init: FormBuilder.() -> Unit) {
myWholePanel.layout = BorderLayout()
@@ -58,8 +58,7 @@ abstract class AbstractKotlinInplaceIntroducer<D: KtNamedDeclaration>(
// myExprMarker was invalidated by stopIntroduce()
myExprMarker = myExpr?.let { createMarker(it) }
startInplaceIntroduceTemplate()
}
finally {
} finally {
myEditor.putUserData(InplaceRefactoring.INTRODUCE_RESTART, false)
}
}
@@ -74,10 +73,10 @@ abstract class AbstractKotlinInplaceIntroducer<D: KtNamedDeclaration>(
override fun getActionName(): String? = null
override fun restoreExpression(
containingFile: PsiFile,
declaration: D,
marker: RangeMarker,
exprText: String?
containingFile: PsiFile,
declaration: D,
marker: RangeMarker,
exprText: String?
): KtExpression? {
if (exprText == null || !declaration.isValid) return null
@@ -89,8 +88,8 @@ abstract class AbstractKotlinInplaceIntroducer<D: KtNamedDeclaration>(
val occurrenceExprText = (myExpr as? KtProperty)?.name ?: exprText
return leaf
.getNonStrictParentOfType<KtSimpleNameExpression>()
?.replaced(KtPsiFactory(myProject).createExpression(occurrenceExprText))
.getNonStrictParentOfType<KtSimpleNameExpression>()
?.replaced(KtPsiFactory(myProject).createExpression(occurrenceExprText))
}
override fun updateTitle(declaration: D?) = updateTitle(declaration, null)
@@ -72,23 +72,23 @@ import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
import java.util.*
data class ExtractSuperInfo(
val originalClass: KtClassOrObject,
val memberInfos: Collection<KotlinMemberInfo>,
val targetParent: PsiElement,
val targetFileName: String,
val newClassName: String,
val isInterface: Boolean,
val docPolicy: DocCommentPolicy<*>
val originalClass: KtClassOrObject,
val memberInfos: Collection<KotlinMemberInfo>,
val targetParent: PsiElement,
val targetFileName: String,
val newClassName: String,
val isInterface: Boolean,
val docPolicy: DocCommentPolicy<*>
)
class ExtractSuperRefactoring(
private var extractInfo: ExtractSuperInfo
private var extractInfo: ExtractSuperInfo
) {
companion object {
private fun getElementsToMove(
memberInfos: Collection<KotlinMemberInfo>,
originalClass: KtClassOrObject,
isExtractInterface: Boolean
memberInfos: Collection<KotlinMemberInfo>,
originalClass: KtClassOrObject,
isExtractInterface: Boolean
): Map<KtElement, KotlinMemberInfo?> {
val project = originalClass.project
val elementsToMove = LinkedHashMap<KtElement, KotlinMemberInfo?>()
@@ -98,8 +98,7 @@ class ExtractSuperRefactoring(
val member = memberInfo.member ?: continue
if (memberInfo.isSuperClass) {
superInterfacesToMove += member
}
else {
} else {
elementsToMove[member] = memberInfo
}
}
@@ -107,8 +106,9 @@ class ExtractSuperRefactoring(
val superTypeList = originalClass.getSuperTypeList()
if (superTypeList != null) {
for (superTypeListEntry in originalClass.superTypeListEntries) {
val superType = superTypeListEntry.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, superTypeListEntry.typeReference]
?: continue
val superType =
superTypeListEntry.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, superTypeListEntry.typeReference]
?: continue
val superClassDescriptor = superType.constructor.declarationDescriptor ?: continue
val superClass = DescriptorToSourceUtilsIde.getAnyDeclaration(project, superClassDescriptor) as? KtClass ?: continue
if ((!isExtractInterface && !superClass.isInterface()) || superClass in superInterfacesToMove) {
@@ -121,11 +121,11 @@ class ExtractSuperRefactoring(
}
fun collectConflicts(
originalClass: KtClassOrObject,
memberInfos: List<KotlinMemberInfo>,
targetParent: PsiElement,
newClassName: String,
isExtractInterface: Boolean
originalClass: KtClassOrObject,
memberInfos: List<KotlinMemberInfo>,
targetParent: PsiElement,
newClassName: String,
isExtractInterface: Boolean
): MultiMap<PsiElement, String> {
val conflicts = MultiMap<PsiElement, String>()
@@ -134,9 +134,9 @@ class ExtractSuperRefactoring(
if (targetParent is KtElement) {
val targetSibling = originalClass.parentsWithSelf.first { it.parent == targetParent } as KtElement
targetSibling.getResolutionScope()
.findClassifier(Name.identifier(newClassName), NoLookupLocation.FROM_IDE)
?.let { DescriptorToSourceUtilsIde.getAnyDeclaration(project, it) }
?.let { conflicts.putValue(it, "Class $newClassName already exists in the target scope") }
.findClassifier(Name.identifier(newClassName), NoLookupLocation.FROM_IDE)
?.let { DescriptorToSourceUtilsIde.getAnyDeclaration(project, it) }
?.let { conflicts.putValue(it, "Class $newClassName already exists in the target scope") }
}
val elementsToMove = getElementsToMove(memberInfos, originalClass, isExtractInterface).keys
@@ -144,16 +144,15 @@ class ExtractSuperRefactoring(
val moveTarget = if (targetParent is PsiDirectory) {
val targetPackage = targetParent.getPackage() ?: return conflicts
KotlinMoveTargetForDeferredFile(FqName(targetPackage.qualifiedName), targetParent) { null }
}
else {
} else {
KotlinMoveTargetForExistingElement(targetParent as KtElement)
}
val conflictChecker = MoveConflictChecker(
project,
elementsToMove,
moveTarget,
originalClass,
memberInfos.asSequence().filter { it.isToAbstract }.mapNotNull { it.member }.toList()
project,
elementsToMove,
moveTarget,
originalClass,
memberInfos.asSequence().filter { it.isToAbstract }.mapNotNull { it.member }.toList()
)
project.runSynchronouslyWithProgress(RefactoringBundle.message("detecting.possible.conflicts"), true) {
@@ -163,11 +162,11 @@ class ExtractSuperRefactoring(
ReferencesSearch.search(element).mapTo(usages) { MoveRenameUsageInfo(it, element) }
if (element is KtCallableDeclaration) {
element.toLightMethods().flatMapTo(usages) {
MethodReferencesSearch.search(it).map { MoveRenameUsageInfo(it, element) }
MethodReferencesSearch.search(it).map { reference -> MoveRenameUsageInfo(reference, element) }
}
}
}
conflictChecker.checkAllConflicts(usages, LinkedHashSet<UsageInfo>(), conflicts)
conflictChecker.checkAllConflicts(usages, LinkedHashSet(), conflicts)
if (targetParent is PsiDirectory) {
ExtractSuperClassUtil.checkSuperAccessible(targetParent, conflicts, originalClass.toLightClass())
}
@@ -190,11 +189,11 @@ class ExtractSuperRefactoring(
if (refTarget is KtTypeParameter && refTarget.getStrictParentOfType<KtTypeParameterListOwner>() == extractInfo.originalClass) {
typeParameters += refTarget
refTarget.accept(
object : KtTreeVisitorVoid() {
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
(expression.mainReference.resolve() as? KtTypeParameter)?.let { typeParameters += it }
}
object : KtTreeVisitorVoid() {
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
(expression.mainReference.resolve() as? KtTypeParameter)?.let { typeParameters += it }
}
}
)
}
}
@@ -207,12 +206,12 @@ class ExtractSuperRefactoring(
}
}
getElementsToMove(extractInfo.memberInfos, extractInfo.originalClass, extractInfo.isInterface)
.asSequence()
.flatMap {
val (element, info) = it
info?.getChildrenToAnalyze()?.asSequence() ?: sequenceOf(element)
}
.forEach { it.accept(visitor) }
.asSequence()
.flatMap {
val (element, info) = it
info?.getChildrenToAnalyze()?.asSequence() ?: sequenceOf(element)
}
.forEach { it.accept(visitor) }
}
private fun createClass(superClassEntry: KtSuperTypeListEntry?): KtClass? {
@@ -228,8 +227,7 @@ class ExtractSuperRefactoring(
NewKotlinFileAction.createFileFromTemplate(extractInfo.targetFileName, template, targetParent) ?: return null
}
file.add(prototype) as KtClass
}
else {
} else {
val targetSibling = originalClass.parentsWithSelf.first { it.parent == targetParent }
insertDeclaration(prototype, targetSibling)
}
@@ -256,13 +254,12 @@ class ExtractSuperRefactoring(
}
}
val needSuperCall = !extractInfo.isInterface
&& (superClassEntry is KtSuperTypeCallEntry
|| originalClass.hasPrimaryConstructor()
|| originalClass.secondaryConstructors.isEmpty())
&& (superClassEntry is KtSuperTypeCallEntry
|| originalClass.hasPrimaryConstructor()
|| originalClass.secondaryConstructors.isEmpty())
val newSuperTypeListEntry = if (needSuperCall) {
psiFactory.createSuperTypeCallEntry("$superTypeText()")
}
else {
} else {
psiFactory.createSuperTypeEntry(superTypeText)
}
if (superClassEntry != null) {
@@ -271,12 +268,10 @@ class ExtractSuperRefactoring(
}
val superClassEntryToAdd = if (qualifiedTypeRefText != null) {
superClassEntry.copied().apply { typeReference?.replace(psiFactory.createType(qualifiedTypeRefText)) }
}
else superClassEntry
} else superClassEntry
newClass.addSuperTypeListEntry(superClassEntryToAdd)
ShortenReferences.DEFAULT.process(superClassEntry.replaced(newSuperTypeListEntry))
}
else {
} else {
ShortenReferences.DEFAULT.process(originalClass.addSuperTypeListEntry(newSuperTypeListEntry))
}
@@ -297,8 +292,7 @@ class ExtractSuperRefactoring(
originalClass.superTypeListEntries.firstOrNull {
bindingContext[BindingContext.TYPE, it.typeReference]?.constructor?.declarationDescriptor == superClassDescriptor
}
}
else null
} else null
project.runSynchronouslyWithProgress(RefactoringBundle.message("progress.text"), true) { runReadAction { analyzeContext() } }
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassOrObject
object KotlinExtractInterfaceHandler : KotlinExtractSuperHandlerBase(true) {
val REFACTORING_NAME = "Extract Interface"
const val REFACTORING_NAME = "Extract Interface"
override fun getErrorMessage(klass: KtClassOrObject): String? {
val superMessage = super.getErrorMessage(klass)
@@ -33,9 +33,9 @@ object KotlinExtractInterfaceHandler : KotlinExtractSuperHandlerBase(true) {
override fun createDialog(klass: KtClassOrObject, targetParent: PsiElement) =
KotlinExtractInterfaceDialog(
originalClass = klass,
targetParent = targetParent,
conflictChecker = { checkConflicts(klass, it) },
refactoring = { ExtractSuperRefactoring(it).performRefactoring() }
originalClass = klass,
targetParent = targetParent,
conflictChecker = { checkConflicts(klass, it) },
refactoring = { ExtractSuperRefactoring(it).performRefactoring() }
)
}
@@ -68,11 +68,11 @@ abstract class KotlinExtractSuperHandlerBase(private val isExtractInterface: Boo
getErrorMessage(klass)?.let {
CommonRefactoringUtil.showErrorHint(
project,
editor,
RefactoringBundle.getCannotRefactorMessage(it),
KotlinExtractSuperclassHandler.REFACTORING_NAME,
HelpID.EXTRACT_SUPERCLASS
project,
editor,
RefactoringBundle.getCannotRefactorMessage(it),
KotlinExtractSuperclassHandler.REFACTORING_NAME,
HelpID.EXTRACT_SUPERCLASS
)
return false
}
@@ -90,22 +90,22 @@ abstract class KotlinExtractSuperHandlerBase(private val isExtractInterface: Boo
if (editor == null) return doInvoke(klass, containers.first())
chooseContainerElementIfNecessary(
containers,
editor,
if (containers.first() is KtFile) "Select target file" else "Select target code block / file",
true,
{ it },
{ doInvoke(klass, if (it is SeparateFileWrapper) klass.containingFile.parent!! else it) }
containers,
editor,
if (containers.first() is KtFile) "Select target file" else "Select target code block / file",
true,
{ it },
{ doInvoke(klass, if (it is SeparateFileWrapper) klass.containingFile.parent!! else it) }
)
}
protected fun checkConflicts(originalClass: KtClassOrObject, dialog: KotlinExtractSuperDialogBase): Boolean {
val conflicts = ExtractSuperRefactoring.collectConflicts(
originalClass,
dialog.selectedMembers,
dialog.selectedTargetParent,
dialog.extractedSuperName,
isExtractInterface
originalClass,
dialog.selectedMembers,
dialog.selectedTargetParent,
dialog.extractedSuperName,
isExtractInterface
)
return ExtractSuperClassUtil.showConflicts(dialog, conflicts, originalClass.project)
}
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassOrObject
object KotlinExtractSuperclassHandler : KotlinExtractSuperHandlerBase(false) {
val REFACTORING_NAME = "Extract Superclass"
const val REFACTORING_NAME = "Extract Superclass"
override fun getErrorMessage(klass: KtClassOrObject): String? {
val superMessage = super.getErrorMessage(klass)
@@ -38,9 +38,9 @@ object KotlinExtractSuperclassHandler : KotlinExtractSuperHandlerBase(false) {
override fun createDialog(klass: KtClassOrObject, targetParent: PsiElement) =
KotlinExtractSuperclassDialog(
originalClass = klass,
targetParent = targetParent,
conflictChecker = { checkConflicts(klass, it) },
refactoring = { ExtractSuperRefactoring(it).performRefactoring() }
originalClass = klass,
targetParent = targetParent,
conflictChecker = { checkConflicts(klass, it) },
refactoring = { ExtractSuperRefactoring(it).performRefactoring() }
)
}
@@ -36,13 +36,20 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
class KotlinExtractInterfaceDialog(
originalClass: KtClassOrObject,
targetParent: PsiElement,
conflictChecker: (KotlinExtractSuperDialogBase) -> Boolean,
refactoring: (ExtractSuperInfo) -> Unit
) : KotlinExtractSuperDialogBase(originalClass, targetParent, conflictChecker, true, KotlinExtractInterfaceHandler.REFACTORING_NAME, refactoring) {
originalClass: KtClassOrObject,
targetParent: PsiElement,
conflictChecker: (KotlinExtractSuperDialogBase) -> Boolean,
refactoring: (ExtractSuperInfo) -> Unit
) : KotlinExtractSuperDialogBase(
originalClass,
targetParent,
conflictChecker,
true,
KotlinExtractInterfaceHandler.REFACTORING_NAME,
refactoring
) {
companion object {
private val DESTINATION_PACKAGE_RECENT_KEY = "KotlinExtractInterfaceDialog.RECENT_KEYS"
private const val DESTINATION_PACKAGE_RECENT_KEY = "KotlinExtractInterfaceDialog.RECENT_KEYS"
}
init {
@@ -44,12 +44,12 @@ import java.awt.BorderLayout
import javax.swing.*
abstract class KotlinExtractSuperDialogBase(
protected val originalClass: KtClassOrObject,
protected val targetParent: PsiElement,
private val conflictChecker: (KotlinExtractSuperDialogBase) -> Boolean,
private val isExtractInterface: Boolean,
refactoringName: String,
private val refactoring: (ExtractSuperInfo) -> Unit
protected val originalClass: KtClassOrObject,
protected val targetParent: PsiElement,
private val conflictChecker: (KotlinExtractSuperDialogBase) -> Boolean,
private val isExtractInterface: Boolean,
refactoringName: String,
private val refactoring: (ExtractSuperInfo) -> Unit
) : JavaExtractSuperBaseDialog(originalClass.project, originalClass.toLightClass()!!, emptyList(), refactoringName) {
private var initComplete: Boolean = false
@@ -61,10 +61,15 @@ abstract class KotlinExtractSuperDialogBase(
private val fileNameField = JTextField()
open class MemberInfoModelBase(
originalClass: KtClassOrObject,
val memberInfos: List<KotlinMemberInfo>,
interfaceContainmentVerifier: (KtNamedDeclaration) -> Boolean
) : KotlinUsesAndInterfacesDependencyMemberInfoModel<KtNamedDeclaration, KotlinMemberInfo>(originalClass, null, false, interfaceContainmentVerifier) {
originalClass: KtClassOrObject,
val memberInfos: List<KotlinMemberInfo>,
interfaceContainmentVerifier: (KtNamedDeclaration) -> Boolean
) : KotlinUsesAndInterfacesDependencyMemberInfoModel<KtNamedDeclaration, KotlinMemberInfo>(
originalClass,
null,
false,
interfaceContainmentVerifier
) {
override fun isMemberEnabled(member: KotlinMemberInfo): Boolean {
val declaration = member.member ?: return false
return !declaration.hasModifier(KtTokens.CONST_KEYWORD)
@@ -73,8 +78,8 @@ abstract class KotlinExtractSuperDialogBase(
override fun isAbstractEnabled(memberInfo: KotlinMemberInfo): Boolean {
val member = memberInfo.member
return !(member.hasModifier(KtTokens.INLINE_KEYWORD) ||
member.hasModifier(KtTokens.EXTERNAL_KEYWORD) ||
member.hasModifier(KtTokens.LATEINIT_KEYWORD))
member.hasModifier(KtTokens.EXTERNAL_KEYWORD) ||
member.hasModifier(KtTokens.LATEINIT_KEYWORD))
}
override fun isFixedAbstract(memberInfo: KotlinMemberInfo?) = true
@@ -140,9 +145,9 @@ abstract class KotlinExtractSuperDialogBase(
return JPanel(BorderLayout()).apply {
val memberSelectionPanel = KotlinMemberSelectionPanel(
RefactoringBundle.message(if (isExtractInterface) "members.to.form.interface" else "members.to.form.superclass"),
memberInfoModel.memberInfos,
RefactoringBundle.message("make.abstract")
RefactoringBundle.message(if (isExtractInterface) "members.to.form.interface" else "members.to.form.superclass"),
memberInfoModel.memberInfos,
RefactoringBundle.message("make.abstract")
)
memberSelectionPanel.table.memberInfoModel = memberInfoModel
memberSelectionPanel.table.addMemberInfoChangeListener(memberInfoModel)
@@ -178,13 +183,13 @@ abstract class KotlinExtractSuperDialogBase(
override fun executeRefactoring() {
val extractInfo = ExtractSuperInfo(
mySourceClass.unwrapped as KtClassOrObject,
selectedMembers,
if (targetParent is PsiDirectory) targetDirectory else targetParent,
targetFileName,
extractedSuperName.quoteIfNeeded(),
isExtractInterface,
DocCommentPolicy<PsiComment>(docCommentPolicy)
mySourceClass.unwrapped as KtClassOrObject,
selectedMembers,
if (targetParent is PsiDirectory) targetDirectory else targetParent,
targetFileName,
extractedSuperName.quoteIfNeeded(),
isExtractInterface,
DocCommentPolicy<PsiComment>(docCommentPolicy)
)
refactoring(extractInfo)
}
@@ -31,13 +31,20 @@ import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtProperty
class KotlinExtractSuperclassDialog(
originalClass: KtClassOrObject,
targetParent: PsiElement,
conflictChecker: (KotlinExtractSuperDialogBase) -> Boolean,
refactoring: (ExtractSuperInfo) -> Unit
) : KotlinExtractSuperDialogBase(originalClass, targetParent, conflictChecker, false, KotlinExtractSuperclassHandler.REFACTORING_NAME, refactoring) {
originalClass: KtClassOrObject,
targetParent: PsiElement,
conflictChecker: (KotlinExtractSuperDialogBase) -> Boolean,
refactoring: (ExtractSuperInfo) -> Unit
) : KotlinExtractSuperDialogBase(
originalClass,
targetParent,
conflictChecker,
false,
KotlinExtractSuperclassHandler.REFACTORING_NAME,
refactoring
) {
companion object {
private val DESTINATION_PACKAGE_RECENT_KEY = "KotlinExtractSuperclassDialog.RECENT_KEYS"
private const val DESTINATION_PACKAGE_RECENT_KEY = "KotlinExtractSuperclassDialog.RECENT_KEYS"
}
init {
@@ -46,9 +53,9 @@ class KotlinExtractSuperclassDialog(
override fun createMemberInfoModel(): MemberInfoModelBase {
return object : MemberInfoModelBase(
originalClass,
extractClassMembers(originalClass),
getInterfaceContainmentVerifier { selectedMembers }
originalClass,
extractClassMembers(originalClass),
getInterfaceContainmentVerifier { selectedMembers }
) {
override fun isAbstractEnabled(memberInfo: KotlinMemberInfo): Boolean {
if (!super.isAbstractEnabled(memberInfo)) return false
@@ -42,19 +42,19 @@ fun showErrorHintByKey(project: Project, editor: Editor, messageKey: String, tit
}
fun selectElementsWithTargetSibling(
operationName: String,
editor: Editor,
file: KtFile,
title: String,
elementKinds: Collection<CodeInsightUtils.ElementKind>,
elementValidator: (List<PsiElement>) -> String?,
getContainers: (elements: List<PsiElement>, commonParent: PsiElement) -> List<PsiElement>,
continuation: (elements: List<PsiElement>, targetSibling: PsiElement) -> Unit
operationName: String,
editor: Editor,
file: KtFile,
title: String,
elementKinds: Collection<CodeInsightUtils.ElementKind>,
elementValidator: (List<PsiElement>) -> String?,
getContainers: (elements: List<PsiElement>, commonParent: PsiElement) -> List<PsiElement>,
continuation: (elements: List<PsiElement>, targetSibling: PsiElement) -> Unit
) {
fun onSelectionComplete(elements: List<PsiElement>, targetContainer: PsiElement) {
val physicalElements = elements.map { it.substringContextOrThis }
val parent = PsiTreeUtil.findCommonParent(physicalElements)
?: throw AssertionError("Should have at least one parent: ${physicalElements.joinToString("\n")}")
?: throw AssertionError("Should have at least one parent: ${physicalElements.joinToString("\n")}")
if (parent == targetContainer) {
continuation(elements, physicalElements.first())
@@ -74,14 +74,14 @@ fun selectElementsWithTargetSibling(
}
fun selectElementsWithTargetParent(
operationName: String,
editor: Editor,
file: KtFile,
title: String,
elementKinds: Collection<CodeInsightUtils.ElementKind>,
elementValidator: (List<PsiElement>) -> String?,
getContainers: (elements: List<PsiElement>, commonParent: PsiElement) -> List<PsiElement>,
continuation: (elements: List<PsiElement>, targetParent: PsiElement) -> Unit
operationName: String,
editor: Editor,
file: KtFile,
title: String,
elementKinds: Collection<CodeInsightUtils.ElementKind>,
elementValidator: (List<PsiElement>) -> String?,
getContainers: (elements: List<PsiElement>, commonParent: PsiElement) -> List<PsiElement>,
continuation: (elements: List<PsiElement>, targetParent: PsiElement) -> Unit
) {
fun showErrorHintByKey(key: String) {
showErrorHintByKey(file.project, editor, key, operationName)
@@ -95,7 +95,7 @@ fun selectElementsWithTargetParent(
val physicalElements = elements.map { it.substringContextOrThis }
val parent = PsiTreeUtil.findCommonParent(physicalElements)
?: throw AssertionError("Should have at least one parent: ${physicalElements.joinToString("\n")}")
?: throw AssertionError("Should have at least one parent: ${physicalElements.joinToString("\n")}")
val containers = getContainers(physicalElements, parent)
if (containers.isEmpty()) {
@@ -104,12 +104,12 @@ fun selectElementsWithTargetParent(
}
chooseContainerElementIfNecessary(
containers,
editor,
title,
true,
{ it },
{ continuation(elements, it) }
containers,
editor,
title,
true,
{ it },
{ continuation(elements, it) }
)
}
@@ -133,8 +133,7 @@ fun selectElementsWithTargetParent(
selectElement(editor, file, false, elementKinds) { expr ->
if (expr != null) {
selectTargetContainer(listOf(expr))
}
else {
} else {
if (!editor.selectionModel.hasSelection()) {
if (elementKinds.singleOrNull() == CodeInsightUtils.ElementKind.EXPRESSION) {
val elementAtCaret = file.findElementAt(editor.caretModel.offset)
@@ -221,7 +220,7 @@ fun ExtractableSubstringInfo.replaceWith(replacement: KtExpression): KtExpressio
fun KtExpression.mustBeParenthesizedInInitializerPosition(): Boolean {
if (this !is KtBinaryExpression) return false
if (left?.mustBeParenthesizedInInitializerPosition() ?: false) return true
if (left?.mustBeParenthesizedInInitializerPosition() == true) return true
return PsiChildRange(left, operationReference).any { (it is PsiWhiteSpace) && it.textContains('\n') }
}
@@ -36,9 +36,9 @@ import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
import java.util.*
class KotlinMemberInfoStorage(
classOrObject: KtClassOrObject,
filter: (KtNamedDeclaration) -> Boolean = { true }
): AbstractMemberInfoStorage<KtNamedDeclaration, PsiNamedElement, KotlinMemberInfo>(classOrObject, filter) {
classOrObject: KtClassOrObject,
filter: (KtNamedDeclaration) -> Boolean = { true }
) : AbstractMemberInfoStorage<KtNamedDeclaration, PsiNamedElement, KotlinMemberInfo>(classOrObject, filter) {
override fun memberConflict(member1: KtNamedDeclaration, member: KtNamedDeclaration): Boolean {
val descriptor1 = member1.resolveToDescriptorWrapperAware()
val descriptor = member.resolveToDescriptorWrapperAware()
@@ -50,7 +50,7 @@ class KotlinMemberInfoStorage(
!overloadUtil.isOverloadable(descriptor1, descriptor)
}
descriptor1 is PropertyDescriptor && descriptor is PropertyDescriptor ||
descriptor1 is ClassDescriptor && descriptor is ClassDescriptor -> true
descriptor1 is ClassDescriptor && descriptor is ClassDescriptor -> true
else -> false
}
}
@@ -81,14 +81,14 @@ class KotlinMemberInfoStorage(
}
fun extractClassMembers(
aClass: KtClassOrObject,
collectSuperTypeEntries: Boolean = true,
filter: ((KtNamedDeclaration) -> Boolean)? = null
aClass: KtClassOrObject,
collectSuperTypeEntries: Boolean = true,
filter: ((KtNamedDeclaration) -> Boolean)? = null
): List<KotlinMemberInfo> {
fun KtClassOrObject.extractFromClassBody(
filter: ((KtNamedDeclaration) -> Boolean)?,
isCompanion: Boolean,
result: MutableCollection<KotlinMemberInfo>
filter: ((KtNamedDeclaration) -> Boolean)?,
isCompanion: Boolean,
result: MutableCollection<KotlinMemberInfo>
) {
declarations
.asSequence()
@@ -98,7 +98,7 @@ fun extractClassMembers(
&& !(it is KtObjectDeclaration && it.isCompanion())
&& (filter == null || filter(it))
}
.mapTo(result) { KotlinMemberInfo(it as KtNamedDeclaration, isCompanionMember = isCompanion) }
.mapTo(result) { KotlinMemberInfo(it as KtNamedDeclaration, isCompanionMember = isCompanion) }
}
val result = ArrayList<KotlinMemberInfo>()
@@ -107,26 +107,25 @@ fun extractClassMembers(
aClass.superTypeListEntries
.asSequence()
.filterIsInstance<KtSuperTypeEntry>()
.mapNotNull {
val typeReference = it.typeReference ?: return@mapNotNull null
val type = typeReference.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, typeReference]
val classDescriptor = type?.constructor?.declarationDescriptor as? ClassDescriptor
val classPsi = classDescriptor?.source?.getPsi()
when (classPsi) {
is KtClass -> classPsi
is PsiClass -> KtPsiClassWrapper(classPsi)
else -> null
}
.mapNotNull {
val typeReference = it.typeReference ?: return@mapNotNull null
val type = typeReference.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, typeReference]
val classDescriptor = type?.constructor?.declarationDescriptor as? ClassDescriptor
when (val classPsi = classDescriptor?.source?.getPsi()) {
is KtClass -> classPsi
is PsiClass -> KtPsiClassWrapper(classPsi)
else -> null
}
.filter { it.isInterfaceClass() }
.mapTo(result) { KotlinMemberInfo(it, true) }
}
.filter { it.isInterfaceClass() }
.mapTo(result) { KotlinMemberInfo(it, true) }
}
aClass.primaryConstructor
?.valueParameters
?.asSequence()
?.filter { it.hasValOrVar() }
?.mapTo(result) { KotlinMemberInfo(it) }
?.mapTo(result) { KotlinMemberInfo(it) }
aClass.extractFromClassBody(filter, false, result)
(aClass as? KtClass)?.companionObjects?.firstOrNull()?.extractFromClassBody(filter, true, result)