From 5327031300c5dd27c1253c8fefc53822ff85b57e Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 4 Mar 2014 15:24:22 +0400 Subject: [PATCH] Update references when moving Kotlin file #KT-1696 Fixed --- .../moveFilesOrDirectories/annotations.xml | 24 ++ .../jet/lang/psi/JetPackageDirective.java | 11 +- .../jet/lang/psi/psiUtil/jetPsiUtil.kt | 6 +- idea/src/META-INF/plugin.xml | 1 + .../plugin/refactoring/jetRefactoringUtil.kt | 8 + .../refactoring/move/MoveKotlinFileHandler.kt | 210 ++++++++++++++++++ .../references/JetSimpleNameReference.java | 14 +- .../after/_a/dependency.kt | 13 ++ .../after/_a/noImports.kt | 10 + .../after/_a/specificImportsWithAliases.kt | 12 + .../after/a/noImports.java | 12 + .../after/a/noImports.kt | 10 + .../after/a/onDemandStaticImport.java | 12 + .../after/a/specificImportsWithAliases.kt | 12 + .../after/a/specificStaticImports.java | 16 ++ .../after/b/dependency.kt | 13 ++ .../moveFileWithPackageRename/after/b/main.kt | 24 ++ .../after/c/dependency.kt | 13 ++ .../after/c/noImports.java | 12 + .../after/c/noImports.kt | 10 + .../after/c/onDemandImport.java | 12 + .../after/c/onDemandImport.kt | 11 + .../after/c/onDemandStaticImport.java | 12 + .../after/c/specificImports.java | 12 + .../after/c/specificImports.kt | 12 + .../after/c/specificImportsWithAliases.kt | 12 + .../after/c/specificStaticImports.java | 16 ++ .../before/_a/dependency.kt | 13 ++ .../before/_a/noImports.kt | 8 + .../before/_a/specificImportsWithAliases.kt | 12 + .../before/a/main.kt | 24 ++ .../before/a/noImports.java | 10 + .../before/a/noImports.kt | 8 + .../before/a/onDemandStaticImport.java | 12 + .../before/a/specificImportsWithAliases.kt | 12 + .../before/a/specificStaticImports.java | 14 ++ .../before/b/dependency.kt | 13 ++ .../before/c/dependency.kt | 13 ++ .../before/c/noImports.java | 10 + .../before/c/noImports.kt | 8 + .../before/c/onDemandImport.java | 12 + .../before/c/onDemandImport.kt | 10 + .../before/c/onDemandStaticImport.java | 12 + .../before/c/specificImports.java | 13 ++ .../before/c/specificImports.kt | 12 + .../before/c/specificImportsWithAliases.kt | 12 + .../before/c/specificStaticImports.java | 14 ++ .../moveFileWithPackageRename.test | 5 + .../after/_a/dependency.kt | 13 ++ .../after/_a/noImports.kt | 8 + .../after/_a/specificImportsWithAliases.kt | 12 + .../after/a/noImports.java | 10 + .../after/a/noImports.kt | 8 + .../after/a/onDemandStaticImport.java | 12 + .../after/a/specificImportsWithAliases.kt | 12 + .../after/a/specificStaticImports.java | 14 ++ .../after/b/dependency.kt | 13 ++ .../after/b/main.kt | 24 ++ .../after/c/dependency.kt | 13 ++ .../after/c/noImports.java | 10 + .../after/c/noImports.kt | 8 + .../after/c/onDemandImport.java | 12 + .../after/c/onDemandImport.kt | 10 + .../after/c/onDemandStaticImport.java | 12 + .../after/c/specificImports.java | 13 ++ .../after/c/specificImports.kt | 12 + .../after/c/specificImportsWithAliases.kt | 12 + .../after/c/specificStaticImports.java | 14 ++ .../before/_a/dependency.kt | 13 ++ .../before/_a/main.kt | 24 ++ .../before/_a/noImports.kt | 8 + .../before/_a/specificImportsWithAliases.kt | 12 + .../before/a/noImports.java | 10 + .../before/a/noImports.kt | 8 + .../before/a/onDemandStaticImport.java | 12 + .../before/a/specificImportsWithAliases.kt | 12 + .../before/a/specificStaticImports.java | 14 ++ .../before/b/dependency.kt | 13 ++ .../before/c/dependency.kt | 13 ++ .../before/c/noImports.java | 10 + .../before/c/noImports.kt | 8 + .../before/c/onDemandImport.java | 12 + .../before/c/onDemandImport.kt | 10 + .../before/c/onDemandStaticImport.java | 12 + .../before/c/specificImports.java | 13 ++ .../before/c/specificImports.kt | 12 + .../before/c/specificImportsWithAliases.kt | 12 + .../before/c/specificStaticImports.java | 14 ++ .../moveFileWithoutPackageRename.test | 5 + .../move/JetMoveTestGenerated.java | 10 + 90 files changed, 1265 insertions(+), 11 deletions(-) create mode 100644 annotations/com/intellij/refactoring/move/moveFilesOrDirectories/annotations.xml create mode 100644 idea/src/org/jetbrains/jet/plugin/refactoring/move/MoveKotlinFileHandler.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/_a/dependency.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/_a/noImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/_a/specificImportsWithAliases.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/a/noImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/a/noImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/a/onDemandStaticImport.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/a/specificImportsWithAliases.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/a/specificStaticImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/b/dependency.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/b/main.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/c/dependency.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/c/noImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/c/noImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/c/onDemandImport.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/c/onDemandImport.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/c/onDemandStaticImport.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/c/specificImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/c/specificImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/c/specificImportsWithAliases.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/after/c/specificStaticImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/_a/dependency.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/_a/noImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/_a/specificImportsWithAliases.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/a/main.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/a/noImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/a/noImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/a/onDemandStaticImport.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/a/specificImportsWithAliases.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/a/specificStaticImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/b/dependency.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/c/dependency.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/c/noImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/c/noImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/c/onDemandImport.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/c/onDemandImport.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/c/onDemandStaticImport.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/c/specificImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/c/specificImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/c/specificImportsWithAliases.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/before/c/specificStaticImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithPackageRename/moveFileWithPackageRename.test create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/_a/dependency.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/_a/noImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/_a/specificImportsWithAliases.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/a/noImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/a/noImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/a/onDemandStaticImport.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/a/specificImportsWithAliases.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/a/specificStaticImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/b/dependency.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/b/main.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/c/dependency.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/c/noImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/c/noImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/c/onDemandImport.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/c/onDemandImport.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/c/onDemandStaticImport.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/c/specificImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/c/specificImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/c/specificImportsWithAliases.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/after/c/specificStaticImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/_a/dependency.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/_a/main.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/_a/noImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/_a/specificImportsWithAliases.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/a/noImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/a/noImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/a/onDemandStaticImport.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/a/specificImportsWithAliases.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/a/specificStaticImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/b/dependency.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/c/dependency.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/c/noImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/c/noImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/c/onDemandImport.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/c/onDemandImport.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/c/onDemandStaticImport.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/c/specificImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/c/specificImports.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/c/specificImportsWithAliases.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/before/c/specificStaticImports.java create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutPackageRename/moveFileWithoutPackageRename.test diff --git a/annotations/com/intellij/refactoring/move/moveFilesOrDirectories/annotations.xml b/annotations/com/intellij/refactoring/move/moveFilesOrDirectories/annotations.xml new file mode 100644 index 00000000000..680dfefb336 --- /dev/null +++ b/annotations/com/intellij/refactoring/move/moveFilesOrDirectories/annotations.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPackageDirective.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPackageDirective.java index a932de43d7a..8ef4442cc79 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPackageDirective.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPackageDirective.java @@ -60,14 +60,17 @@ public class JetPackageDirective extends JetReferenceExpression { } @Nullable - public PsiElement getNameIdentifier() { + public JetSimpleNameExpression getLastReferenceExpression() { JetExpression nameExpression = getPackageNameExpression(); if (nameExpression == null) return null; - JetSimpleNameExpression lastPart = (JetSimpleNameExpression)PsiUtilPackage.getQualifiedElementSelector(nameExpression); - if (lastPart == null) return null; + return (JetSimpleNameExpression)PsiUtilPackage.getQualifiedElementSelector(nameExpression); + } - return lastPart.getIdentifier(); + @Nullable + public PsiElement getNameIdentifier() { + JetSimpleNameExpression lastPart = getLastReferenceExpression(); + return lastPart != null ? lastPart.getIdentifier() : null; } @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/psiUtil/jetPsiUtil.kt b/compiler/frontend/src/org/jetbrains/jet/lang/psi/psiUtil/jetPsiUtil.kt index 38f4d2b2f76..3a5f179f3a2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/psiUtil/jetPsiUtil.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/psiUtil/jetPsiUtil.kt @@ -55,6 +55,8 @@ import com.intellij.psi.PsiPackage import com.intellij.psi.PsiClass import com.intellij.psi.PsiMember import org.jetbrains.jet.lang.psi.JetNamedDeclaration +import com.intellij.psi.JavaDirectoryService +import com.intellij.psi.PsiDirectory public fun PsiElement.getParentByTypesAndPredicate( strict : Boolean = false, vararg parentClasses : Class, predicate: (T) -> Boolean @@ -277,4 +279,6 @@ public fun PsiElement.getFqName(): FqName? { is JetNamedDeclaration -> JetPsiUtil.getFQName(this) else -> null } -} \ No newline at end of file +} + +public fun PsiDirectory.getPackage(): PsiPackage? = JavaDirectoryService.getInstance()!!.getPackage(this) \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 9df381d5e37..40f90fe2009 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -171,6 +171,7 @@ + diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/jetRefactoringUtil.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/jetRefactoringUtil.kt index 01e7bba7624..ec5fbdd482a 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/jetRefactoringUtil.kt +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/jetRefactoringUtil.kt @@ -24,6 +24,8 @@ import org.jetbrains.jet.lang.psi.JetPsiFactory import org.jetbrains.jet.lang.psi.psiUtil.getQualifiedElement import org.jetbrains.jet.lang.psi.JetUserType import org.jetbrains.jet.lang.resolve.name.isOneSegmentFQN +import com.intellij.psi.PsiElement +import com.intellij.openapi.util.Key /** * Replace [[JetSimpleNameExpression]] (and its enclosing qualifier) with qualified element given by FqName @@ -48,4 +50,10 @@ fun JetSimpleNameExpression.changeQualifiedName(fqName: FqName): JetElement { is JetUserType -> elementToReplace.replace(JetPsiFactory.createType(project, text).getTypeElement()!!) else -> elementToReplace.replace(JetPsiFactory.createExpression(project, text)) } as JetElement +} + +fun PsiElement.getAndRemoveCopyableUserData(key: Key): T? { + val data = getCopyableUserData(key) + putCopyableUserData(key, null) + return data } \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/move/MoveKotlinFileHandler.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/move/MoveKotlinFileHandler.kt new file mode 100644 index 00000000000..1a0240371df --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/move/MoveKotlinFileHandler.kt @@ -0,0 +1,210 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.refactoring.move + +import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler +import com.intellij.psi.PsiFile +import com.intellij.psi.PsiDirectory +import com.intellij.psi.PsiElement +import com.intellij.usageView.UsageInfo +import com.intellij.openapi.roots.JavaProjectRootsUtil +import com.intellij.psi.PsiCompiledElement +import org.jetbrains.jet.lang.psi.JetFile +import java.util.ArrayList +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.psi.search.searches.ReferencesSearch +import com.intellij.refactoring.util.MoveRenameUsageInfo +import org.jetbrains.jet.lang.psi.JetClassOrObject +import com.intellij.refactoring.util.TextOccurrencesUtil +import org.jetbrains.jet.plugin.search.usagesSearch.descriptor +import org.jetbrains.jet.lang.resolve.DescriptorUtils +import org.jetbrains.jet.lang.psi.JetNamedDeclaration +import com.intellij.openapi.util.text.StringUtil +import com.intellij.psi.PsiReference +import org.jetbrains.jet.lang.resolve.name.FqName +import java.util.Collections +import org.jetbrains.jet.plugin.references.JetSimpleNameReference +import com.intellij.openapi.util.Key +import org.jetbrains.jet.plugin.refactoring.getAndRemoveCopyableUserData +import org.jetbrains.jet.lang.psi.JetSimpleNameExpression +import org.jetbrains.jet.lang.psi.psiUtil.getPackage +import org.jetbrains.jet.plugin.codeInsight.JetFileReferencesResolver +import org.jetbrains.jet.lang.resolve.BindingContext +import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor +import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor +import org.jetbrains.jet.plugin.references.JetReference +import org.jetbrains.jet.asJava.toLightElements +import org.jetbrains.jet.lang.psi.JetDeclaration +import org.jetbrains.jet.lang.psi.JetPsiUtil +import com.intellij.openapi.util.TextRange +import com.intellij.openapi.diagnostic.Logger + +public class MoveKotlinFileHandler : MoveFileHandler() { + class object { + private val LOG = Logger.getInstance(javaClass()) + + class MoveRenameKotlinUsageInfo( + reference: JetSimpleNameReference, + range: TextRange, + referencedElement: JetDeclaration, + val newFqName: FqName + ) : MoveRenameUsageInfo(reference.getElement(), reference, range.getStartOffset(), range.getEndOffset(), referencedElement, false) { + val jetReference: JetSimpleNameReference get() = getReference() as JetSimpleNameReference + } + + class MoveRenameJavaUsageInfo( + reference: PsiReference, + range: TextRange, + referencedElement: JetDeclaration, + val lightElementIndex: Int + ) : MoveRenameUsageInfo(reference.getElement(), reference, range.getStartOffset(), range.getEndOffset(), referencedElement, false) { + val jetDeclaration: JetDeclaration get() = getReferencedElement() as JetDeclaration + } + + class PackageNameInfo(val oldPackageName: FqName, val newPackageName: FqName) + + private val PACKAGE_NAME_INFO_KEY = + Key.create("${javaClass().getCanonicalName()}.PACKAGE_NAME_INFO_KEY") + } + + private fun JetFile.packageMatchesDirectory(): Boolean { + return getPackageName() == getParent()?.getPackage()?.getQualifiedName() + } + + override fun canProcessElement(element: PsiFile?): Boolean { + if (element is PsiCompiledElement || element !is JetFile) return false + return !JavaProjectRootsUtil.isOutsideJavaSourceRoot(element) + } + + override fun prepareMovedFile(file: PsiFile, moveDestination: PsiDirectory, oldToNewMap: Map) { + if (file is JetFile && file.packageMatchesDirectory()) { + val newPackage = moveDestination.getPackage() + if (newPackage != null) { + file.putCopyableUserData( + PACKAGE_NAME_INFO_KEY, + PackageNameInfo(JetPsiUtil.getFQName(file), FqName(newPackage.getQualifiedName())) + ) + } + } + } + + override fun findUsages( + psiFile: PsiFile, + newParent: PsiDirectory, + searchInComments: Boolean, + searchInNonJavaFiles: Boolean + ): List? { + if (psiFile !is JetFile || !psiFile.packageMatchesDirectory()) return null + + val project = psiFile.getProject() + val newPackageName = newParent.getPackage()?.getQualifiedName() ?: "" + + return psiFile.getDeclarations().flatMap { declaration -> + val name = (declaration as? JetNamedDeclaration)?.getName() + if (name != null) { + val newFqName = StringUtil.getQualifiedName(newPackageName, name)!! + + val results = ReferencesSearch.search(declaration, GlobalSearchScope.projectScope(project), false) + .toSet() + .mapTo(ArrayList()) { ref -> + val range = ref.getRangeInElement()!! + + when (ref) { + is JetSimpleNameReference -> + MoveRenameKotlinUsageInfo(ref, range, declaration, FqName(newFqName)) + is JetReference -> + // Can't rebind other JetReferences + null + else -> { + val lightElementWithIndex = + declaration.toLightElements().withIndices().find { p -> ref.isReferenceTo(p.second) } + if (lightElementWithIndex != null && lightElementWithIndex.first >= 0) { + MoveRenameJavaUsageInfo(ref, range, declaration, lightElementWithIndex.first) + } + else null + } + } + } + .filterNotNull() + if (declaration is JetClassOrObject) { + declaration.descriptor?.let { DescriptorUtils.getFqName(it).asString() }?.let { stringToSearch -> + TextOccurrencesUtil.findNonCodeUsages( + declaration, stringToSearch, searchInComments, searchInNonJavaFiles, newFqName, results + ) + } + } + + results + } + else Collections.emptyList() + } + } + + override fun retargetUsages(usageInfos: List?, oldToNewMap: Map?) { + usageInfos?.forEach { usage -> + when (usage) { + is MoveRenameKotlinUsageInfo -> { + usage.jetReference.bindToFqName(usage.newFqName, false) + } + is MoveRenameJavaUsageInfo -> { + val lightElements = usage.jetDeclaration.toLightElements() + val index = usage.lightElementIndex + if (index < lightElements.size) { + usage.getReference()!!.bindToElement(lightElements[index]) + } + else { + LOG.error("Can't find light element with index $index for ${usage.jetDeclaration.getText()} ") + } + } + } + } + } + + override fun updateMovedFile(file: PsiFile) { + if (file !is JetFile) return + + val packageNameInfo = file.getAndRemoveCopyableUserData(PACKAGE_NAME_INFO_KEY) + if (packageNameInfo == null) return + + val referenceToContext = JetFileReferencesResolver.resolve(file = file, visitReceivers = false) + + for ((refExpr, bindingContext) in referenceToContext) { + if (refExpr !is JetSimpleNameExpression) continue + + val descriptor = bindingContext[BindingContext.REFERENCE_TARGET, refExpr]?.let { descriptor -> + if (descriptor is ConstructorDescriptor) descriptor.getContainingDeclaration() else descriptor + } + if (descriptor == null) continue + + val packageName = DescriptorUtils.getParentOfType( + descriptor, javaClass(), false + )?.let { DescriptorUtils.getFqName(it).toSafe() } + when (packageName) { + packageNameInfo.oldPackageName, + packageNameInfo.newPackageName -> { + val fqName = DescriptorUtils.getFqName(descriptor) + if (fqName.isSafe()) { + (refExpr.getReference() as? JetSimpleNameReference)?.bindToFqName(fqName.toSafe(), false) + } + } + } + } + + val packageRef = file.getPackageDirective()?.getLastReferenceExpression()?.getReference() as? JetSimpleNameReference + packageRef?.bindToFqName(packageNameInfo.newPackageName, true) + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java index 866198ae0e9..6260494786d 100644 --- a/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java +++ b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java @@ -68,15 +68,17 @@ public class JetSimpleNameReference extends JetSimpleReference