shortenClassReferences: dequalify references which are statically imported

This commit is contained in:
Tagir Valeev
2018-06-14 10:08:16 +07:00
parent c5546db7d5
commit 79ed1b2dc3
7 changed files with 86 additions and 92 deletions
@@ -5,7 +5,6 @@ import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.daemon.impl.quickfix.DeleteCatchFix;
import com.intellij.codeInsight.daemon.impl.quickfix.DeleteMultiCatchFix;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
@@ -14,7 +13,6 @@ import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.ig.psiutils.CommentTracker;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.ImportUtils;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nls;
@@ -249,14 +247,6 @@ public class CharsetObjectCanBeUsedInspection extends AbstractBaseJavaLocalInspe
CommentTracker ct = new CommentTracker();
String replacement = "java.nio.charset." + myConstantName;
PsiReferenceExpression ref = (PsiReferenceExpression)ct.replaceAndRestoreComments(expression, replacement);
PsiField field = ObjectUtils.tryCast(ref.resolve(), PsiField.class);
PsiExpression qualifier = ref.getQualifierExpression();
if (field != null && qualifier != null && ImportUtils.isStaticallyImported(field, ref)) {
PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(project).getResolveHelper();
if (field.equals(resolveHelper.resolveAccessibleReferencedVariable(StringUtil.getShortName(myConstantName), ref))) {
qualifier.delete();
}
}
JavaCodeStyleManager.getInstance(project).shortenClassReferences(ref);
while (true) {
PsiTryStatement tryStatement =
@@ -31,6 +31,7 @@ import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.jsp.JspFile;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.ig.psiutils.ImportUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -43,6 +44,13 @@ public class JavaReferenceAdjuster implements ReferenceAdjuster {
IElementType elementType = element.getElementType();
if ((elementType == JavaElementType.JAVA_CODE_REFERENCE || elementType == JavaElementType.REFERENCE_EXPRESSION) && !isAnnotated(element)) {
IElementType parentType = element.getTreeParent().getElementType();
if (elementType == JavaElementType.REFERENCE_EXPRESSION) {
PsiReferenceExpression ref = (PsiReferenceExpression)element.getPsi();
if (ImportUtils.isAlreadyStaticallyImported(ref)) {
deQualifyImpl((CompositeElement)element);
return element;
}
}
if (elementType == JavaElementType.JAVA_CODE_REFERENCE || incompleteCode ||
parentType == JavaElementType.REFERENCE_EXPRESSION || parentType == JavaElementType.METHOD_REF_EXPRESSION) {
PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)element.getPsi();
@@ -2,12 +2,13 @@
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static java.util.stream.Collectors.*;
public class Main<T> {
public static List<String> test() {
List<String> strings = IntStream.range(0, 10).<String>mapToObj(x -> null).collect(Collectors.toList());
List<String> strings = IntStream.range(0, 10).<String>mapToObj(x -> null).collect(toList());
return strings;
}
}
@@ -2,6 +2,7 @@
import java.util.ArrayList;
import java.util.List;
import static java.util.stream.Collectors.*;
public class Main<T> {
public static List<String> test() {
@@ -21,6 +21,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleSettingsFacade;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.util.ObjectUtils;
import com.siyeh.HardcodedMethodConstants;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NonNls;
@@ -471,6 +472,69 @@ public final class ImportUtils {
return visitor.isReferenceFound();
}
private static boolean isReferenceCorrectWithoutQualifier(PsiJavaCodeReferenceElement reference, PsiMember member) {
final String referenceName = reference.getReferenceName();
if (referenceName == null) {
return false;
}
final Project project = reference.getProject();
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
final PsiResolveHelper resolveHelper = psiFacade.getResolveHelper();
if (member instanceof PsiMethod) {
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)reference.getParent().copy();
final PsiElement qualifier = methodCallExpression.getMethodExpression().getQualifier();
assert qualifier != null;
qualifier.delete();
if (!member.equals(methodCallExpression.resolveMethod())) {
return false;
}
}
else if (member instanceof PsiField) {
final PsiVariable variable = resolveHelper.resolveAccessibleReferencedVariable(referenceName, reference);
if (!member.equals(variable)) {
return false;
}
}
else if (member instanceof PsiClass) {
final PsiClass aClass = resolveHelper.resolveReferencedClass(referenceName, reference);
if (!member.equals(aClass)) {
return false;
}
}
return true;
}
public static boolean isAlreadyStaticallyImported(PsiJavaCodeReferenceElement reference) {
if (reference instanceof PsiMethodReferenceExpression) return false;
PsiJavaCodeReferenceElement qualifier = ObjectUtils.tryCast(reference.getQualifier(), PsiJavaCodeReferenceElement.class);
if (qualifier == null) return false;
if (PsiTreeUtil.getParentOfType(reference, PsiImportStatementBase.class) != null) return false;
if (isGenericReference(reference, qualifier)) return false;
final PsiMember member = ObjectUtils.tryCast(reference.resolve(), PsiMember.class);
if (member == null) return false;
if (!(qualifier.resolve() instanceof PsiClass)) return false;
return isStaticallyImported(member, reference) &&
isReferenceCorrectWithoutQualifier(reference, member);
}
public static boolean isGenericReference(PsiJavaCodeReferenceElement referenceElement, PsiJavaCodeReferenceElement qualifierElement) {
final PsiReferenceParameterList qualifierParameterList = qualifierElement.getParameterList();
if (qualifierParameterList != null) {
final PsiTypeElement[] typeParameterElements = qualifierParameterList.getTypeParameterElements();
if (typeParameterElements.length > 0) {
return true;
}
}
final PsiReferenceParameterList parameterList = referenceElement.getParameterList();
if (parameterList != null) {
final PsiTypeElement[] typeParameterElements = parameterList.getTypeParameterElements();
if (typeParameterElements.length > 0) {
return true;
}
}
return false;
}
private static class MemberReferenceVisitor extends JavaRecursiveElementWalkingVisitor {
private final PsiMember[] members;
private boolean referenceFound;
@@ -28,6 +28,7 @@ import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ClassUtils;
import com.siyeh.ig.psiutils.ImportUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -142,7 +143,7 @@ public class UnnecessarilyQualifiedStaticUsageInspection extends BaseInspection
return false;
}
final PsiJavaCodeReferenceElement qualifier = (PsiJavaCodeReferenceElement)qualifierElement;
if (isGenericReference(referenceElement, qualifier)) {
if (ImportUtils.isGenericReference(referenceElement, qualifier)) {
return false;
}
final PsiElement target = referenceElement.resolve();
@@ -224,22 +225,4 @@ public class UnnecessarilyQualifiedStaticUsageInspection extends BaseInspection
}
return false;
}
static boolean isGenericReference(PsiJavaCodeReferenceElement referenceElement, PsiJavaCodeReferenceElement qualifierElement) {
final PsiReferenceParameterList qualifierParameterList = qualifierElement.getParameterList();
if (qualifierParameterList != null) {
final PsiTypeElement[] typeParameterElements = qualifierParameterList.getTypeParameterElements();
if (typeParameterElements.length > 0) {
return true;
}
}
final PsiReferenceParameterList parameterList = referenceElement.getParameterList();
if (parameterList != null) {
final PsiTypeElement[] typeParameterElements = parameterList.getTypeParameterElements();
if (typeParameterElements.length > 0) {
return true;
}
}
return false;
}
}
@@ -19,8 +19,10 @@ import com.intellij.codeInspection.CleanupLocalInspectionTool;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiJavaCodeReferenceElement;
import com.intellij.psi.PsiMember;
import com.intellij.psi.PsiReferenceExpression;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -29,6 +31,8 @@ import com.siyeh.ig.psiutils.ImportUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
public class UnnecessarilyQualifiedStaticallyImportedElementInspection extends BaseInspection implements CleanupLocalInspectionTool{
@Nls
@@ -80,66 +84,9 @@ public class UnnecessarilyQualifiedStaticallyImportedElementInspection extends B
@Override
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
super.visitReferenceElement(reference);
if (reference instanceof PsiMethodReferenceExpression) {
return;
if (ImportUtils.isAlreadyStaticallyImported(reference)) {
registerError(Objects.requireNonNull(reference.getQualifier()), ProblemHighlightType.LIKE_UNUSED_SYMBOL, reference.resolve());
}
final PsiElement qualifier = reference.getQualifier();
if (!(qualifier instanceof PsiJavaCodeReferenceElement)) {
return;
}
if (PsiTreeUtil.getParentOfType(reference, PsiImportStatementBase.class) != null) {
return;
}
if (UnnecessarilyQualifiedStaticUsageInspection.isGenericReference(reference, (PsiJavaCodeReferenceElement)qualifier)) return;
final PsiElement target = reference.resolve();
if (!(target instanceof PsiMember)) {
return;
}
final PsiMember member = (PsiMember)target;
final PsiJavaCodeReferenceElement referenceExpression = (PsiJavaCodeReferenceElement)qualifier;
final PsiElement qualifierTarget = referenceExpression.resolve();
if (!(qualifierTarget instanceof PsiClass)) {
return;
}
if (!ImportUtils.isStaticallyImported(member, reference)) {
return;
}
if (!isReferenceCorrectWithoutQualifier(reference, member)) {
return;
}
registerError(qualifier, ProblemHighlightType.LIKE_UNUSED_SYMBOL, member);
}
private static boolean isReferenceCorrectWithoutQualifier(PsiJavaCodeReferenceElement reference, PsiMember member) {
final String referenceName = reference.getReferenceName();
if (referenceName == null) {
return false;
}
final Project project = reference.getProject();
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
final PsiResolveHelper resolveHelper = psiFacade.getResolveHelper();
if (member instanceof PsiMethod) {
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)reference.getParent().copy();
final PsiElement qualifier = methodCallExpression.getMethodExpression().getQualifier();
assert qualifier != null;
qualifier.delete();
if (!member.equals(methodCallExpression.resolveMethod())) {
return false;
}
}
else if (member instanceof PsiField) {
final PsiVariable variable = resolveHelper.resolveAccessibleReferencedVariable(referenceName, reference);
if (!member.equals(variable)) {
return false;
}
}
else if (member instanceof PsiClass) {
final PsiClass aClass = resolveHelper.resolveReferencedClass(referenceName, reference);
if (!member.equals(aClass)) {
return false;
}
}
return true;
}
}
}