trivial method reference inspection (IDEA-123298)

This commit is contained in:
Anna Kozlova
2016-01-11 20:14:09 +01:00
parent b73d0d273c
commit a2c90af6b3
8 changed files with 167 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2000-2016 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.codeInspection;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.MethodSignatureUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
public class TrivialMethodReferenceInspection extends BaseJavaBatchLocalInspectionTool {
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new JavaElementVisitor() {
@Override
public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
final PsiExpression qualifierExpression = expression.getQualifierExpression();
final PsiElement referenceNameElement = expression.getReferenceNameElement();
if (qualifierExpression != null && referenceNameElement != null) {
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(expression);
if (interfaceMethod != null) {
final PsiElement resolve = expression.resolve();
if (resolve instanceof PsiMethod &&
(interfaceMethod == resolve || MethodSignatureUtil.isSuperMethod(interfaceMethod, (PsiMethod)resolve))) {
holder.registerProblem(referenceNameElement, "Method reference can be replaced with qualifier", new ReplaceMethodRefWithQualifierFix());
}
}
}
}
};
}
private static class ReplaceMethodRefWithQualifierFix implements LocalQuickFix {
@Nls
@NotNull
@Override
public String getName() {
return getFamilyName();
}
@Nls
@NotNull
@Override
public String getFamilyName() {
return "Replace with qualifier";
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = descriptor.getPsiElement();
final PsiElement parent = element != null ? element.getParent() : null;
if (parent instanceof PsiMethodReferenceExpression) {
final PsiExpression qualifierExpression = ((PsiMethodReferenceExpression)parent).getQualifierExpression();
if (qualifierExpression != null) {
parent.replace(qualifierExpression);
}
}
}
}
}

View File

@@ -0,0 +1,8 @@
// "Replace with qualifier" "true"
import java.util.function.Predicate;
class Test {
void foo(Predicate<String> p){
Predicate<String> stringPredicate = p;
}
}

View File

@@ -0,0 +1,12 @@
// "Replace with qualifier" "true"
import java.util.function.Predicate;
class Test implements Predicate<String> {
void foo(){
Predicate<String> stringPredicate = this;
}
public boolean test(String s) {
return true;
}
}

View File

@@ -0,0 +1,8 @@
// "Replace with qualifier" "true"
import java.util.function.Predicate;
class Test {
void foo(Predicate<String> p){
Predicate<String> stringPredicate = p::te<caret>st;
}
}

View File

@@ -0,0 +1,12 @@
// "Replace with qualifier" "true"
import java.util.function.Predicate;
class Test implements Predicate<String> {
void foo(){
Predicate<String> stringPredicate = this::te<caret>st;
}
public boolean test(String s) {
return true;
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2000-2016 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.daemon.quickFix;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.TrivialMethodReferenceInspection;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.testFramework.IdeaTestUtil;
import org.jetbrains.annotations.NotNull;
public class TrivialMethodReferenceInspectionTest extends LightQuickFixParameterizedTestCase {
@NotNull
@Override
protected LocalInspectionTool[] configureLocalInspectionTools() {
return new LocalInspectionTool[]{
new TrivialMethodReferenceInspection(),
};
}
public void test() throws Exception { doAllTests(); }
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/trivialMethodReference";
}
@Override
protected Sdk getProjectJDK() {
return IdeaTestUtil.getMockJdk18();
}
}

View File

@@ -0,0 +1,5 @@
<html>
<body>
This inspection reports method references which point to the abstract methods of the same functional interface types and hence can be replaced with their qualifiers
</body>
</html>

View File

@@ -726,6 +726,9 @@
<localInspection groupPath="Java" language="JAVA" shortName="Convert2MethodRef" displayName="Lambda can be replaced with method reference"
groupKey="group.names.language.level.specific.issues.and.migration.aids" groupBundle="messages.InspectionsBundle" enabledByDefault="true" level="WARNING"
implementationClass="com.intellij.codeInspection.LambdaCanBeMethodReferenceInspection" />
<localInspection groupPath="Java" language="JAVA" shortName="TrivialMethodReference" displayName="Method reference can be replaced with its qualifier"
groupKey="group.names.language.level.specific.issues.and.migration.aids" groupBundle="messages.InspectionsBundle" enabledByDefault="true" level="WARNING"
implementationClass="com.intellij.codeInspection.TrivialMethodReferenceInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="CodeBlock2Expr" displayName="Statement lambda can be replaced with expression lambda"
groupKey="group.names.language.level.specific.issues.and.migration.aids" groupBundle="messages.InspectionsBundle" enabledByDefault="true" level="WARNING"
implementationClass="com.intellij.codeInspection.RedundantLambdaCodeBlockInspection" />