Convert to anonymous object: fix wrong replacement when SAM is nested interface
#KT-33660 Fixed
This commit is contained in:
committed by
Dmitry Gridin
parent
2e3428bbe7
commit
6a329210cb
+12
-2
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.Severity
|
import org.jetbrains.kotlin.diagnostics.Severity
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||||
import org.jetbrains.kotlin.idea.core.replaced
|
import org.jetbrains.kotlin.idea.core.replaced
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
@@ -21,8 +22,10 @@ import org.jetbrains.kotlin.psi.KtCallExpression
|
|||||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||||
|
|
||||||
@@ -84,7 +87,12 @@ class SamConversionToAnonymousObjectIntention : SelfTargetingRangeIntention<KtCa
|
|||||||
functionDescriptor: FunctionDescriptor,
|
functionDescriptor: FunctionDescriptor,
|
||||||
functionName: String
|
functionName: String
|
||||||
) {
|
) {
|
||||||
val interfaceName = call.calleeExpression?.text ?: return
|
val parentOfCall = call.getQualifiedExpressionForSelector()
|
||||||
|
val interfaceName = if (parentOfCall != null) {
|
||||||
|
parentOfCall.resolveToCall()?.resultingDescriptor?.fqNameSafe?.asString()
|
||||||
|
} else {
|
||||||
|
call.calleeExpression?.text
|
||||||
|
} ?: return
|
||||||
val typeArguments = call.typeArguments.mapNotNull { it.typeReference }
|
val typeArguments = call.typeArguments.mapNotNull { it.typeReference }
|
||||||
val typeArgumentsText =
|
val typeArgumentsText =
|
||||||
if (typeArguments.isEmpty()) "" else typeArguments.joinToString(prefix = "<", postfix = ">", separator = ", ") { it.text }
|
if (typeArguments.isEmpty()) "" else typeArguments.joinToString(prefix = "<", postfix = ">", separator = ", ") { it.text }
|
||||||
@@ -92,7 +100,9 @@ class SamConversionToAnonymousObjectIntention : SelfTargetingRangeIntention<KtCa
|
|||||||
val typeParameters = classDescriptor?.declaredTypeParameters?.map { it.name.asString() }?.zip(typeArguments)?.toMap().orEmpty()
|
val typeParameters = classDescriptor?.declaredTypeParameters?.map { it.name.asString() }?.zip(typeArguments)?.toMap().orEmpty()
|
||||||
LambdaToAnonymousFunctionIntention.convertLambdaToFunction(lambda, functionDescriptor, functionName, typeParameters) {
|
LambdaToAnonymousFunctionIntention.convertLambdaToFunction(lambda, functionDescriptor, functionName, typeParameters) {
|
||||||
it.addModifier(KtTokens.OVERRIDE_KEYWORD)
|
it.addModifier(KtTokens.OVERRIDE_KEYWORD)
|
||||||
call.replaced(KtPsiFactory(it).createExpression("object : $interfaceName$typeArgumentsText { ${it.text} }"))
|
(parentOfCall ?: call).replaced(
|
||||||
|
KtPsiFactory(it).createExpression("object : $interfaceName$typeArgumentsText { ${it.text} }")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
public class J {
|
||||||
|
public void foo(Sam sam) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Sam {
|
||||||
|
void bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
public class J {
|
||||||
|
public void foo(Sam sam) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Sam {
|
||||||
|
void bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun main() {
|
||||||
|
J().foo(J.Sam<caret> {})
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun main() {
|
||||||
|
J().foo(object : J.Sam {
|
||||||
|
override fun bar() {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -14652,6 +14652,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
runTest("idea/testData/intentions/samConversionToAnonymousObject/labeledReturn_ni.kt");
|
runTest("idea/testData/intentions/samConversionToAnonymousObject/labeledReturn_ni.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedClass.kt")
|
||||||
|
public void testNestedClass() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/samConversionToAnonymousObject/nestedClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("notJavaInterface.kt")
|
@TestMetadata("notJavaInterface.kt")
|
||||||
public void testNotJavaInterface() throws Exception {
|
public void testNotJavaInterface() throws Exception {
|
||||||
runTest("idea/testData/intentions/samConversionToAnonymousObject/notJavaInterface.kt");
|
runTest("idea/testData/intentions/samConversionToAnonymousObject/notJavaInterface.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user