コード例 #1
0
 private static boolean localVariableAreEquivalent(
     @NotNull PsiLocalVariable var1, @NotNull PsiLocalVariable var2) {
   final PsiType type1 = var1.getType();
   final PsiType type2 = var2.getType();
   if (!typesAreEquivalent(type1, type2)) {
     return false;
   }
   final String name1 = var1.getName();
   final String name2 = var2.getName();
   if (!name1.equals(name2)) {
     return false;
   }
   final PsiExpression initializer1 = var1.getInitializer();
   final PsiExpression initializer2 = var2.getInitializer();
   return expressionsAreEquivalent(initializer1, initializer2);
 }
コード例 #2
0
 public IntroduceFieldRunnable(
     boolean rebindNeeded,
     PsiLocalVariable local,
     PsiClass aClass,
     BaseExpressionToFieldHandler.Settings settings,
     boolean isStatic,
     PsiExpression[] occurrences) {
   myVariableName = local.getName();
   myFieldName = settings.getFieldName();
   myRebindNeeded = rebindNeeded;
   myLocal = local;
   myProject = local.getProject();
   myDestinationClass = aClass;
   mySettings = settings;
   myInitializerPlace = settings.getInitializerPlace();
   myOccurences = occurrences;
 }
コード例 #3
0
 private static PsiDeclarationStatement createNewDeclaration(
     @NotNull PsiLocalVariable variable, PsiExpression initializer)
     throws IncorrectOperationException {
   final PsiManager manager = variable.getManager();
   final PsiElementFactory factory =
       JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
   final PsiDeclarationStatement newDeclaration =
       factory.createVariableDeclarationStatement(
           variable.getName(), variable.getType(), initializer);
   if (variable.hasModifierProperty(PsiModifier.FINAL)) {
     final PsiLocalVariable newVariable =
         (PsiLocalVariable) newDeclaration.getDeclaredElements()[0];
     final PsiModifierList modifierList = newVariable.getModifierList();
     modifierList.setModifierProperty(PsiModifier.FINAL, true);
   }
   return newDeclaration;
 }
コード例 #4
0
 public static boolean containsConflictingDeclarations(
     PsiCodeBlock block, PsiCodeBlock parentBlock) {
   final PsiStatement[] statements = block.getStatements();
   if (statements.length == 0) {
     return false;
   }
   final List<PsiCodeBlock> followingBlocks = new ArrayList<>();
   collectFollowingBlocks(block.getParent().getNextSibling(), followingBlocks);
   final Project project = block.getProject();
   final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
   final PsiResolveHelper resolveHelper = facade.getResolveHelper();
   for (final PsiStatement statement : statements) {
     if (!(statement instanceof PsiDeclarationStatement)) {
       continue;
     }
     final PsiDeclarationStatement declaration = (PsiDeclarationStatement) statement;
     final PsiElement[] variables = declaration.getDeclaredElements();
     for (PsiElement variable : variables) {
       if (!(variable instanceof PsiLocalVariable)) {
         continue;
       }
       final PsiLocalVariable localVariable = (PsiLocalVariable) variable;
       final String variableName = localVariable.getName();
       if (variableName == null) {
         continue;
       }
       final PsiVariable target =
           resolveHelper.resolveAccessibleReferencedVariable(variableName, parentBlock);
       if (target instanceof PsiLocalVariable) {
         return true;
       }
       for (PsiCodeBlock codeBlock : followingBlocks) {
         final PsiVariable target1 =
             resolveHelper.resolveAccessibleReferencedVariable(variableName, codeBlock);
         if (target1 instanceof PsiLocalVariable) {
           return true;
         }
       }
     }
   }
   return false;
 }
 @Nullable
 private static String buildFromOffsetText(PsiExpression expression, PsiLocalVariable variable)
     throws IncorrectOperationException {
   expression = ParenthesesUtils.stripParentheses(expression);
   if (expression == null) {
     return null;
   }
   final String expressionText = expression.getText();
   final String variableName = variable.getName();
   if (expressionText.equals(variableName)) {
     final PsiExpression initialValue = variable.getInitializer();
     if (initialValue == null) {
       return null;
     }
     return initialValue.getText();
   }
   if (expression instanceof PsiBinaryExpression) {
     final PsiBinaryExpression binaryExpression = (PsiBinaryExpression) expression;
     final PsiExpression lhs = binaryExpression.getLOperand();
     final PsiExpression rhs = binaryExpression.getROperand();
     final String rhsText = buildFromOffsetText(rhs, variable);
     final PsiJavaToken sign = binaryExpression.getOperationSign();
     final IElementType tokenType = sign.getTokenType();
     if (ExpressionUtils.isZero(lhs)) {
       if (tokenType.equals(JavaTokenType.MINUS)) {
         return '-' + rhsText;
       }
       return rhsText;
     }
     final String lhsText = buildFromOffsetText(lhs, variable);
     if (ExpressionUtils.isZero(rhs)) {
       return lhsText;
     }
     return collapseConstant(lhsText + sign.getText() + rhsText, variable);
   }
   return collapseConstant(expression.getText(), variable);
 }
