Move: Fix processing of callable references to nested Java classes and static methods
#KT-17827 Fixed
This commit is contained in:
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.psi.psiUtil
|
|||||||
import com.intellij.extapi.psi.StubBasedPsiElementBase
|
import com.intellij.extapi.psi.StubBasedPsiElementBase
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.PsiParameter
|
|
||||||
import com.intellij.psi.PsiParameterList
|
|
||||||
import com.intellij.psi.PsiWhiteSpace
|
|
||||||
import com.intellij.psi.stubs.StubElement
|
import com.intellij.psi.stubs.StubElement
|
||||||
import com.intellij.psi.tree.TokenSet
|
import com.intellij.psi.tree.TokenSet
|
||||||
import org.jetbrains.kotlin.KtNodeTypes
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
@@ -596,4 +593,12 @@ fun String?.isIdentifier(): Boolean {
|
|||||||
return lexer.tokenType == null
|
return lexer.tokenType == null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun String.quoteIfNeeded(): String = if (this.isIdentifier()) this else "`$this`"
|
fun String.quoteIfNeeded(): String = if (this.isIdentifier()) this else "`$this`"
|
||||||
|
|
||||||
|
fun PsiElement.isTopLevelKtOrJavaMember(): Boolean {
|
||||||
|
return when (this) {
|
||||||
|
is KtDeclaration -> parent is KtFile
|
||||||
|
is PsiClass -> containingClass == null && this.qualifiedName != null
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
-6
@@ -25,6 +25,7 @@ import com.intellij.util.SmartList
|
|||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
||||||
|
import org.jetbrains.kotlin.idea.codeInsight.shorten.addDelayedImportRequest
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
|
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
|
||||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||||
import org.jetbrains.kotlin.idea.core.copied
|
import org.jetbrains.kotlin.idea.core.copied
|
||||||
@@ -152,9 +153,9 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
|
|||||||
bindToElement(element, ShorteningMode.DELAYED_SHORTENING)
|
bindToElement(element, ShorteningMode.DELAYED_SHORTENING)
|
||||||
|
|
||||||
fun bindToElement(element: PsiElement, shorteningMode: ShorteningMode): PsiElement =
|
fun bindToElement(element: PsiElement, shorteningMode: ShorteningMode): PsiElement =
|
||||||
element.getKotlinFqName()?.let { fqName -> bindToFqName(fqName, shorteningMode) } ?: expression
|
element.getKotlinFqName()?.let { fqName -> bindToFqName(fqName, shorteningMode, element) } ?: expression
|
||||||
|
|
||||||
fun bindToFqName(fqName: FqName, shorteningMode: ShorteningMode = ShorteningMode.DELAYED_SHORTENING): PsiElement {
|
fun bindToFqName(fqName: FqName, shorteningMode: ShorteningMode = ShorteningMode.DELAYED_SHORTENING, targetElement: PsiElement? = null): PsiElement {
|
||||||
val expression = expression
|
val expression = expression
|
||||||
if (fqName.isRoot) return expression
|
if (fqName.isRoot) return expression
|
||||||
|
|
||||||
@@ -162,7 +163,7 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
|
|||||||
if (expression !is KtNameReferenceExpression) return expression
|
if (expression !is KtNameReferenceExpression) return expression
|
||||||
if (expression.parent is KtThisExpression || expression.parent is KtSuperExpression) return expression // TODO: it's a bad design of PSI tree, we should change it
|
if (expression.parent is KtThisExpression || expression.parent is KtSuperExpression) return expression // TODO: it's a bad design of PSI tree, we should change it
|
||||||
|
|
||||||
val newExpression = expression.changeQualifiedName(fqName.quoteIfNeeded())
|
val newExpression = expression.changeQualifiedName(fqName.quoteIfNeeded(), targetElement)
|
||||||
val newQualifiedElement = newExpression.getQualifiedElementOrCallableRef()
|
val newQualifiedElement = newExpression.getQualifiedElementOrCallableRef()
|
||||||
|
|
||||||
if (shorteningMode == ShorteningMode.NO_SHORTENING) return newExpression
|
if (shorteningMode == ShorteningMode.NO_SHORTENING) return newExpression
|
||||||
@@ -184,7 +185,7 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
|
|||||||
* Result is either the same as original element, or [[KtQualifiedExpression]], or [[KtUserType]]
|
* Result is either the same as original element, or [[KtQualifiedExpression]], or [[KtUserType]]
|
||||||
* Note that FqName may not be empty
|
* Note that FqName may not be empty
|
||||||
*/
|
*/
|
||||||
private fun KtNameReferenceExpression.changeQualifiedName(fqName: FqName): KtNameReferenceExpression {
|
private fun KtNameReferenceExpression.changeQualifiedName(fqName: FqName, targetElement: PsiElement? = null): KtNameReferenceExpression {
|
||||||
assert(!fqName.isRoot) { "Can't set empty FqName for element $this" }
|
assert(!fqName.isRoot) { "Can't set empty FqName for element $this" }
|
||||||
|
|
||||||
val shortName = fqName.shortName().asString()
|
val shortName = fqName.shortName().asString()
|
||||||
@@ -195,7 +196,7 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
|
|||||||
val qualifier = parent.qualifier
|
val qualifier = parent.qualifier
|
||||||
val qualifierReference = qualifier?.referenceExpression as? KtNameReferenceExpression
|
val qualifierReference = qualifier?.referenceExpression as? KtNameReferenceExpression
|
||||||
if (qualifierReference != null && qualifier.typeArguments.isNotEmpty()) {
|
if (qualifierReference != null && qualifier.typeArguments.isNotEmpty()) {
|
||||||
qualifierReference.changeQualifiedName(fqName.parent())
|
qualifierReference.changeQualifiedName(fqName.parent(), targetElement)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,7 +211,15 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
|
|||||||
parentDelimiter = ""
|
parentDelimiter = ""
|
||||||
val callableRefCopy = parent.copied()
|
val callableRefCopy = parent.copied()
|
||||||
callableRefCopy.receiverExpression?.delete()
|
callableRefCopy.receiverExpression?.delete()
|
||||||
callableRefCopy.callableReference.replace(psiFactory.createSimpleName(shortName)).parent!!.text
|
val newCallableRef = callableRefCopy
|
||||||
|
.callableReference
|
||||||
|
.replace(psiFactory.createSimpleName(shortName))
|
||||||
|
.parent as KtCallableReferenceExpression
|
||||||
|
if (targetElement != null && targetElement.isTopLevelKtOrJavaMember()) {
|
||||||
|
addDelayedImportRequest(targetElement, parent.containingKtFile)
|
||||||
|
return parent.replaced(newCallableRef).callableReference as KtNameReferenceExpression
|
||||||
|
}
|
||||||
|
newCallableRef.text
|
||||||
}
|
}
|
||||||
else -> shortName
|
else -> shortName
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ class CallableReferenceMoveRenameUsageInfo(
|
|||||||
val element = element ?: return null
|
val element = element ?: return null
|
||||||
val reference = reference ?: return null
|
val reference = reference ?: return null
|
||||||
val referencedElement = referencedElement ?: return null
|
val referencedElement = referencedElement ?: return null
|
||||||
if (target is KtDeclaration && target.parent is KtFile) {
|
if (target != null && target.isTopLevelKtOrJavaMember()) {
|
||||||
element.getStrictParentOfType<KtCallableReferenceExpression>()?.receiverExpression?.delete()
|
element.getStrictParentOfType<KtCallableReferenceExpression>()?.receiverExpression?.delete()
|
||||||
return UnqualifiableMoveRenameUsageInfo(element, reference, referencedElement, element.containingFile!!, addImportToOriginalFile, isInternal)
|
return UnqualifiableMoveRenameUsageInfo(element, reference, referencedElement, element.containingFile!!, addImportToOriginalFile, isInternal)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
val v = MemberNewEndJava::NestedJava
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberEndJava {
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberNewEndJava {
|
||||||
|
public static class NestedJava {}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
val v = MemberEndJava::NestedJava
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberEndJava {
|
||||||
|
public static class <caret>NestedJava {}
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberNewEndJava {
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"mainFile": "foo/MemberEndJava.java",
|
||||||
|
"type": "MOVE_MEMBERS",
|
||||||
|
"targetClass": "foo.MemberNewEndJava"
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package bar;
|
||||||
|
|
||||||
|
public class MemberNewEndJava {
|
||||||
|
public static class NestedJava {}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
import bar.MemberNewEndJava
|
||||||
|
|
||||||
|
val v = MemberNewEndJava::NestedJava
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberEndJava {
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package bar;
|
||||||
|
|
||||||
|
public class MemberNewEndJava {
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
val v = MemberEndJava::NestedJava
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberEndJava {
|
||||||
|
public static class <caret>NestedJava {}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"mainFile": "foo/MemberEndJava.java",
|
||||||
|
"type": "MOVE_MEMBERS",
|
||||||
|
"targetClass": "bar.MemberNewEndJava"
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
val v = ::NestedJava
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberEndJava {
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class NestedJava {}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
val v = MemberEndJava::NestedJava
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberEndJava {
|
||||||
|
public static class <caret>NestedJava {}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"mainFile": "foo/MemberEndJava.java",
|
||||||
|
"type": "MOVE_INNER_CLASS",
|
||||||
|
"targetPackage": "foo"
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package bar;
|
||||||
|
|
||||||
|
public class NestedJava {}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
import bar.NestedJava
|
||||||
|
|
||||||
|
val v = ::NestedJava
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberEndJava {
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
val v = MemberEndJava::NestedJava
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberEndJava {
|
||||||
|
public static class <caret>NestedJava {}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"mainFile": "foo/MemberEndJava.java",
|
||||||
|
"type": "MOVE_INNER_CLASS",
|
||||||
|
"targetPackage": "bar"
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
val v2 = MemberNewEndJava::staticMethod
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberEndJava {
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberNewEndJava {
|
||||||
|
public static void staticMethod() {}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
val v2 = MemberEndJava::staticMethod
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberEndJava {
|
||||||
|
public static void <caret>staticMethod() {}
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberNewEndJava {
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"mainFile": "foo/MemberEndJava.java",
|
||||||
|
"type": "MOVE_MEMBERS",
|
||||||
|
"targetClass": "foo.MemberNewEndJava"
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package bar;
|
||||||
|
|
||||||
|
public class MemberNewEndJava {
|
||||||
|
public static void staticMethod() {}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
import bar.MemberNewEndJava
|
||||||
|
|
||||||
|
val v2 = MemberNewEndJava::staticMethod
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberEndJava {
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package bar;
|
||||||
|
|
||||||
|
public class MemberNewEndJava {
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
val v2 = MemberEndJava::staticMethod
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package foo;
|
||||||
|
|
||||||
|
public class MemberEndJava {
|
||||||
|
public static void <caret>staticMethod() {}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"mainFile": "foo/MemberEndJava.java",
|
||||||
|
"type": "MOVE_MEMBERS",
|
||||||
|
"targetClass": "bar.MemberNewEndJava"
|
||||||
|
}
|
||||||
+36
@@ -25,6 +25,30 @@ public class MoveTestGenerated extends AbstractMoveTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentInSingleGeneratedClass(this.getClass(), new File("idea/testData/refactoring/move"), Pattern.compile("^(.+)\\.test$"), TargetBackend.ANY);
|
KotlinTestUtils.assertAllTestsPresentInSingleGeneratedClass(this.getClass(), new File("idea/testData/refactoring/move"), Pattern.compile("^(.+)\\.test$"), TargetBackend.ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("java/moveClass/callableReferences/nestedToAnotherClass/nestedToAnotherClass.test")
|
||||||
|
public void testJava_moveClass_callableReferences_nestedToAnotherClass_NestedToAnotherClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/java/moveClass/callableReferences/nestedToAnotherClass/nestedToAnotherClass.test");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("java/moveClass/callableReferences/nestedToAnotherClassAndAnotherPackage/nestedToAnotherClassAndAnotherPackage.test")
|
||||||
|
public void testJava_moveClass_callableReferences_nestedToAnotherClassAndAnotherPackage_NestedToAnotherClassAndAnotherPackage() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/java/moveClass/callableReferences/nestedToAnotherClassAndAnotherPackage/nestedToAnotherClassAndAnotherPackage.test");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("java/moveClass/callableReferences/nestedToTopLevel/nestedToTopLevel.test")
|
||||||
|
public void testJava_moveClass_callableReferences_nestedToTopLevel_NestedToTopLevel() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/java/moveClass/callableReferences/nestedToTopLevel/nestedToTopLevel.test");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("java/moveClass/callableReferences/nestedToTopLevelAndAnotherPackage/nestedToTopLevelAndAnotherPackage.test")
|
||||||
|
public void testJava_moveClass_callableReferences_nestedToTopLevelAndAnotherPackage_NestedToTopLevelAndAnotherPackage() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/java/moveClass/callableReferences/nestedToTopLevelAndAnotherPackage/nestedToTopLevelAndAnotherPackage.test");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("java/moveClass/moveAsMember/moveClassToExternalNestedClass/moveClassToExternalNestedClass.test")
|
@TestMetadata("java/moveClass/moveAsMember/moveClassToExternalNestedClass/moveClassToExternalNestedClass.test")
|
||||||
public void testJava_moveClass_moveAsMember_moveClassToExternalNestedClass_MoveClassToExternalNestedClass() throws Exception {
|
public void testJava_moveClass_moveAsMember_moveClassToExternalNestedClass_MoveClassToExternalNestedClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/java/moveClass/moveAsMember/moveClassToExternalNestedClass/moveClassToExternalNestedClass.test");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/java/moveClass/moveAsMember/moveClassToExternalNestedClass/moveClassToExternalNestedClass.test");
|
||||||
@@ -157,6 +181,18 @@ public class MoveTestGenerated extends AbstractMoveTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("java/moveMethod/callableReferences/staticMethodToTopLevelClass/staticMethodToTopLevelClass.test")
|
||||||
|
public void testJava_moveMethod_callableReferences_staticMethodToTopLevelClass_StaticMethodToTopLevelClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/java/moveMethod/callableReferences/staticMethodToTopLevelClass/staticMethodToTopLevelClass.test");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("java/moveMethod/callableReferences/staticMethodToTopLevelClassInAnotherPackage/staticMethodToTopLevelClassInAnotherPackage.test")
|
||||||
|
public void testJava_moveMethod_callableReferences_staticMethodToTopLevelClassInAnotherPackage_StaticMethodToTopLevelClassInAnotherPackage() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/java/moveMethod/callableReferences/staticMethodToTopLevelClassInAnotherPackage/staticMethodToTopLevelClassInAnotherPackage.test");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("java/moveMethod/moveMethodToExternalNestedClass/moveMethodToExternalNestedClass.test")
|
@TestMetadata("java/moveMethod/moveMethodToExternalNestedClass/moveMethodToExternalNestedClass.test")
|
||||||
public void testJava_moveMethod_moveMethodToExternalNestedClass_MoveMethodToExternalNestedClass() throws Exception {
|
public void testJava_moveMethod_moveMethodToExternalNestedClass_MoveMethodToExternalNestedClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/java/moveMethod/moveMethodToExternalNestedClass/moveMethodToExternalNestedClass.test");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/java/moveMethod/moveMethodToExternalNestedClass/moveMethodToExternalNestedClass.test");
|
||||||
|
|||||||
Reference in New Issue
Block a user