Fix Android extensions import rename
#KT-17890 Fixed
This commit is contained in:
+6
-2
@@ -79,8 +79,12 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun isReferenceTo(element: PsiElement?): Boolean {
|
override fun isReferenceTo(element: PsiElement?): Boolean {
|
||||||
if (element != null && !canBeReferenceTo(element)) {
|
if (element != null) {
|
||||||
return false
|
if (!canBeReferenceTo(element)) return false
|
||||||
|
|
||||||
|
for (extension in Extensions.getArea(element.project).getExtensionPoint(SimpleNameReferenceExtension.EP_NAME).extensions) {
|
||||||
|
if (extension.isReferenceTo(this, element)) return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.isReferenceTo(element)
|
return super.isReferenceTo(element)
|
||||||
|
|||||||
+2
@@ -27,5 +27,7 @@ interface SimpleNameReferenceExtension {
|
|||||||
ExtensionPointName.create("org.jetbrains.kotlin.simpleNameReferenceExtension")
|
ExtensionPointName.create("org.jetbrains.kotlin.simpleNameReferenceExtension")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isReferenceTo(reference: KtSimpleNameReference, element: PsiElement): Boolean
|
||||||
|
|
||||||
fun handleElementRename(reference: KtSimpleNameReference, psiFactory: KtPsiFactory, newElementName: String): PsiElement?
|
fun handleElementRename(reference: KtSimpleNameReference, psiFactory: KtPsiFactory, newElementName: String): PsiElement?
|
||||||
}
|
}
|
||||||
+26
-3
@@ -18,18 +18,21 @@ package org.jetbrains.kotlin.android.synthetic.idea
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.xml.XmlAttributeValue
|
import com.intellij.psi.xml.XmlAttributeValue
|
||||||
import org.jetbrains.android.dom.wrappers.ValueResourceElementWrapper
|
import com.intellij.psi.xml.XmlFile
|
||||||
|
import org.jetbrains.android.facet.AndroidFacet
|
||||||
import org.jetbrains.android.util.AndroidResourceUtil
|
import org.jetbrains.android.util.AndroidResourceUtil
|
||||||
import org.jetbrains.kotlin.android.synthetic.AndroidConst
|
import org.jetbrains.kotlin.android.synthetic.AndroidConst
|
||||||
import org.jetbrains.kotlin.android.synthetic.androidIdToName
|
import org.jetbrains.kotlin.android.synthetic.androidIdToName
|
||||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||||
import org.jetbrains.kotlin.plugin.references.SimpleNameReferenceExtension
|
import org.jetbrains.kotlin.plugin.references.SimpleNameReferenceExtension
|
||||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
|
|
||||||
class AndroidSimpleNameReferenceExtension : SimpleNameReferenceExtension {
|
class AndroidSimpleNameReferenceExtension : SimpleNameReferenceExtension {
|
||||||
|
|
||||||
|
override fun isReferenceTo(reference: KtSimpleNameReference, element: PsiElement): Boolean =
|
||||||
|
element is XmlFile && reference.isReferenceToXmlFile(element)
|
||||||
|
|
||||||
private fun isLayoutPackageIdentifier(reference: KtSimpleNameReference): Boolean {
|
private fun isLayoutPackageIdentifier(reference: KtSimpleNameReference): Boolean {
|
||||||
val probablyVariant = reference.element?.parent as? KtDotQualifiedExpression ?: return false
|
val probablyVariant = reference.element?.parent as? KtDotQualifiedExpression ?: return false
|
||||||
val probablyKAS = probablyVariant.receiverExpression as? KtDotQualifiedExpression ?: return false
|
val probablyKAS = probablyVariant.receiverExpression as? KtDotQualifiedExpression ?: return false
|
||||||
@@ -43,9 +46,29 @@ class AndroidSimpleNameReferenceExtension : SimpleNameReferenceExtension {
|
|||||||
return psiFactory.createNameIdentifier(newSyntheticPropertyName.name)
|
return psiFactory.createNameIdentifier(newSyntheticPropertyName.name)
|
||||||
}
|
}
|
||||||
else if (isLayoutPackageIdentifier(reference)) {
|
else if (isLayoutPackageIdentifier(reference)) {
|
||||||
return psiFactory.createSimpleName(newElementName.substringBeforeLast(".xml")).getIdentifier()
|
return psiFactory.createSimpleName(newElementName.removeSuffix(".xml")).getIdentifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KtSimpleNameReference.isReferenceToXmlFile(xmlFile: XmlFile): Boolean {
|
||||||
|
if (!isLayoutPackageIdentifier(this)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xmlFile.name.removeSuffix(".xml") != element.getReferencedName()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val virtualFile = xmlFile.virtualFile ?: return false
|
||||||
|
val layoutDir = virtualFile.parent
|
||||||
|
if (layoutDir.name != "layout" && !layoutDir.name.startsWith("layout-")) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val resourceDirectories = AndroidFacet.getInstance(element)?.allResourceDirectories ?: return false
|
||||||
|
val resourceDirectory = virtualFile.parent?.parent ?: return false
|
||||||
|
return resourceDirectories.any { it == resourceDirectory }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+4
-14
@@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.android
|
package org.jetbrains.kotlin.android
|
||||||
|
|
||||||
import com.intellij.codeInsight.TargetElementUtil
|
|
||||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil
|
|
||||||
import com.intellij.refactoring.rename.RenameProcessor
|
|
||||||
import com.intellij.psi.impl.source.xml.XmlAttributeValueImpl
|
|
||||||
import com.intellij.psi.xml.XmlFile
|
import com.intellij.psi.xml.XmlFile
|
||||||
import org.jetbrains.kotlin.android.synthetic.AndroidConst
|
import org.jetbrains.kotlin.android.synthetic.AndroidConst
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
@@ -32,17 +28,11 @@ abstract class AbstractAndroidLayoutRenameTest : KotlinAndroidTestCase() {
|
|||||||
copyResourceDirectoryForTest(path)
|
copyResourceDirectoryForTest(path)
|
||||||
val virtualFile = myFixture.copyFileToProject(path + getTestName(true) + ".kt", "src/" + getTestName(true) + ".kt")
|
val virtualFile = myFixture.copyFileToProject(path + getTestName(true) + ".kt", "src/" + getTestName(true) + ".kt")
|
||||||
myFixture.configureFromExistingVirtualFile(virtualFile)
|
myFixture.configureFromExistingVirtualFile(virtualFile)
|
||||||
|
val xmlFile = myFixture.elementAtCaret.containingFile as XmlFile
|
||||||
|
|
||||||
val completionEditor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myFixture.editor, myFixture.file)
|
myFixture.renameElement(xmlFile, NEW_NAME_XML)
|
||||||
|
|
||||||
val element = TargetElementUtil.findTargetElement(
|
val expectedImportName = AndroidConst.SYNTHETIC_PACKAGE + ".main." + NEW_NAME
|
||||||
completionEditor,
|
assertTrue((myFixture.file as KtFile).importDirectives.any { it.importedFqName?.asString() == expectedImportName })
|
||||||
TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED or TargetElementUtil.ELEMENT_NAME_ACCEPTED) as XmlAttributeValueImpl
|
|
||||||
|
|
||||||
val file = element.containingFile as XmlFile
|
|
||||||
|
|
||||||
RenameProcessor(myFixture.project, file, NEW_NAME_XML, false, true).run()
|
|
||||||
|
|
||||||
(myFixture.file as KtFile).importDirectives.any { it.importedFqName!!.asString() == AndroidConst.SYNTHETIC_PACKAGE + ".main." + NEW_NAME }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user