From 1ed2c820089a6b6a0fa6fb189ffaebb47ed694a5 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 16 Mar 2015 15:33:08 +0300 Subject: [PATCH] Quick-Fixes: Approximate non-denotable type with nearest denotable supertype #KT-5915 Fixed --- .../kotlin/resolve/scopes/JetScopeUtils.java | 32 +++++++++- .../QuickFixFactoryForTypeMismatchError.java | 63 +++++++++++++------ .../refactoring/JetNameValidatorImpl.java | 28 +-------- .../afterAccessibleLocalClassInReturn.kt | 8 +++ .../afterAnonymousObjectInCall.kt | 10 +++ .../afterAnonymousObjectInInfixCall.kt | 8 +++ .../afterAnonymousObjectInInitializer.kt | 6 ++ .../afterAnonymousObjectInReturn.kt | 6 ++ .../quickfix/typeMismatch/afterAnyInReturn.kt | 6 ++ .../typeMismatch/afterLocalClassInReturn1.kt | 10 +++ .../typeMismatch/afterLocalClassInReturn2.kt | 9 +++ .../beforeAccessibleLocalClassInReturn.kt | 8 +++ .../beforeAnonymousObjectInCall.kt | 10 +++ .../beforeAnonymousObjectInInfixCall.kt | 8 +++ .../beforeAnonymousObjectInInitializer.kt | 6 ++ .../beforeAnonymousObjectInReturn.kt | 6 ++ .../typeMismatch/beforeAnyInReturn.kt | 6 ++ .../typeMismatch/beforeLocalClassInReturn1.kt | 10 +++ .../typeMismatch/beforeLocalClassInReturn2.kt | 9 +++ .../idea/quickfix/QuickFixTestGenerated.java | 48 ++++++++++++++ 20 files changed, 251 insertions(+), 46 deletions(-) create mode 100644 idea/testData/quickfix/typeMismatch/afterAccessibleLocalClassInReturn.kt create mode 100644 idea/testData/quickfix/typeMismatch/afterAnonymousObjectInCall.kt create mode 100644 idea/testData/quickfix/typeMismatch/afterAnonymousObjectInInfixCall.kt create mode 100644 idea/testData/quickfix/typeMismatch/afterAnonymousObjectInInitializer.kt create mode 100644 idea/testData/quickfix/typeMismatch/afterAnonymousObjectInReturn.kt create mode 100644 idea/testData/quickfix/typeMismatch/afterAnyInReturn.kt create mode 100644 idea/testData/quickfix/typeMismatch/afterLocalClassInReturn1.kt create mode 100644 idea/testData/quickfix/typeMismatch/afterLocalClassInReturn2.kt create mode 100644 idea/testData/quickfix/typeMismatch/beforeAccessibleLocalClassInReturn.kt create mode 100644 idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInCall.kt create mode 100644 idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInInfixCall.kt create mode 100644 idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInInitializer.kt create mode 100644 idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInReturn.kt create mode 100644 idea/testData/quickfix/typeMismatch/beforeAnyInReturn.kt create mode 100644 idea/testData/quickfix/typeMismatch/beforeLocalClassInReturn1.kt create mode 100644 idea/testData/quickfix/typeMismatch/beforeLocalClassInReturn2.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/JetScopeUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/JetScopeUtils.java index 87d3f56d597..bf95e912af8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/JetScopeUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/JetScopeUtils.java @@ -19,12 +19,17 @@ package org.jetbrains.kotlin.resolve.scopes; import com.google.common.base.Function; import com.google.common.collect.Collections2; import com.google.common.collect.Lists; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; -import org.jetbrains.kotlin.descriptors.PropertyDescriptor; -import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor; -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; +import org.jetbrains.kotlin.analyzer.AnalysisResult; +import org.jetbrains.kotlin.descriptors.*; +import org.jetbrains.kotlin.psi.JetClassBody; +import org.jetbrains.kotlin.psi.JetClassOrObject; +import org.jetbrains.kotlin.psi.JetExpression; +import org.jetbrains.kotlin.psi.JetFile; +import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingTrace; import org.jetbrains.kotlin.resolve.TraceBasedRedeclarationHandler; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; @@ -151,4 +156,25 @@ public final class JetScopeUtils { } return out.toString(); } + + @Nullable + public static JetScope getResolutionScope(@NotNull JetExpression expression, @NotNull AnalysisResult analysisResult) { + PsiElement parent = expression.getParent(); + + if (parent instanceof JetClassBody) { + JetClassOrObject classOrObject = (JetClassOrObject) parent.getParent(); + ClassDescriptor classDescriptor = analysisResult.getBindingContext().get(BindingContext.CLASS, classOrObject); + if (classDescriptor instanceof ClassDescriptorWithResolutionScopes) { + return ((ClassDescriptorWithResolutionScopes) classDescriptor).getScopeForMemberDeclarationResolution(); + } + return null; + } + + if (parent instanceof JetFile) { + PackageViewDescriptor packageView = analysisResult.getModuleDescriptor().getPackage(((JetFile) parent).getPackageFqName()); + return packageView != null ? packageView.getMemberScope() : null; + } + + return analysisResult.getBindingContext().get(BindingContext.RESOLUTION_SCOPE, expression); + } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixFactoryForTypeMismatchError.java b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixFactoryForTypeMismatchError.java index 5f42376455b..9f3fde12fc8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixFactoryForTypeMismatchError.java +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixFactoryForTypeMismatchError.java @@ -20,22 +20,31 @@ import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; +import kotlin.Function1; +import kotlin.KotlinPackage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.analyzer.AnalysisResult; +import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.descriptors.CallableDescriptor; +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor; import org.jetbrains.kotlin.diagnostics.Diagnostic; import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters1; import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters2; import org.jetbrains.kotlin.diagnostics.Errors; import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages; import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage; +import org.jetbrains.kotlin.idea.imports.ImportsPackage; import org.jetbrains.kotlin.idea.util.UtilPackage; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilPackage; import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; +import org.jetbrains.kotlin.resolve.scopes.JetScope; +import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils; import org.jetbrains.kotlin.types.JetType; +import org.jetbrains.kotlin.types.TypeUtils; import java.util.Collections; import java.util.LinkedList; @@ -45,12 +54,36 @@ import java.util.List; public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFactory { private final static Logger LOG = Logger.getInstance(QuickFixFactoryForTypeMismatchError.class); + private static boolean isResolvableType(@NotNull JetType type, @Nullable JetScope scope) { + if (ImportsPackage.canBeReferencedViaImport(type)) return true; + + ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); + if (descriptor == null || descriptor.getName().isSpecial()) return false; + + return scope != null && scope.getClassifier(descriptor.getName()) == descriptor; + } + + private static JetType approximateWithResolvableType(@NotNull JetType type, @Nullable final JetScope scope) { + if (isResolvableType(type, scope)) return type; + JetType superType = KotlinPackage.firstOrNull( + TypeUtils.getAllSupertypes(type), + new Function1() { + @Override + public Boolean invoke(JetType type) { + return isResolvableType(type, scope); + } + } + ); + return superType != null ? superType : KotlinBuiltIns.getInstance().getAnyType(); + } + @NotNull @Override protected List doCreateActions(@NotNull Diagnostic diagnostic) { List actions = new LinkedList(); - BindingContext context = ResolvePackage.analyzeFully((JetFile) diagnostic.getPsiFile()); + AnalysisResult analysisResult = ResolvePackage.analyzeFullyAndGetResult((JetFile) diagnostic.getPsiFile()); + BindingContext context = analysisResult.getBindingContext(); PsiElement diagnosticElement = diagnostic.getPsiElement(); if (!(diagnosticElement instanceof JetExpression)) { @@ -97,9 +130,12 @@ public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFact JetProperty property = PsiTreeUtil.getParentOfType(expression, JetProperty.class); if (property != null) { JetPropertyAccessor getter = property.getGetter(); - if (QuickFixUtil.canEvaluateTo(property.getInitializer(), expression) || + JetExpression initializer = property.getInitializer(); + if (QuickFixUtil.canEvaluateTo(initializer, expression) || (getter != null && QuickFixUtil.canFunctionOrGetterReturnExpression(property.getGetter(), expression))) { - actions.add(new ChangeVariableTypeFix(property, expressionType)); + JetScope scope = JetScopeUtils.getResolutionScope(property, analysisResult); + JetType typeToInsert = approximateWithResolvableType(expressionType, scope); + actions.add(new ChangeVariableTypeFix(property, typeToInsert)); } } @@ -111,7 +147,9 @@ public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFact ? BindingContextUtilPackage.getTargetFunction((JetReturnExpression) expressionParent, context) : PsiTreeUtil.getParentOfType(expression, JetFunction.class, true); if (function instanceof JetFunction && QuickFixUtil.canFunctionOrGetterReturnExpression(function, expression)) { - actions.add(new ChangeFunctionReturnTypeFix((JetFunction) function, expressionType)); + JetScope scope = JetScopeUtils.getResolutionScope(function, analysisResult); + JetType typeToInsert = approximateWithResolvableType(expressionType, scope); + actions.add(new ChangeFunctionReturnTypeFix((JetFunction) function, typeToInsert)); } // Fixing overloaded operators: @@ -124,19 +162,6 @@ public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFact } } } - if (expression.getParent() instanceof JetBinaryExpression) { - JetBinaryExpression parentBinary = (JetBinaryExpression) expression.getParent(); - if (parentBinary.getRight() == expression) { - ResolvedCall resolvedCall = CallUtilPackage.getResolvedCall(parentBinary, context); - if (resolvedCall != null) { - JetFunction declaration = getFunctionDeclaration(resolvedCall); - if (declaration != null) { - JetParameter binaryOperatorParameter = declaration.getValueParameters().get(0); - actions.add(new ChangeParameterTypeFix(binaryOperatorParameter, expressionType)); - } - } - } - } // Change function return type when TYPE_MISMATCH is reported on call expression: if (expression instanceof JetCallExpression) { @@ -162,7 +187,9 @@ public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFact ? expressionType : context.get(BindingContext.EXPRESSION_TYPE, valueArgument.getArgumentExpression()); if (correspondingParameter != null && valueArgumentType != null) { - actions.add(new ChangeParameterTypeFix(correspondingParameter, valueArgumentType)); + JetScope scope = JetScopeUtils.getResolutionScope(valueArgument.getArgumentExpression(), analysisResult); + JetType typeToInsert = approximateWithResolvableType(valueArgumentType, scope); + actions.add(new ChangeParameterTypeFix(correspondingParameter, typeToInsert)); } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/JetNameValidatorImpl.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/JetNameValidatorImpl.java index f04abce739e..4e785687269 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/JetNameValidatorImpl.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/JetNameValidatorImpl.java @@ -23,13 +23,13 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.analyzer.AnalysisResult; import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes; -import org.jetbrains.kotlin.descriptors.ModuleDescriptor; import org.jetbrains.kotlin.descriptors.PackageViewDescriptor; import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.scopes.JetScope; +import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils; import java.util.HashSet; import java.util.Set; @@ -76,9 +76,7 @@ public class JetNameValidatorImpl extends JetNameValidator { private boolean checkElement(String name, PsiElement sibling, final Set visitedScopes) { if (!(sibling instanceof JetElement)) return true; - AnalysisResult analysisResult = ResolvePackage.analyzeAndGetResult((JetElement) sibling); - final BindingContext bindingContext = analysisResult.getBindingContext(); - final ModuleDescriptor module = analysisResult.getModuleDescriptor(); + final AnalysisResult analysisResult = ResolvePackage.analyzeAndGetResult((JetElement) sibling); final Name identifier = Name.identifier(name); final Ref result = new Ref(true); @@ -90,29 +88,9 @@ public class JetNameValidatorImpl extends JetNameValidator { } } - @Nullable - private JetScope getScope(@NotNull JetExpression expression) { - PsiElement parent = expression.getParent(); - - if (parent instanceof JetClassBody) { - JetClassOrObject classOrObject = (JetClassOrObject) parent.getParent(); - ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, classOrObject); - return classDescriptor instanceof ClassDescriptorWithResolutionScopes - ? ((ClassDescriptorWithResolutionScopes) classDescriptor).getScopeForMemberDeclarationResolution() - : null; - } - - if (parent instanceof JetFile) { - PackageViewDescriptor packageViewDescriptor = module.getPackage(((JetFile) parent).getPackageFqName()); - return packageViewDescriptor != null ? packageViewDescriptor.getMemberScope() : null; - } - - return bindingContext.get(BindingContext.RESOLUTION_SCOPE, expression); - } - @Override public void visitExpression(@NotNull JetExpression expression) { - JetScope resolutionScope = getScope(expression); + JetScope resolutionScope = JetScopeUtils.getResolutionScope(expression, analysisResult); if (resolutionScope != null) { if (!visitedScopes.add(resolutionScope)) return; diff --git a/idea/testData/quickfix/typeMismatch/afterAccessibleLocalClassInReturn.kt b/idea/testData/quickfix/typeMismatch/afterAccessibleLocalClassInReturn.kt new file mode 100644 index 00000000000..e9002022d5e --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/afterAccessibleLocalClassInReturn.kt @@ -0,0 +1,8 @@ +// "Change 'bar' function return type to 'A'" "true" +fun foo() { + open class A + + fun bar(): A { + return object: A() {} + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/afterAnonymousObjectInCall.kt b/idea/testData/quickfix/typeMismatch/afterAnonymousObjectInCall.kt new file mode 100644 index 00000000000..761bf1a1717 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/afterAnonymousObjectInCall.kt @@ -0,0 +1,10 @@ +// "Change parameter 't' type of function 'foo' to 'T'" "true" +trait T + +fun Int.foo(t: T) { + +} + +fun foo() { + 1.foo(object: T{}) +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/afterAnonymousObjectInInfixCall.kt b/idea/testData/quickfix/typeMismatch/afterAnonymousObjectInInfixCall.kt new file mode 100644 index 00000000000..d9953fb9045 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/afterAnonymousObjectInInfixCall.kt @@ -0,0 +1,8 @@ +// "Change parameter 't' type of function 'foo' to 'T'" "true" +trait T + +fun Int.foo(t: T) = this + +fun foo() { + 1 foo object: T{} +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/afterAnonymousObjectInInitializer.kt b/idea/testData/quickfix/typeMismatch/afterAnonymousObjectInInitializer.kt new file mode 100644 index 00000000000..465950f4304 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/afterAnonymousObjectInInitializer.kt @@ -0,0 +1,6 @@ +// "Change 't' type to 'T'" "true" +trait T + +fun foo() { + val t: T = object: T{} +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/afterAnonymousObjectInReturn.kt b/idea/testData/quickfix/typeMismatch/afterAnonymousObjectInReturn.kt new file mode 100644 index 00000000000..439fb225691 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/afterAnonymousObjectInReturn.kt @@ -0,0 +1,6 @@ +// "Change 'foo' function return type to 'T'" "true" +trait T + +fun foo(): T { + return object: T{} +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/afterAnyInReturn.kt b/idea/testData/quickfix/typeMismatch/afterAnyInReturn.kt new file mode 100644 index 00000000000..17cb32305f7 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/afterAnyInReturn.kt @@ -0,0 +1,6 @@ +// "Change 'foo' function return type to 'Any'" "true" +fun foo(): Any { + class A + + return A() +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/afterLocalClassInReturn1.kt b/idea/testData/quickfix/typeMismatch/afterLocalClassInReturn1.kt new file mode 100644 index 00000000000..70acb9155e7 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/afterLocalClassInReturn1.kt @@ -0,0 +1,10 @@ +// "Change 'foo' function return type to 'U'" "true" +trait T +trait U + +fun foo(): U { + open class A: T + class B: A(), U + + return B() +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/afterLocalClassInReturn2.kt b/idea/testData/quickfix/typeMismatch/afterLocalClassInReturn2.kt new file mode 100644 index 00000000000..f7f98908194 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/afterLocalClassInReturn2.kt @@ -0,0 +1,9 @@ +// "Change 'foo' function return type to 'T'" "true" +trait T + +fun foo(): T { + open class A: T + class B: A() + + return B() +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/beforeAccessibleLocalClassInReturn.kt b/idea/testData/quickfix/typeMismatch/beforeAccessibleLocalClassInReturn.kt new file mode 100644 index 00000000000..4fa799e4cd2 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/beforeAccessibleLocalClassInReturn.kt @@ -0,0 +1,8 @@ +// "Change 'bar' function return type to 'A'" "true" +fun foo() { + open class A + + fun bar(): Int { + return object: A() {} + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInCall.kt b/idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInCall.kt new file mode 100644 index 00000000000..3d13d58fb98 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInCall.kt @@ -0,0 +1,10 @@ +// "Change parameter 't' type of function 'foo' to 'T'" "true" +trait T + +fun Int.foo(t: Int) { + +} + +fun foo() { + 1.foo(object: T{}) +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInInfixCall.kt b/idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInInfixCall.kt new file mode 100644 index 00000000000..7b777945146 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInInfixCall.kt @@ -0,0 +1,8 @@ +// "Change parameter 't' type of function 'foo' to 'T'" "true" +trait T + +fun Int.foo(t: Int) = this + +fun foo() { + 1 foo object: T{} +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInInitializer.kt b/idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInInitializer.kt new file mode 100644 index 00000000000..a0f4413e808 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInInitializer.kt @@ -0,0 +1,6 @@ +// "Change 't' type to 'T'" "true" +trait T + +fun foo() { + val t: Int = object: T{} +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInReturn.kt b/idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInReturn.kt new file mode 100644 index 00000000000..97518e26d96 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInReturn.kt @@ -0,0 +1,6 @@ +// "Change 'foo' function return type to 'T'" "true" +trait T + +fun foo() { + return object: T{} +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/beforeAnyInReturn.kt b/idea/testData/quickfix/typeMismatch/beforeAnyInReturn.kt new file mode 100644 index 00000000000..8ec04dc3940 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/beforeAnyInReturn.kt @@ -0,0 +1,6 @@ +// "Change 'foo' function return type to 'Any'" "true" +fun foo() { + class A + + return A() +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/beforeLocalClassInReturn1.kt b/idea/testData/quickfix/typeMismatch/beforeLocalClassInReturn1.kt new file mode 100644 index 00000000000..1919274de64 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/beforeLocalClassInReturn1.kt @@ -0,0 +1,10 @@ +// "Change 'foo' function return type to 'U'" "true" +trait T +trait U + +fun foo() { + open class A: T + class B: A(), U + + return B() +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/beforeLocalClassInReturn2.kt b/idea/testData/quickfix/typeMismatch/beforeLocalClassInReturn2.kt new file mode 100644 index 00000000000..b289985a493 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/beforeLocalClassInReturn2.kt @@ -0,0 +1,9 @@ +// "Change 'foo' function return type to 'T'" "true" +trait T + +fun foo() { + open class A: T + class B: A() + + return B() +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 6d07f8b9d9c..404c9f45c50 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -4588,10 +4588,46 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { }) @RunWith(JUnit3RunnerWithInners.class) public static class TypeMismatch extends AbstractQuickFixTest { + @TestMetadata("beforeAccessibleLocalClassInReturn.kt") + public void testAccessibleLocalClassInReturn() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeAccessibleLocalClassInReturn.kt"); + doTest(fileName); + } + public void testAllFilesPresentInTypeMismatch() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch"), Pattern.compile("^before(\\w+)\\.kt$"), true); } + @TestMetadata("beforeAnonymousObjectInCall.kt") + public void testAnonymousObjectInCall() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInCall.kt"); + doTest(fileName); + } + + @TestMetadata("beforeAnonymousObjectInInfixCall.kt") + public void testAnonymousObjectInInfixCall() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInInfixCall.kt"); + doTest(fileName); + } + + @TestMetadata("beforeAnonymousObjectInInitializer.kt") + public void testAnonymousObjectInInitializer() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInInitializer.kt"); + doTest(fileName); + } + + @TestMetadata("beforeAnonymousObjectInReturn.kt") + public void testAnonymousObjectInReturn() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeAnonymousObjectInReturn.kt"); + doTest(fileName); + } + + @TestMetadata("beforeAnyInReturn.kt") + public void testAnyInReturn() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeAnyInReturn.kt"); + doTest(fileName); + } + @TestMetadata("beforeChangeFunctionLiteralParameterTypeToFunctionType.kt") public void testChangeFunctionLiteralParameterTypeToFunctionType() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeChangeFunctionLiteralParameterTypeToFunctionType.kt"); @@ -4676,6 +4712,18 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("beforeLocalClassInReturn1.kt") + public void testLocalClassInReturn1() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeLocalClassInReturn1.kt"); + doTest(fileName); + } + + @TestMetadata("beforeLocalClassInReturn2.kt") + public void testLocalClassInReturn2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeLocalClassInReturn2.kt"); + doTest(fileName); + } + @TestMetadata("beforeMakeReturnTypeNullable.kt") public void testMakeReturnTypeNullable() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeMakeReturnTypeNullable.kt");