mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 09:19:13 +07:00
optimization: convert to visitor to avoid multiple instanceof checks
GitOrigin-RevId: 781e5a88a348d9af4579869cb39ff042f871b78f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
279415219b
commit
615818a8d2
+15
-15
@@ -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) {
|
||||
|
||||
+1
-3
@@ -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 {
|
||||
|
||||
+219
-268
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -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{
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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++;
|
||||
}
|
||||
|
||||
+2
-2
@@ -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();
|
||||
}
|
||||
|
||||
+2
-2
@@ -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{
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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++;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user