optimization: convert to visitor to avoid multiple instanceof checks

GitOrigin-RevId: 781e5a88a348d9af4579869cb39ff042f871b78f
This commit is contained in:
Alexey Kudravtsev
2023-08-24 15:59:36 +00:00
committed by intellij-monorepo-bot
parent 279415219b
commit 615818a8d2
10 changed files with 249 additions and 300 deletions
@@ -102,7 +102,7 @@ public final class UnusedSymbolUtil {
tooltip = XmlStringUtil.wrapInHtml(XmlStringUtil.escapeString(message));
}
HighlightInfo.@NotNull Builder info = HighlightInfo.newHighlightInfo(highlightInfoType).range(element)
HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(highlightInfoType).range(element)
.description(message).escapedToolTip(tooltip).group(
GeneralHighlightingPass.POST_UPDATE_ALL);
@@ -115,25 +115,25 @@ public final class UnusedSymbolUtil {
return info;
}
public static boolean isFieldUnused(@NotNull Project project,
@NotNull PsiFile containingFile,
@NotNull PsiField field,
@NotNull ProgressIndicator progress,
@NotNull GlobalUsageHelper helper) {
public static boolean isFieldUsed(@NotNull Project project,
@NotNull PsiFile containingFile,
@NotNull PsiField field,
@NotNull ProgressIndicator progress,
@NotNull GlobalUsageHelper helper) {
if (helper.isLocallyUsed(field)) {
return false;
return true;
}
if (field instanceof PsiEnumConstant && isEnumValuesMethodUsed(project, containingFile, field, progress, helper)) {
return false;
return true;
}
return weAreSureThereAreNoUsages(project, containingFile, field, progress, helper);
return !weAreSureThereAreNoUsages(project, containingFile, field, progress, helper);
}
public static boolean isMethodReferenced(@NotNull Project project,
@NotNull PsiFile containingFile,
@NotNull PsiMethod method,
@NotNull ProgressIndicator progress,
@NotNull GlobalUsageHelper helper) {
public static boolean isMethodUsed(@NotNull Project project,
@NotNull PsiFile containingFile,
@NotNull PsiMethod method,
@NotNull ProgressIndicator progress,
@NotNull GlobalUsageHelper helper) {
if (helper.isLocallyUsed(method)) return true;
boolean isPrivate = method.hasModifierProperty(PsiModifier.PRIVATE);
@@ -302,7 +302,7 @@ public final class UnusedSymbolUtil {
final PsiClass containingClass = member.getContainingClass();
if (!(containingClass instanceof PsiClassImpl)) return true;
final PsiMethod valuesMethod = ((PsiClassImpl)containingClass).getValuesMethod();
return valuesMethod == null || isMethodReferenced(project, containingFile, valuesMethod, progress, helper);
return valuesMethod == null || isMethodUsed(project, containingFile, valuesMethod, progress, helper);
}
private static boolean canBeReferencedViaWeirdNames(@NotNull PsiMember member, @NotNull PsiFile containingFile) {
@@ -17,7 +17,6 @@ import com.intellij.lang.jvm.JvmModifiersOwner;
import com.intellij.lang.jvm.actions.JvmElementActionFactories;
import com.intellij.lang.jvm.actions.MemberRequestsKt;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
@@ -215,7 +214,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
try {
prepare(holder, file);
if (updateWholeFile) {
ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
GlobalInspectionContextBase.assertUnderDaemonProgress();
Project project = file.getProject();
Document document = PsiDocumentManager.getInstance(project).getDocument(file);
@@ -237,7 +235,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
ProgressManager.checkCanceled();
refCountHolder.storeReadyHolder(file);
if (document != null) {
new PostHighlightingVisitor(file, document, refCountHolder).collectHighlights(holder, progress);
new PostHighlightingVisitor(file, document, refCountHolder).collectHighlights(holder);
}
}
else {
@@ -22,8 +22,9 @@ import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsContexts;
@@ -31,7 +32,6 @@ import com.intellij.openapi.util.Predicates;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.PomNamedTarget;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
@@ -46,22 +46,24 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.PropertyKey;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
class PostHighlightingVisitor {
class PostHighlightingVisitor extends JavaElementVisitor {
private final RefCountHolder myRefCountHolder;
@NotNull private final Project myProject;
private final PsiFile myFile;
@NotNull private final Document myDocument;
private final GlobalUsageHelper myGlobalUsageHelper;
private IntentionAction myOptimizeImportsFix; // when not null, there are redundant/mis-sorted imports in the file
private int myCurrentEntryIndex = -1;
private final UnusedSymbolLocalInspectionBase myUnusedSymbolInspection;
private final HighlightDisplayKey myDeadCodeKey;
private final HighlightInfoType myDeadCodeInfoType;
private final UnusedDeclarationInspectionBase myDeadCodeInspection;
private boolean errorFound;
PostHighlightingVisitor(@NotNull PsiFile file, @NotNull Document document, @NotNull RefCountHolder refCountHolder) throws ProcessCanceledException {
ApplicationManager.getApplication().assertIsNonDispatchThread();
@@ -72,20 +74,25 @@ class PostHighlightingVisitor {
myRefCountHolder = refCountHolder;
InspectionProfileImpl profile = InspectionProjectProfileManager.getInstance(myProject).getCurrentProfile();
myDeadCodeKey = HighlightDisplayKey.find(UnusedDeclarationInspectionBase.SHORT_NAME);
myDeadCodeInspection = (UnusedDeclarationInspectionBase)profile.getUnwrappedTool(UnusedDeclarationInspectionBase.SHORT_NAME, myFile);
myUnusedSymbolInspection = myDeadCodeInspection == null ? null : myDeadCodeInspection.getSharedLocalInspectionTool();
UnusedDeclarationInspectionBase deadCodeInspection = (UnusedDeclarationInspectionBase)profile.getUnwrappedTool(UnusedDeclarationInspectionBase.SHORT_NAME, myFile);
myUnusedSymbolInspection = deadCodeInspection == null ? null : deadCodeInspection.getSharedLocalInspectionTool();
myDeadCodeInfoType = myDeadCodeKey == null ? HighlightInfoType.UNUSED_SYMBOL
: new HighlightInfoType.HighlightInfoTypeImpl(profile.getErrorLevel(myDeadCodeKey, myFile).getSeverity(),
ObjectUtils.notNull(profile.getEditorAttributes(myDeadCodeKey.toString(), myFile),
HighlightInfoType.UNUSED_SYMBOL.getAttributesKey()));
myGlobalUsageHelper = myRefCountHolder.getGlobalUsageHelper(myFile, deadCodeInspection);
}
void collectHighlights(@NotNull HighlightInfoHolder holder, @NotNull ProgressIndicator progress) {
void collectHighlights(@NotNull HighlightInfoHolder holder) {
ApplicationManager.getApplication().assertIsNonDispatchThread();
AtomicBoolean errorFound = new AtomicBoolean();
if (isToolEnabled(myDeadCodeKey)) {
if (myDeadCodeKey != null && isToolEnabled(myDeadCodeKey)) {
TextRange priorityRange = holder.getAnnotationSession().getPriorityRange();
GlobalUsageHelper globalUsageHelper = myRefCountHolder.getGlobalUsageHelper(myFile, myDeadCodeInspection);
JavaElementVisitor identifierVisitor = new JavaElementVisitor() {
@Override
public void visitIdentifier(@NotNull PsiIdentifier identifier) {
processIdentifier(holder, identifier);
}
};
Divider.divideInsideAndOutsideAllRoots(myFile, myFile.getTextRange(), priorityRange, Predicates.alwaysTrue(), dividedElements -> {
ProgressManager.checkCanceled();
PsiFile psiRoot = dividedElements.psiRoot();
@@ -95,17 +102,11 @@ class PostHighlightingVisitor {
}
for (PsiElement element : dividedElements.inside()) {
ProgressManager.checkCanceled();
if (element instanceof PsiIdentifier identifier) {
HighlightInfo.Builder builder = processIdentifier(identifier, progress, globalUsageHelper);
addInfo(holder, builder, errorFound);
}
element.accept(identifierVisitor);
}
for (PsiElement element : dividedElements.outside()) {
ProgressManager.checkCanceled();
if (element instanceof PsiIdentifier identifier) {
HighlightInfo.Builder builder = processIdentifier(identifier, progress, globalUsageHelper);
addInfo(holder, builder, errorFound);
}
element.accept(identifierVisitor);
}
return true;
});
@@ -113,18 +114,18 @@ class PostHighlightingVisitor {
HighlightDisplayKey unusedImportKey = HighlightDisplayKey.find(UnusedImportInspection.SHORT_NAME);
if (unusedImportKey != null && isUnusedImportEnabled(unusedImportKey)) {
PsiImportList importList = ((PsiJavaFile)myFile).getImportList();
PsiJavaFile javaFile = (PsiJavaFile)myFile;
PsiImportList importList = javaFile.getImportList();
if (importList != null) {
PsiImportStatementBase[] imports = importList.getAllImportStatements();
for (PsiImportStatementBase statement : imports) {
ProgressManager.checkCanceled();
HighlightInfo.Builder builder = processImport(statement, unusedImportKey);
addInfo(holder, builder, errorFound);
processImport(holder, javaFile, statement, unusedImportKey);
}
}
}
if (errorFound.get()) {
if (errorFound) {
DaemonCodeAnalyzerEx daemonCodeAnalyzer = DaemonCodeAnalyzerEx.getInstanceEx(myProject);
FileStatusMap fileStatusMap = daemonCodeAnalyzer.getFileStatusMap();
fileStatusMap.setErrorFoundFlag(myProject, myDocument, true);
@@ -135,25 +136,23 @@ class PostHighlightingVisitor {
}
}
private static void addInfo(@NotNull HighlightInfoHolder holder, @Nullable HighlightInfo.Builder builder, @NotNull AtomicBoolean errorFound) {
if (builder != null) {
HighlightInfo info = builder.create();
if (info != null && info.getSeverity() == HighlightSeverity.ERROR) {
errorFound.set(true);
}
holder.add(info);
private void addInfo(@NotNull HighlightInfoHolder holder, @NotNull HighlightInfo.Builder builder) {
HighlightInfo info = builder.create();
if (info != null && info.getSeverity() == HighlightSeverity.ERROR) {
errorFound = true;
}
holder.add(info);
}
private boolean isUnusedImportEnabled(@NotNull HighlightDisplayKey unusedImportKey) {
if (isToolEnabled(unusedImportKey)) return true;
for (ImplicitUsageProvider provider : ImplicitUsageProvider.EP_NAME.getExtensionList()) {
if (provider instanceof UnusedImportProvider && ((UnusedImportProvider)provider).isUnusedImportEnabled(myFile)) return true;
if (provider instanceof UnusedImportProvider uip && uip.isUnusedImportEnabled(myFile)) return true;
}
return false;
}
private boolean isToolEnabled(HighlightDisplayKey displayKey) {
private boolean isToolEnabled(@NotNull HighlightDisplayKey displayKey) {
if (!(myFile instanceof PsiJavaFile) || myUnusedSymbolInspection == null) {
return false;
}
@@ -170,51 +169,87 @@ class PostHighlightingVisitor {
return custom != null ? custom.apply(currentProfile).getInspectionProfile() : currentProfile;
}
private HighlightInfo.Builder processIdentifier(@NotNull PsiIdentifier identifier, @NotNull ProgressIndicator progress, @NotNull GlobalUsageHelper helper) {
private String message;
private final List<IntentionAction> quickFixes = new ArrayList<>();
private final List<IntentionAction> quickFixOptions = new ArrayList<>();
public void visitLocalVariable(@NotNull PsiLocalVariable variable) {
if (myUnusedSymbolInspection.LOCAL_VARIABLE) {
processLocalVariable(variable);
}
}
@Override
public void visitField(@NotNull PsiField field) {
if (compareVisibilities(field, myUnusedSymbolInspection.getFieldVisibility())) {
processField(myProject, field);
}
}
@Override
public void visitParameter(@NotNull PsiParameter parameter) {
PsiElement declarationScope = parameter.getDeclarationScope();
boolean needToProcessParameter;
if (declarationScope instanceof PsiMethod || declarationScope instanceof PsiLambdaExpression) {
if (declarationScope instanceof PsiLambdaExpression) {
declarationScope = PsiTreeUtil.getParentOfType(declarationScope, PsiModifierListOwner.class);
}
needToProcessParameter = compareVisibilities((PsiModifierListOwner)declarationScope, myUnusedSymbolInspection.getParameterVisibility());
}
else {
needToProcessParameter = myUnusedSymbolInspection.LOCAL_VARIABLE;
}
if (needToProcessParameter) {
processParameter(myProject, parameter);
}
}
@Override
public void visitMethod(@NotNull PsiMethod method) {
if (myUnusedSymbolInspection.isIgnoreAccessors() && PropertyUtilBase.isSimplePropertyAccessor(method)) {
return;
}
if (compareVisibilities(method, myUnusedSymbolInspection.getMethodVisibility())) {
processMethod(myProject, method);
}
}
@Override
public void visitClass(@NotNull PsiClass aClass) {
String acceptedVisibility = aClass.getContainingClass() == null ? myUnusedSymbolInspection.getClassVisibility()
: myUnusedSymbolInspection.getInnerClassVisibility();
if (compareVisibilities(aClass, acceptedVisibility)) {
processClass(myProject, aClass);
}
}
private void processIdentifier(@NotNull HighlightInfoHolder holder, @NotNull PsiIdentifier identifier) {
PsiElement parent = identifier.getParent();
if (!(parent instanceof PsiVariable || parent instanceof PsiMember)) return null;
if (parent == null) return;
if ((parent instanceof PsiVariable || parent instanceof PsiMember) && SuppressionUtil.inspectionResultSuppressed(identifier, myUnusedSymbolInspection)) return;
if (parent instanceof PsiParameter && SuppressionUtil.isSuppressed(identifier, UnusedSymbolLocalInspectionBase.UNUSED_PARAMETERS_SHORT_NAME)) return;
if (SuppressionUtil.inspectionResultSuppressed(identifier, myUnusedSymbolInspection)) return null;
if (parent instanceof PsiLocalVariable && myUnusedSymbolInspection.LOCAL_VARIABLE) {
return processLocalVariable((PsiLocalVariable)parent, identifier);
parent.accept(this);
if (message != null) {
HighlightInfo.Builder builder =
UnusedSymbolUtil.createUnusedSymbolInfoBuilder(identifier, message, myDeadCodeInfoType, UnusedDeclarationInspectionBase.SHORT_NAME);
for (IntentionAction fix : quickFixes) {
TextRange fixRange = HighlightMethodUtil.getFixRange(parent);
builder.registerFix(fix, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), fixRange, myDeadCodeKey);
}
for (IntentionAction fix : quickFixOptions) {
TextRange fixRange = HighlightMethodUtil.getFixRange(parent);
builder.registerFix(fix, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), fixRange, null);
}
addInfo(holder, builder);
message = null;
quickFixes.clear();
quickFixOptions.clear();
}
if (parent instanceof PsiField && compareVisibilities((PsiModifierListOwner)parent, myUnusedSymbolInspection.getFieldVisibility())) {
return processField(myProject, (PsiField)parent, identifier, progress, helper);
else {
assert quickFixes.isEmpty();
assert quickFixOptions.isEmpty();
}
if (parent instanceof PsiParameter) {
PsiElement declarationScope = ((PsiParameter)parent).getDeclarationScope();
boolean needToProcessParameter;
if (declarationScope instanceof PsiMethod || declarationScope instanceof PsiLambdaExpression) {
if (declarationScope instanceof PsiLambdaExpression) {
declarationScope = PsiTreeUtil.getParentOfType(declarationScope, PsiModifierListOwner.class);
}
needToProcessParameter = compareVisibilities((PsiModifierListOwner)declarationScope, myUnusedSymbolInspection.getParameterVisibility());
}
else {
needToProcessParameter = myUnusedSymbolInspection.LOCAL_VARIABLE;
}
if (needToProcessParameter) {
if (SuppressionUtil.isSuppressed(identifier, UnusedSymbolLocalInspectionBase.UNUSED_PARAMETERS_SHORT_NAME)) return null;
return processParameter(myProject, (PsiParameter)parent, identifier);
}
}
if (parent instanceof PsiMethod) {
if (myUnusedSymbolInspection.isIgnoreAccessors() && PropertyUtilBase.isSimplePropertyAccessor((PsiMethod)parent)) {
return null;
}
if (compareVisibilities((PsiModifierListOwner)parent, myUnusedSymbolInspection.getMethodVisibility())) {
return processMethod(myProject, (PsiMethod)parent, identifier, progress, helper);
}
}
if (parent instanceof PsiClass) {
String acceptedVisibility = ((PsiClass)parent).getContainingClass() == null ? myUnusedSymbolInspection.getClassVisibility()
: myUnusedSymbolInspection.getInnerClassVisibility();
if (compareVisibilities((PsiModifierListOwner)parent, acceptedVisibility)) {
return processClass(myProject, (PsiClass)parent, identifier, progress, helper);
}
}
return null;
}
private static boolean compareVisibilities(PsiModifierListOwner listOwner, String visibility) {
@@ -229,136 +264,90 @@ class PostHighlightingVisitor {
return false;
}
private HighlightInfo.Builder processLocalVariable(@NotNull PsiLocalVariable variable, @NotNull PsiIdentifier identifier) {
if (variable.isUnnamed() || PsiUtil.isIgnoredName(variable.getName())) return null;
if (UnusedSymbolUtil.isImplicitUsage(myProject, variable)) return null;
private void processLocalVariable(@NotNull PsiLocalVariable variable) {
if (variable.isUnnamed() || PsiUtil.isIgnoredName(variable.getName())) return;
if (UnusedSymbolUtil.isImplicitUsage(myProject, variable)) return;
String message = null;
IntentionAction fix = null;
if (!myRefCountHolder.isReferenced(variable)) {
message = JavaErrorBundle.message("local.variable.is.never.used", identifier.getText());
fix = variable instanceof PsiResourceVariable ? QuickFixFactory.getInstance().createRenameToIgnoredFix(variable, false)
: QuickFixFactory.getInstance().createRemoveUnusedVariableFix(variable);
message = JavaErrorBundle.message("local.variable.is.never.used", variable.getName());
quickFixes.add(variable instanceof PsiResourceVariable ? QuickFixFactory.getInstance().createRenameToIgnoredFix(variable, false)
: QuickFixFactory.getInstance().createRemoveUnusedVariableFix(variable));
}
else if (!myRefCountHolder.isReferencedForRead(variable) && !UnusedSymbolUtil.isImplicitRead(myProject, variable)) {
message = JavaErrorBundle.message("local.variable.is.not.used.for.reading", identifier.getText());
fix = QuickFixFactory.getInstance().createRemoveUnusedVariableFix(variable);
message = JavaErrorBundle.message("local.variable.is.not.used.for.reading", variable.getName());
quickFixes.add(QuickFixFactory.getInstance().createRemoveUnusedVariableFix(variable));
}
else if (!variable.hasInitializer() &&
!myRefCountHolder.isReferencedForWrite(variable) &&
!UnusedSymbolUtil.isImplicitWrite(myProject, variable)) {
message = JavaErrorBundle.message("local.variable.is.not.assigned", identifier.getText());
fix = QuickFixFactory.getInstance().createAddVariableInitializerFix(variable);
message = JavaErrorBundle.message("local.variable.is.not.assigned", variable.getName());
quickFixes.add(QuickFixFactory.getInstance().createAddVariableInitializerFix(variable));
}
if (message != null) {
HighlightInfo.Builder highlightInfo = UnusedSymbolUtil.createUnusedSymbolInfoBuilder(identifier, message, myDeadCodeInfoType, UnusedDeclarationInspectionBase.SHORT_NAME);
highlightInfo.registerFix(fix, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
return highlightInfo;
}
return null;
}
@Nullable
private HighlightInfo.Builder processField(@NotNull Project project,
@NotNull PsiField field,
@NotNull PsiIdentifier identifier,
@NotNull ProgressIndicator progress,
@NotNull GlobalUsageHelper helper) {
private void processField(@NotNull Project project, @NotNull PsiField field) {
if (HighlightUtil.isSerializationImplicitlyUsedField(field)) {
return null;
return;
}
if (field.hasModifierProperty(PsiModifier.PRIVATE)) {
QuickFixFactory quickFixFactory = QuickFixFactory.getInstance();
if (!myRefCountHolder.isReferenced(field) && !UnusedSymbolUtil.isImplicitUsage(myProject, field)) {
String message = JavaErrorBundle.message("private.field.is.not.used", identifier.getText());
HighlightInfo.Builder builder = suggestionsToMakeFieldUsed(field, identifier, message);
message = JavaErrorBundle.message("private.field.is.not.used", field.getName());
suggestionsToMakeFieldUsed(field);
if (!field.hasInitializer() && !field.hasModifierProperty(PsiModifier.FINAL)) {
TextRange fixRange = HighlightMethodUtil.getFixRange(field);
IntentionAction action = quickFixFactory.createCreateConstructorParameterFromFieldFix(field);
builder.registerFix(action, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), fixRange, myDeadCodeKey);
quickFixes.add(QuickFixFactory.getInstance().createCreateConstructorParameterFromFieldFix(field));
}
return builder;
return;
}
boolean readReferenced = myRefCountHolder.isReferencedForRead(field);
if (!readReferenced && !UnusedSymbolUtil.isImplicitRead(project, field)) {
String message = getNotUsedForReadingMessage(field, identifier);
return suggestionsToMakeFieldUsed(field, identifier, message);
message = getNotUsedForReadingMessage(field);
suggestionsToMakeFieldUsed(field);
return;
}
if (field.hasInitializer()) {
return null;
return;
}
boolean writeReferenced = myRefCountHolder.isReferencedForWrite(field);
if (!writeReferenced && !UnusedSymbolUtil.isImplicitWrite(project, field)) {
String message = JavaErrorBundle.message("private.field.is.not.assigned", identifier.getText());
HighlightInfo.Builder
info = UnusedSymbolUtil.createUnusedSymbolInfoBuilder(identifier, message, myDeadCodeInfoType, UnusedDeclarationInspectionBase.SHORT_NAME);
message = JavaErrorBundle.message("private.field.is.not.assigned", field.getName());
IntentionAction action1 = quickFixFactory.createCreateGetterOrSetterFix(false, true, field);
info.registerFix(action1, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
quickFixes.add(QuickFixFactory.getInstance().createCreateGetterOrSetterFix(false, true, field));
if (!field.hasModifierProperty(PsiModifier.FINAL)) {
TextRange fixRange = HighlightMethodUtil.getFixRange(field);
IntentionAction action = quickFixFactory.createCreateConstructorParameterFromFieldFix(field);
info.registerFix(action, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), fixRange, myDeadCodeKey);
quickFixes.add(QuickFixFactory.getInstance().createCreateConstructorParameterFromFieldFix(field));
}
SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(field, annoName -> {
IntentionAction action = quickFixFactory.createAddToImplicitlyWrittenFieldsFix(project, annoName);
info.registerFix(action, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
return true;
});
return info;
SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(field, annoName ->
quickFixes.add(QuickFixFactory.getInstance().createAddToImplicitlyWrittenFieldsFix(project, annoName)));
}
}
else if (UnusedSymbolUtil.isImplicitUsage(myProject, field) && !UnusedSymbolUtil.isImplicitWrite(myProject, field)) {
return null;
}
else if (UnusedSymbolUtil.isFieldUnused(myProject, myFile, field, progress, helper)) {
else if (!UnusedSymbolUtil.isFieldUsed(myProject, myFile, field, ProgressManager.getGlobalProgressIndicator(), myGlobalUsageHelper)) {
if (UnusedSymbolUtil.isImplicitWrite(myProject, field)) {
String message = getNotUsedForReadingMessage(field, identifier);
HighlightInfo.Builder
highlightInfo = UnusedSymbolUtil.createUnusedSymbolInfoBuilder(identifier, message, myDeadCodeInfoType, UnusedDeclarationInspectionBase.SHORT_NAME);
IntentionAction action = QuickFixFactory.getInstance().createSafeDeleteFix(field);
highlightInfo.registerFix(action, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
return highlightInfo;
message = getNotUsedForReadingMessage(field);
quickFixes.add(QuickFixFactory.getInstance().createSafeDeleteFix(field));
}
else if (!UnusedSymbolUtil.isImplicitUsage(myProject, field)) {
formatUnusedSymbolHighlightInfo(project, "field.is.not.used", field);
}
return formatUnusedSymbolHighlightInfo(project, "field.is.not.used", field, myDeadCodeKey, myDeadCodeInfoType, identifier);
}
return null;
}
@NotNull
private static @NlsContexts.DetailedDescription String getNotUsedForReadingMessage(@NotNull PsiField field, @NotNull PsiIdentifier identifier) {
private static @NlsContexts.DetailedDescription String getNotUsedForReadingMessage(@NotNull PsiField field) {
String visibility = VisibilityUtil.getVisibilityStringToDisplay(field);
String message = JavaErrorBundle.message("field.is.not.used.for.reading", visibility, identifier.getText());
String message = JavaErrorBundle.message("field.is.not.used.for.reading", visibility, field.getName());
return StringUtil.capitalize(message);
}
@NotNull
private HighlightInfo.Builder suggestionsToMakeFieldUsed(@NotNull PsiField field, @NotNull PsiIdentifier identifier, @NotNull @NlsContexts.DetailedDescription String message) {
HighlightInfo.Builder builder = UnusedSymbolUtil.createUnusedSymbolInfoBuilder(identifier, message, myDeadCodeInfoType, UnusedDeclarationInspectionBase.SHORT_NAME);
SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(field, annoName -> {
@Nullable IntentionAction action =
QuickFixFactory.getInstance().createAddToDependencyInjectionAnnotationsFix(field.getProject(), annoName);
builder.registerFix(action, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
return true;
});
IntentionAction action3 = QuickFixFactory.getInstance().createRemoveUnusedVariableFix(field);
builder.registerFix(action3, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
IntentionAction action2 = QuickFixFactory.getInstance().createCreateGetterOrSetterFix(true, false, field);
builder.registerFix(action2, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
IntentionAction action1 = QuickFixFactory.getInstance().createCreateGetterOrSetterFix(false, true, field);
builder.registerFix(action1, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
IntentionAction action = QuickFixFactory.getInstance().createCreateGetterOrSetterFix(true, true, field);
builder.registerFix(action, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
return builder;
private void suggestionsToMakeFieldUsed(@NotNull PsiField field) {
SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(field, annoName ->
quickFixes.add(QuickFixFactory.getInstance().createAddToDependencyInjectionAnnotationsFix(field.getProject(), annoName)));
quickFixes.add(QuickFixFactory.getInstance().createRemoveUnusedVariableFix(field));
quickFixes.add(QuickFixFactory.getInstance().createCreateGetterOrSetterFix(true, false, field));
quickFixes.add(QuickFixFactory.getInstance().createCreateGetterOrSetterFix(false, true, field));
quickFixes.add(QuickFixFactory.getInstance().createCreateGetterOrSetterFix(true, true, field));
}
private final Map<PsiMethod, Boolean> isOverriddenOrOverrides = ConcurrentFactoryMap.createMap(method-> {
@@ -371,14 +360,12 @@ class PostHighlightingVisitor {
return isOverriddenOrOverrides.get(method);
}
private HighlightInfo.Builder processParameter(@NotNull Project project,
@NotNull PsiParameter parameter,
@NotNull PsiIdentifier identifier) {
if (parameter.isUnnamed() || PsiUtil.isIgnoredName(parameter.getName())) return null;
private void processParameter(@NotNull Project project, @NotNull PsiParameter parameter) {
if (parameter.isUnnamed() || PsiUtil.isIgnoredName(parameter.getName())) return;
PsiElement declarationScope = parameter.getDeclarationScope();
QuickFixFactory quickFixFactory = QuickFixFactory.getInstance();
if (declarationScope instanceof PsiMethod method) {
if (PsiUtilCore.hasErrorElementChild(method)) return null;
if (PsiUtilCore.hasErrorElementChild(method)) return;
if ((method.isConstructor() ||
method.hasModifierProperty(PsiModifier.PRIVATE) ||
method.hasModifierProperty(PsiModifier.STATIC) ||
@@ -387,34 +374,32 @@ class PostHighlightingVisitor {
!method.hasModifierProperty(PsiModifier.NATIVE) &&
!JavaHighlightUtil.isSerializationRelatedMethod(method, method.getContainingClass()) &&
!PsiClassImplUtil.isMainOrPremainMethod(method)) {
if (UnusedSymbolUtil.isInjected(project, method)) return null;
HighlightInfo.Builder highlightInfo = checkUnusedParameter(parameter, identifier, method);
if (highlightInfo != null) {
IntentionAction action1 = quickFixFactory.createRenameToIgnoredFix(parameter, true);
highlightInfo.registerFix(action1, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
IntentionAction action = PriorityIntentionActionWrapper.highPriority(quickFixFactory.createSafeDeleteUnusedParameterInHierarchyFix(parameter, myUnusedSymbolInspection.checkParameterExcludingHierarchy() && isOverriddenOrOverrides(method)));
highlightInfo.registerFix(action, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
return highlightInfo;
if (UnusedSymbolUtil.isInjected(project, method)) return;
checkUnusedParameter(parameter, method);
if (message != null) {
quickFixes.add(quickFixFactory.createRenameToIgnoredFix(parameter, true));
quickFixes.add(PriorityIntentionActionWrapper.highPriority(
quickFixFactory.createSafeDeleteUnusedParameterInHierarchyFix(parameter,
myUnusedSymbolInspection.checkParameterExcludingHierarchy() &&
isOverriddenOrOverrides(method))));
}
}
}
else if (declarationScope instanceof PsiForeachStatement) {
HighlightInfo.Builder highlightInfo = checkUnusedParameter(parameter, identifier, null);
if (highlightInfo != null) {
IntentionAction action = quickFixFactory.createRenameToIgnoredFix(parameter, false);
highlightInfo.registerFix(action, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
return highlightInfo;
checkUnusedParameter(parameter, null);
if (message != null) {
quickFixes.add(quickFixFactory.createRenameToIgnoredFix(parameter, false));
}
}
else if (parameter instanceof PsiPatternVariable variable) {
HighlightInfo.Builder highlightInfo = checkUnusedParameter(parameter, identifier, null);
PsiPattern pattern = variable.getPattern();
if (highlightInfo != null) {
checkUnusedParameter(parameter, null);
if (message != null) {
PsiPattern pattern = variable.getPattern();
IntentionAction action = null;
if (HighlightingFeature.UNNAMED_PATTERNS_AND_VARIABLES.isAvailable(parameter)) {
if (pattern instanceof PsiTypeTestPattern && pattern.getParent() instanceof PsiDeconstructionList) {
if (pattern instanceof PsiTypeTestPattern ttPattern && pattern.getParent() instanceof PsiDeconstructionList) {
PsiRecordComponent component = JavaPsiPatternUtil.getRecordComponentForPattern(pattern);
PsiTypeElement checkType = ((PsiTypeTestPattern)pattern).getCheckType();
PsiTypeElement checkType = ttPattern.getCheckType();
if (component != null && checkType != null && checkType.getType().isAssignableFrom(component.getType())) {
action = new ReplaceWithUnnamedPatternFix(pattern).asIntention();
}
@@ -429,35 +414,25 @@ class PostHighlightingVisitor {
action = quickFixFactory.createDeleteFix(parameter);
}
if (action != null) {
highlightInfo.registerFix(action, null, null, null, null);
quickFixOptions.add(action);
}
return highlightInfo;
}
}
else if ((myUnusedSymbolInspection.checkParameterExcludingHierarchy() ||
HighlightingFeature.UNNAMED_PATTERNS_AND_VARIABLES.isAvailable(declarationScope))
&& declarationScope instanceof PsiLambdaExpression) {
HighlightInfo.Builder highlightInfo = checkUnusedParameter(parameter, identifier, null);
if (highlightInfo != null) {
IntentionAction action1 = quickFixFactory.createRenameToIgnoredFix(parameter, true);
highlightInfo.registerFix(action1, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
IntentionAction action =
PriorityIntentionActionWrapper.lowPriority(quickFixFactory.createSafeDeleteUnusedParameterInHierarchyFix(parameter, true));
highlightInfo.registerFix(action, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
return highlightInfo;
checkUnusedParameter(parameter, null);
if (message != null) {
quickFixes.add(quickFixFactory.createRenameToIgnoredFix(parameter, true));
quickFixes.add(PriorityIntentionActionWrapper.lowPriority(quickFixFactory.createSafeDeleteUnusedParameterInHierarchyFix(parameter, true)));
}
}
return null;
}
private HighlightInfo.Builder checkUnusedParameter(@NotNull PsiParameter parameter,
@NotNull PsiIdentifier identifier,
@Nullable PsiMethod declarationMethod) {
private void checkUnusedParameter(@NotNull PsiParameter parameter, @Nullable PsiMethod declarationMethod) {
if (!myRefCountHolder.isReferenced(parameter) && !UnusedSymbolUtil.isImplicitUsage(myProject, parameter)) {
String message = JavaErrorBundle.message(parameter instanceof PsiPatternVariable ?
"pattern.variable.is.not.used" : "parameter.is.not.used", identifier.getText());
HighlightInfo.Builder info = UnusedSymbolUtil.createUnusedSymbolInfoBuilder(identifier, message, myDeadCodeInfoType, UnusedDeclarationInspectionBase.SHORT_NAME);
message = JavaErrorBundle.message(parameter instanceof PsiPatternVariable ?
"pattern.variable.is.not.used" : "parameter.is.not.used", parameter.getName());
if (declarationMethod != null) {
IntentionAction assignFix = QuickFixFactory.getInstance().createAssignFieldFromParameterFix();
IntentionAction createFieldFix = QuickFixFactory.getInstance().createCreateFieldFromParameterFix();
@@ -465,21 +440,15 @@ class PostHighlightingVisitor {
assignFix = PriorityIntentionActionWrapper.lowPriority(assignFix);
createFieldFix = PriorityIntentionActionWrapper.lowPriority(createFieldFix);
}
info.registerFix(assignFix, null, null, null, null);
info.registerFix(createFieldFix, null, null, null, null);
quickFixOptions.add(assignFix);
quickFixOptions.add(createFieldFix);
}
return info;
}
return null;
}
private HighlightInfo.Builder processMethod(@NotNull Project project,
@NotNull PsiMethod method,
@NotNull PsiIdentifier identifier,
@NotNull ProgressIndicator progress,
@NotNull GlobalUsageHelper helper) {
if (UnusedSymbolUtil.isMethodReferenced(myProject, myFile, method, progress, helper)) {
return null;
private void processMethod(@NotNull Project project, @NotNull PsiMethod method) {
if (UnusedSymbolUtil.isMethodUsed(myProject, myFile, method, ProgressIndicatorProvider.getGlobalProgressIndicator(), myGlobalUsageHelper)) {
return;
}
String key;
if (method.hasModifierProperty(PsiModifier.PRIVATE)) {
@@ -490,25 +459,15 @@ class PostHighlightingVisitor {
}
int options = PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.SHOW_FQ_CLASS_NAMES;
String symbolName = HighlightMessageUtil.getSymbolName(method, PsiSubstitutor.EMPTY, options);
String message = JavaErrorBundle.message(key, symbolName);
HighlightInfo.Builder builder = UnusedSymbolUtil.createUnusedSymbolInfoBuilder(identifier, message, myDeadCodeInfoType, UnusedDeclarationInspectionBase.SHORT_NAME);
IntentionAction action = QuickFixFactory.getInstance().createSafeDeleteFix(method);
builder.registerFix(action, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(method, annoName -> {
IntentionAction fix = QuickFixFactory.getInstance().createAddToDependencyInjectionAnnotationsFix(project, annoName);
builder.registerFix(fix, null, HighlightDisplayKey.getDisplayNameByKey(myDeadCodeKey), null, myDeadCodeKey);
return true;
});
return builder;
message = JavaErrorBundle.message(key, symbolName);
quickFixes.add(QuickFixFactory.getInstance().createSafeDeleteFix(method));
SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(method, annoName ->
quickFixes.add(QuickFixFactory.getInstance().createAddToDependencyInjectionAnnotationsFix(project, annoName)));
}
private HighlightInfo.Builder processClass(@NotNull Project project,
@NotNull PsiClass aClass,
@NotNull PsiIdentifier identifier,
@NotNull ProgressIndicator progress,
@NotNull GlobalUsageHelper helper) {
if (UnusedSymbolUtil.isClassUsed(project, myFile, aClass, progress, helper)) {
return null;
private void processClass(@NotNull Project project, @NotNull PsiClass aClass) {
if (UnusedSymbolUtil.isClassUsed(project, myFile, aClass, ProgressIndicatorProvider.getGlobalProgressIndicator(), myGlobalUsageHelper)) {
return;
}
String pattern;
@@ -532,56 +491,50 @@ class PostHighlightingVisitor {
else {
pattern = "class.is.not.used";
}
return formatUnusedSymbolHighlightInfo(myProject, pattern, aClass, myDeadCodeKey, myDeadCodeInfoType, identifier);
formatUnusedSymbolHighlightInfo(myProject, pattern, aClass);
}
@NotNull
private static HighlightInfo.Builder formatUnusedSymbolHighlightInfo(@NotNull Project project,
@NotNull @PropertyKey(resourceBundle = JavaErrorBundle.BUNDLE) String pattern,
@NotNull PsiNameIdentifierOwner aClass,
HighlightDisplayKey highlightDisplayKey,
@NotNull HighlightInfoType highlightInfoType,
@NotNull PsiElement identifier) {
String symbolName = aClass.getName();
String message = JavaErrorBundle.message(pattern, symbolName);
HighlightInfo.Builder highlightInfo = UnusedSymbolUtil.createUnusedSymbolInfoBuilder(identifier, message, highlightInfoType, UnusedDeclarationInspectionBase.SHORT_NAME);
IntentionAction action1 = QuickFixFactory.getInstance().createSafeDeleteFix(aClass);
highlightInfo.registerFix(action1, null, HighlightDisplayKey.getDisplayNameByKey(highlightDisplayKey), null, highlightDisplayKey);
SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes((PsiModifierListOwner)aClass, annoName -> {
IntentionAction action = QuickFixFactory.getInstance().createAddToDependencyInjectionAnnotationsFix(project, annoName);
highlightInfo.registerFix(action, null, HighlightDisplayKey.getDisplayNameByKey(highlightDisplayKey), null, highlightDisplayKey);
return true;
});
return highlightInfo;
private void formatUnusedSymbolHighlightInfo(@NotNull Project project,
@NotNull @PropertyKey(resourceBundle = JavaErrorBundle.BUNDLE) String pattern,
@NotNull PsiMember member) {
String symbolName = member.getName();
message = JavaErrorBundle.message(pattern, symbolName);
quickFixes.add(QuickFixFactory.getInstance().createSafeDeleteFix(member));
SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(member, annoName ->
quickFixes.add(QuickFixFactory.getInstance().createAddToDependencyInjectionAnnotationsFix(project, annoName)));
}
private HighlightInfo.Builder processImport(@NotNull PsiImportStatementBase importStatement, @NotNull HighlightDisplayKey unusedImportKey) {
private void processImport(@NotNull HighlightInfoHolder holder,
@NotNull PsiJavaFile javaFile,
@NotNull PsiImportStatementBase importStatement,
@NotNull HighlightDisplayKey unusedImportKey) {
// jsp include directive hack
if (importStatement.isForeignFileImport()) return null;
if (importStatement.isForeignFileImport()) return;
if (PsiUtilCore.hasErrorElementChild(importStatement)) return null;
if (PsiUtilCore.hasErrorElementChild(importStatement)) return;
boolean isRedundant = myRefCountHolder.isRedundant(importStatement);
if (!isRedundant && !(importStatement instanceof PsiImportStaticStatement)) {
// check import from the same package
String packageName = ((PsiClassOwner)importStatement.getContainingFile()).getPackageName();
String packageName = javaFile.getPackageName();
PsiJavaCodeReferenceElement reference = importStatement.getImportReference();
PsiElement resolved = reference == null ? null : reference.resolve();
if (resolved instanceof PsiPackage) {
isRedundant = packageName.equals(((PsiQualifiedNamedElement)resolved).getQualifiedName());
if (resolved instanceof PsiPackage psiPackage) {
isRedundant = packageName.equals(psiPackage.getQualifiedName());
}
else if (resolved instanceof PsiClass && !importStatement.isOnDemand()) {
String qName = ((PsiClass)resolved).getQualifiedName();
else if (resolved instanceof PsiClass psiClass && !importStatement.isOnDemand()) {
String qName = psiClass.getQualifiedName();
if (qName != null) {
String name = ((PomNamedTarget)resolved).getName();
String name = psiClass.getName();
isRedundant = qName.equals(packageName + '.' + name);
}
}
}
if (isRedundant) {
return registerRedundantImport(importStatement, unusedImportKey);
registerRedundantImport(holder, importStatement, unusedImportKey);
return;
}
int entryIndex = JavaCodeStyleManager.getInstance(myProject).findEntryIndex(importStatement);
@@ -590,36 +543,34 @@ class PostHighlightingVisitor {
myOptimizeImportsFix = QuickFixFactory.getInstance().createOptimizeImportsFix(true, myFile);
}
myCurrentEntryIndex = entryIndex;
return null;
}
@NotNull
private HighlightInfo.Builder registerRedundantImport(@NotNull PsiImportStatementBase importStatement, @NotNull HighlightDisplayKey unusedImportKey) {
private void registerRedundantImport(@NotNull HighlightInfoHolder holder,
@NotNull PsiImportStatementBase importStatement, @NotNull HighlightDisplayKey unusedImportKey) {
VirtualFile virtualFile = PsiUtilCore.getVirtualFile(myFile);
Set<String> imports = virtualFile != null ? virtualFile.getCopyableUserData(ImportsHighlightUtil.IMPORTS_FROM_TEMPLATE) : null;
boolean predefinedImport = imports != null && imports.contains(importStatement.getText());
String description = !predefinedImport ? JavaAnalysisBundle.message("unused.import.statement") :
JavaAnalysisBundle.message("text.unused.import.in.template");
InspectionProfile profile = getCurrentProfile();
TextAttributesKey key = ObjectUtils.notNull(profile.getEditorAttributes(unusedImportKey.toString(), myFile),
JavaHighlightInfoTypes.UNUSED_IMPORT.getAttributesKey());
HighlightInfoType.HighlightInfoTypeImpl configHighlightType =
new HighlightInfoType.HighlightInfoTypeImpl(profile.getErrorLevel(unusedImportKey, myFile).getSeverity(),
ObjectUtils.notNull(profile.getEditorAttributes(unusedImportKey.toString(), myFile),
JavaHighlightInfoTypes.UNUSED_IMPORT.getAttributesKey()));
new HighlightInfoType.HighlightInfoTypeImpl(profile.getErrorLevel(unusedImportKey, myFile).getSeverity(), key);
HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(configHighlightType)
HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(configHighlightType)
.range(importStatement)
.descriptionAndTooltip(description)
.group(GeneralHighlightingPass.POST_UPDATE_ALL);
IntentionAction optimizeFix = QuickFixFactory.getInstance().createOptimizeImportsFix(false, myFile);
info.registerFix(optimizeFix, null, HighlightDisplayKey.getDisplayNameByKey(unusedImportKey), null, unusedImportKey);
builder.registerFix(optimizeFix, null, HighlightDisplayKey.getDisplayNameByKey(unusedImportKey), null, unusedImportKey);
IntentionAction switchFix = QuickFixFactory.getInstance().createEnableOptimizeImportsOnTheFlyFix();
info.registerFix(switchFix, null, HighlightDisplayKey.getDisplayNameByKey(unusedImportKey), null, unusedImportKey);
builder.registerFix(switchFix, null, HighlightDisplayKey.getDisplayNameByKey(unusedImportKey), null, unusedImportKey);
if (!predefinedImport && myOptimizeImportsFix == null) {
myOptimizeImportsFix = QuickFixFactory.getInstance().createOptimizeImportsFix(true, myFile);
}
return info;
addInfo(holder, builder);
}
}
@@ -1,7 +1,7 @@
// "Suppress for method" "true"
import java.io.IOException;
class a {
class a implements Runnable {
/** @noinspection RedundantThrowsDeclaration*/
private void run() throws <caret>IOException{
public void run() throws <caret>IOException{
}
}
@@ -1,10 +1,10 @@
// "Suppress for statement" "true"
class a {
class a implements Runnable {
/**
* @deprecated
*/
int b;
private void aa(){
public void run(){
//noinspection deprecation
b++;
}
@@ -1,12 +1,12 @@
// "Suppress for statement" "true"
class a {
class a implements Runnable {
/**
* @deprecated
*/
public void aa(){
}
private void aaa(){
public void run(){
//noinspection deprecation
<caret>aa();
}
@@ -1,6 +1,6 @@
// "Suppress for method" "true"
import java.io.IOException;
class a {
private void run() throws <caret>IOException{
class a implements Runnable {
public void run() throws <caret>IOException{
}
}
@@ -1,10 +1,10 @@
// "Suppress for statement" "true"
class a {
class a implements Runnable {
/**
* @deprecated
*/
int b;
private void aa(){
public void run(){
<caret>b++;
}
}
@@ -1,12 +1,12 @@
// "Suppress for statement" "true"
class a {
class a implements Runnable {
/**
* @deprecated
*/
public void aa(){
}
private void aaa(){
public void run(){
<caret>aa();
}
}
@@ -115,7 +115,7 @@ public class GroovyPostHighlightingPass extends TextEditorHighlightingPass {
usageHelper.shouldCheckContributors = false;
}
try {
if (!UnusedSymbolUtil.isMethodReferenced(method.getProject(), method.getContainingFile(), method, progress, usageHelper)) {
if (!UnusedSymbolUtil.isMethodUsed(method.getProject(), method.getContainingFile(), method, progress, usageHelper)) {
String message;
if (method.isConstructor()) {
message = GroovyBundle.message("text.constructor.0.is.unused", name);
@@ -197,7 +197,7 @@ public class GroovyPostHighlightingPass extends TextEditorHighlightingPass {
}
private static boolean isFieldUnused(GrField field, ProgressIndicator progress, GlobalUsageHelper usageHelper) {
if (!UnusedSymbolUtil.isFieldUnused(field.getProject(), field.getContainingFile(), field, progress, usageHelper)) return false;
if (UnusedSymbolUtil.isFieldUsed(field.getProject(), field.getContainingFile(), field, progress, usageHelper)) return false;
final GrAccessorMethod[] getters = field.getGetters();
final GrAccessorMethod setter = field.getSetter();