예제 #1
0
 @Override
 public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
   final PsiElement element = descriptor.getPsiElement();
   if (!(element instanceof PsiReferenceExpression)) {
     return;
   }
   final PsiElement parent = PsiUtil.skipParenthesizedExprUp(element.getParent());
   if (parent instanceof PsiVariable) {
     element.delete();
   }
   if (!(parent instanceof PsiAssignmentExpression)) {
     return;
   }
   final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) parent;
   final PsiExpression lhs = assignmentExpression.getLExpression();
   final PsiExpression rhs = assignmentExpression.getRExpression();
   if (PsiTreeUtil.isAncestor(lhs, element, false)) {
     if (rhs != null) {
       assignmentExpression.replace(rhs);
     } else {
       assignmentExpression.delete();
     }
   } else {
     final PsiElement grandParent = assignmentExpression.getParent();
     if (grandParent instanceof PsiExpressionStatement) {
       grandParent.delete();
     } else {
       assignmentExpression.replace(element);
     }
   }
 }
  /**
   * Allows to check if static import may be performed for the given element.
   *
   * @param element element to check
   * @return target class that may be statically imported if any; <code>null</code> otherwise
   */
  @Nullable
  public static PsiClass getClassToPerformStaticImport(@NotNull PsiElement element) {
    if (!PsiUtil.isLanguageLevel5OrHigher(element)) return null;
    if (!(element instanceof PsiIdentifier)
        || !(element.getParent() instanceof PsiJavaCodeReferenceElement)) {
      return null;
    }
    PsiJavaCodeReferenceElement refExpr = (PsiJavaCodeReferenceElement) element.getParent();
    if (refExpr instanceof PsiMethodReferenceExpression) return null;
    final PsiElement gParent = refExpr.getParent();
    if (gParent instanceof PsiMethodReferenceExpression) return null;
    if (!(gParent instanceof PsiJavaCodeReferenceElement)
        || isParameterizedReference((PsiJavaCodeReferenceElement) gParent)) return null;

    PsiElement resolved = refExpr.resolve();
    if (!(resolved instanceof PsiClass)) {
      return null;
    }
    PsiClass psiClass = (PsiClass) resolved;
    if (PsiUtil.isFromDefaultPackage(psiClass)
        || psiClass.hasModifierProperty(PsiModifier.PRIVATE)
        || psiClass.getQualifiedName() == null) return null;

    final PsiElement ggParent = gParent.getParent();
    if (ggParent instanceof PsiMethodCallExpression) {
      final PsiMethodCallExpression call = (PsiMethodCallExpression) ggParent.copy();
      final PsiElement qualifier = call.getMethodExpression().getQualifier();
      if (qualifier == null) return null;
      qualifier.delete();
      final PsiMethod method = call.resolveMethod();
      if (method != null && method.getContainingClass() != psiClass) return null;
    } else {
      final PsiJavaCodeReferenceElement copy = (PsiJavaCodeReferenceElement) gParent.copy();
      final PsiElement qualifier = copy.getQualifier();
      if (qualifier == null) return null;
      qualifier.delete();
      final PsiElement target = copy.resolve();
      if (target != null && PsiTreeUtil.getParentOfType(target, PsiClass.class) != psiClass)
        return null;
    }

    PsiFile file = refExpr.getContainingFile();
    if (!(file instanceof PsiJavaFile)) return null;
    PsiImportList importList = ((PsiJavaFile) file).getImportList();
    if (importList == null) return null;

    return psiClass;
  }
  private void changeParameter(
      int parameterIndex, JetParameter parameter, JetParameterInfo parameterInfo) {
    ASTNode valOrVarAstNode = parameter.getValOrVarNode();
    PsiElement valOrVarNode = valOrVarAstNode != null ? valOrVarAstNode.getPsi() : null;
    JetValVar valOrVar = parameterInfo.getValOrVar();

    JetPsiFactory psiFactory = JetPsiFactory(getProject());
    if (valOrVarNode != null) {
      if (valOrVar == JetValVar.None) {
        valOrVarNode.delete();
      } else {
        valOrVarNode.replace(psiFactory.createValOrVarNode(valOrVar.toString()).getPsi());
      }
    } else if (valOrVar != JetValVar.None) {
      PsiElement firstChild = parameter.getFirstChild();
      parameter.addBefore(psiFactory.createValOrVarNode(valOrVar.toString()).getPsi(), firstChild);
      parameter.addBefore(psiFactory.createWhiteSpace(), firstChild);
    }

    if (parameterInfo.getIsTypeChanged() && parameter.getTypeReference() != null) {
      String renderedType = parameterInfo.renderType(parameterIndex, this);
      parameter.setTypeReference(psiFactory.createType(renderedType));
    }

    PsiElement identifier = parameter.getNameIdentifier();

    if (identifier != null) {
      //noinspection unchecked
      String newName =
          parameterInfo.getInheritedName((JetFunctionDefinitionUsage<PsiElement>) this);
      identifier.replace(psiFactory.createIdentifier(newName));
    }
  }
