@Nullable static HighlightInfo checkCannotWriteToFinal( @NotNull PsiExpression expression, @NotNull PsiFile containingFile) { PsiReferenceExpression reference = null; boolean readBeforeWrite = false; if (expression instanceof PsiAssignmentExpression) { final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) expression; final PsiExpression left = PsiUtil.skipParenthesizedExprDown(assignmentExpression.getLExpression()); if (left instanceof PsiReferenceExpression) { reference = (PsiReferenceExpression) left; } readBeforeWrite = assignmentExpression.getOperationTokenType() != JavaTokenType.EQ; } else if (expression instanceof PsiPostfixExpression) { final PsiExpression operand = PsiUtil.skipParenthesizedExprDown(((PsiPostfixExpression) expression).getOperand()); final IElementType sign = ((PsiPostfixExpression) expression).getOperationTokenType(); if (operand instanceof PsiReferenceExpression && (sign == JavaTokenType.PLUSPLUS || sign == JavaTokenType.MINUSMINUS)) { reference = (PsiReferenceExpression) operand; } readBeforeWrite = true; } else if (expression instanceof PsiPrefixExpression) { final PsiExpression operand = PsiUtil.skipParenthesizedExprDown(((PsiPrefixExpression) expression).getOperand()); final IElementType sign = ((PsiPrefixExpression) expression).getOperationTokenType(); if (operand instanceof PsiReferenceExpression && (sign == JavaTokenType.PLUSPLUS || sign == JavaTokenType.MINUSMINUS)) { reference = (PsiReferenceExpression) operand; } readBeforeWrite = true; } final PsiElement resolved = reference == null ? null : reference.resolve(); PsiVariable variable = resolved instanceof PsiVariable ? (PsiVariable) resolved : null; if (variable == null || !variable.hasModifierProperty(PsiModifier.FINAL)) return null; final boolean canWrite = canWriteToFinal(variable, expression, reference, containingFile) && checkWriteToFinalInsideLambda(variable, reference) == null; if (readBeforeWrite || !canWrite) { final String name = variable.getName(); String description = canWrite ? JavaErrorMessages.message("variable.not.initialized", name) : JavaErrorMessages.message("assignment.to.final.variable", name); final HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(reference.getTextRange()) .descriptionAndTooltip(description) .create(); final PsiElement innerClass = getInnerClassVariableReferencedFrom(variable, expression); if (innerClass == null || variable instanceof PsiField) { QuickFixAction.registerQuickFixAction( highlightInfo, QUICK_FIX_FACTORY.createModifierListFix(variable, PsiModifier.FINAL, false, false)); } else { QuickFixAction.registerQuickFixAction( highlightInfo, QUICK_FIX_FACTORY.createVariableAccessFromInnerClassFix(variable, innerClass)); } return highlightInfo; } return null; }