diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationDialog.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationDialog.kt index 913ad394925..07cd6092a65 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationDialog.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationDialog.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.copy @@ -53,9 +42,9 @@ import kotlin.math.max // Based on com.intellij.refactoring.copy.CopyClassDialog class CopyKotlinDeclarationDialog( - declaration: KtNamedDeclaration, - private val defaultTargetDirectory: PsiDirectory?, - private val project: Project + declaration: KtNamedDeclaration, + private val defaultTargetDirectory: PsiDirectory?, + private val project: Project ) : DialogWrapper(project, true) { private val informationLabel = JLabel() private val classNameField = EditorTextField("") @@ -76,18 +65,19 @@ class CopyKotlinDeclarationDialog( get() = ((destinationComboBox.comboBox.selectedItem as? DirectoryChooser.ItemWrapper)?.directory ?: originalFile).sourceRoot init { - informationLabel.text = RefactoringBundle.message("copy.class.copy.0.1", UsageViewUtil.getType(declaration), UsageViewUtil.getLongName(declaration)) + informationLabel.text = + RefactoringBundle.message("copy.class.copy.0.1", UsageViewUtil.getType(declaration), UsageViewUtil.getLongName(declaration)) informationLabel.font = informationLabel.font.deriveFont(Font.BOLD) init() destinationComboBox.setData( - project, - defaultTargetDirectory, - Pass { setErrorText(it, destinationComboBox) }, - packageNameField.childComponent + project, + defaultTargetDirectory, + Pass { setErrorText(it, destinationComboBox) }, + packageNameField.childComponent ) - classNameField.setText(UsageViewUtil.getShortName(declaration)) + classNameField.text = UsageViewUtil.getShortName(declaration) classNameField.selectAll() } @@ -97,7 +87,8 @@ class CopyKotlinDeclarationDialog( override fun createNorthPanel(): JComponent? { val qualifiedName = qualifiedName - packageNameField = PackageNameReferenceEditorCombo(qualifiedName, project, RECENTS_KEY, RefactoringBundle.message("choose.destination.package")) + packageNameField = + PackageNameReferenceEditorCombo(qualifiedName, project, RECENTS_KEY, RefactoringBundle.message("choose.destination.package")) packageNameField.setTextFieldPreferredWidth(max(qualifiedName.length + 5, 40)) packageLabel.text = RefactoringBundle.message("destination.package") packageLabel.labelFor = packageNameField @@ -111,12 +102,12 @@ class CopyKotlinDeclarationDialog( val panel = JPanel(BorderLayout()) panel.add(openInEditorCheckBox, BorderLayout.EAST) return FormBuilder.createFormBuilder() - .addComponent(informationLabel) - .addLabeledComponent(RefactoringBundle.message("copy.files.new.name.label"), classNameField, UIUtil.LARGE_VGAP) - .addLabeledComponent(packageLabel, packageNameField) - .addLabeledComponent(label, destinationComboBox) - .addComponent(panel) - .panel + .addComponent(informationLabel) + .addLabeledComponent(RefactoringBundle.message("copy.files.new.name.label"), classNameField, UIUtil.LARGE_VGAP) + .addLabeledComponent(packageLabel, packageNameField) + .addLabeledComponent(label, destinationComboBox) + .addComponent(panel) + .panel } private val qualifiedName: String @@ -144,8 +135,7 @@ class CopyKotlinDeclarationDialog( try { targetDirectory = destinationComboBox.selectDirectory(PackageWrapper(manager, packageName), false) - } - catch (e: IncorrectOperationException) { + } catch (e: IncorrectOperationException) { return e.message } @@ -180,6 +170,7 @@ class CopyKotlinDeclarationDialog( override fun getHelpId() = HelpID.COPY_CLASS companion object { - @NonNls private val RECENTS_KEY = "CopyKotlinDeclarationDialog.RECENTS_KEY" + @NonNls + private val RECENTS_KEY = "CopyKotlinDeclarationDialog.RECENTS_KEY" } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt index 36bcb1c67ee..425713b36f7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.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.copy @@ -66,15 +55,12 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { var Project.newName: String? by UserDataProperty(Key.create("NEW_NAME")) private fun PsiElement.getCopyableElement() = - parentsWithSelf.firstOrNull { it is KtFile || (it is KtNamedDeclaration && it.parent is KtFile) } as? KtElement + parentsWithSelf.firstOrNull { it is KtFile || (it is KtNamedDeclaration && it.parent is KtFile) } as? KtElement - private fun PsiElement.getDeclarationsToCopy(): List { - val declarationOrFile = getCopyableElement() - return when (declarationOrFile) { - is KtFile -> declarationOrFile.declarations.filterIsInstance().ifEmpty { listOf(declarationOrFile) } - is KtNamedDeclaration -> listOf(declarationOrFile) - else -> emptyList() - } + private fun PsiElement.getDeclarationsToCopy(): List = when (val declarationOrFile = getCopyableElement()) { + is KtFile -> declarationOrFile.declarations.filterIsInstance().ifEmpty { listOf(declarationOrFile) } + is KtNamedDeclaration -> listOf(declarationOrFile) + else -> emptyList() } } @@ -82,8 +68,8 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { private fun getSourceFiles(elements: Array): Array? { return elements - .map { it.containingFile ?: it as? PsiFileSystemItem ?: return null } - .toTypedArray() + .map { it.containingFile ?: it as? PsiFileSystemItem ?: return null } + .toTypedArray() } private fun canCopyFiles(elements: Array, fromUpdate: Boolean): Boolean { @@ -94,11 +80,11 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { private fun canCopyDeclarations(elements: Array): Boolean { val containingFile = - elements - .flatMap { it.getDeclarationsToCopy().ifEmpty { return false } } - .distinctBy { it.containingFile } - .singleOrNull() - ?.containingFile ?: return false + elements + .flatMap { it.getDeclarationsToCopy().ifEmpty { return false } } + .distinctBy { it.containingFile } + .singleOrNull() + ?.containingFile ?: return false return containingFile.sourceRoot != null } @@ -111,20 +97,18 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { } private fun getOrCreateTargetFile( - originalFile: KtFile, - targetDirectory: PsiDirectory, - targetFileName: String, - commandName: String + originalFile: KtFile, + targetDirectory: PsiDirectory, + targetFileName: String, + commandName: String ): KtFile? { val existingFile = targetDirectory.findFile(targetFileName) if (existingFile == originalFile) return null - if (existingFile != null) { - val policy = getFilePolicy(existingFile, targetFileName, targetDirectory, commandName) - when (policy) { - ExistingFilePolicy.APPEND -> {} - ExistingFilePolicy.OVERWRITE -> runWriteAction { existingFile.delete() } - ExistingFilePolicy.SKIP -> return null + if (existingFile != null) when (getFilePolicy(existingFile, targetFileName, targetDirectory, commandName)) { + ExistingFilePolicy.APPEND -> { } + ExistingFilePolicy.OVERWRITE -> runWriteAction { existingFile.delete() } + ExistingFilePolicy.SKIP -> return null } return runWriteAction { if (existingFile != null && existingFile.isValid) { @@ -136,34 +120,33 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { } private fun getFilePolicy( - existingFile: PsiFile?, - targetFileName: String, - targetDirectory: PsiDirectory, - commandName: String + existingFile: PsiFile?, + targetFileName: String, + targetDirectory: PsiDirectory, + commandName: String ): ExistingFilePolicy { val isUnitTestMode = ApplicationManager.getApplication().isUnitTestMode return if (existingFile !is KtFile) { if (isUnitTestMode) return ExistingFilePolicy.OVERWRITE val answer = Messages.showOkCancelDialog( - "File $targetFileName already exists in ${targetDirectory.virtualFile.path}", - commandName, - "Overwrite", - "Cancel", - Messages.getQuestionIcon() + "File $targetFileName already exists in ${targetDirectory.virtualFile.path}", + commandName, + "Overwrite", + "Cancel", + Messages.getQuestionIcon() ) if (answer == Messages.OK) ExistingFilePolicy.OVERWRITE else ExistingFilePolicy.SKIP - } - else { + } else { if (isUnitTestMode) return ExistingFilePolicy.APPEND val answer = Messages.showYesNoCancelDialog( - "File $targetFileName already exists in ${targetDirectory.virtualFile.path}", - commandName, - "Append", - "Overwrite", - "Cancel", - Messages.getQuestionIcon() + "File $targetFileName already exists in ${targetDirectory.virtualFile.path}", + commandName, + "Append", + "Overwrite", + "Cancel", + Messages.getQuestionIcon() ) when (answer) { Messages.YES -> ExistingFilePolicy.APPEND @@ -187,7 +170,8 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { val originalFile = elementsToCopy.first().containingFile as KtFile val initialTargetDirectory = defaultTargetDirectory ?: originalFile.containingDirectory ?: return - val isSingleDeclarationInFile = singleElementToCopy is KtNamedDeclaration && originalFile.declarations.singleOrNull() == singleElementToCopy + val isSingleDeclarationInFile = + singleElementToCopy is KtNamedDeclaration && originalFile.declarations.singleOrNull() == singleElementToCopy val project = initialTargetDirectory.project @@ -210,8 +194,7 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { newName = dialog.newName ?: singleElementToCopy.name targetDirWrapper = dialog.targetDirectory?.toDirectoryWrapper() ?: return targetSourceRoot = dialog.targetSourceRoot - } - else { + } else { val dialog = CopyFilesOrDirectoriesDialog(arrayOf(originalFile), initialTargetDirectory, project, false) if (!dialog.showAndGet()) return openInEditor = dialog.openInEditor() @@ -219,8 +202,7 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { targetDirWrapper = dialog.targetDirectory?.toDirectoryWrapper() ?: return targetSourceRoot = dialog.targetDirectory?.sourceRoot } - } - else { + } else { project.newName?.let { newName = it } } @@ -229,8 +211,8 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { val internalUsages = runReadAction { val targetPackageName = targetDirWrapper.getPackageName() val changeInfo = ContainerChangeInfo( - ContainerInfo.Package(originalFile.packageFqName), - ContainerInfo.Package(FqName(targetPackageName)) + ContainerInfo.Package(originalFile.packageFqName), + ContainerInfo.Package(FqName(targetPackageName)) ) elementsToCopy.flatMapTo(LinkedHashSet()) { elementToCopy -> elementToCopy.getInternalReferencesToUpdateOnPackageNameChange(changeInfo).filter { @@ -247,7 +229,8 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { project.executeCommand(commandName) { try { val targetDirectory = runWriteAction { targetDirWrapper.getOrCreateDirectory(initialTargetDirectory) } - val targetFileName = if (newName?.contains(".") ?: false) newName!! else newName + "." + originalFile.virtualFile.extension + val targetFileName = + if (newName?.contains(".") == true) newName!! else newName + "." + originalFile.virtualFile.extension val oldToNewElementsMapping = HashMap() @@ -271,9 +254,9 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { copiedDeclaration = if (isSingleDeclarationInFile && targetFile is KtFile) { targetFile.declarations.singleOrNull() as? KtNamedDeclaration } else null - } - else { - targetFile = getOrCreateTargetFile(originalFile, targetDirectory, targetFileName, commandName) ?: return@executeCommand + } else { + targetFile = + getOrCreateTargetFile(originalFile, targetDirectory, targetFileName, commandName) ?: return@executeCommand runWriteAction { val newElements = elementsToCopy.map { targetFile.add(it.copy()) as KtNamedDeclaration } elementsToCopy.zip(newElements).toMap(oldToNewElementsMapping) @@ -301,11 +284,9 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { if (openInEditor) { EditorHelper.openFilesInEditor(arrayOf(targetFile)) } - } - catch (e: IncorrectOperationException) { + } catch (e: IncorrectOperationException) { Messages.showMessageDialog(project, e.message, RefactoringBundle.message("error.title"), Messages.getErrorIcon()) - } - finally { + } finally { cleanUpInternalUsages(internalUsages + restoredInternalUsages) } } @@ -317,10 +298,10 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { val targetSourceRootPsi = targetSourceRoot?.toPsiDirectory(project) if (targetSourceRootPsi != null && project == originalFile.project) { val conflictChecker = MoveConflictChecker( - project, - elementsToCopy, - KotlinDirectoryMoveTarget(FqName.ROOT, targetSourceRootPsi), - originalFile + project, + elementsToCopy, + KotlinDirectoryMoveTarget(FqName.ROOT, targetSourceRootPsi), + originalFile ) conflictChecker.checkModuleConflictsInDeclarations(internalUsages, conflicts) conflictChecker.checkVisibilityInDeclarations(conflicts)