boolean (@NotNull PsiLocalVariable variable, @Nullable PsiExpression expression) { if (expression instanceof PsiTypeCastExpression) { PsiExpression operand = ((PsiTypeCastExpression)expression).getOperand(); if (operand instanceof PsiReferenceExpression && RedundantCastUtil.isCastRedundant((PsiTypeCastExpression)expression)) { expression = operand; } } if (!(expression instanceof PsiReferenceExpression reference)) { return false; } final PsiVariable initialization = ObjectUtils.tryCast(reference.resolve(), PsiVariable.class); if (initialization == null) { return false; } if (!(initialization instanceof PsiResourceVariable) && variable instanceof PsiResourceVariable) { return false; } if (!(initialization instanceof PsiLocalVariable || initialization instanceof PsiParameter)) { if (!isFinalChain(reference) || ReferencesSearch.search(variable).findAll().size() != 1) { // only warn when variable is referenced once, to avoid warning when a field is cached in local variable // as in e.g. gnu.trove.TObjectHash#forEach() return false; } } final PsiCodeBlock containingScope = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class); if (containingScope == null) { return false; } if (variableMayChange(containingScope, null, variable)) { return false; } if (variableMayChange(containingScope, PsiUtil.skipParenthesizedExprDown(reference.getQualifierExpression()), initialization)) { return false; } final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(containingScope.getProject()).getResolveHelper(); final String initializationName = initialization.getName(); if (initializationName == null) { return false; } final boolean finalVariableIntroduction = !initialization.hasModifierProperty(PsiModifier.FINAL) && variable.hasModifierProperty(PsiModifier.FINAL) || PsiUtil.isLanguageLevel8OrHigher(initialization) && !HighlightControlFlowUtil.isEffectivelyFinal(initialization, containingScope, null) && HighlightControlFlowUtil.isEffectivelyFinal(variable, containingScope, null); final boolean canCaptureThis = initialization instanceof PsiField && !initialization.hasModifierProperty(PsiModifier.STATIC); final PsiType variableType = variable.getType(); final PsiType initializationType = initialization.getType(); final boolean sameType = Comparing.equal(variableType, initializationType); for (PsiReference ref : ReferencesSearch.search(variable, new LocalSearchScope(containingScope))) { final PsiElement refElement = ref.getElement(); if (finalVariableIntroduction || canCaptureThis) { final PsiElement element = PsiTreeUtil.getParentOfType(refElement, PsiClass.class, PsiLambdaExpression.class); if (element != null && PsiTreeUtil.isAncestor(containingScope, element, true)) { return false; } } if (resolveHelper.resolveReferencedVariable(initializationName, refElement) != initialization) { return false; } if (!sameType) { final PsiElement parent = refElement.getParent(); if (parent instanceof PsiReferenceExpression) { final PsiElement resolve = ((PsiReferenceExpression)parent).resolve(); if (resolve instanceof PsiMember && ((PsiMember)resolve).hasModifierProperty(PsiModifier.PRIVATE)) { return false; } } } } return !TypeConversionUtil.boxingConversionApplicable(variableType, initializationType); }