예제 #4
0
  public static void removeVariable(GrVariable variable) {
    final GrVariableDeclaration varDecl = (GrVariableDeclaration) variable.getParent();
    final List<GrVariable> variables = Arrays.asList(varDecl.getVariables());
    if (!variables.contains(variable)) {
      throw new IllegalArgumentException();
    }

    final PsiElement parent = varDecl.getParent();
    final ASTNode owner = parent.getNode();
    if (variables.size() == 1 && owner != null) {
      PsiElement next = varDecl.getNextSibling();

      // remove redundant semicolons
      //noinspection ConstantConditions
      while (next != null && next.getNode() != null && next.getNode().getElementType() == mSEMI) {
        PsiElement tmpNext = next.getNextSibling();
        //noinspection ConstantConditions
        next.delete();
        next = tmpNext;
      }

      removeNewLineAfter(varDecl);
      varDecl.delete();
      return;
    }
    variable.delete();
  }
예제 #5
0
 @Override
 public boolean flip(PsiElement left, PsiElement right) {
   if (left instanceof PsiVariable && right instanceof PsiVariable) {
     final PsiElement first = left.getFirstChild();
     if (!(first instanceof PsiModifierList)) {
       return false;
     }
     final PsiElement child = PsiTreeUtil.skipSiblingsForward(first, PsiWhiteSpace.class);
     if (!(child instanceof PsiTypeElement)) {
       return false;
     }
     final PsiElement last = child.getNextSibling();
     if (!(last instanceof PsiWhiteSpace)) {
       return false;
     }
     final PsiElement anchor = right.getFirstChild();
     if (!(anchor instanceof PsiIdentifier)) {
       return false;
     }
     final PsiElement semiColon = right.getLastChild();
     if (!(semiColon instanceof PsiJavaToken)) {
       return false;
     }
     right.addRangeBefore(first, last, anchor);
     left.deleteChildRange(first, last);
     left.add(semiColon);
     semiColon.delete();
     final PsiElement copy = left.copy();
     left.replace(right);
     right.replace(copy);
     return true;
   }
   return false;
 }
  @Override
  protected void performRefactoring(@NotNull UsageInfo[] usages) {
    try {
      for (UsageInfo usage : usages) {
        if (usage instanceof SafeDeleteCustomUsageInfo) {
          ((SafeDeleteCustomUsageInfo) usage).performRefactoring();
        }
      }

      DumbService.allowStartingDumbModeInside(
          DumbModePermission.MAY_START_MODAL,
          () -> {
            for (PsiElement element : myElements) {
              for (SafeDeleteProcessorDelegate delegate :
                  Extensions.getExtensions(SafeDeleteProcessorDelegate.EP_NAME)) {
                if (delegate.handlesElement(element)) {
                  delegate.prepareForDeletion(element);
                }
              }

              element.delete();
            }
          });
    } catch (IncorrectOperationException e) {
      RefactoringUIUtil.processIncorrectOperation(myProject, e);
    }
  }
 private static PsiDeclarationStatement moveDeclarationToReference(
     @NotNull PsiElement referenceElement,
     @NotNull PsiLocalVariable variable,
     @NotNull PsiCodeBlock block)
     throws IncorrectOperationException {
   PsiStatement statement = PsiTreeUtil.getParentOfType(referenceElement, PsiStatement.class);
   assert statement != null;
   if (statement.getParent() instanceof PsiForStatement) {
     statement = (PsiStatement) statement.getParent();
   }
   final PsiElement referenceParent = referenceElement.getParent();
   if (referenceParent instanceof PsiAssignmentExpression) {
     final PsiAssignmentExpression assignmentExpression =
         (PsiAssignmentExpression) referenceParent;
     if (referenceElement.equals(assignmentExpression.getLExpression())) {
       PsiDeclarationStatement newDeclaration =
           createNewDeclaration(variable, assignmentExpression.getRExpression());
       newDeclaration = (PsiDeclarationStatement) block.addBefore(newDeclaration, statement);
       final PsiElement parent = assignmentExpression.getParent();
       assert parent != null;
       parent.delete();
       return newDeclaration;
     }
   }
   return createNewDeclaration(variable, null);
 }
 private static XmlTag createTag(
     @NotNull XmlTag contextTag, @NotNull XmlElementDescriptor descriptor) {
   String namespace = getNamespace(descriptor);
   XmlTag tag = contextTag.createChildTag(descriptor.getName(), namespace, null, false);
   PsiElement lastChild = tag.getLastChild();
   assert lastChild != null;
   lastChild.delete(); // remove XML_EMPTY_ELEMENT_END
   return tag;
 }
