Do not drop use of SAM-constructor when it's required for labeled return
This commit is contained in:
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor
|
|||||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
@@ -167,6 +168,8 @@ public class RedundantSamConstructorInspection : AbstractKotlinInspection() {
|
|||||||
|
|
||||||
if (samConstructorCallArguments.isEmpty()) return emptyList()
|
if (samConstructorCallArguments.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
if (samConstructorCallArguments.any { hasLabeledReturnPreventingConversion(it.toCallExpression()!!) }) return emptyList()
|
||||||
|
|
||||||
val originalFunctionDescriptor = functionResolvedCall.resultingDescriptor.original as? FunctionDescriptor ?: return emptyList()
|
val originalFunctionDescriptor = functionResolvedCall.resultingDescriptor.original as? FunctionDescriptor ?: return emptyList()
|
||||||
val containingClass = originalFunctionDescriptor.containingDeclaration as? ClassDescriptor ?: return emptyList()
|
val containingClass = originalFunctionDescriptor.containingDeclaration as? ClassDescriptor ?: return emptyList()
|
||||||
|
|
||||||
@@ -226,5 +229,11 @@ public class RedundantSamConstructorInspection : AbstractKotlinInspection() {
|
|||||||
|
|
||||||
return parametersWithSamTypeCount == samConstructorsCount
|
return parametersWithSamTypeCount == samConstructorsCount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun hasLabeledReturnPreventingConversion(samConstructorCall: KtCallExpression): Boolean {
|
||||||
|
val argument = samConstructorCall.samConstructorValueArgument()!!
|
||||||
|
val samConstructorName = (samConstructorCall.calleeExpression as KtSimpleNameExpression).getReferencedNameAsName()
|
||||||
|
return argument.anyDescendantOfType<KtReturnExpression> { it.getLabelNameAsName() == samConstructorName }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,11 +2,21 @@ package redundantSamConstructor
|
|||||||
|
|
||||||
import a.*
|
import a.*
|
||||||
|
|
||||||
fun testNonApplicableAmbiguity() {
|
fun testNonApplicableAmbiguity(p: Int) {
|
||||||
GenericClassCantBeReplaced.staticFun1(JFunction0 { "" })
|
GenericClassCantBeReplaced.staticFun1(JFunction0 { "" })
|
||||||
GenericClassCantBeReplaced.staticFun2(JFunction0 { "" }, JFunction0 { "" })
|
GenericClassCantBeReplaced.staticFun2(JFunction0 { "" }, JFunction0 { "" })
|
||||||
|
|
||||||
val klass = GenericClassCantBeReplaced()
|
val klass = GenericClassCantBeReplaced()
|
||||||
klass.memberFun1(JFunction0 { "" })
|
klass.memberFun1(JFunction0 { "" })
|
||||||
klass.memberFun2(JFunction0 { "" }, JFunction0 { "" })
|
klass.memberFun2(JFunction0 { "" }, JFunction0 { "" })
|
||||||
|
|
||||||
|
MyJavaClass.staticFun1(Runnable {
|
||||||
|
if (p > 0) return@Runnable
|
||||||
|
print(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
MyJavaClass.staticFun2(Runnable { }, Runnable {
|
||||||
|
if (p > 0) return@Runnable
|
||||||
|
print(1)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
import javax.swing.SwingUtilities
|
||||||
|
|
||||||
|
fun bar(p: Int) {
|
||||||
|
SwingUtilities.invokeLater(<caret>object: Runnable {
|
||||||
|
override fun run() {
|
||||||
|
if (p < 0) return
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
import javax.swing.SwingUtilities
|
||||||
|
|
||||||
|
fun bar(p: Int) {
|
||||||
|
SwingUtilities.invokeLater(Runnable {
|
||||||
|
if (p < 0) return@Runnable
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -133,4 +133,13 @@
|
|||||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Convert object literal to lambda</problem_class>
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Convert object literal to lambda</problem_class>
|
||||||
<description>Convert to lambda</description>
|
<description>Convert to lambda</description>
|
||||||
</problem>
|
</problem>
|
||||||
|
|
||||||
|
<problem>
|
||||||
|
<file>SamAdapterNeededBecauseOfLabeledReturn.kt</file>
|
||||||
|
<line>6</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="SamAdapterNeededBecauseOfLabeledReturn.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Convert object literal to lambda</problem_class>
|
||||||
|
<description>Convert to lambda</description>
|
||||||
|
</problem>
|
||||||
</problems>
|
</problems>
|
||||||
@@ -5943,6 +5943,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("SamAdapterNeededBecauseOfLabeledReturn.kt")
|
||||||
|
public void testSamAdapterNeededBecauseOfLabeledReturn() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/objectLiteralToLambda/SamAdapterNeededBecauseOfLabeledReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("Simple.kt")
|
@TestMetadata("Simple.kt")
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/objectLiteralToLambda/Simple.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/objectLiteralToLambda/Simple.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user