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;
 }
コード例 #2
0
  public void invoke(@NotNull Project project, Editor editor, PsiFile file)
      throws IncorrectOperationException {
    LOG.assertTrue(myOutOfScopeVariable != null);
    PsiManager manager = file.getManager();
    myOutOfScopeVariable.normalizeDeclaration();
    PsiUtil.setModifierProperty(myOutOfScopeVariable, PsiModifier.FINAL, false);
    PsiElement commonParent =
        PsiTreeUtil.findCommonParent(myOutOfScopeVariable, myUnresolvedReference);
    LOG.assertTrue(commonParent != null);
    PsiElement child =
        myOutOfScopeVariable.getTextRange().getStartOffset()
                < myUnresolvedReference.getTextRange().getStartOffset()
            ? myOutOfScopeVariable
            : myUnresolvedReference;

    while (child.getParent() != commonParent) child = child.getParent();
    PsiDeclarationStatement newDeclaration =
        (PsiDeclarationStatement)
            JavaPsiFacade.getInstance(manager.getProject())
                .getElementFactory()
                .createStatementFromText("int i = 0", null);
    PsiVariable variable =
        (PsiVariable) newDeclaration.getDeclaredElements()[0].replace(myOutOfScopeVariable);
    if (variable.getInitializer() != null) {
      variable.getInitializer().delete();
    }

    while (!(child instanceof PsiStatement) || !(child.getParent() instanceof PsiCodeBlock)) {
      child = child.getParent();
      commonParent = commonParent.getParent();
    }
    LOG.assertTrue(commonParent != null);
    PsiDeclarationStatement added =
        (PsiDeclarationStatement) commonParent.addBefore(newDeclaration, child);
    PsiLocalVariable addedVar = (PsiLocalVariable) added.getDeclaredElements()[0];
    manager.getCodeStyleManager().reformat(commonParent);

    // Leave initializer assignment
    PsiExpression initializer = myOutOfScopeVariable.getInitializer();
    if (initializer != null) {
      PsiExpressionStatement assignment =
          (PsiExpressionStatement)
              JavaPsiFacade.getInstance(manager.getProject())
                  .getElementFactory()
                  .createStatementFromText(myOutOfScopeVariable.getName() + "= e;", null);
      ((PsiAssignmentExpression) assignment.getExpression()).getRExpression().replace(initializer);
      assignment = (PsiExpressionStatement) manager.getCodeStyleManager().reformat(assignment);
      PsiDeclarationStatement declStatement =
          PsiTreeUtil.getParentOfType(myOutOfScopeVariable, PsiDeclarationStatement.class);
      LOG.assertTrue(declStatement != null);
      PsiElement parent = declStatement.getParent();
      if (parent instanceof PsiForStatement) {
        declStatement.replace(assignment);
      } else {
        parent.addAfter(assignment, declStatement);
      }
    }

    if (myOutOfScopeVariable.isValid()) {
      myOutOfScopeVariable.delete();
    }

    if (HighlightControlFlowUtil.checkVariableInitializedBeforeUsage(
            myUnresolvedReference,
            addedVar,
            new THashMap<PsiElement, Collection<PsiReferenceExpression>>())
        != null) {
      initialize(addedVar);
    }

    DaemonCodeAnalyzer.getInstance(project).updateVisibleHighlighters(editor);
  }