예제 #9
0
  private static void fixCommaIfNeeded(@NotNull PsiElement element, boolean willBeLast) {
    PsiElement comma = getComma(element);
    if (willBeLast && comma != null) {
      comma.delete();
    } else if (!willBeLast && comma == null) {
      PsiElement parent = element.getParent();
      assert parent != null;

      parent.addAfter(JetPsiFactory(parent.getProject()).createComma(), element);
    }
  }
  public static PsiElement[] move(
      @NotNull PsiElement container,
      @NotNull PsiElement[] statements,
      boolean generateDefaultInitializers) {
    if (statements.length == 0) {
      return statements;
    }

    Project project = container.getProject();

    List<PsiElement> resultStatements = new ArrayList<PsiElement>();
    List<KtProperty> propertiesDeclarations = new ArrayList<KtProperty>();

    // Dummy element to add new declarations at the beginning
    KtPsiFactory psiFactory = KtPsiFactoryKt.KtPsiFactory(project);
    PsiElement dummyFirstStatement =
        container.addBefore(psiFactory.createExpression("dummyStatement"), statements[0]);

    try {
      SearchScope scope = new LocalSearchScope(container);
      int lastStatementOffset = statements[statements.length - 1].getTextRange().getEndOffset();

      for (PsiElement statement : statements) {
        if (needToDeclareOut(statement, lastStatementOffset, scope)) {
          if (statement instanceof KtProperty
              && ((KtProperty) statement).getInitializer() != null) {
            KtProperty property = (KtProperty) statement;
            KtProperty declaration =
                createVariableDeclaration(property, generateDefaultInitializers);
            declaration = (KtProperty) container.addBefore(declaration, dummyFirstStatement);
            propertiesDeclarations.add(declaration);
            container.addAfter(psiFactory.createNewLine(), declaration);

            KtBinaryExpression assignment = createVariableAssignment(property);
            resultStatements.add(property.replace(assignment));
          } else {
            PsiElement newStatement = container.addBefore(statement, dummyFirstStatement);
            container.addAfter(psiFactory.createNewLine(), newStatement);
            container.deleteChildRange(statement, statement);
          }
        } else {
          resultStatements.add(statement);
        }
      }
    } finally {
      dummyFirstStatement.delete();
    }

    ShortenReferences.DEFAULT.process(propertiesDeclarations);

    return PsiUtilCore.toPsiElementArray(resultStatements);
  }
예제 #11
0
 private static void deleteOverrideAnnotationIfFound(PsiMethod oMethod) {
   final PsiAnnotation annotation =
       AnnotationUtil.findAnnotation(oMethod, CommonClassNames.JAVA_LANG_OVERRIDE);
   if (annotation != null) {
     PsiElement prev = annotation.getPrevSibling();
     PsiElement next = annotation.getNextSibling();
     if ((prev == null || org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLineFeed(prev))
         && org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLineFeed(next)) {
       next.delete();
     }
     annotation.delete();
   }
 }
예제 #12
0
 static void deleteWholeStatement(PsiElement element, PsiElementFactory factory)
     throws IncorrectOperationException {
   // just delete it altogether
   if (element.getParent() instanceof PsiExpressionStatement) {
     PsiExpressionStatement parent = (PsiExpressionStatement) element.getParent();
     if (parent.getParent() instanceof PsiCodeBlock) {
       parent.delete();
     } else {
       // replace with empty statement (to handle with 'if (..) i=0;' )
       parent.replace(createStatementIfNeeded(null, factory, element));
     }
   } else {
     element.delete();
   }
 }
