void (final PsiClass aClass, ProblemsHolder holder, final List<String> excludeAnnos, boolean ignoreFieldsUsedInMultipleMethods) { if (aClass.isInterface()) return; final PsiField[] fields = aClass.getFields(); final Set<PsiField> candidates = new LinkedHashSet<>(); for (PsiField field : fields) { if (!field.isPhysical() || AnnotationUtil.isAnnotated(field, excludeAnnos, 0)) { continue; } if (field.hasModifierProperty(PsiModifier.VOLATILE)) { // Assume that fields marked as volatile can be modified concurrently // (e.g. if the only method where they are changed is called from several threads) continue; } if (field.hasModifierProperty(PsiModifier.PRIVATE) && !(field.hasModifierProperty(PsiModifier.STATIC) && field.hasModifierProperty(PsiModifier.FINAL))) { candidates.add(field); } } removeFieldsReferencedFromInitializers(aClass, aClass, candidates); if (candidates.isEmpty()) return; final Set<PsiField> usedFields = new HashSet<>(); removeReadFields(aClass, candidates, usedFields, ignoreFieldsUsedInMultipleMethods); if (candidates.isEmpty()) return; final List<ImplicitUsageProvider> implicitUsageProviders = ImplicitUsageProvider.EP_NAME.getExtensionList(); final PsiClass scope = findVariableScope(aClass); FieldLoop: for (final PsiField field : candidates) { if (usedFields.contains(field) && !hasImplicitReadOrWriteUsage(field, implicitUsageProviders)) { final List<PsiReferenceExpression> references = VariableAccessUtils.getVariableReferences(field, scope); final Map<PsiCodeBlock, Collection<PsiReferenceExpression>> refs = new HashMap<>(); for (PsiReferenceExpression reference : references) { final PsiElement qualifier = reference.getQualifier(); if (qualifier != null && (!(qualifier instanceof PsiThisExpression thisExpression) || thisExpression.getQualifier() != null) || !groupReferenceByCodeBlocks(refs, reference)) { continue FieldLoop; } } final String message = JavaBundle.message("inspection.field.can.be.local.problem.descriptor"); final ArrayList<LocalQuickFix> fixes = new ArrayList<>(); SpecialAnnotationsUtilBase.processUnknownAnnotations(field, qualifiedName -> { fixes.add(new AddToInspectionOptionListFix<>( this, QuickFixBundle.message("fix.add.special.annotation.text", qualifiedName), qualifiedName, insp -> insp.EXCLUDE_ANNOS)); return true; }); fixes.add(new ConvertFieldToLocalQuickFix(refs)); holder.registerProblem(field.getNameIdentifier(), message, fixes.toArray(LocalQuickFix.EMPTY_ARRAY)); } } }