From 2948875cadb146867429d86fd82d7798cf3ecac8 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 5 Dec 2012 21:00:56 +0400 Subject: [PATCH] QuickFix: adding <*> for 'raw' type inside javaClass() call --- .../quickfix/AddStarProjectionsFix.java | 55 +++++++++++++++++-- .../jet/plugin/quickfix/QuickFixes.java | 3 +- .../javaClass/afterFooOfC2.kt | 9 +++ .../javaClass/afterJavaClassOfC1Runtime.kt | 6 ++ .../javaClass/afterJavaClassOfC2Runtime.kt | 6 ++ .../javaClass/afterJavaClassOfCRuntime.kt | 7 +++ .../javaClass/beforeFooOfC2.kt | 9 +++ .../javaClass/beforeJavaClassOfC1Runtime.kt | 6 ++ .../javaClass/beforeJavaClassOfC2Runtime.kt | 6 ++ .../javaClass/beforeJavaClassOfCRuntime.kt | 7 +++ 10 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 idea/testData/quickfix/addStarProjections/javaClass/afterFooOfC2.kt create mode 100644 idea/testData/quickfix/addStarProjections/javaClass/afterJavaClassOfC1Runtime.kt create mode 100644 idea/testData/quickfix/addStarProjections/javaClass/afterJavaClassOfC2Runtime.kt create mode 100644 idea/testData/quickfix/addStarProjections/javaClass/afterJavaClassOfCRuntime.kt create mode 100644 idea/testData/quickfix/addStarProjections/javaClass/beforeFooOfC2.kt create mode 100644 idea/testData/quickfix/addStarProjections/javaClass/beforeJavaClassOfC1Runtime.kt create mode 100644 idea/testData/quickfix/addStarProjections/javaClass/beforeJavaClassOfC2Runtime.kt create mode 100644 idea/testData/quickfix/addStarProjections/javaClass/beforeJavaClassOfCRuntime.kt diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AddStarProjectionsFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AddStarProjectionsFix.java index 0ba9abde473..ba56e9c993b 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/AddStarProjectionsFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AddStarProjectionsFix.java @@ -19,19 +19,19 @@ package org.jetbrains.jet.plugin.quickfix; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters2; import org.jetbrains.jet.lang.diagnostics.Errors; -import org.jetbrains.jet.lang.psi.JetPsiFactory; -import org.jetbrains.jet.lang.psi.JetTypeElement; -import org.jetbrains.jet.lang.psi.JetUserType; +import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.plugin.JetBundle; -public class AddStarProjectionsFix extends JetIntentionAction { +public abstract class AddStarProjectionsFix extends JetIntentionAction { private final int argumentCount; @@ -68,7 +68,7 @@ public class AddStarProjectionsFix extends JetIntentionAction { return true; } - public static JetIntentionActionFactory createFactory() { + public static JetIntentionActionFactory createFactoryForIsExpression() { return new JetIntentionActionFactory() { @Override public IntentionAction createAction(Diagnostic diagnostic) { @@ -79,7 +79,50 @@ public class AddStarProjectionsFix extends JetIntentionAction { JetUserType userType = QuickFixUtil.getParentElementOfType(diagnostic, JetUserType.class); if (userType == null) return null; Integer size = diagnosticWithParameters.getA(); - return new AddStarProjectionsFix(userType, size); + return new AddStarProjectionsFix(userType, size) {}; + } + }; + } + + public static JetIntentionActionFactory createFactoryForJavaClass() { + return new JetIntentionActionFactory() { + @Override + public IntentionAction createAction(Diagnostic diagnostic) { + assert diagnostic.getFactory() == Errors.WRONG_NUMBER_OF_TYPE_ARGUMENTS; + @SuppressWarnings("unchecked") + DiagnosticWithParameters1 diagnosticWithParameters = (DiagnosticWithParameters1) diagnostic; + + Integer size = diagnosticWithParameters.getA(); + + JetUserType userType = QuickFixUtil.getParentElementOfType(diagnostic, JetUserType.class); + if (userType == null) return null; + + return new AddStarProjectionsFix(userType, size) { + @Override + public boolean isAvailable( + @NotNull Project project, Editor editor, PsiFile file + ) { + // We are looking for the occurrence of Type in javaClass() + return super.isAvailable(project, editor, file) && isZeroTypeArguments() && isInsideJavaClassCall(); + } + + private boolean isZeroTypeArguments() { + return element.getTypeArguments().isEmpty(); + } + + private boolean isInsideJavaClassCall() { + PsiElement parent = element.getParent().getParent().getParent().getParent(); + if (parent instanceof JetCallExpression) { + JetExpression calleeExpression = ((JetCallExpression) parent).getCalleeExpression(); + if (calleeExpression instanceof JetSimpleNameExpression) { + JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) calleeExpression; + // Resolve is expensive so we use a heuristic here: the case is rare enough not to be annoying + return "javaClass".equals(simpleNameExpression.getReferencedName()); + } + } + return false; + } + }; } }; } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index ea1d097b9fa..36108f12f8a 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -145,6 +145,7 @@ public class QuickFixes { factories.put(NO_ELSE_IN_WHEN, AddWhenElseBranchFix.createFactory()); - factories.put(NO_TYPE_ARGUMENTS_ON_RHS_OF_IS_EXPRESSION, AddStarProjectionsFix.createFactory()); + factories.put(NO_TYPE_ARGUMENTS_ON_RHS_OF_IS_EXPRESSION, AddStarProjectionsFix.createFactoryForIsExpression()); + factories.put(WRONG_NUMBER_OF_TYPE_ARGUMENTS, AddStarProjectionsFix.createFactoryForJavaClass()); } } diff --git a/idea/testData/quickfix/addStarProjections/javaClass/afterFooOfC2.kt b/idea/testData/quickfix/addStarProjections/javaClass/afterFooOfC2.kt new file mode 100644 index 00000000000..2dd8487de0b --- /dev/null +++ b/idea/testData/quickfix/addStarProjections/javaClass/afterFooOfC2.kt @@ -0,0 +1,9 @@ +// "Add '<*, *>'" "false" +// ERROR: Type argument expected +class C2 + +fun foo() {} + +fun test() { + foo>() +} \ No newline at end of file diff --git a/idea/testData/quickfix/addStarProjections/javaClass/afterJavaClassOfC1Runtime.kt b/idea/testData/quickfix/addStarProjections/javaClass/afterJavaClassOfC1Runtime.kt new file mode 100644 index 00000000000..fc9405afbb6 --- /dev/null +++ b/idea/testData/quickfix/addStarProjections/javaClass/afterJavaClassOfC1Runtime.kt @@ -0,0 +1,6 @@ +// "Add '<*>'" "true" +class C1 + +fun test() { + javaClass>() +} \ No newline at end of file diff --git a/idea/testData/quickfix/addStarProjections/javaClass/afterJavaClassOfC2Runtime.kt b/idea/testData/quickfix/addStarProjections/javaClass/afterJavaClassOfC2Runtime.kt new file mode 100644 index 00000000000..a8487023cac --- /dev/null +++ b/idea/testData/quickfix/addStarProjections/javaClass/afterJavaClassOfC2Runtime.kt @@ -0,0 +1,6 @@ +// "Add '<*, *>'" "true" +class C2 + +fun test() { + javaClass>() +} \ No newline at end of file diff --git a/idea/testData/quickfix/addStarProjections/javaClass/afterJavaClassOfCRuntime.kt b/idea/testData/quickfix/addStarProjections/javaClass/afterJavaClassOfCRuntime.kt new file mode 100644 index 00000000000..4738bca4829 --- /dev/null +++ b/idea/testData/quickfix/addStarProjections/javaClass/afterJavaClassOfCRuntime.kt @@ -0,0 +1,7 @@ +// "Add '<*>'" "false" +// "Add '<*, *>'" "false" +class C + +fun test() { + javaClass> +} \ No newline at end of file diff --git a/idea/testData/quickfix/addStarProjections/javaClass/beforeFooOfC2.kt b/idea/testData/quickfix/addStarProjections/javaClass/beforeFooOfC2.kt new file mode 100644 index 00000000000..2dd8487de0b --- /dev/null +++ b/idea/testData/quickfix/addStarProjections/javaClass/beforeFooOfC2.kt @@ -0,0 +1,9 @@ +// "Add '<*, *>'" "false" +// ERROR: Type argument expected +class C2 + +fun foo() {} + +fun test() { + foo>() +} \ No newline at end of file diff --git a/idea/testData/quickfix/addStarProjections/javaClass/beforeJavaClassOfC1Runtime.kt b/idea/testData/quickfix/addStarProjections/javaClass/beforeJavaClassOfC1Runtime.kt new file mode 100644 index 00000000000..812be8ad556 --- /dev/null +++ b/idea/testData/quickfix/addStarProjections/javaClass/beforeJavaClassOfC1Runtime.kt @@ -0,0 +1,6 @@ +// "Add '<*>'" "true" +class C1 + +fun test() { + javaClass>() +} \ No newline at end of file diff --git a/idea/testData/quickfix/addStarProjections/javaClass/beforeJavaClassOfC2Runtime.kt b/idea/testData/quickfix/addStarProjections/javaClass/beforeJavaClassOfC2Runtime.kt new file mode 100644 index 00000000000..1a52b5dbca2 --- /dev/null +++ b/idea/testData/quickfix/addStarProjections/javaClass/beforeJavaClassOfC2Runtime.kt @@ -0,0 +1,6 @@ +// "Add '<*, *>'" "true" +class C2 + +fun test() { + javaClass>() +} \ No newline at end of file diff --git a/idea/testData/quickfix/addStarProjections/javaClass/beforeJavaClassOfCRuntime.kt b/idea/testData/quickfix/addStarProjections/javaClass/beforeJavaClassOfCRuntime.kt new file mode 100644 index 00000000000..3f00e7d7d07 --- /dev/null +++ b/idea/testData/quickfix/addStarProjections/javaClass/beforeJavaClassOfCRuntime.kt @@ -0,0 +1,7 @@ +// "Add '<*>'" "false" +// "Add '<*, *>'" "false" +class C + +fun test() { + javaClass>() +} \ No newline at end of file