コード例 #6
0
  protected void performRefactoring(UsageInfo[] usages) {
    try {
      PsiElementFactory factory =
          JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory();
      PsiType initializerType =
          getInitializerType(myForcedType, myParameterInitializer, myLocalVariable);
      setForcedType(initializerType);

      // Converting myParameterInitializer
      if (myParameterInitializer == null) {
        LOG.assertTrue(myLocalVariable != null);
        myParameterInitializer =
            factory.createExpressionFromText(myLocalVariable.getName(), myLocalVariable);
      } else if (myParameterInitializer instanceof PsiArrayInitializerExpression) {
        final PsiExpression newExprArrayInitializer =
            RefactoringUtil.createNewExpressionFromArrayInitializer(
                (PsiArrayInitializerExpression) myParameterInitializer, initializerType);
        myParameterInitializer =
            (PsiExpression) myParameterInitializer.replace(newExprArrayInitializer);
      }

      myInitializerWrapper = new JavaExpressionWrapper(myParameterInitializer);

      // Changing external occurences (the tricky part)

      IntroduceParameterUtil.processUsages(usages, this);

      if (myGenerateDelegate) {
        generateDelegate(myMethodToReplaceIn);
        if (myMethodToReplaceIn != myMethodToSearchFor) {
          final PsiMethod method = generateDelegate(myMethodToSearchFor);
          if (method.getContainingClass().isInterface()) {
            final PsiCodeBlock block = method.getBody();
            if (block != null) {
              block.delete();
            }
          }
        }
      }

      // Changing signature of initial method
      // (signature of myMethodToReplaceIn will be either changed now or have already been changed)
      LOG.assertTrue(initializerType.isValid());
      final FieldConflictsResolver fieldConflictsResolver =
          new FieldConflictsResolver(myParameterName, myMethodToReplaceIn.getBody());
      IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts(
          new UsageInfo(myMethodToReplaceIn), usages, this);
      if (myMethodToSearchFor != myMethodToReplaceIn) {
        IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts(
            new UsageInfo(myMethodToSearchFor), usages, this);
      }
      ChangeContextUtil.clearContextInfo(myParameterInitializer);

      // Replacing expression occurrences
      for (UsageInfo usage : usages) {
        if (usage instanceof ChangedMethodCallInfo) {
          PsiElement element = usage.getElement();

          processChangedMethodCall(element);
        } else if (usage instanceof InternalUsageInfo) {
          PsiElement element = usage.getElement();
          if (element instanceof PsiExpression) {
            element = RefactoringUtil.outermostParenthesizedExpression((PsiExpression) element);
          }
          if (element != null) {
            if (element.getParent() instanceof PsiExpressionStatement) {
              element.getParent().delete();
            } else {
              PsiExpression newExpr = factory.createExpressionFromText(myParameterName, element);
              IntroduceVariableBase.replace((PsiExpression) element, newExpr, myProject);
            }
          }
        }
      }

      if (myLocalVariable != null && myRemoveLocalVariable) {
        myLocalVariable.normalizeDeclaration();
        myLocalVariable.getParent().delete();
      }
      fieldConflictsResolver.fix();
    } catch (IncorrectOperationException ex) {
      LOG.error(ex);
    }
  }