예제 #13
0
  public void setInitializer(@Nullable PsiExpression psiExpression)
      throws IncorrectOperationException {
    GrExpression oldInitializer = getInitializerGroovy();
    if (psiExpression == null) {
      if (oldInitializer != null) {
        oldInitializer.delete();
        PsiElement assign = findChildByType(GroovyTokenTypes.mASSIGN);
        if (assign != null) {
          assign.delete();
        }
      }
      return;
    }

    GrExpression newInitializer =
        GroovyPsiElementFactory.getInstance(getProject())
            .createExpressionFromText(psiExpression.getText());
    if (oldInitializer != null) {
      oldInitializer.replaceWithExpression(newInitializer, true);
    } else {
      getNode().addLeaf(GroovyTokenTypes.mASSIGN, "=", getNode().getLastChildNode());
      addAfter(newInitializer, getLastChild());
    }
  }
  private void setModifierPropertyInternal(String name, boolean doSet) {
    if (doSet) {
      PsiElement modifier =
          GroovyPsiElementFactory.getInstance(getProject()).createModifierFromText(name);
      PsiElement anchor = findAnchor(name);
      addAfter(modifier, anchor);
    } else {
      final PsiElement[] modifiers = findChildrenByType(TokenSets.MODIFIERS, PsiElement.class);
      for (PsiElement modifier : modifiers) {
        if (name.equals(modifier.getText())) {
          deleteChildRange(modifier, modifier);
          break;
        }
      }

      if (getTextLength() == 0) {
        final PsiElement nextSibling = getNextSibling();
        if (nextSibling != null
            && TokenSets.WHITE_SPACES_SET.contains(nextSibling.getNode().getElementType())) {
          nextSibling.delete();
        }
      }
    }
  }
 public void deletePropertyIfExist(String key, PropertiesFile file) {
   final IProperty property = file.findPropertyByKey(key);
   if (property != null && myKeysOrder != null) {
     boolean keyExistInOtherPropertiesFiles = false;
     for (PropertiesFile propertiesFile : myResourceBundle.getPropertiesFiles()) {
       if (!propertiesFile.equals(file) && propertiesFile.findPropertyByKey(key) != null) {
         keyExistInOtherPropertiesFiles = true;
         break;
       }
     }
     if (!keyExistInOtherPropertiesFiles) {
       myKeysOrder.remove(key);
     }
   }
   if (property != null) {
     PsiElement anElement = property.getPsiElement();
     if (anElement instanceof PomTargetPsiElement) {
       final PomTarget xmlProperty = ((PomTargetPsiElement) anElement).getTarget();
       LOG.assertTrue(xmlProperty instanceof XmlProperty);
       anElement = ((XmlProperty) xmlProperty).getNavigationElement();
     }
     anElement.delete();
   }
 }
  private static void processMethodUsage(
      PsiElement element,
      JavaChangeInfo changeInfo,
      boolean toChangeArguments,
      boolean toCatchExceptions,
      GrClosureSignatureUtil.ArgInfo<PsiElement>[] map,
      PsiSubstitutor substitutor) {
    if (map == null) return;
    if (changeInfo.isNameChanged()) {
      if (element instanceof GrReferenceElement) {
        element = ((GrReferenceElement) element).handleElementRename(changeInfo.getNewName());
      }
    }
    if (toChangeArguments) {
      JavaParameterInfo[] parameters = changeInfo.getNewParameters();
      GrArgumentList argumentList = PsiUtil.getArgumentsList(element);
      GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(element.getProject());
      if (argumentList == null) {
        if (element instanceof GrEnumConstant) {
          argumentList = factory.createArgumentList();
          argumentList = (GrArgumentList) element.add(argumentList);
        } else {
          return;
        }
      }
      Set<PsiElement> argsToDelete = new HashSet<PsiElement>(map.length * 2);
      for (GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo : map) {
        argsToDelete.addAll(argInfo.args);
      }

      for (JavaParameterInfo parameter : parameters) {
        int index = parameter.getOldIndex();
        if (index >= 0) {
          argsToDelete.removeAll(map[index].args);
        }
      }

      for (PsiElement arg : argsToDelete) {
        arg.delete();
      }

      boolean skipOptionals = false;
      PsiElement anchor = null; // PsiTreeUtil.getChildOfAnyType(argumentList, GrExpression.class,
      // GrNamedArgument.class);
      for (int i = 0; i < parameters.length; i++) {
        JavaParameterInfo parameter = parameters[i];
        int index = parameter.getOldIndex();
        if (index >= 0) {
          GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo = map[index];
          List<PsiElement> arguments = argInfo.args;
          if (argInfo.isMultiArg) { // arguments for Map and varArg
            if ((i != 0
                    || !(!arguments.isEmpty()
                        && arguments.iterator().next() instanceof GrNamedArgument))
                && (i != parameters.length - 1 || !parameter.isVarargType())) {
              final PsiType type =
                  parameter.createType(
                      changeInfo.getMethod().getParameterList(), argumentList.getManager());
              final GrExpression arg =
                  GroovyRefactoringUtil.generateArgFromMultiArg(
                      substitutor, arguments, type, element.getProject());
              for (PsiElement argument : arguments) {
                argument.delete();
              }
              anchor = argumentList.addAfter(arg, anchor);
              JavaCodeStyleManager.getInstance(anchor.getProject()).shortenClassReferences(anchor);
            }
          } else { // arguments for simple parameters
            if (arguments.size() == 1) { // arg exists
              PsiElement arg = arguments.iterator().next();
              if (i == parameters.length - 1 && parameter.isVarargType()) {
                if (arg instanceof GrSafeCastExpression) {
                  PsiElement expr = ((GrSafeCastExpression) arg).getOperand();
                  if (expr instanceof GrListOrMap && !((GrListOrMap) expr).isMap()) {
                    final PsiElement copy = expr.copy();
                    PsiElement[] newVarargs = ((GrListOrMap) copy).getInitializers();
                    for (PsiElement vararg : newVarargs) {
                      anchor = argumentList.addAfter(vararg, anchor);
                    }
                    arg.delete();
                    continue;
                  }
                }
              }

              PsiElement curArg = getNextOfType(argumentList, anchor, GrExpression.class);
              if (curArg == arg) {
                anchor = arg;
              } else {
                final PsiElement copy = arg.copy();
                anchor = argumentList.addAfter(copy, anchor);
                arg.delete();
              }
            } else { // arg is skipped. Parameter is optional
              skipOptionals = true;
            }
          }
        } else {
          if (skipOptionals && isParameterOptional(parameter)) continue;

          if (forceOptional(parameter)) {
            skipOptionals = true;
            continue;
          }
          try {

            GrExpression value = createDefaultValue(factory, changeInfo, parameter, argumentList);
            if (i > 0 && (value == null || anchor == null)) {
              PsiElement comma =
                  Factory.createSingleLeafElement(
                          GroovyTokenTypes.mCOMMA,
                          ",",
                          0,
                          1,
                          SharedImplUtil.findCharTableByTree(argumentList.getNode()),
                          argumentList.getManager())
                      .getPsi();
              if (anchor == null) anchor = argumentList.getLeftParen();

              anchor = argumentList.addAfter(comma, anchor);
            }
            if (value != null) {
              anchor = argumentList.addAfter(value, anchor);
            }
          } catch (IncorrectOperationException e) {
            LOG.error(e.getMessage());
          }
        }
      }

      GrCall call = GroovyRefactoringUtil.getCallExpressionByMethodReference(element);
      if (argumentList.getText().trim().isEmpty()
          && (call == null || !PsiImplUtil.hasClosureArguments(call))) {
        argumentList = argumentList.replaceWithArgumentList(factory.createArgumentList());
      }
      CodeStyleManager.getInstance(argumentList.getProject()).reformat(argumentList);
    }

    if (toCatchExceptions) {
      final ThrownExceptionInfo[] exceptionInfos = changeInfo.getNewExceptions();
      PsiClassType[] exceptions = getExceptions(exceptionInfos, element, element.getManager());
      fixExceptions(element, exceptions);
    }
  }
