Convert to lambda: report at INFORMATION level if anonymous object super type does not match function parameter type exactly
#KT-28081 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
3649e61c2f
commit
0075e90042
@@ -25,6 +25,7 @@ import com.intellij.psi.search.searches.ReferencesSearch
|
|||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
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.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||||
import org.jetbrains.kotlin.idea.core.canMoveLambdaOutsideParentheses
|
import org.jetbrains.kotlin.idea.core.canMoveLambdaOutsideParentheses
|
||||||
@@ -37,13 +38,11 @@ import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
|||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
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.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.contentRange
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
@@ -51,8 +50,16 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
|
|
||||||
class ObjectLiteralToLambdaInspection : IntentionBasedInspection<KtObjectLiteralExpression>(ObjectLiteralToLambdaIntention::class) {
|
class ObjectLiteralToLambdaInspection : IntentionBasedInspection<KtObjectLiteralExpression>(ObjectLiteralToLambdaIntention::class) {
|
||||||
override fun problemHighlightType(element: KtObjectLiteralExpression): ProblemHighlightType {
|
override fun problemHighlightType(element: KtObjectLiteralExpression): ProblemHighlightType {
|
||||||
val (_, _, singleFunction) = extractData(element) ?: return super.problemHighlightType(element)
|
val (_, baseType, singleFunction) = extractData(element) ?: return super.problemHighlightType(element)
|
||||||
if (singleFunction.bodyExpression?.anyDescendantOfType<KtReturnExpression> { true } == true) return ProblemHighlightType.INFORMATION
|
if (singleFunction.bodyExpression?.anyDescendantOfType<KtReturnExpression> { true } == true) return ProblemHighlightType.INFORMATION
|
||||||
|
|
||||||
|
val valueArgument = element.parent as? KtValueArgument
|
||||||
|
val call = valueArgument?.getStrictParentOfType<KtCallExpression>()
|
||||||
|
if (call != null) {
|
||||||
|
val argumentMatch = call.resolveToCall()?.getArgumentMapping(valueArgument) as? ArgumentMatch
|
||||||
|
if (baseType.constructor != argumentMatch?.valueParameter?.type?.constructor) return ProblemHighlightType.INFORMATION
|
||||||
|
}
|
||||||
|
|
||||||
return super.problemHighlightType(element)
|
return super.problemHighlightType(element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaInspection
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
@FunctionalInterface
|
||||||
|
public interface Foo {
|
||||||
|
void foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Bar {
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface FooBar extends Foo, Bar {
|
||||||
|
}
|
||||||
Vendored
+11
@@ -0,0 +1,11 @@
|
|||||||
|
@FunctionalInterface
|
||||||
|
public interface Foo {
|
||||||
|
void foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Bar {
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface FooBar extends Foo, Bar {
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// HIGHLIGHT: INFORMATION
|
||||||
|
fun main() {
|
||||||
|
test("", <caret>object : FooBar {
|
||||||
|
override fun foo() {
|
||||||
|
}
|
||||||
|
}, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(s: String, foo: Foo, i: Int) {}
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// HIGHLIGHT: INFORMATION
|
||||||
|
fun main() {
|
||||||
|
test("", FooBar { }, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(s: String, foo: Foo, i: Int) {}
|
||||||
+18
@@ -4416,6 +4416,24 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/inspectionsLocal/objectLiteralToLambda")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class ObjectLiteralToLambda extends AbstractLocalInspectionTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInObjectLiteralToLambda() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/objectLiteralToLambda"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notMatchFunctionParameterType.kt")
|
||||||
|
public void testNotMatchFunctionParameterType() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/objectLiteralToLambda/notMatchFunctionParameterType.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/inspectionsLocal/recursiveEqualsCall")
|
@TestMetadata("idea/testData/inspectionsLocal/recursiveEqualsCall")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user