From 123ba34507abc3a86984727630188cef01bc1265 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 28 Mar 2014 19:43:07 +0100 Subject: [PATCH] create enum constant: support constant creation when static import is used, process varargs method candidates as vararg/basic separately (IDEA-121287) --- .../codeInsight/ExpectedTypesProvider.java | 2 +- .../CreateEnumConstantFromUsageFix.java | 30 +++++++++++++++++++ .../com/intellij/psi/PsiResolveHelper.java | 12 ++++++++ .../source/resolve/PsiResolveHelperImpl.java | 19 ++++++++++-- .../afterStaticImport.java | 21 +++++++++++++ .../afterVarargs.java | 18 +++++++++++ .../beforeStaticImport.java | 21 +++++++++++++ .../beforeVarargs.java | 18 +++++++++++ 8 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/afterStaticImport.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/afterVarargs.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/beforeStaticImport.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/beforeVarargs.java diff --git a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java index 1d458c28d40f..0929b4a057e2 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java @@ -529,7 +529,7 @@ public class ExpectedTypesProvider { PsiResolveHelper helper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper(); if (list.getParent() instanceof PsiMethodCallExpression) { PsiMethodCallExpression methodCall = (PsiMethodCallExpression)list.getParent(); - CandidateInfo[] candidates = helper.getReferencedMethodCandidates(methodCall, false); + CandidateInfo[] candidates = helper.getReferencedMethodCandidates(methodCall, false, true); Collections.addAll(myResult, getExpectedArgumentTypesForMethodCall(candidates, list, myExpr, myForCompletion)); } else if (list.getParent() instanceof PsiEnumConstant) { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateEnumConstantFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateEnumConstantFromUsageFix.java index 4972ed18db35..b5b93f658ff9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateEnumConstantFromUsageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateEnumConstantFromUsageFix.java @@ -28,9 +28,11 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.Function; import org.jetbrains.annotations.NotNull; +import java.util.Collections; import java.util.List; public class CreateEnumConstantFromUsageFix extends CreateVarFromUsageFix implements HighPriorityAction{ @@ -87,6 +89,34 @@ public class CreateEnumConstantFromUsageFix extends CreateVarFromUsageFix implem } } + @NotNull + @Override + protected List getTargetClasses(PsiElement element) { + final List classes = super.getTargetClasses(element); + PsiClass enumClass = null; + for (PsiClass aClass : classes) { + if (aClass.isEnum()) { + if (enumClass == null) { + enumClass = aClass; + } else { + enumClass = null; + break; + } + } + } + + if (enumClass != null) { + return Collections.singletonList(enumClass); + } + ExpectedTypeInfo[] typeInfos = CreateFromUsageUtils.guessExpectedTypes(myReferenceExpression, false); + for (final ExpectedTypeInfo typeInfo : typeInfos) { + final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(typeInfo.getType()); + if (psiClass != null && psiClass.isEnum()) { + return Collections.singletonList(psiClass); + } + } + return Collections.emptyList(); + } @Override protected boolean isAvailableImpl(int offset) { diff --git a/java/java-psi-api/src/com/intellij/psi/PsiResolveHelper.java b/java/java-psi-api/src/com/intellij/psi/PsiResolveHelper.java index 3e4cea41f989..2e3de888a0ed 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiResolveHelper.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiResolveHelper.java @@ -80,6 +80,18 @@ public interface PsiResolveHelper { @NotNull CandidateInfo[] getReferencedMethodCandidates(@NotNull PsiCallExpression call, boolean dummyImplicitConstructor); + /** + * Resolves a call expression and returns an array of possible resolve results. + * + * @param call the call expression to resolve. + * @param dummyImplicitConstructor if true, implicit empty constructor which does not actually exist + * can be returned as a candidate for the resolve. + * @param checkVarargs true if varargs method should lead to 2 candidates in the result array + * @return the array of resolve results. + */ + @NotNull + CandidateInfo[] getReferencedMethodCandidates(@NotNull PsiCallExpression call, boolean dummyImplicitConstructor, boolean checkVarargs); + /** * Resolves a reference to a class, given the text of the reference and the context * in which it was encountered. diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java index 65a2ef6d7d1e..59c8d7f386a1 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java @@ -127,11 +127,18 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { return JavaResolveUtil.isAccessible(member, containingClass, modifierList, place, accessObjectClass, currentFileResolveScope); } - @Override @NotNull - public CandidateInfo[] getReferencedMethodCandidates(@NotNull PsiCallExpression expr, boolean dummyImplicitConstructor) { + @Override + public CandidateInfo[] getReferencedMethodCandidates(@NotNull PsiCallExpression expr, + boolean dummyImplicitConstructor, + final boolean checkVarargs) { PsiFile containingFile = expr.getContainingFile(); - final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(expr, containingFile); + final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(expr, containingFile) { + @Override + protected boolean acceptVarargs() { + return checkVarargs; + } + }; try { PsiScopesUtil.setupAndRunProcessor(processor, expr, dummyImplicitConstructor); } @@ -141,6 +148,12 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { return processor.getCandidates(); } + @NotNull + @Override + public CandidateInfo[] getReferencedMethodCandidates(@NotNull PsiCallExpression call, boolean dummyImplicitConstructor) { + return getReferencedMethodCandidates(call, dummyImplicitConstructor, false); + } + @Override public PsiType inferTypeForMethodTypeParameter(@NotNull PsiTypeParameter typeParameter, @NotNull PsiParameter[] parameters, diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/afterStaticImport.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/afterStaticImport.java new file mode 100644 index 000000000000..27470ff5f9f7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/afterStaticImport.java @@ -0,0 +1,21 @@ +// "Create Enum Constant 'CRIME'" "true" +import java.util.Arrays; +import java.util.List; + +import static AutomaticTypeInference.E.*; + +class AutomaticTypeInference { + + AutomaticTypeInference(List gs) { + } + + public static void main(String[] args) { + + new AutomaticTypeInference(Arrays.asList(ACTION, CRIME)); + + } + + enum E { + ACTION, CRIME; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/afterVarargs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/afterVarargs.java new file mode 100644 index 000000000000..3c48ba6e6f7e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/afterVarargs.java @@ -0,0 +1,18 @@ +// "Create Enum Constant 'CRIME'" "true" +import java.util.*; + +class AutomaticTypeInference { + + AutomaticTypeInference(List gs) { + } + + public static void main(String[] args) { + + new AutomaticTypeInference(Arrays.asList(E.ACTION, E.CRIME)); + + } + + enum E { + ACTION, CRIME; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/beforeStaticImport.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/beforeStaticImport.java new file mode 100644 index 000000000000..e34874cd45e5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/beforeStaticImport.java @@ -0,0 +1,21 @@ +// "Create Enum Constant 'CRIME'" "true" +import java.util.Arrays; +import java.util.List; + +import static AutomaticTypeInference.E.*; + +class AutomaticTypeInference { + + AutomaticTypeInference(List gs) { + } + + public static void main(String[] args) { + + new AutomaticTypeInference(Arrays.asList(ACTION, CRIME)); + + } + + enum E { + ACTION; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/beforeVarargs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/beforeVarargs.java new file mode 100644 index 000000000000..3ce84a9a56f3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createEnumConstantFromUsage/beforeVarargs.java @@ -0,0 +1,18 @@ +// "Create Enum Constant 'CRIME'" "true" +import java.util.*; + +class AutomaticTypeInference { + + AutomaticTypeInference(List gs) { + } + + public static void main(String[] args) { + + new AutomaticTypeInference(Arrays.asList(E.ACTION, E.CRIME)); + + } + + enum E { + ACTION; + } +} \ No newline at end of file