Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,11 @@
import consulo.annotation.access.RequiredReadAction;
import consulo.application.progress.ProgressIndicator;
import consulo.application.progress.ProgressManager;
import consulo.application.util.function.Processor;
import consulo.content.scope.SearchScope;
import consulo.find.FindUsagesOptions;
import consulo.java.language.impl.psi.augment.JavaEnumAugmentProvider;
import consulo.language.editor.ImplicitUsageProvider;
import consulo.language.editor.intention.IntentionAction;
import consulo.language.editor.intention.QuickFixAction;
import consulo.language.editor.rawHighlight.HighlightInfo;
import consulo.language.editor.rawHighlight.HighlightInfoType;
import consulo.language.psi.PsiComment;
Expand All @@ -44,10 +42,11 @@
import consulo.language.psi.search.PsiSearchHelper;
import consulo.project.Project;
import consulo.usage.UsageInfo;

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;

import java.util.function.Predicate;

import static consulo.language.psi.search.PsiSearchHelper.SearchCostResult.TOO_MANY_OCCURRENCES;

public class UnusedSymbolUtil {
Expand All @@ -71,44 +70,48 @@ public static boolean isImplicitRead(@Nonnull PsiVariable variable) {
}

public static boolean isImplicitRead(@Nonnull Project project, @Nonnull PsiVariable element, @Nullable ProgressIndicator progress) {
return project.getExtensionPoint(ImplicitUsageProvider.class).findFirstSafe(provider -> {
return project.getExtensionPoint(ImplicitUsageProvider.class).anyMatchSafe(provider -> {
ProgressManager.checkCanceled();
return provider.isImplicitRead(element);
}) != null || isInjected(project, element);
}) || isInjected(project, element);
}

public static boolean isImplicitWrite(@Nonnull PsiVariable variable) {
return isImplicitWrite(variable.getProject(), variable, null);
}

public static boolean isImplicitWrite(@Nonnull Project project, @Nonnull PsiVariable element, @Nullable ProgressIndicator progress) {
return project.getExtensionPoint(ImplicitUsageProvider.class).findFirstSafe(provider -> {
return project.getExtensionPoint(ImplicitUsageProvider.class).anyMatchSafe(provider -> {
ProgressManager.checkCanceled();
return provider.isImplicitWrite(element);
}) != null || isInjected(project, element);
}) || isInjected(project, element);
}

@Nullable
@RequiredReadAction
public static HighlightInfo createUnusedSymbolInfo(
@Nonnull PsiElement element,
@Nonnull String message,
@Nonnull final HighlightInfoType highlightInfoType
@Nonnull HighlightInfoType highlightInfoType
) {
HighlightInfo info = HighlightInfo.newHighlightInfo(highlightInfoType).range(element).descriptionAndTooltip
(message).create();
HighlightInfo info = HighlightInfo.newHighlightInfo(highlightInfoType)
.range(element)
.descriptionAndTooltip(message).create();

if (info == null) {
return null; //filtered out
}

for (UnusedDeclarationFixProvider provider : UnusedDeclarationFixProvider.EP_NAME.getExtensionList()) {
IntentionAction[] fixes = provider.getQuickFixes(element);
for (IntentionAction fix : fixes) {
QuickFixAction.registerQuickFixAction(info, fix);
info.registerFix(fix, null, null, null, null);
}
}
return info;
}

@RequiredReadAction
public static boolean isFieldUnused(
@Nonnull Project project,
@Nonnull PsiFile containingFile,
Expand All @@ -119,12 +122,14 @@ public static boolean isFieldUnused(
if (helper.isLocallyUsed(field)) {
return false;
}
//noinspection SimplifiableIfStatement
if (field instanceof PsiEnumConstant && isEnumValuesMethodUsed(project, containingFile, field, progress, helper)) {
return false;
}
return weAreSureThereAreNoUsages(project, containingFile, field, progress, helper);
}

@RequiredReadAction
public static boolean isMethodReferenced(
@Nonnull Project project,
@Nonnull PsiFile containingFile,
Expand All @@ -136,7 +141,7 @@ public static boolean isMethodReferenced(
return true;
}

boolean isPrivate = method.hasModifierProperty(PsiModifier.PRIVATE);
boolean isPrivate = method.isPrivate();
PsiClass containingClass = method.getContainingClass();
if (JavaHighlightUtil.isSerializationRelatedMethod(method, containingClass)) {
return true;
Expand Down Expand Up @@ -170,10 +175,11 @@ public static boolean isMethodReferenced(
return false;
}

@RequiredReadAction
private static boolean weAreSureThereAreNoUsages(
@Nonnull Project project,
@Nonnull PsiFile containingFile,
@Nonnull final PsiMember member,
@Nonnull PsiMember member,
@Nonnull ProgressIndicator progress,
@Nonnull GlobalUsageHelper helper
) {
Expand All @@ -183,11 +189,15 @@ private static boolean weAreSureThereAreNoUsages(
return false;
}

final PsiFile ignoreFile = helper.isCurrentFileAlreadyChecked() ? containingFile : null;
PsiFile ignoreFile = helper.isCurrentFileAlreadyChecked() ? containingFile : null;

boolean sure = processUsages(project, containingFile, member, progress, ignoreFile, new Processor<UsageInfo>() {
@Override
public boolean process(UsageInfo info) {
boolean sure = processUsages(
project,
containingFile,
member,
progress,
ignoreFile,
info -> {
PsiFile psiFile = info.getFile();
if (psiFile == ignoreFile || psiFile == null) {
return true; // ignore usages in containingFile because isLocallyUsed() method would have caught
Expand All @@ -202,7 +212,7 @@ public boolean process(UsageInfo info) {
log("* " + member.getName() + ": usage :" + element);
return inComment; // ignore comments
}
});
);
log("* " + member.getName() + ": result:" + sure);
return sure;
}
Expand All @@ -219,15 +229,15 @@ public static boolean processUsages(
@Nonnull PsiMember member,
@Nonnull ProgressIndicator progress,
@Nullable PsiFile ignoreFile,
@Nonnull Processor<UsageInfo> usageInfoProcessor
@Nonnull @RequiredReadAction Predicate<UsageInfo> usageInfoProcessor
) {
String name = member.getName();
if (name == null) {
log("* " + member.getName() + " no name; false");
return false;
}
SearchScope useScope = member.getUseScope();
PsiSearchHelper searchHelper = PsiSearchHelper.SERVICE.getInstance(project);
PsiSearchHelper searchHelper = project.getInstance(PsiSearchHelper.class);
if (useScope instanceof GlobalSearchScope globalSearchScope) {
// some classes may have references from within XML outside dependent modules, e.g. our actions
if (member instanceof PsiClass) {
Expand Down Expand Up @@ -294,14 +304,15 @@ else if (member instanceof PsiVariable) {
return JavaFindUsagesHelper.processElementUsages(member, options, usageInfoProcessor);
}

@RequiredReadAction
private static boolean isEnumValuesMethodUsed(
@Nonnull Project project,
@Nonnull PsiFile containingFile,
@Nonnull PsiMember member,
@Nonnull ProgressIndicator progress,
@Nonnull GlobalUsageHelper helper
) {
final PsiClass containingClass = member.getContainingClass();
PsiClass containingClass = member.getContainingClass();
if (!(containingClass instanceof PsiClassImpl)) {
return true;
}
Expand All @@ -314,8 +325,7 @@ private static boolean isEnumValuesMethodUsed(

PsiMethod valuesMethod = null;
for (PsiMethod psiMethod : methodsByName) {
if (psiMethod.getParameterList().getParametersCount() == 0 && psiMethod.hasModifierProperty
(PsiModifier.STATIC)) {
if (psiMethod.getParameterList().getParametersCount() == 0 && psiMethod.isStatic()) {
valuesMethod = psiMethod;
break;
}
Expand All @@ -337,12 +347,14 @@ private static boolean canBeReferencedViaWeirdNames(@Nonnull PsiMember member, @
if (member instanceof PsiField) {
return false; //Java field cannot be referenced by anything but its name
}
//noinspection SimplifiableIfStatement
if (member instanceof PsiMethod method) {
return PropertyUtil.isSimplePropertyAccessor(method); //Java accessors can be referenced by field name from Groovy
}
return false;
}

@RequiredReadAction
public static boolean isClassUsed(
@Nonnull Project project,
@Nonnull PsiFile containingFile,
Expand All @@ -358,6 +370,7 @@ public static boolean isClassUsed(
return result;
}

@RequiredReadAction
private static boolean isReallyUsed(
@Nonnull Project project,
@Nonnull PsiFile containingFile,
Expand All @@ -369,9 +382,9 @@ private static boolean isReallyUsed(
return true;
}
if (helper.isCurrentFileAlreadyChecked()) {
if (aClass.getContainingClass() != null && aClass.hasModifierProperty(PsiModifier.PRIVATE) ||
aClass.getParent() instanceof PsiDeclarationStatement ||
aClass instanceof PsiTypeParameter) {
if (aClass.getContainingClass() != null && aClass.isPrivate()
|| aClass.getParent() instanceof PsiDeclarationStatement
|| aClass instanceof PsiTypeParameter) {
return false;
}
}
Expand Down
Loading
Loading