From 1a9abaeb2ac8a2b47c5d0a3c5de166ba7a768791 Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Tue, 2 Jul 2019 20:38:35 +0700 Subject: [PATCH] Clean up move refactoring --- .../MoveMemberOutOfObjectIntention.kt | 8 +- .../move/AutocreatingPsiDirectoryWrapper.kt | 17 +- .../MoveJavaInnerClassKotlinUsagesHandler.kt | 30 +- ...veClassesOrPackagesToNewDirectoryDialog.kt | 21 +- ...ractDeclarationFromCurrentFileIntention.kt | 72 ++-- ...linAwareMoveFilesOrDirectoriesProcessor.kt | 71 ++-- .../move/moveDeclarations/KotlinMoveTarget.kt | 53 ++- .../MoveDeclarationsDelegate.kt | 44 +-- ...MoveFilesWithDeclarationsViewDescriptor.kt | 36 +- .../MoveKotlinDeclarationsProcessor.kt | 27 +- .../MoveToKotlinFileProcessor.kt | 70 ++-- .../moveDeclarations/moveConflictUtils.kt | 59 ++-- ...KotlinAwareMoveFilesOrDirectoriesDialog.kt | 58 ++-- ...otlinSelectNestedClassRefactoringDialog.kt | 49 ++- .../ui/MoveKotlinNestedClassesDialog.java | 103 +++--- ...KotlinNestedClassesToUpperLevelDialog.java | 101 +++--- .../MoveKotlinTopLevelDeclarationsDialog.java | 235 ++++--------- .../FqNameFixingMoveJavaFIleHandler.kt | 29 +- .../KotlinMoveDirectoryWithClassesHelper.kt | 67 ++-- .../KotlinMoveFilesOrDirectoriesHandler.kt | 31 +- .../MoveKotlinFileHandler.kt | 49 ++- .../kotlin/idea/refactoring/move/moveUtils.kt | 313 ++++++++++-------- .../idea/refactoring/move/AbstractMoveTest.kt | 139 ++++---- 23 files changed, 714 insertions(+), 968 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfObjectIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfObjectIntention.kt index 33f64c32172..28e43eb14bf 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfObjectIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfObjectIntention.kt @@ -49,10 +49,10 @@ abstract class MoveMemberOutOfObjectIntention(text: String) : SelfTargetingRange if (element is KtClassOrObject) { val moveDescriptor = MoveDeclarationsDescriptor( - project, - MoveSource(element), - KotlinMoveTargetForExistingElement(destination), - MoveDeclarationsDelegate.NestedClass() + project, + MoveSource(element), + KotlinMoveTargetForExistingElement(destination), + MoveDeclarationsDelegate.NestedClass() ) object : CompositeRefactoringRunner(project, MoveKotlinDeclarationsProcessor.REFACTORING_ID) { override fun runRefactoring() = MoveKotlinDeclarationsProcessor(moveDescriptor).run() diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/AutocreatingPsiDirectoryWrapper.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/AutocreatingPsiDirectoryWrapper.kt index 11f2378685b..0e61488f74d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/AutocreatingPsiDirectoryWrapper.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/AutocreatingPsiDirectoryWrapper.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move @@ -28,7 +17,7 @@ sealed class AutocreatingPsiDirectoryWrapper { class ByMoveDestination(private val moveDestination: MoveDestination) : AutocreatingPsiDirectoryWrapper() { override fun getPackageName() = moveDestination.targetPackage.qualifiedName - override fun getOrCreateDirectory(source: PsiDirectory) = moveDestination.getTargetDirectory(source) + override fun getOrCreateDirectory(source: PsiDirectory): PsiDirectory = moveDestination.getTargetDirectory(source) } abstract fun getPackageName(): String diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/MoveJavaInnerClassKotlinUsagesHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/MoveJavaInnerClassKotlinUsagesHandler.kt index 3edaceb07c2..84d17922b37 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/MoveJavaInnerClassKotlinUsagesHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/MoveJavaInnerClassKotlinUsagesHandler.kt @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move @@ -26,7 +15,7 @@ import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.psi.KtValueArgumentList import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector -class MoveJavaInnerClassKotlinUsagesHandler: MoveInnerClassUsagesHandler { +class MoveJavaInnerClassKotlinUsagesHandler : MoveInnerClassUsagesHandler { override fun correctInnerClassUsage(usage: UsageInfo, outerClass: PsiClass) { val innerCall = usage.element?.parent as? KtCallExpression ?: return val receiverExpression = innerCall.getQualifiedExpressionForSelector()?.receiverExpression @@ -35,13 +24,12 @@ class MoveJavaInnerClassKotlinUsagesHandler: MoveInnerClassUsagesHandler { val argumentToAdd = psiFactory.createArgument(receiverExpression ?: psiFactory.createExpression("this")) - val argumentList = - innerCall.valueArgumentList - ?: (innerCall.lambdaArguments.firstOrNull()?.let { lambdaArg -> - val anchor = PsiTreeUtil.skipSiblingsBackward(lambdaArg, PsiWhiteSpace::class.java) - innerCall.addAfter(psiFactory.createCallArguments("()"), anchor) - } as KtValueArgumentList?) - ?: return + val argumentList = innerCall.valueArgumentList + ?: (innerCall.lambdaArguments.firstOrNull()?.let { lambdaArg -> + val anchor = PsiTreeUtil.skipSiblingsBackward(lambdaArg, PsiWhiteSpace::class.java) + innerCall.addAfter(psiFactory.createCallArguments("()"), anchor) + } as KtValueArgumentList?) + ?: return argumentList.addArgumentAfter(argumentToAdd, null) } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveClassesOrPackages/KotlinAwareMoveClassesOrPackagesToNewDirectoryDialog.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveClassesOrPackages/KotlinAwareMoveClassesOrPackagesToNewDirectoryDialog.kt index 16965b54536..b990fc5f221 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveClassesOrPackages/KotlinAwareMoveClassesOrPackagesToNewDirectoryDialog.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveClassesOrPackages/KotlinAwareMoveClassesOrPackagesToNewDirectoryDialog.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveClassesOrPackages @@ -24,9 +13,9 @@ import com.intellij.refactoring.move.MoveCallback import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesToNewDirectoryDialog class KotlinAwareMoveClassesOrPackagesToNewDirectoryDialog( - directory: PsiDirectory, - elementsToMove: Array, - moveCallback: MoveCallback? + directory: PsiDirectory, + elementsToMove: Array, + moveCallback: MoveCallback? ) : MoveClassesOrPackagesToNewDirectoryDialog(directory, elementsToMove, moveCallback) { override fun createDestination(aPackage: PsiPackage, directory: PsiDirectory): MoveDestination? { val delegate = super.createDestination(aPackage, directory) ?: return null diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ExtractDeclarationFromCurrentFileIntention.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ExtractDeclarationFromCurrentFileIntention.kt index 63f5dc10131..fa86c37ab31 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ExtractDeclarationFromCurrentFileIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ExtractDeclarationFromCurrentFileIntention.kt @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations @@ -45,8 +34,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny private const val TIMEOUT_FOR_IMPORT_OPTIMIZING_MS: Long = 700L class ExtractDeclarationFromCurrentFileIntention : - SelfTargetingRangeIntention(KtClassOrObject::class.java, "Extract declaration from current file"), - LowPriorityAction { + SelfTargetingRangeIntention(KtClassOrObject::class.java, "Extract declaration from current file"), + LowPriorityAction { override fun applicabilityRange(element: KtClassOrObject): TextRange? { if (element.name == null) return null if (element.parent !is KtFile) return null @@ -89,17 +78,24 @@ class ExtractDeclarationFromCurrentFileIntention : // If automatic move is not possible, fall back to full-fledged Move Declarations refactoring ApplicationManager.getApplication().invokeLater { MoveKotlinTopLevelDeclarationsDialog( - project, - setOf(element), - packageName.asString(), - directory, - targetFile as? KtFile, - true, - true, - true, - MoveCallback { - runBlocking { withTimeoutOrNull(TIMEOUT_FOR_IMPORT_OPTIMIZING_MS) { OptimizeImportsProcessor(project, file).run() } } + project, + setOf(element), + packageName.asString(), + directory, + targetFile as? KtFile, + true, + true, + true, + MoveCallback { + runBlocking { + withTimeoutOrNull(TIMEOUT_FOR_IMPORT_OPTIMIZING_MS) { + OptimizeImportsProcessor( + project, + file + ).run() + } } + } ).show() } return @@ -108,19 +104,19 @@ class ExtractDeclarationFromCurrentFileIntention : createKotlinFile(targetFileName, directory, packageName.asString()) } val descriptor = MoveDeclarationsDescriptor( - project = project, - moveSource = MoveSource(element), - moveTarget = moveTarget, - delegate = MoveDeclarationsDelegate.TopLevel, - searchInCommentsAndStrings = false, - searchInNonCode = false, - moveCallback = MoveCallback { - val newFile = directory.findFile(targetFileName) as KtFile - val newDeclaration = newFile.declarations.first() - NavigationUtil.activateFileWithPsiElement(newFile) - FileEditorManager.getInstance(project).selectedTextEditor?.moveCaret(newDeclaration.startOffset + originalOffset) - runBlocking { withTimeoutOrNull(TIMEOUT_FOR_IMPORT_OPTIMIZING_MS) { OptimizeImportsProcessor(project, file).run() } } - } + project = project, + moveSource = MoveSource(element), + moveTarget = moveTarget, + delegate = MoveDeclarationsDelegate.TopLevel, + searchInCommentsAndStrings = false, + searchInNonCode = false, + moveCallback = MoveCallback { + val newFile = directory.findFile(targetFileName) as KtFile + val newDeclaration = newFile.declarations.first() + NavigationUtil.activateFileWithPsiElement(newFile) + FileEditorManager.getInstance(project).selectedTextEditor?.moveCaret(newDeclaration.startOffset + originalOffset) + runBlocking { withTimeoutOrNull(TIMEOUT_FOR_IMPORT_OPTIMIZING_MS) { OptimizeImportsProcessor(project, file).run() } } + } ) MoveKotlinDeclarationsProcessor(descriptor).run() diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/KotlinAwareMoveFilesOrDirectoriesProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/KotlinAwareMoveFilesOrDirectoriesProcessor.kt index ce875bc9dcf..3d8bbf28aaa 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/KotlinAwareMoveFilesOrDirectoriesProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/KotlinAwareMoveFilesOrDirectoriesProcessor.kt @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations @@ -32,49 +21,40 @@ import org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.allElem import org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.shouldFixFqName import org.jetbrains.kotlin.psi.KtFile -class KotlinAwareMoveFilesOrDirectoriesProcessor @JvmOverloads constructor ( - project: Project, - private val elementsToMove: List, - private val targetDirectory: PsiDirectory, - private val searchReferences: Boolean, - searchInComments: Boolean, - searchInNonJavaFiles: Boolean, - moveCallback: MoveCallback?, - prepareSuccessfulCallback: Runnable = EmptyRunnable.INSTANCE -) : MoveFilesOrDirectoriesProcessor(project, - elementsToMove.toTypedArray(), - targetDirectory, - true, - searchInComments, - searchInNonJavaFiles, - moveCallback, - prepareSuccessfulCallback) { +class KotlinAwareMoveFilesOrDirectoriesProcessor @JvmOverloads constructor( + project: Project, + private val elementsToMove: List, + private val targetDirectory: PsiDirectory, + private val searchReferences: Boolean, + searchInComments: Boolean, + searchInNonJavaFiles: Boolean, + moveCallback: MoveCallback?, + prepareSuccessfulCallback: Runnable = EmptyRunnable.INSTANCE +) : MoveFilesOrDirectoriesProcessor( + project, + elementsToMove.toTypedArray(), + targetDirectory, + true, + searchInComments, + searchInNonJavaFiles, + moveCallback, + prepareSuccessfulCallback +) { override fun createUsageViewDescriptor(usages: Array): UsageViewDescriptor { - return MoveFilesWithDeclarationsViewDescriptor(elementsToMove.toTypedArray(), targetDirectory) + return MoveFilesWithDeclarationsViewDescriptor(elementsToMove.toTypedArray(), targetDirectory) } override fun findUsages(): Array { try { markScopeToMove(elementsToMove) return if (searchReferences) super.findUsages() else UsageInfo.EMPTY_ARRAY - } - finally { + } finally { markScopeToMove(null) } } override fun preprocessUsages(refUsages: Ref>): Boolean { - val usages = refUsages.get() - - val (conflictUsages, usagesToProcess) = usages.partition { it is ConflictUsageInfo } - - val conflicts = MultiMap() - for (conflictUsage in conflictUsages) { - conflicts.putValues(conflictUsage.element, (conflictUsage as ConflictUsageInfo).messages) - } - - refUsages.set(usagesToProcess.toTypedArray()) - + val (conflicts, usages) = MoveToKotlinFileProcessor.preprocessConflictUsages(refUsages) return showConflicts(conflicts, usages) } @@ -101,8 +81,7 @@ class KotlinAwareMoveFilesOrDirectoriesProcessor @JvmOverloads constructor ( try { markShouldFixFqName(true) super.performRefactoring(usages) - } - finally { + } finally { markShouldFixFqName(false) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/KotlinMoveTarget.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/KotlinMoveTarget.kt index 20009f82fbb..4cf1949d97d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/KotlinMoveTarget.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/KotlinMoveTarget.kt @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations @@ -52,16 +41,16 @@ interface KotlinDirectoryBasedMoveTarget : KotlinMoveTarget { get() = super.targetScope ?: directory?.virtualFile } -object EmptyKotlinMoveTarget: KotlinMoveTarget { - override val targetContainerFqName = null - override val targetFile = null +object EmptyKotlinMoveTarget : KotlinMoveTarget { + override val targetContainerFqName: FqName? = null + override val targetFile: VirtualFile? = null - override fun getOrCreateTargetPsi(originalPsi: PsiElement) = null - override fun getTargetPsiIfExists(originalPsi: PsiElement) = null - override fun verify(file: PsiFile) = null + override fun getOrCreateTargetPsi(originalPsi: PsiElement): KtElement? = null + override fun getTargetPsiIfExists(originalPsi: PsiElement): KtElement? = null + override fun verify(file: PsiFile): String? = null } -class KotlinMoveTargetForExistingElement(val targetElement: KtElement): KotlinMoveTarget { +class KotlinMoveTargetForExistingElement(val targetElement: KtElement) : KotlinMoveTarget { override val targetContainerFqName = targetElement.containingKtFile.packageFqName override val targetFile: VirtualFile? = targetElement.containingKtFile.virtualFile @@ -74,9 +63,9 @@ class KotlinMoveTargetForExistingElement(val targetElement: KtElement): KotlinMo override fun verify(file: PsiFile): String? = null } -class KotlinMoveTargetForCompanion(val targetClass: KtClass): KotlinMoveTarget { +class KotlinMoveTargetForCompanion(val targetClass: KtClass) : KotlinMoveTarget { override val targetContainerFqName = targetClass.companionObjects.firstOrNull()?.fqName - ?: targetClass.fqName!!.child(SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT) + ?: targetClass.fqName!!.child(SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT) override val targetFile: VirtualFile? = targetClass.containingKtFile.virtualFile @@ -89,11 +78,11 @@ class KotlinMoveTargetForCompanion(val targetClass: KtClass): KotlinMoveTarget { } class KotlinMoveTargetForDeferredFile( - override val targetContainerFqName: FqName, - override val directory: PsiDirectory?, - override val targetFile: VirtualFile? = directory?.virtualFile, - private val createFile: (KtFile) -> KtFile? -): KotlinDirectoryBasedMoveTarget { + override val targetContainerFqName: FqName, + override val directory: PsiDirectory?, + override val targetFile: VirtualFile? = directory?.virtualFile, + private val createFile: (KtFile) -> KtFile? +) : KotlinDirectoryBasedMoveTarget { private val createdFiles = HashMap() override fun getOrCreateTargetPsi(originalPsi: PsiElement): KtElement? { @@ -101,23 +90,23 @@ class KotlinMoveTargetForDeferredFile( return createdFiles.getOrPutNullable(originalFile) { createFile(originalFile) } } - override fun getTargetPsiIfExists(originalPsi: PsiElement) = null + override fun getTargetPsiIfExists(originalPsi: PsiElement): KtElement? = null // No additional verification is needed override fun verify(file: PsiFile): String? = null } class KotlinDirectoryMoveTarget( - override val targetContainerFqName: FqName, - override val directory: PsiDirectory + override val targetContainerFqName: FqName, + override val directory: PsiDirectory ) : KotlinDirectoryBasedMoveTarget { override val targetFile: VirtualFile? = directory.virtualFile override fun getOrCreateTargetPsi(originalPsi: PsiElement) = originalPsi.containingFile as? KtFile - override fun getTargetPsiIfExists(originalPsi: PsiElement) = null + override fun getTargetPsiIfExists(originalPsi: PsiElement): KtElement? = null - override fun verify(file: PsiFile) = null + override fun verify(file: PsiFile): String? = null } fun KotlinMoveTarget.getTargetModule(project: Project) = targetScope?.getModule(project) \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt index a47ff24b646..db527ef7739 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations @@ -39,9 +28,9 @@ sealed class MoveDeclarationsDelegate { open fun findInternalUsages(descriptor: MoveDeclarationsDescriptor): List = emptyList() open fun collectConflicts( - descriptor: MoveDeclarationsDescriptor, - internalUsages: MutableSet, - conflicts: MultiMap + descriptor: MoveDeclarationsDescriptor, + internalUsages: MutableSet, + conflicts: MultiMap ) { } @@ -63,8 +52,8 @@ sealed class MoveDeclarationsDelegate { } class NestedClass( - val newClassName: String? = null, - val outerInstanceParameterName: String? = null + val newClassName: String? = null, + val outerInstanceParameterName: String? = null ) : MoveDeclarationsDelegate() { override fun getContainerChangeInfo(originalDeclaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): ContainerChangeInfo { val originalInfo = ContainerInfo.Class(originalDeclaration.containingClassOrObject!!.fqName!!) @@ -84,11 +73,10 @@ sealed class MoveDeclarationsDelegate { } private fun isValidTargetForImplicitCompanionAsDispatchReceiver( - moveDescriptor: MoveDeclarationsDescriptor, - companionDescriptor: ClassDescriptor + moveDescriptor: MoveDeclarationsDescriptor, + companionDescriptor: ClassDescriptor ): Boolean { - val moveTarget = moveDescriptor.moveTarget - return when (moveTarget) { + return when (val moveTarget = moveDescriptor.moveTarget) { is KotlinMoveTargetForCompanion -> true is KotlinMoveTargetForExistingElement -> { val targetClass = moveTarget.targetElement as? KtClassOrObject ?: return false @@ -101,9 +89,9 @@ sealed class MoveDeclarationsDelegate { } override fun collectConflicts( - descriptor: MoveDeclarationsDescriptor, - internalUsages: MutableSet, - conflicts: MultiMap + descriptor: MoveDeclarationsDescriptor, + internalUsages: MutableSet, + conflicts: MultiMap ) { val usageIterator = internalUsages.iterator() while (usageIterator.hasNext()) { @@ -141,7 +129,7 @@ sealed class MoveDeclarationsDelegate { if (outerInstanceParameterName != null) { val type = (containingClassOrObject!!.unsafeResolveToDescriptor() as ClassDescriptor).defaultType val parameter = KtPsiFactory(project) - .createParameter("private val $outerInstanceParameterName: ${IdeDescriptorRenderers.SOURCE_CODE.renderType(type)}") + .createParameter("private val $outerInstanceParameterName: ${IdeDescriptorRenderers.SOURCE_CODE.renderType(type)}") createPrimaryConstructorParameterListIfAbsent().addParameter(parameter).isToBeShortened = true } } @@ -162,8 +150,8 @@ sealed class MoveDeclarationsDelegate { val lightOuterClass = outerClass?.toLightClass() if (lightOuterClass != null) { MoveInnerClassUsagesHandler.EP_NAME - .forLanguage(usage.element!!.language) - ?.correctInnerClassUsage(usage, lightOuterClass, outerInstanceParameterName) + .forLanguage(usage.element!!.language) + ?.correctInnerClassUsage(usage, lightOuterClass, outerInstanceParameterName) } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveFilesWithDeclarationsViewDescriptor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveFilesWithDeclarationsViewDescriptor.kt index 53348efff02..c845589e86d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveFilesWithDeclarationsViewDescriptor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveFilesWithDeclarationsViewDescriptor.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations @@ -25,21 +14,24 @@ import com.intellij.usageView.UsageViewDescriptor import com.intellij.usageView.UsageViewUtil internal class MoveFilesWithDeclarationsViewDescriptor( - private val myElementsToMove: Array, - newParent: PsiDirectory + private val myElementsToMove: Array, + newParent: PsiDirectory ) : UsageViewDescriptor { private var myProcessedElementsHeader: String? = null private val myCodeReferencesText: String init { if (myElementsToMove.size == 1) { - myProcessedElementsHeader = RefactoringBundle.message("move.single.element.elements.header", - UsageViewUtil.getType(myElementsToMove[0]), - newParent.virtualFile.presentableUrl).capitalize() - myCodeReferencesText = "References in code to ${UsageViewUtil.getType(myElementsToMove[0])} ${UsageViewUtil.getLongName(myElementsToMove[0])} and its declarations" - } - else { - myProcessedElementsHeader = StringUtil.capitalize(RefactoringBundle.message("move.files.elements.header", newParent.virtualFile.presentableUrl)) + myProcessedElementsHeader = RefactoringBundle.message( + "move.single.element.elements.header", + UsageViewUtil.getType(myElementsToMove[0]), + newParent.virtualFile.presentableUrl + ).capitalize() + myCodeReferencesText = + "References in code to ${UsageViewUtil.getType(myElementsToMove[0])} ${UsageViewUtil.getLongName(myElementsToMove[0])} and its declarations" + } else { + myProcessedElementsHeader = + StringUtil.capitalize(RefactoringBundle.message("move.files.elements.header", newParent.virtualFile.presentableUrl)) myCodeReferencesText = RefactoringBundle.message("references.found.in.code") } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt index 052c83daa61..53befa2a9bb 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations @@ -153,10 +142,13 @@ class MoveKotlinDeclarationsProcessor( private var nonCodeUsages: Array? = null private val moveEntireFile = descriptor.moveSource is MoveSource.File - private val elementsToMove = descriptor.moveSource.elementsToMove.filter { e -> e.parent != descriptor.moveTarget.getTargetPsiIfExists(e) } + private val elementsToMove = descriptor.moveSource.elementsToMove.filter { e -> + e.parent != descriptor.moveTarget.getTargetPsiIfExists(e) + } + private val kotlinToLightElementsBySourceFile = elementsToMove .groupBy { it.containingKtFile } - .mapValues { it.value.keysToMap { it.toLightElements().ifEmpty { listOf(it) } } } + .mapValues { it.value.keysToMap { declaration -> declaration.toLightElements().ifEmpty { listOf(declaration) } } } private val conflicts = MultiMap() override fun getRefactoringId() = REFACTORING_ID @@ -209,10 +201,9 @@ class MoveKotlinDeclarationsProcessor( val results = ReferencesSearch .search(lightElement, searchScope) .mapNotNullTo(ArrayList()) { ref -> - if (foundReferences.add(ref) && elementsToMove.none { it.isAncestor(ref.element)}) { + if (foundReferences.add(ref) && elementsToMove.none { it.isAncestor(ref.element) }) { createMoveUsageInfoIfPossible(ref, lightElement, addImportToOriginalFile = true, isInternal = false) - } - else null + } else null } val name = lightElement.getKotlinFqName()?.quoteIfNeeded()?.asString() diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveToKotlinFileProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveToKotlinFileProcessor.kt index a97dbbefbd5..702193785ed 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveToKotlinFileProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveToKotlinFileProcessor.kt @@ -29,23 +29,25 @@ import com.intellij.util.containers.MultiMap import com.intellij.util.text.UniqueNameGenerator import org.jetbrains.kotlin.psi.KtFile -class MoveToKotlinFileProcessor @JvmOverloads constructor ( - project: Project, - private val sourceFile: KtFile, - private val targetDirectory: PsiDirectory, - private val targetFileName: String, - searchInComments: Boolean, - searchInNonJavaFiles: Boolean, - moveCallback: MoveCallback?, - prepareSuccessfulCallback: Runnable = EmptyRunnable.INSTANCE -) : MoveFilesOrDirectoriesProcessor(project, - arrayOf(sourceFile), - targetDirectory, - true, - searchInComments, - searchInNonJavaFiles, - moveCallback, - prepareSuccessfulCallback) { +class MoveToKotlinFileProcessor @JvmOverloads constructor( + project: Project, + private val sourceFile: KtFile, + private val targetDirectory: PsiDirectory, + private val targetFileName: String, + searchInComments: Boolean, + searchInNonJavaFiles: Boolean, + moveCallback: MoveCallback?, + prepareSuccessfulCallback: Runnable = EmptyRunnable.INSTANCE +) : MoveFilesOrDirectoriesProcessor( + project, + arrayOf(sourceFile), + targetDirectory, + true, + searchInComments, + searchInNonJavaFiles, + moveCallback, + prepareSuccessfulCallback +) { override fun getCommandName() = "Move ${sourceFile.name}" override fun createUsageViewDescriptor(usages: Array): UsageViewDescriptor { @@ -53,17 +55,7 @@ class MoveToKotlinFileProcessor @JvmOverloads constructor ( } override fun preprocessUsages(refUsages: Ref>): Boolean { - val usages = refUsages.get() - - val (conflictUsages, usagesToProcess) = usages.partition { it is ConflictUsageInfo } - - val conflicts = MultiMap() - for (conflictUsage in conflictUsages) { - conflicts.putValues(conflictUsage.element, (conflictUsage as ConflictUsageInfo).messages) - } - - refUsages.set(usagesToProcess.toTypedArray()) - + val (conflicts, usages) = preprocessConflictUsages(refUsages) return showConflicts(conflicts, usages) } @@ -85,11 +77,29 @@ class MoveToKotlinFileProcessor @JvmOverloads constructor ( try { super.performRefactoring(usages) - } - finally { + } finally { if (needTemporaryRename) { sourceFile.name = targetFileName } } } + + companion object { + data class ConflictUsages(val conflicts: MultiMap, @Suppress("ArrayInDataClass") val usages: Array) + + fun preprocessConflictUsages(refUsages: Ref>): ConflictUsages { + val usages: Array = refUsages.get() + + val (conflictUsages, usagesToProcess) = usages.partition { it is ConflictUsageInfo } + + val conflicts = MultiMap() + for (conflictUsage in conflictUsages) { + conflicts.putValues(conflictUsage.element, (conflictUsage as ConflictUsageInfo).messages) + } + + refUsages.set(usagesToProcess.toTypedArray()) + + return ConflictUsages(conflicts, usages) + } + } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt index 9f121f21a18..c84357638fd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations @@ -62,6 +51,7 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.load.java.JavaVisibilities import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.renderer.ClassifierNamePolicy @@ -73,7 +63,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf -import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile import org.jetbrains.kotlin.resolve.source.KotlinSourceElement @@ -115,22 +104,19 @@ class MoveConflictChecker( private fun KotlinMoveTarget.getContainerDescriptor(): DeclarationDescriptor? { return when (this) { - is KotlinMoveTargetForExistingElement -> { - val targetElement = targetElement - when (targetElement) { - is KtNamedDeclaration -> resolutionFacade.resolveToDescriptor(targetElement) + is KotlinMoveTargetForExistingElement -> when (val targetElement = targetElement) { + is KtNamedDeclaration -> resolutionFacade.resolveToDescriptor(targetElement) - is KtFile -> { - val packageFragment = - targetElement - .findModuleDescriptor() - .findPackageFragmentForFile(targetElement) + is KtFile -> { + val packageFragment = + targetElement + .findModuleDescriptor() + .findPackageFragmentForFile(targetElement) - packageFragment?.withSource(targetElement) - } - - else -> null + packageFragment?.withSource(targetElement) } + + else -> null } is KotlinDirectoryBasedMoveTarget -> { @@ -159,8 +145,7 @@ class MoveConflictChecker( ): DeclarationDescriptor? { if (newContainer == null && newVisibility == null) return this - val wrappedDescriptor = this - return when (wrappedDescriptor) { + return when (val wrappedDescriptor = this) { // We rely on visibility not depending on more specific type of CallableMemberDescriptor is CallableMemberDescriptor -> object : CallableMemberDescriptor by wrappedDescriptor { override fun getOriginal() = this @@ -255,7 +240,7 @@ class MoveConflictChecker( val referencedElementsToSkip = newConflicts.keySet().mapNotNullTo(HashSet()) { it.namedUnwrappedElement } externalUsages.removeIf { it is MoveRenameUsageInfo && - it.referencedElement?.namedUnwrappedElement?.let { it in referencedElementsToSkip } ?: false + it.referencedElement?.namedUnwrappedElement?.let { element -> element in referencedElementsToSkip } ?: false } conflicts.putAllValues(newConflicts) } @@ -318,20 +303,20 @@ class MoveConflictChecker( val renderedImportableTarget = DESCRIPTOR_RENDERER_FOR_COMPARISON.render(importableDescriptor) val renderedTarget by lazy { DESCRIPTOR_RENDERER_FOR_COMPARISON.render(targetDescriptor) } - return newTargetDescriptors.any { - if (DESCRIPTOR_RENDERER_FOR_COMPARISON.render(it) != renderedImportableTarget) return@any false + return newTargetDescriptors.any { descriptor -> + if (DESCRIPTOR_RENDERER_FOR_COMPARISON.render(descriptor) != renderedImportableTarget) return@any false if (importableDescriptor == targetDescriptor) return@any true val candidateDescriptors: Collection = when (targetDescriptor) { is ConstructorDescriptor -> { - (it as? ClassDescriptor)?.constructors ?: emptyList() + (descriptor as? ClassDescriptor)?.constructors ?: emptyList() } is PropertyAccessorDescriptor -> { - (it as? PropertyDescriptor) + (descriptor as? PropertyDescriptor) ?.let { if (targetDescriptor is PropertyGetterDescriptor) it.getter else it.setter } ?.let { listOf(it) } - ?: emptyList() + ?: emptyList() } else -> emptyList() @@ -375,7 +360,7 @@ class MoveConflictChecker( referencesToSkip += refExpr } } - internalUsages.removeIf { it.reference?.element?.let { it in referencesToSkip } ?: false } + internalUsages.removeIf { it.reference?.element?.let { element -> element in referencesToSkip } ?: false } } fun checkVisibilityInUsages(usages: Collection, conflicts: MultiMap) { @@ -396,7 +381,7 @@ class MoveConflictChecker( ) continue val container = element.getUsageContext() - if (!declarationToContainers.getOrPut(referencedElement) { HashSet() }.add(container)) continue + if (!declarationToContainers.getOrPut(referencedElement) { HashSet() }.add(container)) continue val targetContainer = moveTarget.getContainerDescriptor() ?: continue diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/KotlinAwareMoveFilesOrDirectoriesDialog.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/KotlinAwareMoveFilesOrDirectoriesDialog.kt index 925eeb3ed95..0843734aa6d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/KotlinAwareMoveFilesOrDirectoriesDialog.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/KotlinAwareMoveFilesOrDirectoriesDialog.kt @@ -1,5 +1,5 @@ /* - * Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -41,13 +41,13 @@ import java.io.File import javax.swing.JComponent class KotlinAwareMoveFilesOrDirectoriesDialog( - private val project: Project, - private val initialDirectory: PsiDirectory?, - private val callback: (KotlinAwareMoveFilesOrDirectoriesDialog?) -> Unit + private val project: Project, + private val initialDirectory: PsiDirectory?, + private val callback: (KotlinAwareMoveFilesOrDirectoriesDialog?) -> Unit ) : DialogWrapper(project, true) { companion object { - private val RECENT_KEYS = "MoveFile.RECENT_KEYS" - private val MOVE_FILES_OPEN_IN_EDITOR = "MoveFile.OpenInEditor" + private const val RECENT_KEYS = "MoveFile.RECENT_KEYS" + private const val MOVE_FILES_OPEN_IN_EDITOR = "MoveFile.OpenInEditor" } private val nameLabel = JBLabelDecorator.createJBLabelDecorator().setBold(true) @@ -81,11 +81,13 @@ class KotlinAwareMoveFilesOrDirectoriesDialog( RecentsManager.getInstance(project).getRecentEntries(RECENT_KEYS)?.let { targetDirectoryField.childComponent.history = it } val descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor() - targetDirectoryField.addBrowseFolderListener(RefactoringBundle.message("select.target.directory"), - RefactoringBundle.message("the.file.will.be.moved.to.this.directory"), - project, - descriptor, - TextComponentAccessor.TEXT_FIELD_WITH_HISTORY_WHOLE_TEXT) + targetDirectoryField.addBrowseFolderListener( + RefactoringBundle.message("select.target.directory"), + RefactoringBundle.message("the.file.will.be.moved.to.this.directory"), + project, + descriptor, + TextComponentAccessor.TEXT_FIELD_WITH_HISTORY_WHOLE_TEXT + ) val textField = targetDirectoryField.childComponent.textEditor FileChooserFactory.getInstance().installFileCompletion(textField, descriptor, true, disposable) textField.onTextChange { validateOKButton() } @@ -96,13 +98,13 @@ class KotlinAwareMoveFilesOrDirectoriesDialog( val shortcutText = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_CODE_COMPLETION)) return FormBuilder.createFormBuilder() - .addComponent(nameLabel) - .addLabeledComponent(RefactoringBundle.message("move.files.to.directory.label"), targetDirectoryField, UIUtil.LARGE_VGAP) - .addTooltip(RefactoringBundle.message("path.completion.shortcut", shortcutText)) - .addComponentToRightColumn(searchReferencesCb, UIUtil.LARGE_VGAP) - .addComponentToRightColumn(openInEditorCb, UIUtil.LARGE_VGAP) - .addComponentToRightColumn(updatePackageDirectiveCb, UIUtil.LARGE_VGAP) - .panel + .addComponent(nameLabel) + .addLabeledComponent(RefactoringBundle.message("move.files.to.directory.label"), targetDirectoryField, UIUtil.LARGE_VGAP) + .addTooltip(RefactoringBundle.message("path.completion.shortcut", shortcutText)) + .addComponentToRightColumn(searchReferencesCb, UIUtil.LARGE_VGAP) + .addComponentToRightColumn(openInEditorCb, UIUtil.LARGE_VGAP) + .addComponentToRightColumn(updatePackageDirectiveCb, UIUtil.LARGE_VGAP) + .panel } fun setData(psiElements: Array, initialTargetDirectory: PsiDirectory?, helpID: String) { @@ -113,8 +115,7 @@ class KotlinAwareMoveFilesOrDirectoriesDialog( is PsiFile -> RefactoringBundle.message("move.file.0", shortenedPath) else -> RefactoringBundle.message("move.directory.0", shortenedPath) } - } - else { + } else { val isFile = psiElements.all { it is PsiFile } val isDirectory = psiElements.all { it is PsiDirectory } nameLabel.text = when { @@ -129,7 +130,7 @@ class KotlinAwareMoveFilesOrDirectoriesDialog( validateOKButton() this.helpID = helpID - with (updatePackageDirectiveCb) { + with(updatePackageDirectiveCb) { val jetFiles = psiElements.filterIsInstance().filter(KtFile::isInJavaSourceRoot) if (jetFiles.isEmpty()) { parent.remove(updatePackageDirectiveCb) @@ -150,7 +151,7 @@ class KotlinAwareMoveFilesOrDirectoriesDialog( } private fun validateOKButton() { - isOKActionEnabled = targetDirectoryField.childComponent.text.length > 0 + isOKActionEnabled = targetDirectoryField.childComponent.text.isNotEmpty() } override fun doOKAction() { @@ -172,17 +173,18 @@ class KotlinAwareMoveFilesOrDirectoriesDialog( } try { targetDirectory = DirectoryUtil.mkdirs(PsiManager.getInstance(project), directoryName) - } - catch (e: IncorrectOperationException) { + } catch (e: IncorrectOperationException) { // ignore } } if (targetDirectory == null) { - CommonRefactoringUtil.showErrorMessage(title, - RefactoringBundle.message("cannot.create.directory"), - helpID, - project) + CommonRefactoringUtil.showErrorMessage( + title, + RefactoringBundle.message("cannot.create.directory"), + helpID, + project + ) return@executeCommand } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/KotlinSelectNestedClassRefactoringDialog.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/KotlinSelectNestedClassRefactoringDialog.kt index e4cdb232a74..0344bfe3c6c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/KotlinSelectNestedClassRefactoringDialog.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/KotlinSelectNestedClassRefactoringDialog.kt @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui @@ -29,10 +18,10 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import java.awt.BorderLayout import javax.swing.* -internal class KotlinSelectNestedClassRefactoringDialog private constructor ( - project: Project, - private val nestedClass: KtClassOrObject, - private val targetContainer: PsiElement? +internal class KotlinSelectNestedClassRefactoringDialog private constructor( + project: Project, + private val nestedClass: KtClassOrObject, + private val targetContainer: PsiElement? ) : DialogWrapper(project, true) { private val moveToUpperLevelButton = JRadioButton() private val moveMembersButton = JRadioButton() @@ -83,32 +72,34 @@ internal class KotlinSelectNestedClassRefactoringDialog private constructor ( companion object { private fun MoveKotlinNestedClassesToUpperLevelDialog( - nestedClass: KtClassOrObject, - targetContainer: PsiElement? + nestedClass: KtClassOrObject, + targetContainer: PsiElement? ): MoveKotlinNestedClassesToUpperLevelDialog? { val outerClass = nestedClass.containingClassOrObject ?: return null val newTarget = targetContainer - ?: outerClass.containingClassOrObject - ?: outerClass.containingFile.let { it.containingDirectory ?: it } + ?: outerClass.containingClassOrObject + ?: outerClass.containingFile.let { it.containingDirectory ?: it } return MoveKotlinNestedClassesToUpperLevelDialog(nestedClass.project, nestedClass, newTarget) } private fun MoveKotlinNestedClassesDialog( - nestedClass: KtClassOrObject, - targetContainer: PsiElement? + nestedClass: KtClassOrObject, + targetContainer: PsiElement? ): MoveKotlinNestedClassesDialog { - return MoveKotlinNestedClassesDialog(nestedClass.project, - listOf(nestedClass), - nestedClass.containingClassOrObject!!, - targetContainer as? KtClassOrObject ?: nestedClass.containingClassOrObject!!, - null) + return MoveKotlinNestedClassesDialog( + nestedClass.project, + listOf(nestedClass), + nestedClass.containingClassOrObject!!, + targetContainer as? KtClassOrObject ?: nestedClass.containingClassOrObject!!, + null + ) } fun chooseNestedClassRefactoring(nestedClass: KtClassOrObject, targetContainer: PsiElement?) { val project = nestedClass.project val dialog = when { targetContainer != null && targetContainer !is KtClassOrObject || - nestedClass is KtClass && nestedClass.isInner() -> { + nestedClass is KtClass && nestedClass.isInner() -> { MoveKotlinNestedClassesToUpperLevelDialog(nestedClass, targetContainer) } nestedClass is KtEnumEntry -> return diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesDialog.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesDialog.java index a6552f6cf28..3062e75a143 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesDialog.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesDialog.java @@ -1,23 +1,10 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui; -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.ide.util.ClassFilter; import com.intellij.ide.util.TreeClassChooser; import com.intellij.ide.util.TreeJavaClassChooserDialog; import com.intellij.openapi.editor.event.DocumentEvent; @@ -36,7 +23,6 @@ import com.intellij.refactoring.move.MoveCallback; import com.intellij.refactoring.move.MoveHandler; import com.intellij.refactoring.ui.RefactoringDialog; import kotlin.collections.CollectionsKt; -import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.asJava.LightClassUtilsKt; @@ -59,8 +45,7 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; - -import static org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveKotlinDeclarationsProcessorKt.MoveSource; +import java.util.Objects; public class MoveKotlinNestedClassesDialog extends RefactoringDialog { private static final String RECENTS_KEY = MoveKotlinNestedClassesDialog.class.getName() + ".RECENTS_KEY"; @@ -74,6 +59,7 @@ public class MoveKotlinNestedClassesDialog extends RefactoringDialog { private JPanel targetClassChooserPanel; private KotlinMemberSelectionTable memberTable; private PsiElement targetClass; + public MoveKotlinNestedClassesDialog( @NotNull Project project, @NotNull List elementsToMove, @@ -111,23 +97,20 @@ public class MoveKotlinNestedClassesDialog extends RefactoringDialog { RefactoringBundle.message("choose.destination.class"), myProject, GlobalSearchScope.projectScope(myProject), - new ClassFilter() { - @Override - public boolean isAccepted(PsiClass aClass) { - if (!(aClass instanceof KtLightClassForSourceDeclaration)) return false; - KtClassOrObject classOrObject = ((KtLightClassForSourceDeclaration) aClass).getKotlinOrigin(); + aClass -> { + if (!(aClass instanceof KtLightClassForSourceDeclaration)) return false; + KtClassOrObject classOrObject = ((KtLightClassForSourceDeclaration) aClass).getKotlinOrigin(); - if (classOrObject instanceof KtObjectDeclaration) { - return !((KtObjectDeclaration) classOrObject).isObjectLiteral(); - } - - if (classOrObject instanceof KtClass) { - KtClass ktClass = (KtClass) classOrObject; - return !(ktClass.isInner() || ktClass.isAnnotation()); - } - - return false; + if (classOrObject instanceof KtObjectDeclaration) { + return !((KtObjectDeclaration) classOrObject).isObjectLiteral(); } + + if (classOrObject instanceof KtClass) { + KtClass ktClass = (KtClass) classOrObject; + return !(ktClass.isInner() || ktClass.isAnnotation()); + } + + return false; }, null, null, @@ -144,13 +127,14 @@ public class MoveKotlinNestedClassesDialog extends RefactoringDialog { return LightClassUtilsKt.toLightClass(((KtClassOrObjectTreeNode) userObject).getValue()); } }; - chooser.selectDirectory((targetClass != null ? targetClass : originalClass).getContainingFile().getContainingDirectory()); + chooser.selectDirectory( + (targetClass != null ? targetClass : originalClass).getContainingFile().getContainingDirectory()); chooser.showDialog(); PsiClass aClass = chooser.getSelected(); if (aClass instanceof KtLightClassForSourceDeclaration) { targetClass = ((KtLightClassForSourceDeclaration) aClass).getKotlinOrigin(); - targetClassChooser.setText(aClass.getQualifiedName()); + targetClassChooser.setText(Objects.requireNonNull(aClass.getQualifiedName())); } else { targetClass = aClass; @@ -164,15 +148,12 @@ public class MoveKotlinNestedClassesDialog extends RefactoringDialog { if (codeFragment != null) { CompletionUtilsKt.setExtraCompletionFilter( codeFragment, - new Function1() { - @Override - public Boolean invoke(LookupElement lookupElement) { - Object lookupObject = lookupElement.getObject(); - if (!(lookupObject instanceof DeclarationLookupObject)) return false; - PsiElement psiElement = ((DeclarationLookupObject) lookupObject).getPsiElement(); - if (lookupObject instanceof PackageLookupObject) return true; - return (psiElement instanceof KtClassOrObject) && KotlinRefactoringUtilKt.canRefactor(psiElement); - } + lookupElement -> { + Object lookupObject = lookupElement.getObject(); + if (!(lookupObject instanceof DeclarationLookupObject)) return false; + PsiElement psiElement = ((DeclarationLookupObject) lookupObject).getPsiElement(); + if (lookupObject instanceof PackageLookupObject) return true; + return (psiElement instanceof KtClassOrObject) && KotlinRefactoringUtilKt.canRefactor(psiElement); } ); } @@ -193,28 +174,27 @@ public class MoveKotlinNestedClassesDialog extends RefactoringDialog { targetClassChooserPanel.add(targetClassChooser); } - private void initMemberInfo(@NotNull final List elementsToMove) { + private void initMemberInfo(@NotNull List elementsToMove) { List memberInfos = CollectionsKt.mapNotNull( originalClass.getDeclarations(), - new Function1() { - @Override - public KotlinMemberInfo invoke(KtDeclaration declaration) { - if (!(declaration instanceof KtClassOrObject)) return null; - KtClassOrObject classOrObject = (KtClassOrObject) declaration; + declaration -> { + if (!(declaration instanceof KtClassOrObject)) return null; + KtClassOrObject classOrObject = (KtClassOrObject) declaration; - if (classOrObject instanceof KtClass && ((KtClass) classOrObject).isInner()) return null; - if (classOrObject instanceof KtObjectDeclaration && ((KtObjectDeclaration) classOrObject).isCompanion()) return null; - - KotlinMemberInfo memberInfo = new KotlinMemberInfo(classOrObject, false); - memberInfo.setChecked(elementsToMove.contains(declaration)); - return memberInfo; + if (classOrObject instanceof KtClass && ((KtClass) classOrObject).isInner()) return null; + if (classOrObject instanceof KtObjectDeclaration && ((KtObjectDeclaration) classOrObject).isCompanion()) { + return null; } + + KotlinMemberInfo memberInfo = new KotlinMemberInfo(classOrObject, false); + memberInfo.setChecked(elementsToMove.contains(declaration)); + return memberInfo; } ); KotlinMemberSelectionPanel selectionPanel = new KotlinMemberSelectionPanel(getTitle(), memberInfos, null); memberTable = selectionPanel.getTable(); MemberInfoModelImpl memberInfoModel = new MemberInfoModelImpl(); - memberInfoModel.memberInfoChanged(new MemberInfoChange(memberInfos)); + memberInfoModel.memberInfoChanged(new MemberInfoChange<>(memberInfos)); selectionPanel.getTable().setMemberInfoModel(memberInfoModel); selectionPanel.getTable().addMemberInfoChangeListener(memberInfoModel); membersInfoPanel.add(selectionPanel, BorderLayout.CENTER); @@ -223,12 +203,7 @@ public class MoveKotlinNestedClassesDialog extends RefactoringDialog { private List getSelectedElementsToMove() { return CollectionsKt.map( memberTable.getSelectedMemberInfos(), - new Function1() { - @Override - public KtClassOrObject invoke(KotlinMemberInfo info) { - return (KtClassOrObject) info.getMember(); - } - } + info -> (KtClassOrObject) info.getMember() ); } @@ -266,7 +241,7 @@ public class MoveKotlinNestedClassesDialog extends RefactoringDialog { MoveDeclarationsDelegate.NestedClass delegate = new MoveDeclarationsDelegate.NestedClass(); MoveDeclarationsDescriptor descriptor = new MoveDeclarationsDescriptor( myProject, - MoveSource(elementsToMove), + MoveKotlinDeclarationsProcessorKt.MoveSource(elementsToMove), target, delegate, false, diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesToUpperLevelDialog.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesToUpperLevelDialog.java index 3f803fba9f6..d0aaddd1381 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesToUpperLevelDialog.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesToUpperLevelDialog.java @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui; @@ -66,13 +55,9 @@ import org.jetbrains.kotlin.types.KotlinType; import javax.swing.*; import java.awt.*; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; import java.util.Collections; import java.util.List; -import static org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveKotlinDeclarationsProcessorKt.MoveSource; - public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase { @NonNls private static final String RECENTS_KEY = MoveKotlinNestedClassesToUpperLevelDialog.class.getName() + ".RECENTS_KEY"; @@ -160,7 +145,7 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase { } private boolean isThisNeeded() { - return innerClass instanceof KtClass && MoveUtilsKt.traverseOuterInstanceReferences((KtClass) innerClass, true); + return innerClass instanceof KtClass && MoveUtilsKt.traverseOuterInstanceReferences(innerClass, true); } @Nullable @@ -180,12 +165,7 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase { if (innerClass instanceof KtClass && ((KtClass) innerClass).isInner()) { passOuterClassCheckBox.setSelected(true); - passOuterClassCheckBox.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - parameterField.setEnabled(passOuterClassCheckBox.isSelected()); - } - }); + passOuterClassCheckBox.addItemListener(e -> parameterField.setEnabled(passOuterClassCheckBox.isSelected())); } else { passOuterClassCheckBox.setSelected(false); @@ -199,12 +179,9 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase { parameterField.setEnabled(thisNeeded); } - passOuterClassCheckBox.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - boolean selected = passOuterClassCheckBox.isSelected(); - parameterField.getComponent().setEnabled(selected); - } + passOuterClassCheckBox.addItemListener(e -> { + boolean selected = passOuterClassCheckBox.isSelected(); + parameterField.getComponent().setEnabled(selected); }); if (!(targetContainer instanceof PsiDirectory)) { @@ -218,7 +195,7 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase { innerClassBody != null ? new NewDeclarationNameValidator(innerClassBody, (PsiElement) null, NewDeclarationNameValidator.Target.VARIABLES, - Collections.emptyList()) + Collections.emptyList()) : new CollectingNameValidator(); List suggestions = KotlinNameSuggester.INSTANCE.suggestNamesByType(getOuterInstanceType(), validator, "outer"); parameterField.setSuggestions(ArrayUtil.toStringArray(suggestions)); @@ -268,8 +245,8 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase { if (!Comparing.equal(oldPackageFqName != null ? oldPackageFqName.asString() : null, targetName)) { ProjectRootManager projectRootManager = ProjectRootManager.getInstance(project); List contentSourceRoots = JavaProjectRootsUtil.getSuitableDestinationSourceRoots(project); - final PackageWrapper newPackage = new PackageWrapper(PsiManager.getInstance(project), targetName); - final VirtualFile targetSourceRoot; + PackageWrapper newPackage = new PackageWrapper(PsiManager.getInstance(project), targetName); + VirtualFile targetSourceRoot; if (contentSourceRoots.size() > 1) { PsiDirectory initialDir = null; PsiPackage oldPackage = oldPackageFqName != null @@ -293,15 +270,12 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase { } PsiDirectory dir = RefactoringUtil.findPackageDirectoryInSourceRoot(newPackage, targetSourceRoot); if (dir == null) { - dir = ApplicationManager.getApplication().runWriteAction(new NullableComputable() { - @Override - public PsiDirectory compute() { - try { - return RefactoringUtil.createPackageDirectoryInSourceRoot(newPackage, targetSourceRoot); - } - catch (IncorrectOperationException e) { - return null; - } + dir = ApplicationManager.getApplication().runWriteAction((NullableComputable) () -> { + try { + return RefactoringUtil.createPackageDirectoryInSourceRoot(newPackage, targetSourceRoot); + } + catch (IncorrectOperationException e) { + return null; } }); } @@ -321,12 +295,20 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase { String className = getClassName(); String parameterName = getParameterName(); - if (className != null && className.isEmpty()) throw new ConfigurationException(RefactoringBundle.message("no.class.name.specified")); - if (!KtPsiUtilKt.isIdentifier(className)) throw new ConfigurationException(RefactoringMessageUtil.getIncorrectIdentifierMessage(className)); + if (className != null && className.isEmpty()) { + throw new ConfigurationException(RefactoringBundle.message("no.class.name.specified")); + } + if (!KtPsiUtilKt.isIdentifier(className)) { + throw new ConfigurationException(RefactoringMessageUtil.getIncorrectIdentifierMessage(className)); + } if (passOuterClassCheckBox.isSelected()) { - if (parameterName != null && parameterName.isEmpty()) throw new ConfigurationException(RefactoringBundle.message("no.parameter.name.specified")); - if (!KtPsiUtilKt.isIdentifier(parameterName)) throw new ConfigurationException(RefactoringMessageUtil.getIncorrectIdentifierMessage(parameterName)); + if (parameterName != null && parameterName.isEmpty()) { + throw new ConfigurationException(RefactoringBundle.message("no.parameter.name.specified")); + } + if (!KtPsiUtilKt.isIdentifier(parameterName)) { + throw new ConfigurationException(RefactoringMessageUtil.getIncorrectIdentifierMessage(parameterName)); + } } PsiElement targetContainer = getTargetContainer(); @@ -350,7 +332,9 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase { .getPackage(targetPackageFqName) .getMemberScope() .getContributedClassifier(Name.identifier(className), NoLookupLocation.FROM_IDE); - if (existingClass != null) throw new ConfigurationException("Class " + className + " already exists in package " + targetPackageFqName); + if (existingClass != null) { + throw new ConfigurationException("Class " + className + " already exists in package " + targetPackageFqName); + } PsiDirectory targetDir = targetContainer instanceof PsiDirectory ? (PsiDirectory) targetContainer @@ -382,34 +366,23 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase { KotlinMoveTarget moveTarget; if (target instanceof PsiDirectory) { - final PsiDirectory targetDir = (PsiDirectory) target; + PsiDirectory targetDir = (PsiDirectory) target; - final FqName targetPackageFqName = getTargetPackageFqName(target); + FqName targetPackageFqName = getTargetPackageFqName(target); if (targetPackageFqName == null) return; - final String targetFileName = KotlinNameSuggester.INSTANCE.suggestNameByName( + String targetFileName = KotlinNameSuggester.INSTANCE.suggestNameByName( newClassName, - new Function1() { - @Override - public Boolean invoke(String s) { - return targetDir.findFile(s + "." + KotlinFileType.EXTENSION) == null; - } - } + s -> targetDir.findFile(s + "." + KotlinFileType.EXTENSION) == null ) + "." + KotlinFileType.EXTENSION; moveTarget = new KotlinMoveTargetForDeferredFile( targetPackageFqName, targetDir, null, - new Function1() { - @Override - public KtFile invoke(@NotNull KtFile originalFile) { - return KotlinRefactoringUtilKt.createKotlinFile(targetFileName, targetDir, targetPackageFqName.asString()); - } - } + originalFile -> KotlinRefactoringUtilKt.createKotlinFile(targetFileName, targetDir, targetPackageFqName.asString()) ); } else { - //noinspection ConstantConditions moveTarget = new KotlinMoveTargetForExistingElement((KtElement) target); } @@ -417,7 +390,7 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase { MoveDeclarationsDelegate delegate = new MoveDeclarationsDelegate.NestedClass(newClassName, outerInstanceParameterName); MoveDeclarationsDescriptor moveDescriptor = new MoveDeclarationsDescriptor( project, - MoveSource(innerClass), + MoveKotlinDeclarationsProcessorKt.MoveSource(innerClass), moveTarget, delegate, isSearchInComments(), diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java index d06c66ea450..25f00633348 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui; @@ -32,8 +21,10 @@ import com.intellij.openapi.util.Pass; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.refactoring.*; import com.intellij.refactoring.classMembers.AbstractMemberInfoModel; +import com.intellij.refactoring.classMembers.MemberInfoBase; import com.intellij.refactoring.classMembers.MemberInfoChange; import com.intellij.refactoring.classMembers.MemberInfoChangeListener; import com.intellij.refactoring.move.MoveCallback; @@ -46,12 +37,9 @@ import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.ui.ComboboxWithBrowseButton; import com.intellij.ui.RecentsManager; import com.intellij.ui.ReferenceEditorComboWithBrowseButton; -import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import com.intellij.util.ui.UIUtil; import kotlin.collections.CollectionsKt; -import kotlin.jvm.functions.Function0; -import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.idea.KotlinFileType; @@ -70,19 +58,17 @@ import org.jetbrains.kotlin.idea.util.application.ApplicationUtilsKt; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.psi.KtNamedDeclaration; +import org.jetbrains.kotlin.psi.KtPureElement; import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.io.File; import java.nio.file.Path; import java.util.List; import java.util.*; import static java.util.Collections.emptyList; -import static org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveKotlinDeclarationsProcessorKt.MoveSource; public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { private static final String RECENTS_KEY = "MoveKotlinTopLevelDeclarationsDialog.RECENTS_KEY"; @@ -143,12 +129,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { return CollectionsKt.distinct( CollectionsKt.map( elementsToMove, - new Function1() { - @Override - public KtFile invoke(KtNamedDeclaration declaration) { - return declaration.getContainingKtFile(); - } - } + KtPureElement::getContainingKtFile ) ); } @@ -159,12 +140,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { CollectionsKt.distinct( CollectionsKt.map( sourceFiles, - new Function1() { - @Override - public PsiDirectory invoke(KtFile jetFile) { - return jetFile.getParent(); - } - } + PsiFileImpl::getParent ) ) ); @@ -174,12 +150,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { return CollectionsKt.filterIsInstance( CollectionsKt.flatMap( sourceFiles, - new Function1>() { - @Override - public Iterable invoke(KtFile ktFile) { - return KtPsiUtilKt.getFileOrScriptDeclarations(ktFile); - } - } + KtPsiUtilKt::getFileOrScriptDeclarations ), KtNamedDeclaration.class ); @@ -196,7 +167,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { private static List getFilesExistingInTargetDir( @NotNull List sourceFiles, @Nullable String targetFileName, - @Nullable final PsiDirectory targetDirectory + @Nullable PsiDirectory targetDirectory ) { if (targetDirectory == null) return emptyList(); @@ -205,62 +176,44 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { ? Collections.singletonList(targetFileName) : CollectionsKt.map( sourceFiles, - new Function1() { - @Override - public String invoke(KtFile jetFile) { - return jetFile.getName(); - } - } + PsiFileImpl::getName ); return CollectionsKt.filterNotNull( CollectionsKt.map( fileNames, - new Function1() { - @Override - public PsiFile invoke(String s) { - return targetDirectory.findFile(s); - } - } + targetDirectory::findFile ) ); } private void initMemberInfo( - @NotNull final Set elementsToMove, + @NotNull Set elementsToMove, @NotNull List sourceFiles ) { - final List memberInfos = CollectionsKt.map( + List memberInfos = CollectionsKt.map( getAllDeclarations(sourceFiles), - new Function1() { - @Override - public KotlinMemberInfo invoke(KtNamedDeclaration declaration) { - KotlinMemberInfo memberInfo = new KotlinMemberInfo(declaration, false); - memberInfo.setChecked(elementsToMove.contains(declaration)); - return memberInfo; - } + declaration -> { + KotlinMemberInfo memberInfo = new KotlinMemberInfo(declaration, false); + memberInfo.setChecked(elementsToMove.contains(declaration)); + return memberInfo; } ); KotlinMemberSelectionPanel selectionPanel = new KotlinMemberSelectionPanel(getTitle(), memberInfos, null); memberTable = selectionPanel.getTable(); MemberInfoModelImpl memberInfoModel = new MemberInfoModelImpl(); - memberInfoModel.memberInfoChanged(new MemberInfoChange(memberInfos)); + memberInfoModel.memberInfoChanged(new MemberInfoChange<>(memberInfos)); selectionPanel.getTable().setMemberInfoModel(memberInfoModel); selectionPanel.getTable().addMemberInfoChangeListener(memberInfoModel); selectionPanel.getTable().addMemberInfoChangeListener( new MemberInfoChangeListener() { - private boolean shouldUpdateFileNameField(final Collection changedMembers) { + private boolean shouldUpdateFileNameField(Collection changedMembers) { if (!tfFileNameInPackage.isEnabled()) return true; Collection previousDeclarations = CollectionsKt.filterNotNull( CollectionsKt.map( memberInfos, - new Function1() { - @Override - public KtNamedDeclaration invoke(KotlinMemberInfo info) { - return changedMembers.contains(info) != info.isChecked() ? info.getMember() : null; - } - } + info -> changedMembers.contains(info) != info.isChecked() ? info.getMember() : null ) ); String suggestedText = previousDeclarations.isEmpty() @@ -270,7 +223,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { } @Override - public void memberInfoChanged(MemberInfoChange event) { + public void memberInfoChanged(@NotNull MemberInfoChange event) { updatePackageDirectiveCheckBox(); updateFileNameInPackageField(); // Update file name field only if it user hasn't changed it to some non-default value @@ -285,7 +238,6 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { private void updateSuggestedFileName() { tfFileNameInPackage.setText(MoveUtilsKt.guessNewFileName(getSelectedElementsToMove())); - } private void updateFileNameInPackageField() { @@ -316,14 +268,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { classPackageChooser.getChildComponent() ); - cbSpecifyFileNameInPackage.addActionListener( - new ActionListener() { - @Override - public void actionPerformed(@NotNull ActionEvent e) { - updateFileNameInPackageField(); - } - } - ); + cbSpecifyFileNameInPackage.addActionListener(e -> updateFileNameInPackageField()); cbUpdatePackageDirective.setSelected(arePackagesAndDirectoryMatched(sourceFiles)); } @@ -342,22 +287,16 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { } rbMoveToPackage.addActionListener( - new ActionListener() { - @Override - public void actionPerformed(@NotNull ActionEvent e) { - classPackageChooser.requestFocus(); - updateControls(); - } + e -> { + classPackageChooser.requestFocus(); + updateControls(); } ); rbMoveToFile.addActionListener( - new ActionListener() { - @Override - public void actionPerformed(@NotNull ActionEvent e) { - fileChooser.requestFocus(); - updateControls(); - } + e -> { + fileChooser.requestFocus(); + updateControls(); } ); } @@ -367,33 +306,30 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { @NotNull Set elementsToMove, @NotNull List sourceFiles ) { - final PsiDirectory sourceDir = sourceFiles.get(0).getParent(); + PsiDirectory sourceDir = sourceFiles.get(0).getParent(); assert sourceDir != null : sourceFiles.get(0).getVirtualFile().getPath(); fileChooser.addActionListener( - new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - KotlinFileChooserDialog dialog = new KotlinFileChooserDialog("Choose Containing File", myProject); + e -> { + KotlinFileChooserDialog dialog = new KotlinFileChooserDialog("Choose Containing File", myProject); - File targetFile = new File(getTargetFilePath()); - PsiFile targetPsiFile = PhysicalFileSystemUtilsKt.toPsiFile(targetFile, myProject); - if (targetPsiFile instanceof KtFile) { - dialog.select((KtFile) targetPsiFile); - } - else { - PsiDirectory targetDir = PhysicalFileSystemUtilsKt.toPsiDirectory(targetFile.getParentFile(), myProject); - if (targetDir == null) { - targetDir = sourceDir; - } - dialog.selectDirectory(targetDir); + File targetFile1 = new File(getTargetFilePath()); + PsiFile targetPsiFile = PhysicalFileSystemUtilsKt.toPsiFile(targetFile1, myProject); + if (targetPsiFile instanceof KtFile) { + dialog.select((KtFile) targetPsiFile); + } + else { + PsiDirectory targetDir = PhysicalFileSystemUtilsKt.toPsiDirectory(targetFile1.getParentFile(), myProject); + if (targetDir == null) { + targetDir = sourceDir; } + dialog.selectDirectory(targetDir); + } - dialog.showDialog(); - KtFile selectedFile = dialog.isOK() ? dialog.getSelected() : null; - if (selectedFile != null) { - fileChooser.setText(selectedFile.getVirtualFile().getPath()); - } + dialog.showDialog(); + KtFile selectedFile = dialog.isOK() ? dialog.getSelected() : null; + if (selectedFile != null) { + fileChooser.setText(selectedFile.getVirtualFile().getPath()); } } ); @@ -446,12 +382,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { private boolean isFullFileMove() { Map> fileToElements = CollectionsKt.groupBy( getSelectedElementsToMove(), - new Function1() { - @Override - public KtFile invoke(KtNamedDeclaration declaration) { - return declaration.getContainingKtFile(); - } - } + KtPureElement::getContainingKtFile ); for (Map.Entry> entry : fileToElements.entrySet()) { if (KtPsiUtilKt.getFileOrScriptDeclarations(entry.getKey()).size() != entry.getValue().size()) return false; @@ -486,7 +417,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { if (ret != Messages.YES) return null; } - DirectoryChooser.ItemWrapper selectedItem = (DirectoryChooser.ItemWrapper)destinationFolderCB.getComboBox().getSelectedItem(); + DirectoryChooser.ItemWrapper selectedItem = (DirectoryChooser.ItemWrapper) destinationFolderCB.getComboBox().getSelectedItem(); PsiDirectory selectedPsiDirectory = selectedItem != null ? selectedItem.getDirectory() : null; if (selectedPsiDirectory == null) { if (initialTargetDirectory != null) { @@ -525,9 +456,9 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { if (targetDirWithMoveDestination == null) return null; VirtualFile targetDir = targetDirWithMoveDestination.getFirst(); - final MoveDestination moveDestination = targetDirWithMoveDestination.getSecond(); + MoveDestination moveDestination = targetDirWithMoveDestination.getSecond(); - final String targetFileName = sourceFiles.size() > 1 ? null : tfFileNameInPackage.getText(); + String targetFileName = sourceFiles.size() > 1 ? null : tfFileNameInPackage.getText(); if (targetFileName != null && !checkTargetFileName(targetFileName)) return null; PsiDirectory targetDirectory = moveDestination.getTargetIfExists(sourceDirectory); @@ -537,12 +468,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { if (filesExistingInTargetDir.size() > 1) { String filePathsToReport = StringUtil.join( filesExistingInTargetDir, - new Function() { - @Override - public String fun(PsiFile file) { - return file.getVirtualFile().getPath(); - } - }, + file -> file.getVirtualFile().getPath(), "\n" ); Messages.showErrorDialog( @@ -560,7 +486,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { "File '%s' already exists. Do you want to move selected declarations to this file?", targetFile.getVirtualFile().getPath() ); - int ret= + int ret = Messages.showYesNoDialog(myProject, question, RefactoringBundle.message("move.title"), Messages.getQuestionIcon()); if (ret != Messages.YES) return null; @@ -576,19 +502,14 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { new FqName(getTargetPackage()), moveDestination.getTargetIfExists(sourceFiles.get(0)), targetDir, - new Function1() { - @Override - public KtFile invoke(@NotNull KtFile originalFile) { - return KotlinRefactoringUtilKt.getOrCreateKotlinFile( - targetFileName != null ? targetFileName : originalFile.getName(), - moveDestination.getTargetDirectory(originalFile) - ); - } - } + originalFile -> KotlinRefactoringUtilKt.getOrCreateKotlinFile( + targetFileName != null ? targetFileName : originalFile.getName(), + moveDestination.getTargetDirectory(originalFile) + ) ); } - final File targetFile = new File(getTargetFilePath()); + File targetFile = new File(getTargetFilePath()); if (!checkTargetFileName(targetFile.getName())) return null; KtFile jetFile = (KtFile) PhysicalFileSystemUtilsKt.toPsiFile(targetFile, myProject); if (jetFile != null) { @@ -602,7 +523,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { Path targetFilePath = targetFile.toPath(); Path targetDirPath = targetFilePath.getParent(); - if (targetDirPath == null || !targetDirPath.startsWith(getProject().getBasePath())) { + if (targetDirPath == null || !targetDirPath.startsWith(Objects.requireNonNull(getProject().getBasePath()))) { setErrorText("Incorrect target path. Directory " + targetDirPath + " does not belong to current project."); return null; } @@ -625,7 +546,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { } File targetDir = targetDirPath.toFile(); - final PsiDirectory psiDirectory = targetDir != null ? PhysicalFileSystemUtilsKt.toPsiDirectory(targetDir, myProject) : null; + PsiDirectory psiDirectory = targetDir != null ? PhysicalFileSystemUtilsKt.toPsiDirectory(targetDir, myProject) : null; if (psiDirectory == null) { setErrorText("No directory found for file: " + targetFile.getPath()); return null; @@ -633,13 +554,8 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { Set sourcePackageFqNames = CollectionsKt.mapTo( sourceFiles, - new LinkedHashSet(), - new Function1() { - @Override - public FqName invoke(KtFile file) { - return file.getPackageFqName(); - } - } + new LinkedHashSet<>(), + KtFile::getPackageFqName ); FqName targetPackageFqName = CollectionsKt.singleOrNull(sourcePackageFqNames); if (targetPackageFqName == null) { @@ -651,17 +567,12 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { targetPackageFqName = new FqName(psiPackage.getQualifiedName()); } - final String finalTargetPackageFqName = targetPackageFqName.asString(); + String finalTargetPackageFqName = targetPackageFqName.asString(); return new KotlinMoveTargetForDeferredFile( targetPackageFqName, psiDirectory, null, - new Function1() { - @Override - public KtFile invoke(@NotNull KtFile originalFile) { - return KotlinRefactoringUtilKt.getOrCreateKotlinFile(targetFile.getName(), psiDirectory, finalTargetPackageFqName); - } - } + originalFile -> KotlinRefactoringUtilKt.getOrCreateKotlinFile(targetFile.getName(), psiDirectory, finalTargetPackageFqName) ); } @@ -692,12 +603,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { private List getSelectedElementsToMove() { return CollectionsKt.map( memberTable.getSelectedMemberInfos(), - new Function1() { - @Override - public KtNamedDeclaration invoke(KotlinMemberInfo info) { - return info.getMember(); - } - } + MemberInfoBase::getMember ); } @@ -736,7 +642,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { List elementsToMove = getSelectedElementsToMove(); List sourceFiles = getSourceFiles(elementsToMove); - final PsiDirectory sourceDirectory = getSourceDirectory(sourceFiles); + PsiDirectory sourceDirectory = getSourceDirectory(sourceFiles); for (PsiElement element : elementsToMove) { String message = target.verify(element.getContainingFile()); @@ -754,7 +660,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { Pair sourceRootWithMoveDestination = selectPackageBasedTargetDirAndDestination(false); //noinspection ConstantConditions - final MoveDestination moveDestination = sourceRootWithMoveDestination.getSecond(); + MoveDestination moveDestination = sourceRootWithMoveDestination.getSecond(); PsiDirectory targetDir = moveDestination.getTargetIfExists(sourceDirectory); String targetFileName = sourceFiles.size() > 1 ? null : tfFileNameInPackage.getText(); @@ -762,12 +668,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { if (filesExistingInTargetDir.isEmpty() || (filesExistingInTargetDir.size() == 1 && sourceFiles.contains(filesExistingInTargetDir.get(0)))) { PsiDirectory targetDirectory = ApplicationUtilsKt.runWriteAction( - new Function0() { - @Override - public PsiDirectory invoke() { - return moveDestination.getTargetDirectory(sourceDirectory); - } - } + () -> moveDestination.getTargetDirectory(sourceDirectory) ); for (KtFile sourceFile : sourceFiles) { @@ -809,7 +710,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { MoveDeclarationsDescriptor options = new MoveDeclarationsDescriptor( myProject, - MoveSource(elementsToMove), + MoveKotlinDeclarationsProcessorKt.MoveSource(elementsToMove), target, MoveDeclarationsDelegate.TopLevel.INSTANCE, isSearchInComments(), diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/FqNameFixingMoveJavaFIleHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/FqNameFixingMoveJavaFIleHandler.kt index 478c63e76dd..d6c28310034 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/FqNameFixingMoveJavaFIleHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/FqNameFixingMoveJavaFIleHandler.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories @@ -31,10 +20,14 @@ class FqNameFixingMoveJavaFileHandler : MoveFileHandler() { private val delegate = MoveJavaFileHandler() override fun canProcessElement(element: PsiFile) = - delegate.canProcessElement(element) + delegate.canProcessElement(element) - override fun findUsages(psiFile: PsiFile, newParent: PsiDirectory?, searchInComments: Boolean, searchInNonJavaFiles: Boolean) = - delegate.findUsages(psiFile, newParent, searchInComments, searchInNonJavaFiles) + override fun findUsages( + psiFile: PsiFile, + newParent: PsiDirectory?, + searchInComments: Boolean, + searchInNonJavaFiles: Boolean + ): MutableList? = delegate.findUsages(psiFile, newParent, searchInComments, searchInNonJavaFiles) override fun prepareMovedFile(file: PsiFile, moveDestination: PsiDirectory, oldToNewMap: MutableMap) { delegate.prepareMovedFile(file, moveDestination, oldToNewMap) @@ -47,8 +40,8 @@ class FqNameFixingMoveJavaFileHandler : MoveFileHandler() { } override fun updateMovedFile(file: PsiFile) = - delegate.updateMovedFile(file) + delegate.updateMovedFile(file) override fun retargetUsages(usageInfos: MutableList, oldToNewMap: MutableMap) = - delegate.retargetUsages(usageInfos, oldToNewMap) + delegate.retargetUsages(usageInfos, oldToNewMap) } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveDirectoryWithClassesHelper.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveDirectoryWithClassesHelper.kt index 147cba16dfd..71b53659470 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveDirectoryWithClassesHelper.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveDirectoryWithClassesHelper.kt @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories @@ -40,14 +29,14 @@ import java.util.* class KotlinMoveDirectoryWithClassesHelper : MoveDirectoryWithClassesHelper() { private data class FileUsagesWrapper( - val psiFile: KtFile, - val usages: List, - val moveDeclarationsProcessor: MoveKotlinDeclarationsProcessor? + val psiFile: KtFile, + val usages: List, + val moveDeclarationsProcessor: MoveKotlinDeclarationsProcessor? ) : UsageInfo(psiFile) private class MoveContext( - val newParent: PsiDirectory, - val moveDeclarationsProcessor: MoveKotlinDeclarationsProcessor? + val newParent: PsiDirectory, + val moveDeclarationsProcessor: MoveKotlinDeclarationsProcessor? ) private val fileHandler = MoveKotlinFileHandler() @@ -62,23 +51,24 @@ class KotlinMoveDirectoryWithClassesHelper : MoveDirectoryWithClassesHelper() { } override fun findUsages( - filesToMove: MutableCollection, - directoriesToMove: Array, - result: MutableCollection, - searchInComments: Boolean, - searchInNonJavaFiles: Boolean, - project: Project) { + filesToMove: MutableCollection, + directoriesToMove: Array, + result: MutableCollection, + searchInComments: Boolean, + searchInNonJavaFiles: Boolean, + project: Project + ) { filesToMove - .filterIsInstance() - .mapTo(result) { FileUsagesWrapper(it, fileHandler.findUsages(it, null, false), null) } + .filterIsInstance() + .mapTo(result) { FileUsagesWrapper(it, fileHandler.findUsages(it, null, false), null) } } override fun preprocessUsages( - project: Project, - files: MutableSet, - infos: Array, - directory: PsiDirectory?, - conflicts: MultiMap + project: Project, + files: MutableSet, + infos: Array, + directory: PsiDirectory?, + conflicts: MultiMap ) { val psiPackage = directory?.getPackage() ?: return val moveTarget = KotlinDirectoryMoveTarget(FqName(psiPackage.qualifiedName), directory) @@ -101,11 +91,11 @@ class KotlinMoveDirectoryWithClassesHelper : MoveDirectoryWithClassesHelper() { // Actual move logic is implemented in postProcessUsages since usages are not available here override fun move( - file: PsiFile, - moveDestination: PsiDirectory, - oldToNewElementsMapping: MutableMap, - movedFiles: MutableList, - listener: RefactoringElementListener? + file: PsiFile, + moveDestination: PsiDirectory, + oldToNewElementsMapping: MutableMap, + movedFiles: MutableList, + listener: RefactoringElementListener? ): Boolean { if (file !is KtFile) return false @@ -130,7 +120,7 @@ class KotlinMoveDirectoryWithClassesHelper : MoveDirectoryWithClassesHelper() { val usagesToProcess = ArrayList() usages .filterIsInstance() - .forEach body@ { + .forEach body@{ val file = it.psiFile val moveContext = fileToMoveContext[file] ?: return@body @@ -142,8 +132,7 @@ class KotlinMoveDirectoryWithClassesHelper : MoveDirectoryWithClassesHelper() { usagesToProcess += FileUsagesWrapper(movedFile as KtFile, it.usages, moveDeclarationsProcessor) } usagesToProcess.forEach { fileHandler.retargetUsages(it.usages, it.moveDeclarationsProcessor!!) } - } - finally { + } finally { this.fileToMoveContext = null } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveFilesOrDirectoriesHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveFilesOrDirectoriesHandler.kt index 77250a34af4..74cfb9fe9ba 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveFilesOrDirectoriesHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveFilesOrDirectoriesHandler.kt @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories @@ -55,14 +44,20 @@ class KotlinMoveFilesOrDirectoriesHandler : MoveFilesOrDirectoriesHandler() { if (!(targetContainer == null || targetContainer is PsiDirectory || targetContainer is PsiDirectoryContainer)) return moveFilesOrDirectories( - project, - adjustForMove(project, elements, targetContainer) ?: return, - targetContainer, - callback?.let { MoveCallback { it.refactoringCompleted() } } + project, + adjustForMove(project, elements, targetContainer) ?: return, + targetContainer, + callback?.let { MoveCallback { it.refactoringCompleted() } } ) } - override fun tryToMove(element: PsiElement, project: Project, dataContext: DataContext?, reference: PsiReference?, editor: Editor?): Boolean { + override fun tryToMove( + element: PsiElement, + project: Project, + dataContext: DataContext?, + reference: PsiReference?, + editor: Editor? + ): Boolean { if (element is KtLightClassForFacade) { doMove(project, element.files.toTypedArray(), dataContext?.getData(LangDataKeys.TARGET_PSI_ELEMENT), null) return true diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt index df25f4ef01d..e3cb4567deb 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories @@ -48,9 +37,9 @@ class MoveKotlinFileHandler : MoveFileHandler() { // This is special 'PsiElement' whose purpose is to wrap MoveKotlinTopLevelDeclarationsProcessor // so that it can be kept in the usage info list private class MoveContext( - val file: PsiFile, - val declarationMoveProcessor: MoveKotlinDeclarationsProcessor - ): LightElement(file.manager, KotlinLanguage.INSTANCE) { + val file: PsiFile, + val declarationMoveProcessor: MoveKotlinDeclarationsProcessor + ) : LightElement(file.manager, KotlinLanguage.INSTANCE) { override fun toString() = "" } @@ -61,12 +50,15 @@ class MoveKotlinFileHandler : MoveFileHandler() { if (!shouldUpdatePackageDirective) return null val oldPackageName = packageFqName - val newPackage = newParent?.getPackage() ?: return ContainerChangeInfo(ContainerInfo.Package(oldPackageName), - ContainerInfo.UnknownPackage) + val newPackage = newParent?.getPackage() ?: return ContainerChangeInfo( + ContainerInfo.Package(oldPackageName), + ContainerInfo.UnknownPackage + ) val newPackageName = FqNameUnsafe(newPackage.qualifiedName) if (oldPackageName.asString() == newPackageName.asString() - && ModuleUtilCore.findModuleForPsiElement(this) == ModuleUtilCore.findModuleForPsiElement(newParent)) return null + && ModuleUtilCore.findModuleForPsiElement(this) == ModuleUtilCore.findModuleForPsiElement(newParent) + ) return null if (!newPackageName.hasIdentifiersOnly()) return null return ContainerChangeInfo(ContainerInfo.Package(oldPackageName), ContainerInfo.Package(newPackageName.toSafe())) @@ -78,8 +70,7 @@ class MoveKotlinFileHandler : MoveFileHandler() { val project = psiFile.project - val newPackage = packageNameInfo.newContainer - val moveTarget = when (newPackage) { + val moveTarget = when (val newPackage = packageNameInfo.newContainer) { ContainerInfo.UnknownPackage -> EmptyKotlinMoveTarget else -> KotlinMoveTargetForDeferredFile(newPackage.fqName!!, newParent) { @@ -108,18 +99,18 @@ class MoveKotlinFileHandler : MoveFileHandler() { } override fun findUsages( - psiFile: PsiFile, - newParent: PsiDirectory?, - searchInComments: Boolean, - searchInNonJavaFiles: Boolean + psiFile: PsiFile, + newParent: PsiDirectory?, + searchInComments: Boolean, + searchInNonJavaFiles: Boolean ): List { return findUsages(psiFile, newParent, true) } fun findUsages( - psiFile: PsiFile, - newParent: PsiDirectory?, - withConflicts: Boolean + psiFile: PsiFile, + newParent: PsiDirectory?, + withConflicts: Boolean ): List { if (psiFile !is KtFile) return emptyList() @@ -149,7 +140,7 @@ class MoveKotlinFileHandler : MoveFileHandler() { override fun retargetUsages(usageInfos: List?, oldToNewMap: Map) { val currentFile = (usageInfos?.firstOrNull() as? FileInfo)?.element - val moveContext = oldToNewMap.keys.firstOrNull { it is MoveContext && it.file == currentFile} as? MoveContext ?: return + val moveContext = oldToNewMap.keys.firstOrNull { it is MoveContext && it.file == currentFile } as? MoveContext ?: return retargetUsages(usageInfos, moveContext.declarationMoveProcessor) } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveUtils.kt index 81bd27d09ee..dc3863b1dec 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveUtils.kt @@ -1,17 +1,6 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.refactoring.move @@ -64,11 +53,11 @@ sealed class ContainerInfo { abstract fun matches(descriptor: DeclarationDescriptor): Boolean object UnknownPackage : ContainerInfo() { - override val fqName = null + override val fqName: FqName? = null override fun matches(descriptor: DeclarationDescriptor) = descriptor is PackageViewDescriptor } - class Package(override val fqName: FqName): ContainerInfo() { + class Package(override val fqName: FqName) : ContainerInfo() { override fun matches(descriptor: DeclarationDescriptor): Boolean { return descriptor is PackageFragmentDescriptor && descriptor.fqName == fqName } @@ -100,8 +89,8 @@ fun KtElement.getInternalReferencesToUpdateOnPackageNameChange(containerChangeIn private typealias UsageInfoFactory = (KtSimpleNameExpression) -> UsageInfo? fun KtElement.processInternalReferencesToUpdateOnPackageNameChange( - containerChangeInfo: ContainerChangeInfo, - body: (originalRefExpr: KtSimpleNameExpression, usageFactory: UsageInfoFactory) -> Unit + containerChangeInfo: ContainerChangeInfo, + body: (originalRefExpr: KtSimpleNameExpression, usageFactory: UsageInfoFactory) -> Unit ) { val file = containingFile as? KtFile ?: return @@ -111,8 +100,7 @@ fun KtElement.processInternalReferencesToUpdateOnPackageNameChange( val fqName = DescriptorUtils.getFqName(descriptor).let { if (it.isSafe) it.toSafe() else return@isImported false } if (importPaths.any { fqName.isImported(it, false) }) return true - val containingDescriptor = descriptor.containingDeclaration - return when (containingDescriptor) { + return when (val containingDescriptor = descriptor.containingDeclaration) { is ClassDescriptor, is PackageViewDescriptor -> isImported(containingDescriptor) else -> false } @@ -138,7 +126,8 @@ fun KtElement.processInternalReferencesToUpdateOnPackageNameChange( var result = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) ?: return@lazy null if (descriptor.isCompanionObject() - && bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, refExpr] != null) { + && bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, refExpr] != null + ) { result = (result as KtObjectDeclaration).containingClassOrObject ?: result } @@ -150,8 +139,8 @@ fun KtElement.processInternalReferencesToUpdateOnPackageNameChange( if (isExtension && containingDescriptor is ClassDescriptor) { val dispatchReceiver = refExpr.getResolvedCall(bindingContext)?.dispatchReceiver val implicitClass = (dispatchReceiver as? ImplicitClassReceiver)?.classDescriptor - if (implicitClass?.isCompanionObject ?: false) { - return { ImplicitCompanionAsDispatchReceiverUsageInfo(it, implicitClass!!) } + if (implicitClass?.isCompanionObject == true) { + return { ImplicitCompanionAsDispatchReceiverUsageInfo(it, implicitClass) } } if (dispatchReceiver != null || containingDescriptor.kind != ClassKind.OBJECT) return null } @@ -159,8 +148,9 @@ fun KtElement.processInternalReferencesToUpdateOnPackageNameChange( if (!isExtension) { if (!(containingDescriptor is PackageFragmentDescriptor - || containingDescriptor is ClassDescriptor && containingDescriptor.kind == ClassKind.OBJECT - || descriptor is JavaCallableMemberDescriptor && ((declaration as? PsiMember)?.hasModifierProperty(PsiModifier.STATIC) ?: false))) return null + || containingDescriptor is ClassDescriptor && containingDescriptor.kind == ClassKind.OBJECT + || descriptor is JavaCallableMemberDescriptor && ((declaration as? PsiMember)?.hasModifierProperty(PsiModifier.STATIC) == true)) + ) return null } } @@ -169,15 +159,15 @@ fun KtElement.processInternalReferencesToUpdateOnPackageNameChange( val (oldContainer, newContainer) = containerChangeInfo val containerFqName = descriptor - .parents - .mapNotNull { - when { - oldContainer.matches(it) -> oldContainer.fqName - newContainer.matches(it) -> newContainer.fqName - else -> null - } + .parents + .mapNotNull { + when { + oldContainer.matches(it) -> oldContainer.fqName + newContainer.matches(it) -> newContainer.fqName + else -> null } - .firstOrNull() + } + .firstOrNull() val isImported = isImported(descriptor) if (isImported && this is KtFile) return null @@ -207,9 +197,9 @@ internal fun markInternalUsages(usages: Collection) { } internal fun restoreInternalUsages( - scope: KtElement, - oldToNewElementsMapping: Map, - forcedRestore: Boolean = false + scope: KtElement, + oldToNewElementsMapping: Map, + forcedRestore: Boolean = false ): List { return scope.collectDescendantsOfType().mapNotNull { val usageInfo = it.internalUsageInfo @@ -226,8 +216,8 @@ internal fun cleanUpInternalUsages(usages: Collection) { } class ImplicitCompanionAsDispatchReceiverUsageInfo( - callee: KtSimpleNameExpression, - val companionDescriptor: ClassDescriptor + callee: KtSimpleNameExpression, + val companionDescriptor: ClassDescriptor ) : UsageInfo(callee) interface KotlinMoveUsage { @@ -237,25 +227,46 @@ interface KotlinMoveUsage { } class UnqualifiableMoveRenameUsageInfo( - element: PsiElement, - reference: PsiReference, - referencedElement: PsiElement, - val originalFile: PsiFile, - val addImportToOriginalFile: Boolean, - override val isInternal: Boolean -): MoveRenameUsageInfo(element, reference, reference.rangeInElement.startOffset, reference.rangeInElement.endOffset, referencedElement, false), KotlinMoveUsage { + element: PsiElement, + reference: PsiReference, + referencedElement: PsiElement, + val originalFile: PsiFile, + val addImportToOriginalFile: Boolean, + override val isInternal: Boolean +) : MoveRenameUsageInfo( + element, + reference, + reference.rangeInElement.startOffset, + reference.rangeInElement.endOffset, + referencedElement, + false +), KotlinMoveUsage { override fun refresh(refExpr: KtSimpleNameExpression, referencedElement: PsiElement): UsageInfo? { - return UnqualifiableMoveRenameUsageInfo(refExpr, refExpr.mainReference, referencedElement, originalFile, addImportToOriginalFile, isInternal) + return UnqualifiableMoveRenameUsageInfo( + refExpr, + refExpr.mainReference, + referencedElement, + originalFile, + addImportToOriginalFile, + isInternal + ) } } class QualifiableMoveRenameUsageInfo( - element: PsiElement, - reference: PsiReference, - referencedElement: PsiElement, - override val isInternal: Boolean -): MoveRenameUsageInfo(element, reference, reference.rangeInElement.startOffset, reference.rangeInElement.endOffset, referencedElement, false), - KotlinMoveUsage { + element: PsiElement, + reference: PsiReference, + referencedElement: PsiElement, + override val isInternal: Boolean +) : MoveRenameUsageInfo( + element, + reference, + reference.rangeInElement.startOffset, + reference.rangeInElement.endOffset, + referencedElement, + false +), + KotlinMoveUsage { override fun refresh(refExpr: KtSimpleNameExpression, referencedElement: PsiElement): UsageInfo? { return QualifiableMoveRenameUsageInfo(refExpr, refExpr.mainReference, referencedElement, isInternal) } @@ -272,9 +283,23 @@ class CallableReferenceMoveRenameUsageInfo( val originalFile: PsiFile, val addImportToOriginalFile: Boolean, override val isInternal: Boolean -) : MoveRenameUsageInfo(element, reference, reference.rangeInElement.startOffset, reference.rangeInElement.endOffset, referencedElement, false), DeferredKotlinMoveUsage { +) : MoveRenameUsageInfo( + element, + reference, + reference.rangeInElement.startOffset, + reference.rangeInElement.endOffset, + referencedElement, + false +), DeferredKotlinMoveUsage { override fun refresh(refExpr: KtSimpleNameExpression, referencedElement: PsiElement): UsageInfo? { - return CallableReferenceMoveRenameUsageInfo(refExpr, refExpr.mainReference, referencedElement, originalFile, addImportToOriginalFile, isInternal) + return CallableReferenceMoveRenameUsageInfo( + refExpr, + refExpr.mainReference, + referencedElement, + originalFile, + addImportToOriginalFile, + isInternal + ) } override fun resolve(newElement: PsiElement): UsageInfo? { @@ -284,28 +309,35 @@ class CallableReferenceMoveRenameUsageInfo( val referencedElement = referencedElement ?: return null if (target != null && target.isTopLevelKtOrJavaMember()) { element.getStrictParentOfType()?.receiverExpression?.delete() - return UnqualifiableMoveRenameUsageInfo(element, reference, referencedElement, element.containingFile!!, addImportToOriginalFile, isInternal) + return UnqualifiableMoveRenameUsageInfo( + element, + reference, + referencedElement, + element.containingFile!!, + addImportToOriginalFile, + isInternal + ) } return QualifiableMoveRenameUsageInfo(element, reference, referencedElement, isInternal) } } fun createMoveUsageInfoIfPossible( - reference: PsiReference, - referencedElement: PsiElement, - addImportToOriginalFile: Boolean, - isInternal: Boolean + reference: PsiReference, + referencedElement: PsiElement, + addImportToOriginalFile: Boolean, + isInternal: Boolean ): UsageInfo? { val element = reference.element return when (getReferenceKind(reference, referencedElement)) { ReferenceKind.QUALIFIABLE -> QualifiableMoveRenameUsageInfo( - element, reference, referencedElement, isInternal + element, reference, referencedElement, isInternal ) ReferenceKind.UNQUALIFIABLE -> UnqualifiableMoveRenameUsageInfo( - element, reference, referencedElement, element.containingFile!!, addImportToOriginalFile, isInternal + element, reference, referencedElement, element.containingFile!!, addImportToOriginalFile, isInternal ) ReferenceKind.CALLABLE_REFERENCE -> CallableReferenceMoveRenameUsageInfo( - element, reference, referencedElement, element.containingFile!!, addImportToOriginalFile, isInternal + element, reference, referencedElement, element.containingFile!!, addImportToOriginalFile, isInternal ) else -> null } @@ -349,14 +381,14 @@ private fun getReferenceKind(reference: PsiReference, referencedElement: PsiElem private fun isCallableReference(reference: PsiReference): Boolean { return reference is KtSimpleNameReference - && reference.element.getParentOfTypeAndBranch { callableReference } != null + && reference.element.getParentOfTypeAndBranch { callableReference } != null } fun guessNewFileName(declarationsToMove: Collection): String? { if (declarationsToMove.isEmpty()) return null val representative = declarationsToMove.singleOrNull() - ?: declarationsToMove.filterIsInstance().singleOrNull() + ?: declarationsToMove.filterIsInstance().singleOrNull() representative?.let { return "${it.name}.${KotlinFileType.EXTENSION}" } return declarationsToMove.first().containingFile.name @@ -384,7 +416,8 @@ private fun updateJavaReference(reference: PsiReferenceExpression, oldElement: P if (newClass != null && reference.qualifierExpression != null) { val mockMoveMembersOptions = MockMoveMembersOptions(newClass.qualifiedName, arrayOf(newElement)) val moveMembersUsageInfo = MoveMembersProcessor.MoveMembersUsageInfo( - newElement, reference.element, newClass, reference.qualifierExpression, reference) + newElement, reference.element, newClass, reference.qualifierExpression, reference + ) val moveMemberHandler = MoveMemberHandler.EP_NAME.forLanguage(reference.element.language) if (moveMemberHandler != null) { moveMemberHandler.changeExternalUsage(mockMoveMembersOptions, moveMembersUsageInfo) @@ -398,10 +431,10 @@ private fun updateJavaReference(reference: PsiReferenceExpression, oldElement: P internal fun mapToNewOrThis(e: PsiElement, oldToNewElementsMapping: Map) = oldToNewElementsMapping[e] ?: e private fun postProcessMoveUsage( - usage: UsageInfo, - oldToNewElementsMapping: Map, - nonCodeUsages: ArrayList, - shorteningMode: ShorteningMode + usage: UsageInfo, + oldToNewElementsMapping: Map, + nonCodeUsages: ArrayList, + shorteningMode: ShorteningMode ) { if (usage is NonCodeUsageInfo) { nonCodeUsages.add(usage) @@ -415,12 +448,17 @@ private fun postProcessMoveUsage( when (usage) { is DeferredKotlinMoveUsage -> { - val newUsage = usage.resolve(newElement) ?: return + val newUsage = usage.resolve(newElement) ?: return postProcessMoveUsage(newUsage, oldToNewElementsMapping, nonCodeUsages, shorteningMode) } is UnqualifiableMoveRenameUsageInfo -> { - val file = with(usage) { if (addImportToOriginalFile) originalFile else mapToNewOrThis(originalFile, oldToNewElementsMapping) } as KtFile + val file = with(usage) { + if (addImportToOriginalFile) originalFile else mapToNewOrThis( + originalFile, + oldToNewElementsMapping + ) + } as KtFile addDelayedImportRequest(newElement, file) } @@ -438,8 +476,7 @@ private fun processReference(reference: PsiReference?, newElement: PsiElement, s reference is PsiReferenceExpression && updateJavaReference(reference, oldElement, newElement) -> return else -> reference?.bindToElement(newElement) } - } - catch (e: IncorrectOperationException) { + } catch (e: IncorrectOperationException) { // Suppress exception if bindToElement is not implemented } } @@ -448,31 +485,31 @@ private fun processReference(reference: PsiReference?, newElement: PsiElement, s * Perform usage postprocessing and return non-code usages */ fun postProcessMoveUsages( - usages: Collection, - oldToNewElementsMapping: Map = Collections.emptyMap(), - shorteningMode: ShorteningMode = ShorteningMode.DELAYED_SHORTENING + usages: Collection, + oldToNewElementsMapping: Map = Collections.emptyMap(), + shorteningMode: ShorteningMode = ShorteningMode.DELAYED_SHORTENING ): List { - val sortedUsages = usages.sortedWith( - Comparator { o1, o2 -> - val file1 = o1.virtualFile - val file2 = o2.virtualFile - if (Comparing.equal(file1, file2)) { - val rangeInElement1 = o1.rangeInElement - val rangeInElement2 = o2.rangeInElement - if (rangeInElement1 != null && rangeInElement2 != null) { - return@Comparator rangeInElement2.startOffset - rangeInElement1.startOffset - } - return@Comparator 0 + val sortedUsages = usages.sortedWith( + Comparator { o1, o2 -> + val file1 = o1.virtualFile + val file2 = o2.virtualFile + if (Comparing.equal(file1, file2)) { + val rangeInElement1 = o1.rangeInElement + val rangeInElement2 = o2.rangeInElement + if (rangeInElement1 != null && rangeInElement2 != null) { + return@Comparator rangeInElement2.startOffset - rangeInElement1.startOffset } - if (file1 == null) return@Comparator -1 - if (file2 == null) return@Comparator 1 - Comparing.compare(file1.path, file2.path) + return@Comparator 0 } + if (file1 == null) return@Comparator -1 + if (file2 == null) return@Comparator 1 + Comparing.compare(file1.path, file2.path) + } ) val nonCodeUsages = ArrayList() - val progressStep = 1.0/sortedUsages.size + val progressStep = 1.0 / sortedUsages.size val progressIndicator = ProgressManager.getInstance().progressIndicator progressIndicator?.text = "Updating usages..." usageLoop@ for ((i, usage) in sortedUsages.withIndex()) { @@ -499,17 +536,17 @@ sealed class OuterInstanceReferenceUsageInfo(element: PsiElement, private val is } class ExplicitThis( - expression: KtThisExpression, - isIndirectOuter: Boolean + expression: KtThisExpression, + isIndirectOuter: Boolean ) : OuterInstanceReferenceUsageInfo(expression, isIndirectOuter) { val expression: KtThisExpression? get() = element as? KtThisExpression } class ImplicitReceiver( - callElement: KtElement, - isIndirectOuter: Boolean, - private val isDoubleReceiver: Boolean + callElement: KtElement, + isIndirectOuter: Boolean, + private val isDoubleReceiver: Boolean ) : OuterInstanceReferenceUsageInfo(callElement, isIndirectOuter) { val callElement: KtElement? get() = element as? KtElement @@ -535,7 +572,11 @@ sealed class OuterInstanceReferenceUsageInfo(element: PsiElement, private val is } @JvmOverloads -fun traverseOuterInstanceReferences(member: KtNamedDeclaration, stopAtFirst: Boolean, body: (OuterInstanceReferenceUsageInfo) -> Unit = {}): Boolean { +fun traverseOuterInstanceReferences( + member: KtNamedDeclaration, + stopAtFirst: Boolean, + body: (OuterInstanceReferenceUsageInfo) -> Unit = {} +): Boolean { if (member is KtObjectDeclaration || member is KtClass && !member.isInner()) return false val context = member.analyzeWithContent() @@ -543,53 +584,53 @@ fun traverseOuterInstanceReferences(member: KtNamedDeclaration, stopAtFirst: Boo val outerClassDescriptor = containingClassOrObject.unsafeResolveToDescriptor() as ClassDescriptor var found = false member.accept( - object : PsiRecursiveElementWalkingVisitor() { - private fun getOuterInstanceReference(element: PsiElement): OuterInstanceReferenceUsageInfo? { - return when (element) { - is KtThisExpression -> { - val descriptor = context[BindingContext.REFERENCE_TARGET, element.instanceReference] - val isIndirect = when { - descriptor == outerClassDescriptor -> false - descriptor?.isAncestorOf(outerClassDescriptor, true) ?: false -> true - else -> return null - } - OuterInstanceReferenceUsageInfo.ExplicitThis(element, isIndirect) + object : PsiRecursiveElementWalkingVisitor() { + private fun getOuterInstanceReference(element: PsiElement): OuterInstanceReferenceUsageInfo? { + return when (element) { + is KtThisExpression -> { + val descriptor = context[BindingContext.REFERENCE_TARGET, element.instanceReference] + val isIndirect = when { + descriptor == outerClassDescriptor -> false + descriptor?.isAncestorOf(outerClassDescriptor, true) ?: false -> true + else -> return null } - is KtSimpleNameExpression -> { - val resolvedCall = element.getResolvedCall(context) ?: return null - val dispatchReceiver = resolvedCall.dispatchReceiver as? ImplicitReceiver - val extensionReceiver = resolvedCall.extensionReceiver as? ImplicitReceiver - var isIndirect = false - val isDoubleReceiver = when (outerClassDescriptor) { - dispatchReceiver?.declarationDescriptor -> extensionReceiver != null - extensionReceiver?.declarationDescriptor -> dispatchReceiver != null - else -> { - isIndirect = true - when { - dispatchReceiver?.declarationDescriptor?.isAncestorOf(outerClassDescriptor, true) ?: false -> - extensionReceiver != null - extensionReceiver?.declarationDescriptor?.isAncestorOf(outerClassDescriptor, true) ?: false -> - dispatchReceiver != null - else -> return null - } + OuterInstanceReferenceUsageInfo.ExplicitThis(element, isIndirect) + } + is KtSimpleNameExpression -> { + val resolvedCall = element.getResolvedCall(context) ?: return null + val dispatchReceiver = resolvedCall.dispatchReceiver as? ImplicitReceiver + val extensionReceiver = resolvedCall.extensionReceiver as? ImplicitReceiver + var isIndirect = false + val isDoubleReceiver = when (outerClassDescriptor) { + dispatchReceiver?.declarationDescriptor -> extensionReceiver != null + extensionReceiver?.declarationDescriptor -> dispatchReceiver != null + else -> { + isIndirect = true + when { + dispatchReceiver?.declarationDescriptor?.isAncestorOf(outerClassDescriptor, true) ?: false -> + extensionReceiver != null + extensionReceiver?.declarationDescriptor?.isAncestorOf(outerClassDescriptor, true) ?: false -> + dispatchReceiver != null + else -> return null } } - OuterInstanceReferenceUsageInfo.ImplicitReceiver(resolvedCall.call.callElement, isIndirect, isDoubleReceiver) } - else -> null + OuterInstanceReferenceUsageInfo.ImplicitReceiver(resolvedCall.call.callElement, isIndirect, isDoubleReceiver) } - } - - override fun visitElement(element: PsiElement) { - getOuterInstanceReference(element)?.let { - body(it) - found = true - if (stopAtFirst) stopWalking() - return - } - super.visitElement(element) + else -> null } } + + override fun visitElement(element: PsiElement) { + getOuterInstanceReference(element)?.let { + body(it) + found = true + if (stopAtFirst) stopWalking() + return + } + super.visitElement(element) + } + } ) return found } diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt index a4e19eae489..6230bce6eb0 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt @@ -24,10 +24,12 @@ import org.jetbrains.kotlin.idea.core.util.toPsiDirectory import org.jetbrains.kotlin.idea.core.util.toPsiFile import org.jetbrains.kotlin.idea.jsonUtils.getNullableString import org.jetbrains.kotlin.idea.jsonUtils.getString -import org.jetbrains.kotlin.idea.refactoring.* +import org.jetbrains.kotlin.idea.refactoring.AbstractMultifileRefactoringTest +import org.jetbrains.kotlin.idea.refactoring.createKotlinFile import org.jetbrains.kotlin.idea.refactoring.move.changePackage.KotlinChangePackageRefactoring import org.jetbrains.kotlin.idea.refactoring.move.moveClassesOrPackages.KotlinAwareDelegatingMoveDestination import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.* +import org.jetbrains.kotlin.idea.refactoring.runRefactoringTest import org.jetbrains.kotlin.idea.search.allScope import org.jetbrains.kotlin.idea.search.projectScope import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex @@ -69,12 +71,12 @@ enum class MoveAction : AbstractMultifileRefactoringTest.RefactoringAction { val targetPackage = config.getString("targetPackage") MoveClassesOrPackagesProcessor( - mainFile.project, - classesToMove.toTypedArray(), - MultipleRootsMoveDestination(PackageWrapper(mainFile.manager, targetPackage)), - /* searchInComments = */ false, - /* searchInNonJavaFiles = */ true, - /* moveCallback = */ null + mainFile.project, + classesToMove.toTypedArray(), + MultipleRootsMoveDestination(PackageWrapper(mainFile.manager, targetPackage)), + /* searchInComments = */ false, + /* searchInNonJavaFiles = */ true, + /* moveCallback = */ null ).run() } }, @@ -93,22 +95,21 @@ enum class MoveAction : AbstractMultifileRefactoringTest.RefactoringAction { val moveDestination = if (targetDirectory != null) { val targetSourceRoot = ProjectRootManager.getInstance(project).fileIndex.getSourceRootForFile(targetDirectory.virtualFile)!! KotlinAwareDelegatingMoveDestination( - AutocreatingSingleSourceRootMoveDestination(targetPackageWrapper, targetSourceRoot), - targetPackage, - targetDirectory + AutocreatingSingleSourceRootMoveDestination(targetPackageWrapper, targetSourceRoot), + targetPackage, + targetDirectory ) - } - else { + } else { MultipleRootsMoveDestination(targetPackageWrapper) } MoveClassesOrPackagesProcessor( - project, - arrayOf(sourcePackage), - moveDestination, - /* searchInComments = */ false, - /* searchInNonJavaFiles = */ true, - /* moveCallback = */ null + project, + arrayOf(sourcePackage), + moveDestination, + /* searchInComments = */ false, + /* searchInNonJavaFiles = */ true, + /* moveCallback = */ null ).run() } }, @@ -121,12 +122,12 @@ enum class MoveAction : AbstractMultifileRefactoringTest.RefactoringAction { val targetClass = config.getString("targetClass") MoveClassToInnerProcessor( - project, - classesToMove.toTypedArray(), - JavaPsiFacade.getInstance(project).findClass(targetClass, project.allScope())!!, - /* searchInComments = */ false, - /* searchInNonJavaFiles = */ true, - /* moveCallback = */ null + project, + classesToMove.toTypedArray(), + JavaPsiFacade.getInstance(project).findClass(targetClass, project.allScope())!!, + /* searchInComments = */ false, + /* searchInNonJavaFiles = */ true, + /* moveCallback = */ null ).run() } }, @@ -141,12 +142,12 @@ enum class MoveAction : AbstractMultifileRefactoringTest.RefactoringAction { val targetPackage = config.getString("targetPackage") MoveInnerProcessor( - project, - classToMove, - newClassName, - outerInstanceParameterName != null, - outerInstanceParameterName, - JavaPsiFacade.getInstance(project).findPackage(targetPackage)!!.directories[0] + project, + classToMove, + newClassName, + outerInstanceParameterName != null, + outerInstanceParameterName, + JavaPsiFacade.getInstance(project).findPackage(targetPackage)!!.directories[0] ).run() } }, @@ -161,29 +162,27 @@ enum class MoveAction : AbstractMultifileRefactoringTest.RefactoringAction { ActionRunner.runInsideWriteAction { VfsUtil.createDirectoryIfMissing(rootDir, targetDirPath) } val newParent = if (targetPackage != null) { JavaPsiFacade.getInstance(project).findPackage(targetPackage)!!.directories[0] - } - else { + } else { rootDir.findFileByRelativePath(targetDirPath)!!.toPsiDirectory(project)!! } MoveFilesOrDirectoriesProcessor( - project, - arrayOf(mainFile), - newParent, - /* searchInComments = */ false, - /* searchInNonJavaFiles = */ true, - /* moveCallback = */ null, - /* prepareSuccessfulCallback = */ null + project, + arrayOf(mainFile), + newParent, + /* searchInComments = */ false, + /* searchInNonJavaFiles = */ true, + /* moveCallback = */ null, + /* prepareSuccessfulCallback = */ null ).run() - } - else { + } else { val targetFile = config.getString("targetFile") MoveHandler.doMove( - project, - arrayOf(mainFile), - PsiManager.getInstance(project).findFile(rootDir.findFileByRelativePath(targetFile)!!)!!, - /* dataContext = */ null, - /* callback = */ null + project, + arrayOf(mainFile), + PsiManager.getInstance(project).findFile(rootDir.findFileByRelativePath(targetFile)!!)!!, + /* dataContext = */ null, + /* callback = */ null ) } } @@ -199,13 +198,13 @@ enum class MoveAction : AbstractMultifileRefactoringTest.RefactoringAction { val targetDirPath = config.getString("targetDirectory") val targetDir = rootDir.findFileByRelativePath(targetDirPath)!!.toPsiDirectory(project)!! KotlinAwareMoveFilesOrDirectoriesProcessor( - project, - elementsToMove, - targetDir, - true, - searchInComments = true, - searchInNonJavaFiles = true, - moveCallback = null + project, + elementsToMove, + targetDir, + true, + searchInComments = true, + searchInNonJavaFiles = true, + moveCallback = null ).run() } }, @@ -251,7 +250,7 @@ enum class MoveAction : AbstractMultifileRefactoringTest.RefactoringAction { val project = mainFile.project val sourceDir = rootDir.findFileByRelativePath(config.getString("sourceDir"))!!.toPsiDirectory(project)!! val targetDir = rootDir.findFileByRelativePath(config.getString("targetDir"))!!.toPsiDirectory(project)!! - MoveDirectoryWithClassesProcessor(project, arrayOf(sourceDir), targetDir, true, true, true, {}).run() + MoveDirectoryWithClassesProcessor(project, arrayOf(sourceDir), targetDir, true, true, true) {}.run() } }, @@ -261,24 +260,24 @@ enum class MoveAction : AbstractMultifileRefactoringTest.RefactoringAction { val elementToMove = elementsAtCaret.single().getNonStrictParentOfType()!! val targetClassName = config.getNullableString("targetClass") val targetClass = - if (targetClassName != null) { - KotlinFullClassNameIndex.getInstance().get(targetClassName, project, project.projectScope()).first()!! - } - else null - val delegate = MoveDeclarationsDelegate.NestedClass(config.getNullableString("newName"), - config.getNullableString("outerInstanceParameter")) + if (targetClassName != null) { + KotlinFullClassNameIndex.getInstance().get(targetClassName, project, project.projectScope()).first()!! + } else null + val delegate = MoveDeclarationsDelegate.NestedClass( + config.getNullableString("newName"), + config.getNullableString("outerInstanceParameter") + ) val moveTarget = - if (targetClass != null) { - KotlinMoveTargetForExistingElement(targetClass) - } - else { - val fileName = (delegate.newClassName ?: elementToMove.name!!) + ".kt" - val targetPackageFqName = (mainFile as KtFile).packageFqName - val targetDir = mainFile.containingDirectory!! - KotlinMoveTargetForDeferredFile(targetPackageFqName, targetDir, null) { - createKotlinFile(fileName, targetDir, targetPackageFqName.asString()) - } + if (targetClass != null) { + KotlinMoveTargetForExistingElement(targetClass) + } else { + val fileName = (delegate.newClassName ?: elementToMove.name!!) + ".kt" + val targetPackageFqName = (mainFile as KtFile).packageFqName + val targetDir = mainFile.containingDirectory!! + KotlinMoveTargetForDeferredFile(targetPackageFqName, targetDir, null) { + createKotlinFile(fileName, targetDir, targetPackageFqName.asString()) } + } val descriptor = MoveDeclarationsDescriptor(project, MoveSource(elementToMove), moveTarget, delegate) MoveKotlinDeclarationsProcessor(descriptor).run() }