From fcd84a0d35a6b282df4098b60c464995c5d3dd12 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 9 Jun 2017 21:13:09 +0300 Subject: [PATCH] add explicit type arguments intention (IDEA-173960) --- .../AddExplicitTypeArgumentsIntention.java | 65 ++++++++++++++ ...AddExplicitTypeArgumentsIntentionTest.java | 86 +++++++++++++++++++ .../src/messages/CodeInsightBundle.properties | 1 + .../after.java.template | 6 ++ .../before.java.template | 6 ++ .../description.html | 5 ++ resources/src/META-INF/IdeaPlugin.xml | 4 + 7 files changed, 173 insertions(+) create mode 100644 java/java-impl/src/com/intellij/codeInsight/intention/impl/AddExplicitTypeArgumentsIntention.java create mode 100644 java/java-tests/testSrc/com/intellij/java/codeInsight/intention/AddExplicitTypeArgumentsIntentionTest.java create mode 100644 resources-en/src/intentionDescriptions/AddExplicitTypeArgumentsIntention/after.java.template create mode 100644 resources-en/src/intentionDescriptions/AddExplicitTypeArgumentsIntention/before.java.template create mode 100644 resources-en/src/intentionDescriptions/AddExplicitTypeArgumentsIntention/description.html diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddExplicitTypeArgumentsIntention.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddExplicitTypeArgumentsIntention.java new file mode 100644 index 000000000000..5985f25296ef --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddExplicitTypeArgumentsIntention.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.intention.impl; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.daemon.impl.quickfix.AddTypeArgumentsFix; +import com.intellij.codeInsight.intention.BaseElementAtCaretIntentionAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.infos.MethodCandidateInfo; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ObjectUtils; +import org.jetbrains.annotations.NotNull; + +public class AddExplicitTypeArgumentsIntention extends BaseElementAtCaretIntentionAction { + @Override + @NotNull + public String getFamilyName() { + return CodeInsightBundle.message("intention.add.explicit.type.arguments.family"); + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { + PsiIdentifier identifier = ObjectUtils.tryCast(element, PsiIdentifier.class); + if (identifier == null) return false; + PsiReferenceExpression methodExpression = ObjectUtils.tryCast(identifier.getParent(), PsiReferenceExpression.class); + if (methodExpression == null) return false; + PsiElement parent = methodExpression.getParent(); + if (parent instanceof PsiMethodCallExpression && ((PsiMethodCallExpression)parent).getTypeArguments().length == 0) { + JavaResolveResult result = ((PsiMethodCallExpression)parent).resolveMethodGenerics(); + if (result instanceof MethodCandidateInfo && ((MethodCandidateInfo)result).isApplicable()) { + PsiElement method = result.getElement(); + setText(getFamilyName()); + return method instanceof PsiMethod && !((PsiMethod)method).isConstructor() && ((PsiMethod)method).hasTypeParameters(); + } + } + return false; + } + + @Override + public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException { + PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class); + assert callExpression != null; + PsiExpression withArgs = AddTypeArgumentsFix.addTypeArguments(callExpression, null); + if (withArgs != null) { + CodeStyleManager.getInstance(project).reformat(callExpression.replace(withArgs)); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/AddExplicitTypeArgumentsIntentionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/AddExplicitTypeArgumentsIntentionTest.java new file mode 100644 index 000000000000..c6677ba6909a --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/AddExplicitTypeArgumentsIntentionTest.java @@ -0,0 +1,86 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.java.codeInsight.intention; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase; + +public class AddExplicitTypeArgumentsIntentionTest extends JavaCodeInsightFixtureTestCase { + + public void testNoStaticQualifier() { + doTest("class Test {\n" + + " static {\n" + + " String s = foo(\"\");\n" + + " }\n" + + " static T foo(T t) {\n" + + " return t;\n" + + " }\n" + + "}", + "class Test {\n" + + " static {\n" + + " String s = Test.foo(\"\");\n" + + " }\n" + + " static T foo(T t) {\n" + + " return t;\n" + + " }\n" + + "}"); + } + + public void testNoThisQualifier() { + doTest("class Test {\n" + + " {\n" + + " String s = foo(\"\");\n" + + " }\n" + + " T foo(T t) {\n" + + " return t;\n" + + " }\n" + + "}", + "class Test {\n" + + " {\n" + + " String s = this.foo(\"\");\n" + + " }\n" + + " T foo(T t) {\n" + + " return t;\n" + + " }\n" + + "}"); + } + + public void testInferredCapturedWildcard() { + doTest("class Test {\n" + + " static void m(java.util.List l) {\n" + + " foo(l.get(0));\n" + + " }\n" + + " static void foo(T t) {\n" + + " }\n" + + "}", + "class Test {\n" + + " static void m(java.util.List l) {\n" + + " Test.foo(l.get(0));\n" + + " }\n" + + " static void foo(T t) {\n" + + " }\n" + + "}"); + } + + private void doTest(String beforeText, String afterText) { + myFixture.configureByText("a.java", beforeText); + final IntentionAction intentionAction = myFixture.findSingleIntention(CodeInsightBundle.message("intention.add.explicit.type.arguments.family")); + assertNotNull(intentionAction); + myFixture.launchAction(intentionAction); + myFixture.checkResult(afterText); + } +} diff --git a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties index 29cfc6953ad2..90e0b98ba265 100644 --- a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties +++ b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties @@ -192,6 +192,7 @@ intention.add.on.demand.static.import.text=Add on demand static import for ''{0} intention.add.single.member.static.import.family=Add Single-Member Static Import intention.add.single.member.static.import.text=Add static import for ''{0}'' intention.add.single.member.import.text=Add import for ''{0}'' +intention.add.explicit.type.arguments.family=Add explicit type arguments intention.replace.concatenation.with.formatted.output.family=Replace Concatenation with Formatted Output intention.replace.concatenation.with.formatted.output.text=Replace '+' with 'java.text.MessageFormat.format()' intention.color.chooser.dialog=Choose Color diff --git a/resources-en/src/intentionDescriptions/AddExplicitTypeArgumentsIntention/after.java.template b/resources-en/src/intentionDescriptions/AddExplicitTypeArgumentsIntention/after.java.template new file mode 100644 index 000000000000..909e44dfaab6 --- /dev/null +++ b/resources-en/src/intentionDescriptions/AddExplicitTypeArgumentsIntention/after.java.template @@ -0,0 +1,6 @@ +import java.util.*; +class Computer { + void f() { + List l = Arrays.asList("a", "b", "c"); + } +} diff --git a/resources-en/src/intentionDescriptions/AddExplicitTypeArgumentsIntention/before.java.template b/resources-en/src/intentionDescriptions/AddExplicitTypeArgumentsIntention/before.java.template new file mode 100644 index 000000000000..868b216c4d06 --- /dev/null +++ b/resources-en/src/intentionDescriptions/AddExplicitTypeArgumentsIntention/before.java.template @@ -0,0 +1,6 @@ +import java.util.*; +class Computer { + void f() { + List l = Arrays.asList("a", "b", "c"); + } +} diff --git a/resources-en/src/intentionDescriptions/AddExplicitTypeArgumentsIntention/description.html b/resources-en/src/intentionDescriptions/AddExplicitTypeArgumentsIntention/description.html new file mode 100644 index 000000000000..24ea3b1d406b --- /dev/null +++ b/resources-en/src/intentionDescriptions/AddExplicitTypeArgumentsIntention/description.html @@ -0,0 +1,5 @@ + + +This intention add explicit type arguments to method calls + + diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index b5fb9748e057..8f900966492d 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -1167,6 +1167,10 @@ com.intellij.codeInsight.intention.impl.AddSingleMemberStaticImportAction Java/Imports + + com.intellij.codeInsight.intention.impl.AddExplicitTypeArgumentsIntention + Java/Declaration + com.intellij.codeInsight.intention.impl.ExpandStaticImportAction Java/Imports