Fix invalid usage of descriptorToDeclaration in QuickFixFactoryForTypeMismatchError

This commit is contained in:
Pavel V. Talanov
2014-06-23 19:17:59 +04:00
parent 0673dc51d6
commit 41dd12d46b
4 changed files with 75 additions and 9 deletions
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters2;
import org.jetbrains.jet.lang.diagnostics.Errors;
@@ -71,9 +72,9 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF
ResolvedCall<?> resolvedCall =
context.get(BindingContext.RESOLVED_CALL, ((JetOperationExpression) expression).getOperationReference());
if (resolvedCall != null) {
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getResultingDescriptor());
if (declaration instanceof JetFunction) {
actions.add(new ChangeFunctionReturnTypeFix((JetFunction) declaration, expectedType));
JetFunction declaration = getFunctionDeclaration(context, resolvedCall);
if (declaration != null) {
actions.add(new ChangeFunctionReturnTypeFix(declaration, expectedType));
}
}
}
@@ -82,9 +83,9 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF
if (parentBinary.getRight() == expression) {
ResolvedCall<?> resolvedCall = context.get(BindingContext.RESOLVED_CALL, parentBinary.getOperationReference());
if (resolvedCall != null) {
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getResultingDescriptor());
if (declaration instanceof JetFunction) {
JetParameter binaryOperatorParameter = ((JetFunction) declaration).getValueParameterList().getParameters().get(0);
JetFunction declaration = getFunctionDeclaration(context, resolvedCall);
if (declaration != null) {
JetParameter binaryOperatorParameter = declaration.getValueParameterList().getParameters().get(0);
actions.add(new ChangeParameterTypeFix(binaryOperatorParameter, expressionType));
}
}
@@ -96,9 +97,9 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF
ResolvedCall<?> resolvedCall =
context.get(BindingContext.RESOLVED_CALL, ((JetCallExpression) expression).getCalleeExpression());
if (resolvedCall != null) {
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getResultingDescriptor());
if (declaration instanceof JetFunction) {
actions.add(new ChangeFunctionReturnTypeFix((JetFunction) declaration, expectedType));
JetFunction declaration = getFunctionDeclaration(context, resolvedCall);
if (declaration != null) {
actions.add(new ChangeFunctionReturnTypeFix(declaration, expectedType));
}
}
}
@@ -128,4 +129,18 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF
}
return actions;
}
@Nullable
private static JetFunction getFunctionDeclaration(@NotNull BindingContext context, @NotNull ResolvedCall<?> resolvedCall) {
List<PsiElement> declarations = BindingContextUtils.descriptorToDeclarations(context, resolvedCall.getResultingDescriptor());
//do not create fix if descriptor has more than one overridden declarations
//TODO: use change signature to deal with this case correctly
if (declarations.size() == 1) {
PsiElement result = declarations.iterator().next();
if (result instanceof JetFunction) {
return (JetFunction) result;
}
}
return null;
}
}
@@ -0,0 +1,19 @@
// "Change 'AA.f' function return type to 'Boolean'" "false"
// ACTION: Change 'AAA.g' function return type to 'Int'
// ACTION: Convert to expression body
// ACTION: Disable 'Convert to Expression Body'
// ACTION: Edit intention settings
// ERROR: <html>Type mismatch.<table><tr><td>Required:</td><td>kotlin.Boolean</td></tr><tr><td>Found:</td><td>kotlin.Int</td></tr></table></html>
trait A {
fun f(): Int
}
open class AA {
fun f() = 3
}
class AAA: AA(), A {
fun g(): Boolean {
return f<caret>()
}
}
@@ -0,0 +1,22 @@
// "Change 'AA.contains' function return type to 'Int'" "false"
// ACTION: Change 'AAA.g' function return type to 'Boolean'
// ACTION: Convert to expression body
// ACTION: Disable 'Convert to Expression Body'
// ACTION: Disable 'Replace Overloaded Operator With Function Call'
// ACTION: Edit intention settings
// ACTION: Edit intention settings
// ACTION: Replace overloaded operator with function call
// ERROR: <html>Type mismatch.<table><tr><td>Required:</td><td>kotlin.Int</td></tr><tr><td>Found:</td><td>kotlin.Boolean</td></tr></table></html>
trait A {
fun contains(i: Int): Boolean
}
open class AA {
fun contains(i: Int) = true
}
class AAA: AA(), A {
fun g(): Int {
return 3 i<caret>n this
}
}
@@ -2306,6 +2306,16 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeExpectedTypeMismatch.kt");
}
@TestMetadata("beforeMultiFakeOverride.kt")
public void testMultiFakeOverride() throws Exception {
doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeMultiFakeOverride.kt");
}
@TestMetadata("beforeMultiFakeOverrideForOperatorConvention.kt")
public void testMultiFakeOverrideForOperatorConvention() throws Exception {
doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeMultiFakeOverrideForOperatorConvention.kt");
}
@TestMetadata("beforePropertyGetterInitializerTypeMismatch.kt")
public void testPropertyGetterInitializerTypeMismatch() throws Exception {
doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforePropertyGetterInitializerTypeMismatch.kt");