@Nullable static HighlightInfo checkFinalVariableInitializedInLoop( @NotNull PsiReferenceExpression expression, @NotNull PsiElement resolved) { if (ControlFlowUtil.isVariableAssignedInLoop(expression, resolved)) { String description = JavaErrorMessages.message( "variable.assigned.in.loop", ((PsiVariable) resolved).getName()); final HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) .descriptionAndTooltip(description) .create(); QuickFixAction.registerQuickFixAction( highlightInfo, QUICK_FIX_FACTORY.createModifierListFix( (PsiVariable) resolved, PsiModifier.FINAL, false, false)); return highlightInfo; } return null; }
private static boolean canBeFinal(PsiVariable variable, List<PsiReferenceExpression> references) { // if there is at least one assignment to this variable, it cannot be final Map<PsiElement, Collection<PsiReferenceExpression>> uninitializedVarProblems = new THashMap<PsiElement, Collection<PsiReferenceExpression>>(); Map<PsiElement, Collection<ControlFlowUtil.VariableInfo>> finalVarProblems = new THashMap<PsiElement, Collection<ControlFlowUtil.VariableInfo>>(); for (PsiReferenceExpression expression : references) { if (ControlFlowUtil.isVariableAssignedInLoop(expression, variable)) return false; HighlightInfo highlightInfo = HighlightControlFlowUtil.checkVariableInitializedBeforeUsage( expression, variable, uninitializedVarProblems); if (highlightInfo != null) return false; highlightInfo = HighlightControlFlowUtil.checkFinalVariableMightAlreadyHaveBeenAssignedTo( variable, expression, finalVarProblems); if (highlightInfo != null) return false; if (variable instanceof PsiParameter && PsiUtil.isAccessedForWriting(expression)) return false; } return true; }