QuickFix: change property type to match expression returned by getter

This commit is contained in:
Wojciech Lopata
2013-05-15 23:48:49 +02:00
parent 16d9abf546
commit 0a541373a5
7 changed files with 44 additions and 8 deletions
@@ -85,7 +85,7 @@ public class ChangeFunctionLiteralReturnTypeFix extends JetIntentionAction<JetFu
}
JetFunction parentFunction = PsiTreeUtil.getParentOfType(element, JetFunction.class, true);
if (parentFunction != null && QuickFixUtil.canFunctionReturnExpression(parentFunction, element)) {
if (parentFunction != null && QuickFixUtil.canFunctionOrGetterReturnExpression(parentFunction, element)) {
JetTypeReference parentFunctionReturnTypeRef = parentFunction.getReturnTypeRef();
JetType parentFunctionReturnType = context.get(BindingContext.TYPE, parentFunctionReturnTypeRef);
if (parentFunctionReturnType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(eventualFunctionLiteralType, parentFunctionReturnType)) {
@@ -74,6 +74,21 @@ public class ChangeVariableTypeFix extends JetIntentionAction<JetVariableDeclara
assert nameIdentifier != null : "ChangeVariableTypeFix applied to variable without name";
Pair<PsiElement, PsiElement> typeWhiteSpaceAndColon = JetPsiFactory.createTypeWhiteSpaceAndColon(project, renderedType);
element.addRangeAfter(typeWhiteSpaceAndColon.first, typeWhiteSpaceAndColon.second, nameIdentifier);
if (element instanceof JetProperty) {
JetPropertyAccessor getter = ((JetProperty) element).getGetter();
JetTypeReference getterReturnTypeRef = getter == null ? null : getter.getReturnTypeReference();
if (getterReturnTypeRef != null) {
getterReturnTypeRef.replace(JetPsiFactory.createType(project, renderedType));
}
JetPropertyAccessor setter = ((JetProperty) element).getSetter();
JetParameter setterParameter = setter == null ? null : setter.getParameter();
JetTypeReference setterParameterTypeRef = setterParameter == null ? null : setterParameter.getTypeReference();
if (setterParameterTypeRef != null) {
setterParameterTypeRef.replace(JetPsiFactory.createType(project, renderedType));
}
}
}
@NotNull
@@ -56,13 +56,17 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF
// Property initializer type mismatch property type:
JetProperty property = PsiTreeUtil.getParentOfType(expression, JetProperty.class);
if (property != null && QuickFixUtil.canEvaluateTo(property.getInitializer(), expression)) {
actions.add(new ChangeVariableTypeFix(property, expressionType));
if (property != null) {
JetPropertyAccessor getter = property.getGetter();
if (QuickFixUtil.canEvaluateTo(property.getInitializer(), expression) ||
(getter != null && QuickFixUtil.canFunctionOrGetterReturnExpression(property.getGetter(), expression))) {
actions.add(new ChangeVariableTypeFix(property, expressionType));
}
}
// Mismatch in returned expression:
JetFunction function = PsiTreeUtil.getParentOfType(expression, JetFunction.class, true);
if (function != null && QuickFixUtil.canFunctionReturnExpression(function, expression)) {
if (function != null && QuickFixUtil.canFunctionOrGetterReturnExpression(function, expression)) {
actions.add(new ChangeFunctionReturnTypeFix(function, expressionType));
}
@@ -175,14 +175,14 @@ public class QuickFixUtil {
return true;
}
public static boolean canFunctionReturnExpression(@NotNull JetFunction function, @NotNull JetExpression expression) {
if (function instanceof JetFunctionLiteral) {
JetBlockExpression functionLiteralBody = ((JetFunctionLiteral) function).getBodyExpression();
public static boolean canFunctionOrGetterReturnExpression(@NotNull JetDeclaration functionOrGetter, @NotNull JetExpression expression) {
if (functionOrGetter instanceof JetFunctionLiteral) {
JetBlockExpression functionLiteralBody = ((JetFunctionLiteral) functionOrGetter).getBodyExpression();
PsiElement returnedElement = functionLiteralBody == null ? null : functionLiteralBody.getLastChild();
return returnedElement instanceof JetExpression && canEvaluateTo((JetExpression) returnedElement, expression);
}
else {
if (function instanceof JetWithExpressionInitializer && canEvaluateTo(((JetWithExpressionInitializer) function).getInitializer(), expression)) {
if (functionOrGetter instanceof JetWithExpressionInitializer && canEvaluateTo(((JetWithExpressionInitializer) functionOrGetter).getInitializer(), expression)) {
return true;
}
JetReturnExpression returnExpression = PsiTreeUtil.getParentOfType(expression, JetReturnExpression.class);
@@ -0,0 +1,6 @@
// "Change 'A.x' type to '() -> Int'" "true"
class A {
var x: () -> Int
get(): () -> Int = if (true) { {42}<caret> } else { {24} }
set(i: () -> Int) {}
}
@@ -0,0 +1,6 @@
// "Change 'A.x' type to '() -> Int'" "true"
class A {
var x: Int
get(): Int = if (true) { {42}<caret> } else { {24} }
set(i: Int) {}
}
@@ -1514,6 +1514,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeExpectedTypeMismatch.kt");
}
@TestMetadata("beforePropertyGetterInitializerTypeMismatch.kt")
public void testPropertyGetterInitializerTypeMismatch() throws Exception {
doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforePropertyGetterInitializerTypeMismatch.kt");
}
@TestMetadata("beforeReturnedExpresionCantEvaluateToExpresionThatTypeMismatch.kt")
public void testReturnedExpresionCantEvaluateToExpresionThatTypeMismatch() throws Exception {
doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeReturnedExpresionCantEvaluateToExpresionThatTypeMismatch.kt");