예제 #17
0
 // Delete element if it doesn't contain children of a given type
 public static <T extends PsiElement> void deleteChildlessElement(
     PsiElement element, Class<T> childClass) {
   if (PsiTreeUtil.getChildrenOfType(element, childClass) == null) {
     element.delete();
   }
 }
예제 #18
0
 /**
  * @param sideEffects if null, delete usages, otherwise collect side effects
  * @return true if there are at least one unrecoverable side effect found, false if no side
  *     effects, null if read usage found (may happen if interval between fix creation in invoke()
  *     call was long enough)
  * @throws com.intellij.util.IncorrectOperationException
  */
 static Boolean processUsage(
     PsiElement element, PsiVariable variable, List<PsiElement> sideEffects, int deleteMode)
     throws IncorrectOperationException {
   if (!element.isValid()) return null;
   PsiElementFactory factory =
       JavaPsiFacade.getInstance(variable.getProject()).getElementFactory();
   while (element != null) {
     if (element instanceof PsiAssignmentExpression) {
       PsiAssignmentExpression expression = (PsiAssignmentExpression) element;
       PsiExpression lExpression = expression.getLExpression();
       // there should not be read access to the variable, otherwise it is not unused
       if (!(lExpression instanceof PsiReferenceExpression)
           || variable != ((PsiReferenceExpression) lExpression).resolve()) {
         return null;
       }
       PsiExpression rExpression = expression.getRExpression();
       rExpression = PsiUtil.deparenthesizeExpression(rExpression);
       if (rExpression == null) return true;
       // replace assignment with expression and resimplify
       boolean sideEffectFound = checkSideEffects(rExpression, variable, sideEffects);
       if (!(element.getParent() instanceof PsiExpressionStatement)
           || PsiUtil.isStatement(rExpression)) {
         if (deleteMode == MAKE_STATEMENT
             || deleteMode == DELETE_ALL
                 && !(element.getParent() instanceof PsiExpressionStatement)) {
           element = replaceElementWithExpression(rExpression, factory, element);
           while (element.getParent() instanceof PsiParenthesizedExpression) {
             element = element.getParent().replace(element);
           }
           List<PsiElement> references = new ArrayList<PsiElement>();
           collectReferences(element, variable, references);
           deleteReferences(variable, references, deleteMode);
         } else if (deleteMode == DELETE_ALL) {
           deleteWholeStatement(element, factory);
         }
         return true;
       } else {
         if (deleteMode != CANCEL) {
           deleteWholeStatement(element, factory);
         }
         return !sideEffectFound;
       }
     } else if (element instanceof PsiExpressionStatement && deleteMode != CANCEL) {
       final PsiElement parent = element.getParent();
       if (parent instanceof PsiIfStatement
           || parent instanceof PsiLoopStatement
               && ((PsiLoopStatement) parent).getBody() == element) {
         element.replace(
             JavaPsiFacade.getElementFactory(element.getProject())
                 .createStatementFromText(";", element));
       } else {
         element.delete();
       }
       break;
     } else if (element instanceof PsiVariable && element == variable) {
       PsiExpression expression = variable.getInitializer();
       if (expression != null) {
         expression = PsiUtil.deparenthesizeExpression(expression);
       }
       boolean sideEffectsFound = checkSideEffects(expression, variable, sideEffects);
       if (expression != null
           && PsiUtil.isStatement(expression)
           && variable instanceof PsiLocalVariable
           && !(variable.getParent() instanceof PsiDeclarationStatement
               && ((PsiDeclarationStatement) variable.getParent()).getDeclaredElements().length
                   > 1)) {
         if (deleteMode == MAKE_STATEMENT) {
           element = element.replace(createStatementIfNeeded(expression, factory, element));
           List<PsiElement> references = new ArrayList<PsiElement>();
           collectReferences(element, variable, references);
           deleteReferences(variable, references, deleteMode);
         } else if (deleteMode == DELETE_ALL) {
           element.delete();
         }
         return true;
       } else {
         if (deleteMode != CANCEL) {
           if (element instanceof PsiField) {
             ((PsiField) element).normalizeDeclaration();
           }
           element.delete();
         }
         return !sideEffectsFound;
       }
     }
     element = element.getParent();
   }
   return true;
 }
  public void replace(final ReplacementInfo info, ReplaceOptions options) {
    PsiElement elementToReplace = info.getMatch(0);
    PsiElement elementParent = elementToReplace.getParent();
    String replacementToMake = info.getReplacement();
    Project project = myContext.getProject();
    PsiElement el = findRealSubstitutionElement(elementToReplace);
    boolean listContext = isListContext(el);

    if (el instanceof PsiAnnotation && !StringUtil.startsWithChar(replacementToMake, '@')) {
      replacementToMake = "@" + replacementToMake;
    }

    PsiElement[] statements =
        ReplacerUtil.createTreeForReplacement(
            replacementToMake,
            el instanceof PsiMember && !isSymbolReplacement(el)
                ? PatternTreeContext.Class
                : PatternTreeContext.Block,
            myContext);

    if (listContext) {
      if (statements.length > 1) {
        elementParent.addRangeBefore(
            statements[0], statements[statements.length - 1], elementToReplace);
      } else if (statements.length == 1) {
        PsiElement replacement = getMatchExpr(statements[0], elementToReplace);

        handleModifierList(el, replacement);
        replacement = handleSymbolReplacement(replacement, el);

        if (replacement instanceof PsiTryStatement) {
          final List<PsiCatchSection> unmatchedCatchSections =
              el.getUserData(JavaMatchingVisitor.UNMATCHED_CATCH_SECTION_CONTENT_VAR_KEY);
          final PsiCatchSection[] catches = ((PsiTryStatement) replacement).getCatchSections();

          if (unmatchedCatchSections != null) {
            for (int i = unmatchedCatchSections.size() - 1; i >= 0; --i) {
              final PsiParameter parameter = unmatchedCatchSections.get(i).getParameter();
              final PsiElementFactory elementFactory =
                  JavaPsiFacade.getInstance(project).getElementFactory();
              final PsiCatchSection catchSection =
                  elementFactory.createCatchSection(parameter.getType(), parameter.getName(), null);

              catchSection.getCatchBlock().replace(unmatchedCatchSections.get(i).getCatchBlock());
              replacement.addAfter(catchSection, catches[catches.length - 1]);
              replacement.addBefore(createWhiteSpace(replacement), replacement.getLastChild());
            }
          }
        }

        try {
          final PsiElement inserted = elementParent.addBefore(replacement, elementToReplace);

          if (replacement instanceof PsiComment
              && (elementParent instanceof PsiIfStatement
                  || elementParent instanceof PsiLoopStatement)) {
            elementParent.addAfter(createSemicolon(replacement), inserted);
          }
        } catch (IncorrectOperationException e) {
          elementToReplace.replace(replacement);
        }
      }
    } else if (statements.length > 0) {
      PsiElement replacement =
          ReplacerUtil.copySpacesAndCommentsBefore(
              elementToReplace, statements, replacementToMake, elementParent);

      replacement = getMatchExpr(replacement, elementToReplace);

      if (replacement instanceof PsiStatement
          && !(replacement.getLastChild() instanceof PsiJavaToken)
          && !(replacement.getLastChild() instanceof PsiComment)) {
        // assert w/o ;
        final PsiElement prevLastChildInParent = replacement.getLastChild().getPrevSibling();

        if (prevLastChildInParent != null) {
          elementParent.addRangeBefore(replacement.getFirstChild(), prevLastChildInParent, el);
        } else {
          elementParent.addBefore(replacement.getFirstChild(), el);
        }

        el.getNode().getTreeParent().removeChild(el.getNode());
      } else {
        // preserve comments
        handleModifierList(el, replacement);

        if (replacement instanceof PsiClass) {
          // modifier list
          final PsiStatement[] searchStatements = getCodeBlock().getStatements();
          if (searchStatements.length > 0
              && searchStatements[0] instanceof PsiDeclarationStatement
              && ((PsiDeclarationStatement) searchStatements[0]).getDeclaredElements()[0]
                  instanceof PsiClass) {
            final PsiClass replaceClazz = (PsiClass) replacement;
            final PsiClass queryClazz =
                (PsiClass) ((PsiDeclarationStatement) searchStatements[0]).getDeclaredElements()[0];
            final PsiClass clazz = (PsiClass) el;

            if (replaceClazz.getExtendsList().getTextLength() == 0
                && queryClazz.getExtendsList().getTextLength() == 0
                && clazz.getExtendsList().getTextLength() != 0) {
              replaceClazz.addBefore(
                  clazz.getExtendsList().getPrevSibling(),
                  replaceClazz.getExtendsList()); // whitespace
              replaceClazz
                  .getExtendsList()
                  .addRange(
                      clazz.getExtendsList().getFirstChild(),
                      clazz.getExtendsList().getLastChild());
            }

            if (replaceClazz.getImplementsList().getTextLength() == 0
                && queryClazz.getImplementsList().getTextLength() == 0
                && clazz.getImplementsList().getTextLength() != 0) {
              replaceClazz.addBefore(
                  clazz.getImplementsList().getPrevSibling(),
                  replaceClazz.getImplementsList()); // whitespace
              replaceClazz
                  .getImplementsList()
                  .addRange(
                      clazz.getImplementsList().getFirstChild(),
                      clazz.getImplementsList().getLastChild());
            }

            if (replaceClazz.getTypeParameterList().getTextLength() == 0
                && queryClazz.getTypeParameterList().getTextLength() == 0
                && clazz.getTypeParameterList().getTextLength() != 0) {
              // skip < and >
              replaceClazz.getTypeParameterList().replace(clazz.getTypeParameterList());
            }
          }
        }

        replacement = handleSymbolReplacement(replacement, el);

        el.replace(replacement);
      }
    } else {
      final PsiElement nextSibling = el.getNextSibling();
      el.delete();
      if (nextSibling instanceof PsiWhiteSpace && nextSibling.isValid()) {
        nextSibling.delete();
      }
    }

    if (listContext) {
      final int matchSize = info.getMatchesCount();

      for (int i = 0; i < matchSize; ++i) {
        PsiElement matchElement = info.getMatch(i);
        PsiElement element = findRealSubstitutionElement(matchElement);

        if (element == null) continue;
        PsiElement firstToDelete = element;
        PsiElement lastToDelete = element;
        PsiElement prevSibling = element.getPrevSibling();
        PsiElement nextSibling = element.getNextSibling();

        if (prevSibling instanceof PsiWhiteSpace) {
          firstToDelete = prevSibling;
          prevSibling = prevSibling != null ? prevSibling.getPrevSibling() : null;
        } else if (prevSibling == null && nextSibling instanceof PsiWhiteSpace) {
          lastToDelete = nextSibling;
        }

        if (nextSibling instanceof XmlText && i + 1 < matchSize) {
          final PsiElement next = info.getMatch(i + 1);
          if (next != null && next == nextSibling.getNextSibling()) {
            lastToDelete = nextSibling;
          }
        }

        if (element instanceof PsiExpression) {
          final PsiElement parent = element.getParent().getParent();
          if ((parent instanceof PsiCall || parent instanceof PsiAnonymousClass)
              && prevSibling instanceof PsiJavaToken
              && ((PsiJavaToken) prevSibling).getTokenType() == JavaTokenType.COMMA) {
            firstToDelete = prevSibling;
          }
        } else if (element instanceof PsiParameter
            && prevSibling instanceof PsiJavaToken
            && ((PsiJavaToken) prevSibling).getTokenType() == JavaTokenType.COMMA) {
          firstToDelete = prevSibling;
        }

        element.getParent().deleteChildRange(firstToDelete, lastToDelete);
      }
    }
  }
 @Override
 public void invoke(@NotNull Project project, Editor editor, JetFile file)
     throws IncorrectOperationException {
   element.delete();
 }