コード例 #7
0
  protected Settings showRefactoringDialog(
      Project project,
      final Editor editor,
      PsiClass parentClass,
      PsiExpression expr,
      PsiType type,
      PsiExpression[] occurrences,
      PsiElement anchorElement,
      PsiElement anchorElementIfAll) {
    final PsiMethod containingMethod =
        PsiTreeUtil.getParentOfType(expr != null ? expr : anchorElement, PsiMethod.class);

    PsiLocalVariable localVariable = null;
    if (expr instanceof PsiReferenceExpression) {
      PsiElement ref = ((PsiReferenceExpression) expr).resolve();
      if (ref instanceof PsiLocalVariable) {
        localVariable = (PsiLocalVariable) ref;
      }
    } else if (anchorElement instanceof PsiLocalVariable) {
      localVariable = (PsiLocalVariable) anchorElement;
    }

    String enteredName = null;
    boolean replaceAllOccurrences = true;

    final AbstractInplaceIntroducer activeIntroducer =
        AbstractInplaceIntroducer.getActiveIntroducer(editor);
    if (activeIntroducer != null) {
      activeIntroducer.stopIntroduce(editor);
      expr = (PsiExpression) activeIntroducer.getExpr();
      localVariable = (PsiLocalVariable) activeIntroducer.getLocalVariable();
      occurrences = (PsiExpression[]) activeIntroducer.getOccurrences();
      enteredName = activeIntroducer.getInputName();
      replaceAllOccurrences = activeIntroducer.isReplaceAllOccurrences();
      type = ((InplaceIntroduceConstantPopup) activeIntroducer).getType();
    }

    for (PsiExpression occurrence : occurrences) {
      if (RefactoringUtil.isAssignmentLHS(occurrence)) {
        String message =
            RefactoringBundle.getCannotRefactorMessage("Selected expression is used for write");
        CommonRefactoringUtil.showErrorHint(
            project, editor, message, REFACTORING_NAME, getHelpID());
        highlightError(project, editor, occurrence);
        return null;
      }
    }

    if (localVariable == null) {
      final PsiElement errorElement = isStaticFinalInitializer(expr);
      if (errorElement != null) {
        String message =
            RefactoringBundle.getCannotRefactorMessage(
                RefactoringBundle.message("selected.expression.cannot.be.a.constant.initializer"));
        CommonRefactoringUtil.showErrorHint(
            project, editor, message, REFACTORING_NAME, getHelpID());
        highlightError(project, editor, errorElement);
        return null;
      }
    } else {
      final PsiExpression initializer = localVariable.getInitializer();
      if (initializer == null) {
        String message =
            RefactoringBundle.getCannotRefactorMessage(
                RefactoringBundle.message(
                    "variable.does.not.have.an.initializer", localVariable.getName()));
        CommonRefactoringUtil.showErrorHint(
            project, editor, message, REFACTORING_NAME, getHelpID());
        return null;
      }
      final PsiElement errorElement = isStaticFinalInitializer(initializer);
      if (errorElement != null) {
        String message =
            RefactoringBundle.getCannotRefactorMessage(
                RefactoringBundle.message(
                    "initializer.for.variable.cannot.be.a.constant.initializer",
                    localVariable.getName()));
        CommonRefactoringUtil.showErrorHint(
            project, editor, message, REFACTORING_NAME, getHelpID());
        highlightError(project, editor, errorElement);
        return null;
      }
    }

    final TypeSelectorManagerImpl typeSelectorManager =
        new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences);
    if (editor != null
        && editor.getSettings().isVariableInplaceRenameEnabled()
        && (expr == null || expr.isPhysical())
        && activeIntroducer == null) {
      myInplaceIntroduceConstantPopup =
          new InplaceIntroduceConstantPopup(
              project,
              editor,
              parentClass,
              expr,
              localVariable,
              occurrences,
              typeSelectorManager,
              anchorElement,
              anchorElementIfAll,
              expr != null ? createOccurrenceManager(expr, parentClass) : null);
      if (myInplaceIntroduceConstantPopup.startInplaceIntroduceTemplate()) {
        return null;
      }
    }

    final IntroduceConstantDialog dialog =
        new IntroduceConstantDialog(
            project,
            parentClass,
            expr,
            localVariable,
            localVariable != null,
            occurrences,
            getParentClass(),
            typeSelectorManager,
            enteredName);
    dialog.setReplaceAllOccurrences(replaceAllOccurrences);
    if (!dialog.showAndGet()) {
      if (occurrences.length > 1) {
        WindowManager.getInstance()
            .getStatusBar(project)
            .setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting"));
      }
      return null;
    }
    return new Settings(
        dialog.getEnteredName(),
        expr,
        occurrences,
        dialog.isReplaceAllOccurrences(),
        true,
        true,
        InitializationPlace.IN_FIELD_DECLARATION,
        dialog.getFieldVisibility(),
        localVariable,
        dialog.getSelectedType(),
        dialog.isDeleteVariable(),
        dialog.getDestinationClass(),
        dialog.isAnnotateAsNonNls(),
        dialog.introduceEnumConstant());
  }
コード例 #8
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);
  }