diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/RedundantTypeArgsInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/RedundantTypeArgsInspection.java index 92d50d59347e..62e33f1c5ba4 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/RedundantTypeArgsInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/RedundantTypeArgsInspection.java @@ -75,7 +75,7 @@ public class RedundantTypeArgsInspection extends GenericsInspectionToolBase { super.visitMethodCallExpression(expression); final PsiType[] typeArguments = expression.getTypeArguments(); if (typeArguments.length > 0) { - checkCallExpression(expression.getMethodExpression(), typeArguments, expression, inspectionManager, problems); + checkCallExpression(expression.getMethodExpression(), typeArguments, expression, inspectionManager, problems, isOnTheFly); } } @@ -86,7 +86,7 @@ public class RedundantTypeArgsInspection extends GenericsInspectionToolBase { if (typeArguments.length > 0) { final PsiJavaCodeReferenceElement classReference = expression.getClassReference(); if (classReference != null) { - checkCallExpression(classReference, typeArguments, expression, inspectionManager, problems); + checkCallExpression(classReference, typeArguments, expression, inspectionManager, problems, isOnTheFly); } } } @@ -94,7 +94,7 @@ public class RedundantTypeArgsInspection extends GenericsInspectionToolBase { @Override public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) { super.visitMethodReferenceExpression(expression); - checkMethodReference(expression, inspectionManager, problems); + checkMethodReference(expression, inspectionManager, problems, isOnTheFly); } }); @@ -106,7 +106,7 @@ public class RedundantTypeArgsInspection extends GenericsInspectionToolBase { final PsiType[] typeArguments, PsiCallExpression expression, final InspectionManager inspectionManager, - final List problems) { + final List problems, boolean isOnTheFly) { PsiExpressionList argumentList = expression.getArgumentList(); if (argumentList == null) return; final JavaResolveResult resolveResult = reference.advancedResolve(false); @@ -115,22 +115,25 @@ public class RedundantTypeArgsInspection extends GenericsInspectionToolBase { if (element instanceof PsiMethod && resolveResult.isValidResult()) { PsiMethod method = (PsiMethod)element; final PsiTypeParameter[] typeParameters = method.getTypeParameters(); - if (typeParameters.length == typeArguments.length) { - if (PsiDiamondTypeUtil.areTypeArgumentsRedundant(typeArguments, expression, false, method, typeParameters)) { - final ProblemDescriptor descriptor = inspectionManager.createProblemDescriptor(expression.getTypeArgumentList(), - InspectionsBundle.message( - "inspection.redundant.type.problem.descriptor"), - ourQuickFixAction, - ProblemHighlightType.LIKE_UNUSED_SYMBOL, false); - problems.add(descriptor); - } + if (typeParameters.length == typeArguments.length && + PsiDiamondTypeUtil.areTypeArgumentsRedundant(typeArguments, expression, false, method, typeParameters) || + typeParameters.length == 0) { + String key = typeParameters.length == 0 ? "inspection.redundant.type.no.generics.problem.descriptor" + : "inspection.redundant.type.problem.descriptor"; + final ProblemDescriptor descriptor = + inspectionManager.createProblemDescriptor(expression.getTypeArgumentList(), + InspectionsBundle.message(key), + ourQuickFixAction, + ProblemHighlightType.LIKE_UNUSED_SYMBOL, isOnTheFly); + problems.add(descriptor); } } } private static void checkMethodReference(PsiMethodReferenceExpression expression, InspectionManager inspectionManager, - List problems) { + List problems, + boolean isOnTheFly) { final PsiTypeElement qualifierTypeElement = expression.getQualifierType(); if (qualifierTypeElement != null) { final PsiType psiType = qualifierTypeElement.getType(); @@ -147,12 +150,30 @@ public class RedundantTypeArgsInspection extends GenericsInspectionToolBase { final PsiReferenceParameterList parameterList = referenceElement.getParameterList(); LOG.assertTrue(parameterList != null); final ProblemDescriptor descriptor = inspectionManager.createProblemDescriptor(parameterList, InspectionsBundle - .message("inspection.redundant.type.problem.descriptor"), new MyMethodReferenceFixAction(), ProblemHighlightType.LIKE_UNUSED_SYMBOL, false); + .message("inspection.redundant.type.problem.descriptor"), new MyMethodReferenceFixAction(), ProblemHighlightType.LIKE_UNUSED_SYMBOL, isOnTheFly); problems.add(descriptor); } } } } + else { + PsiType[] typeArguments = expression.getTypeParameters(); + PsiReferenceParameterList parameterList = expression.getParameterList(); + if (typeArguments.length > 0 && parameterList != null) { + PsiElement resolve = expression.resolve(); + if (resolve == null) return; + PsiTypeParameter[] typeParameters = resolve instanceof PsiClass ? PsiTypeParameter.EMPTY_ARRAY : ((PsiMethod)resolve).getTypeParameters(); + if (typeParameters.length == 0 || + typeParameters.length == typeArguments.length && + PsiDiamondTypeUtil.areTypeArgumentsRedundant(typeArguments, expression, false, ((PsiMethod)resolve), typeParameters)) { + final ProblemDescriptor descriptor = + inspectionManager.createProblemDescriptor(parameterList, + InspectionsBundle.message("inspection.redundant.type.problem.descriptor"), + new MyQuickFixAction(), ProblemHighlightType.LIKE_UNUSED_SYMBOL, isOnTheFly); + problems.add(descriptor); + } + } + } } private static class MyQuickFixAction implements LocalQuickFix { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java index 08bfdb7dcd21..c3a96b85a976 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java @@ -234,8 +234,15 @@ public class PsiDiamondTypeUtil { PsiMethodReferenceExpression methodRefCopy) { final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(methodRefCopy.getProject()).getElementFactory(); PsiTypeElement qualifierType = methodRefCopy.getQualifierType(); - LOG.assertTrue(qualifierType != null); - qualifierType.replace(elementFactory.createTypeElement(((PsiClassType)qualifierType.getType()).rawType())); + if (qualifierType != null) { + qualifierType.replace(elementFactory.createTypeElement(((PsiClassType)qualifierType.getType()).rawType())); + } + else { + PsiReferenceParameterList parameterList = methodRefCopy.getParameterList(); + if (parameterList != null) { + parameterList.delete(); + } + } JavaResolveResult result = methodRefCopy.advancedResolve(false); if (method != null && result.getElement() != method) return false; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/afterMethodReferenceWithRedundantTypeArguments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/afterMethodReferenceWithRedundantTypeArguments.java new file mode 100644 index 000000000000..6290528001f9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/afterMethodReferenceWithRedundantTypeArguments.java @@ -0,0 +1,14 @@ +// "Remove explicit type arguments" "true" + +import java.util.function.Function; +public class TestClassRenamed { + + { + Function r = this::foo; + } + + private T foo(String s) { + return null; + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/afterNonGenericCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/afterNonGenericCall.java new file mode 100644 index 000000000000..ce104088d95e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/afterNonGenericCall.java @@ -0,0 +1,7 @@ +// "Remove explicit type arguments" "true" +class Collectors { + { + Integer.getInteger(""); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/afterNonGenericMethodReference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/afterNonGenericMethodReference.java new file mode 100644 index 000000000000..64bce75bb2be --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/afterNonGenericMethodReference.java @@ -0,0 +1,10 @@ +// "Remove explicit type arguments" "true" + +import java.util.function.Function; +class MyTest { + + { + Function r = Integer::getInteger; + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/beforeMethodReferenceWithRedundantTypeArguments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/beforeMethodReferenceWithRedundantTypeArguments.java new file mode 100644 index 000000000000..9521b87ca4ac --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/beforeMethodReferenceWithRedundantTypeArguments.java @@ -0,0 +1,14 @@ +// "Remove explicit type arguments" "true" + +import java.util.function.Function; +public class TestClassRenamed { + + { + Function r = this::teger>foo; + } + + private T foo(String s) { + return null; + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/beforeNonGenericCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/beforeNonGenericCall.java new file mode 100644 index 000000000000..27130b8d0721 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/beforeNonGenericCall.java @@ -0,0 +1,7 @@ +// "Remove explicit type arguments" "true" +class Collectors { + { + Integer.ing>getInteger(""); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/beforeNonGenericMethodReference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/beforeNonGenericMethodReference.java new file mode 100644 index 000000000000..556b5f3ce6b0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/beforeNonGenericMethodReference.java @@ -0,0 +1,10 @@ +// "Remove explicit type arguments" "true" + +import java.util.function.Function; +class MyTest { + + { + Function r = Integer::eger>getInteger; + } +} + diff --git a/platform/platform-resources-en/src/messages/InspectionsBundle.properties b/platform/platform-resources-en/src/messages/InspectionsBundle.properties index ec81807052b7..69618eea0dbf 100644 --- a/platform/platform-resources-en/src/messages/InspectionsBundle.properties +++ b/platform/platform-resources-en/src/messages/InspectionsBundle.properties @@ -220,6 +220,7 @@ inspection.redundant.type.display.name=Redundant type arguments inspection.redundant.type.remove.quickfix=Remove explicit type arguments inspection.redundant.type.remove.methodref.quickfix=Remove explicit type arguments of method reference inspection.redundant.type.problem.descriptor=Explicit type arguments can be inferred +inspection.redundant.type.no.generics.problem.descriptor=Type arguments are redundant for the non-generic method call inspection.redundant.array.creation.display.name=Redundant array creation inspection.redundant.array.creation.quickfix=Remove explicit array creation