Better behaviour of "Change Type" quickfixes in case of function types
This commit is contained in:
@@ -33,19 +33,22 @@ import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
|
||||
public class CastExpressionFix extends JetIntentionAction<JetExpression> {
|
||||
private final JetType type;
|
||||
private final String renderedType;
|
||||
|
||||
public CastExpressionFix(@NotNull JetExpression element, @NotNull JetType type) {
|
||||
super(element);
|
||||
this.type = type;
|
||||
renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return JetBundle.message("cast.expression.to.type", element.getText(), type.toString());
|
||||
return JetBundle.message("cast.expression.to.type", element.getText(), renderedType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -64,9 +67,9 @@ public class CastExpressionFix extends JetIntentionAction<JetExpression> {
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
JetBinaryExpressionWithTypeRHS castedExpression =
|
||||
(JetBinaryExpressionWithTypeRHS) JetPsiFactory.createExpression(project, "(" + element.getText() + ") as " + type.toString());
|
||||
(JetBinaryExpressionWithTypeRHS) JetPsiFactory.createExpression(project, "(" + element.getText() + ") as " + renderedType);
|
||||
if (JetPsiUtil.areParenthesesUseless((JetParenthesizedExpression) castedExpression.getLeft())) {
|
||||
castedExpression = (JetBinaryExpressionWithTypeRHS) JetPsiFactory.createExpression(project, element.getText() + " as " + type.toString());
|
||||
castedExpression = (JetBinaryExpressionWithTypeRHS) JetPsiFactory.createExpression(project, element.getText() + " as " + renderedType);
|
||||
}
|
||||
|
||||
JetParenthesizedExpression castedExpressionInParentheses =
|
||||
|
||||
@@ -23,38 +23,38 @@ import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
|
||||
public class ChangeAccessorTypeFix extends JetIntentionAction<JetPropertyAccessor> {
|
||||
private String renderedType;
|
||||
|
||||
public ChangeAccessorTypeFix(@NotNull JetPropertyAccessor element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetType getPropertyType() {
|
||||
JetProperty property = PsiTreeUtil.getParentOfType(element, JetProperty.class);
|
||||
if (property == null) return null;
|
||||
return QuickFixUtil.getDeclarationReturnType(property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
JetType type = getPropertyType();
|
||||
return super.isAvailable(project, editor, file) && type != null && !ErrorUtils.isErrorType(type);
|
||||
JetProperty property = PsiTreeUtil.getParentOfType(element, JetProperty.class);
|
||||
if (property == null) return false;
|
||||
JetType type = QuickFixUtil.getDeclarationReturnType(property);
|
||||
if (super.isAvailable(project, editor, file) && type != null && !ErrorUtils.isErrorType(type)) {
|
||||
renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
JetType type = getPropertyType();
|
||||
return element.isGetter()
|
||||
? JetBundle.message("change.getter.type", type)
|
||||
: JetBundle.message("change.setter.type", type);
|
||||
? JetBundle.message("change.getter.type", renderedType)
|
||||
: JetBundle.message("change.setter.type", renderedType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -65,10 +65,8 @@ public class ChangeAccessorTypeFix extends JetIntentionAction<JetPropertyAccesso
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
JetType type = getPropertyType();
|
||||
if (type == null) return;
|
||||
JetPropertyAccessor newElement = (JetPropertyAccessor) element.copy();
|
||||
JetTypeReference newTypeReference = JetPsiFactory.createType(project, type.toString());
|
||||
JetTypeReference newTypeReference = JetPsiFactory.createType(project, renderedType);
|
||||
|
||||
if (element.isGetter()) {
|
||||
JetTypeReference returnTypeReference = newElement.getReturnTypeReference();
|
||||
|
||||
@@ -43,13 +43,16 @@ import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil;
|
||||
import org.jetbrains.jet.plugin.intentions.SpecifyTypeExplicitlyAction;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
|
||||
public class ChangeFunctionReturnTypeFix extends JetIntentionAction<JetNamedFunction> {
|
||||
private final JetType type;
|
||||
private final String renderedType;
|
||||
|
||||
public ChangeFunctionReturnTypeFix(@NotNull JetNamedFunction element, @NotNull JetType type) {
|
||||
super(element);
|
||||
this.type = type;
|
||||
renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -65,8 +68,8 @@ public class ChangeFunctionReturnTypeFix extends JetIntentionAction<JetNamedFunc
|
||||
JetBundle.message("remove.function.return.type", functionName);
|
||||
}
|
||||
return functionName == null ?
|
||||
JetBundle.message("change.no.name.function.return.type", type.toString()) :
|
||||
JetBundle.message("change.function.return.type", functionName, type.toString());
|
||||
JetBundle.message("change.no.name.function.return.type", renderedType) :
|
||||
JetBundle.message("change.function.return.type", functionName, renderedType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -79,7 +82,7 @@ public class ChangeFunctionReturnTypeFix extends JetIntentionAction<JetNamedFunc
|
||||
public void invoke(@NotNull Project project, @Nullable Editor editor, @Nullable PsiFile file) throws IncorrectOperationException {
|
||||
SpecifyTypeExplicitlyAction.removeTypeAnnotation(element);
|
||||
if (!(KotlinBuiltIns.getInstance().isUnit(type) && element.hasBlockBody())) {
|
||||
addReturnTypeAnnotation(project, element, type.toString());
|
||||
addReturnTypeAnnotation(project, element, renderedType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,19 +31,20 @@ import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.psi.JetTypeReference;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
|
||||
public class ChangeTypeFix extends JetIntentionAction<JetTypeReference> {
|
||||
private final JetType type;
|
||||
private final String renderedType;
|
||||
|
||||
public ChangeTypeFix(@NotNull JetTypeReference element, JetType type) {
|
||||
super(element);
|
||||
this.type = type;
|
||||
renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return JetBundle.message("change.type", element.getText(), type);
|
||||
return JetBundle.message("change.type", element.getText(), renderedType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -54,7 +55,7 @@ public class ChangeTypeFix extends JetIntentionAction<JetTypeReference> {
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
element.replace(JetPsiFactory.createType(project, type.toString()));
|
||||
element.replace(JetPsiFactory.createType(project, renderedType));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -36,19 +36,20 @@ import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil;
|
||||
import org.jetbrains.jet.plugin.intentions.SpecifyTypeExplicitlyAction;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
|
||||
public class ChangeVariableTypeFix extends JetIntentionAction<JetVariableDeclaration> {
|
||||
private final JetType type;
|
||||
private final String renderedType;
|
||||
|
||||
public ChangeVariableTypeFix(@NotNull JetVariableDeclaration element, @NotNull JetType type) {
|
||||
super(element);
|
||||
this.type = type;
|
||||
renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return JetBundle.message("change.element.type", element.getName(), type);
|
||||
return JetBundle.message("change.element.type", element.getName(), renderedType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -62,7 +63,7 @@ public class ChangeVariableTypeFix extends JetIntentionAction<JetVariableDeclara
|
||||
SpecifyTypeExplicitlyAction.removeTypeAnnotation(element);
|
||||
PsiElement nameIdentifier = element.getNameIdentifier();
|
||||
assert nameIdentifier != null : "ChangeVariableTypeFix applied to variable without name";
|
||||
Pair<PsiElement, PsiElement> typeWhiteSpaceAndColon = JetPsiFactory.createTypeWhiteSpaceAndColon(project, type.toString());
|
||||
Pair<PsiElement, PsiElement> typeWhiteSpaceAndColon = JetPsiFactory.createTypeWhiteSpaceAndColon(project, renderedType);
|
||||
element.addRangeAfter(typeWhiteSpaceAndColon.first, typeWhiteSpaceAndColon.second, nameIdentifier);
|
||||
}
|
||||
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Change 'x' type to '(String) -> Int'" "true"
|
||||
trait A {
|
||||
var x: (String) -> Int
|
||||
}
|
||||
trait B : A {
|
||||
override var x: (String) -> Int
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Change 'x' type to '(String) -> Int'" "true"
|
||||
trait A {
|
||||
var x: (String) -> Int
|
||||
}
|
||||
trait B : A {
|
||||
override var x: (Int) -> String<caret>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Change getter type to (String) -> Int" "true"
|
||||
class A {
|
||||
val x: (String) -> Int
|
||||
get(): (String) -> Int<caret> = {42}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Change getter type to (String) -> Int" "true"
|
||||
class A {
|
||||
val x: (String) -> Int
|
||||
get(): Int<caret> = {42}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Change type from 'String' to '(Int) -> String'" "true"
|
||||
fun foo(f: ((Int) -> String) -> String) {
|
||||
foo {
|
||||
(f: (Int) -> String<caret>) -> f(42)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Change 'foo' function return type to '(Long) -> Int'" "true"
|
||||
fun foo(x: Any): (Long) -> Int {
|
||||
return {(x: Long) -> 42}<caret>
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Change type from 'String' to '(Int) -> String'" "true"
|
||||
fun foo(f: ((Int) -> String) -> String) {
|
||||
foo {
|
||||
(f: String<caret>) -> f(42)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Change 'foo' function return type to '(Long) -> Int'" "true"
|
||||
fun foo(x: Any): Int {
|
||||
return {(x: Long) -> 42}<caret>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Cast expression 'x' to '() -> Int'" "true"
|
||||
fun foo(x: Any): () -> Int {
|
||||
return x as () -> Int<caret>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Cast expression 'x' to '() -> Int'" "true"
|
||||
fun foo(x: Any): () -> Int {
|
||||
return x<caret>
|
||||
}
|
||||
@@ -1018,6 +1018,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/override/typeMismatchOnOverride"), Pattern.compile("^before(\\w+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("beforeChangeOverridingPropertyTypeToFunctionType.kt")
|
||||
public void testChangeOverridingPropertyTypeToFunctionType() throws Exception {
|
||||
doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverridingPropertyTypeToFunctionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("beforePropertyReturnTypeMismatchOnOverride.kt")
|
||||
public void testPropertyReturnTypeMismatchOnOverride() throws Exception {
|
||||
doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyReturnTypeMismatchOnOverride.kt");
|
||||
@@ -1149,6 +1154,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
doTest("idea/testData/quickfix/typeAddition/beforeAmbiguousPropertyReturnType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("beforeChangeAccessorTypeToFunctionType.kt")
|
||||
public void testChangeAccessorTypeToFunctionType() throws Exception {
|
||||
doTest("idea/testData/quickfix/typeAddition/beforeChangeAccessorTypeToFunctionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("beforeNoAddErrorType.kt")
|
||||
public void testNoAddErrorType() throws Exception {
|
||||
doTest("idea/testData/quickfix/typeAddition/beforeNoAddErrorType.kt");
|
||||
@@ -1236,6 +1246,16 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/typeMismatch"), Pattern.compile("^before(\\w+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("beforeChangeFunctionReturnTypeToFunctionType.kt")
|
||||
public void testChangeFunctionReturnTypeToFunctionType() throws Exception {
|
||||
doTest("idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToFunctionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("beforeChangeParameterTypeToFunctionType.kt")
|
||||
public void testChangeParameterTypeToFunctionType() throws Exception {
|
||||
doTest("idea/testData/quickfix/typeMismatch/beforeChangeParameterTypeToFunctionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("beforeChangeReturnTypeWhenFunctionNameIsMissing.kt")
|
||||
public void testChangeReturnTypeWhenFunctionNameIsMissing() throws Exception {
|
||||
doTest("idea/testData/quickfix/typeMismatch/beforeChangeReturnTypeWhenFunctionNameIsMissing.kt");
|
||||
@@ -1332,6 +1352,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
doTest("idea/testData/quickfix/typeMismatch/casts/beforeAutocastImpossible3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("beforeCastToFunctionType.kt")
|
||||
public void testCastToFunctionType() throws Exception {
|
||||
doTest("idea/testData/quickfix/typeMismatch/casts/beforeCastToFunctionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("beforeTypeMismatch1.kt")
|
||||
public void testTypeMismatch1() throws Exception {
|
||||
doTest("idea/testData/quickfix/typeMismatch/casts/beforeTypeMismatch1.kt");
|
||||
|
||||
Reference in New Issue
Block a user