Move: Support quoted package names

#KT-12411 Fixed
(cherry picked from commit 95239e5)
This commit is contained in:
Alexey Sedunov
2016-06-21 20:57:11 +03:00
parent 89816c5f12
commit 542f8d9fd2
48 changed files with 290 additions and 28 deletions
@@ -60,7 +60,7 @@ import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches.Paramete
import org.jetbrains.kotlin.idea.debugger.evaluate.compilingEvaluator.loadClasses
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.ExtractionResult
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
import org.jetbrains.kotlin.idea.refactoring.quoteSegmentsIfNeeded
import org.jetbrains.kotlin.idea.core.quoteSegmentsIfNeeded
import org.jetbrains.kotlin.idea.util.DebuggerUtils
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.idea.util.attachment.attachmentByPsiFile
@@ -687,11 +687,9 @@ fun invokeOnceOnCommandFinish(action: () -> Unit) {
commandProcessor.addCommandListener(listener)
}
fun FqName.quoteSegmentsIfNeeded(): String {
return pathSegments().map { it.asString().quoteIfNeeded() }.joinToString(".")
}
fun FqNameUnsafe.hasIdentifiersOnly(): Boolean = pathSegments().all { KotlinNameSuggester.isIdentifier(it.asString().quoteIfNeeded()) }
fun FqNameUnsafe.hasIdentifiersOnly(): Boolean = pathSegments().all { KotlinNameSuggester.isIdentifier(it.asString()) }
fun FqName.hasIdentifiersOnly(): Boolean = pathSegments().all { KotlinNameSuggester.isIdentifier(it.asString().quoteIfNeeded()) }
fun PsiNamedElement.isInterfaceClass(): Boolean = this is KtClass && isInterface() || this is PsiClass && isInterface
@@ -26,6 +26,7 @@ import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
import org.jetbrains.kotlin.idea.intentions.SelfTargetingOffsetIndependentIntention
import org.jetbrains.kotlin.idea.refactoring.hasIdentifiersOnly
import org.jetbrains.kotlin.idea.core.quoteSegmentsIfNeeded
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
@@ -84,7 +85,7 @@ class ChangePackageIntention: SelfTargetingOffsetIndependentIntention<KtPackageD
val document = editor.document
project.executeWriteCommand(text) {
document.replaceString(affectedRange!!.startOffset, affectedRange!!.endOffset, currentName)
document.replaceString(affectedRange!!.startOffset, affectedRange!!.endOffset, FqName(currentName).quoteSegmentsIfNeeded())
}
PsiDocumentManager.getInstance(project).commitDocument(document)
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document)
@@ -32,7 +32,7 @@ class ChangePackageToMatchDirectoryIntention : SelfTargetingOffsetIndependentInt
if (file.isInjectedFragment || file.packageMatchesDirectory()) return false
val fqNameByDirectory = file.getFqNameByDirectory()
if (!fqNameByDirectory.toUnsafe().hasIdentifiersOnly()) {
if (!fqNameByDirectory.hasIdentifiersOnly()) {
if (isIntentionBaseInspectionEnabled(file.project, element)) {
text = "File package doesn't match directory"
return true
@@ -47,7 +47,7 @@ class ChangePackageToMatchDirectoryIntention : SelfTargetingOffsetIndependentInt
override fun applyTo(element: KtPackageDirective, editor: Editor?) {
val file = element.getContainingKtFile()
val newFqName = file.getFqNameByDirectory()
if (!newFqName.toUnsafe().hasIdentifiersOnly()) return
if (!newFqName.hasIdentifiersOnly()) return
KotlinChangePackageRefactoring(file).run(newFqName)
}
}
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.refactoring.move.ContainerInfo
import org.jetbrains.kotlin.idea.refactoring.move.getInternalReferencesToUpdateOnPackageNameChange
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
import org.jetbrains.kotlin.idea.refactoring.move.postProcessMoveUsages
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
@@ -63,7 +64,7 @@ class KotlinChangePackageRefactoring(val file: KtFile) {
val internalUsages = file.getInternalReferencesToUpdateOnPackageNameChange(changeInfo)
project.executeWriteCommand("Change file's package to '${newFqName.asString()}'") {
packageDirective.fqName = newFqName
packageDirective.fqName = newFqName.quoteIfNeeded()
postProcessMoveUsages(internalUsages)
project.runWithElementsToShortenIsEmptyIgnored { declarationProcessor.execute(declarationUsages) }
}
@@ -28,6 +28,7 @@ import com.intellij.util.Function
import org.jetbrains.kotlin.idea.core.getPackage
import org.jetbrains.kotlin.idea.refactoring.invokeOnceOnCommandFinish
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveKotlinDeclarationsProcessor
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
import java.util.ArrayList
@@ -89,7 +90,7 @@ class KotlinMoveDirectoryWithClassesHelper : MoveDirectoryWithClassesHelper() {
moveContextMap[file] = MoveContext(moveDestination,
fileHandler.findInternalUsages(file, moveDestination),
moveDeclarationsProcessor)
moveDestination.getPackage()?.let { newPackage -> file.packageDirective?.fqName = FqName(newPackage.qualifiedName) }
moveDestination.getPackage()?.let { newPackage -> file.packageDirective?.fqName = FqName(newPackage.qualifiedName).quoteIfNeeded() }
return true
}
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.idea.core.packageMatchesDirectory
import org.jetbrains.kotlin.idea.refactoring.hasIdentifiersOnly
import org.jetbrains.kotlin.idea.refactoring.move.*
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedDeclaration
@@ -128,7 +129,7 @@ class MoveKotlinFileHandler : MoveFileHandler() {
if (file !is KtFile) return
val newDirectory = file.parent ?: return
val packageNameInfo = file.getPackageNameInfo(newDirectory, true) ?: return
file.packageDirective?.fqName = packageNameInfo.newContainer.fqName!!
file.packageDirective?.fqName = packageNameInfo.newContainer.fqName!!.quoteIfNeeded()
}
override fun retargetUsages(usageInfos: List<UsageInfo>?, oldToNewMap: Map<PsiElement, PsiElement>) {