예제 #21
0
  private void tryToMoveInitializers(
      PsiMethod constructor,
      HashSet<PsiMethod> subConstructors,
      LinkedHashSet<PsiField> movedFields)
      throws IncorrectOperationException {
    final LinkedHashMap<PsiField, Initializer> fieldsToInitializers =
        new LinkedHashMap<PsiField, Initializer>();
    boolean anyFound = false;

    for (PsiField field : movedFields) {
      PsiStatement commonInitializer = null;
      final ArrayList<PsiElement> fieldInitializersToRemove = new ArrayList<PsiElement>();
      for (PsiMethod subConstructor : subConstructors) {
        commonInitializer =
            hasCommonInitializer(
                commonInitializer, subConstructor, field, fieldInitializersToRemove);
        if (commonInitializer == null) break;
      }
      if (commonInitializer != null) {
        final ParametersAndMovedFieldsUsedCollector visitor =
            new ParametersAndMovedFieldsUsedCollector(movedFields);
        commonInitializer.accept(visitor);
        fieldsToInitializers.put(
            field,
            new Initializer(
                commonInitializer,
                visitor.getUsedFields(),
                visitor.getUsedParameters(),
                fieldInitializersToRemove));
        anyFound = true;
      }
    }

    if (!anyFound) return;

    {
      final Set<PsiField> initializedFields = fieldsToInitializers.keySet();
      Set<PsiField> unmovable =
          RefactoringUtil.transitiveClosure(
              new RefactoringUtil.Graph<PsiField>() {
                public Set<PsiField> getVertices() {
                  return initializedFields;
                }

                public Set<PsiField> getTargets(PsiField source) {
                  return fieldsToInitializers.get(source).movedFieldsUsed;
                }
              },
              new Condition<PsiField>() {
                public boolean value(PsiField object) {
                  return !initializedFields.contains(object);
                }
              });

      for (PsiField psiField : unmovable) {
        fieldsToInitializers.remove(psiField);
      }
    }

    final PsiElementFactory factory = JavaPsiFacade.getElementFactory(myProject);

    if (constructor == null) {
      constructor = (PsiMethod) myTargetSuperClass.add(factory.createConstructor());
      final String visibilityModifier =
          VisibilityUtil.getVisibilityModifier(myTargetSuperClass.getModifierList());
      PsiUtil.setModifierProperty(constructor, visibilityModifier, true);
    }

    ArrayList<PsiField> initializedFields = new ArrayList<PsiField>(fieldsToInitializers.keySet());

    Collections.sort(
        initializedFields,
        new Comparator<PsiField>() {
          public int compare(PsiField field1, PsiField field2) {
            Initializer i1 = fieldsToInitializers.get(field1);
            Initializer i2 = fieldsToInitializers.get(field2);
            if (i1.movedFieldsUsed.contains(field2)) return 1;
            if (i2.movedFieldsUsed.contains(field1)) return -1;
            return 0;
          }
        });

    for (final PsiField initializedField : initializedFields) {
      Initializer initializer = fieldsToInitializers.get(initializedField);

      // correct constructor parameters and subConstructors super calls
      final PsiParameterList parameterList = constructor.getParameterList();
      for (final PsiParameter parameter : initializer.usedParameters) {
        parameterList.add(parameter);
      }

      for (final PsiMethod subConstructor : subConstructors) {
        modifySuperCall(subConstructor, initializer.usedParameters);
      }

      PsiStatement assignmentStatement =
          (PsiStatement) constructor.getBody().add(initializer.initializer);

      PsiManager manager = PsiManager.getInstance(myProject);
      ChangeContextUtil.decodeContextInfo(
          assignmentStatement,
          myTargetSuperClass,
          RefactoringChangeUtil.createThisExpression(manager, null));
      for (PsiElement psiElement : initializer.statementsToRemove) {
        psiElement.delete();
      }
    }
  }