private static boolean allSuperMethodsSelectedToDelete(
     List<PsiMethod> unselectedMethods, PsiMethod method) {
   final ArrayList<PsiMethod> superMethods =
       new ArrayList<>(Arrays.asList(method.findSuperMethods()));
   superMethods.retainAll(unselectedMethods);
   return superMethods.isEmpty();
 }
    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;

      AllowedValues a2 = (AllowedValues) o;
      if (canBeOred != a2.canBeOred) {
        return false;
      }
      Set<PsiAnnotationMemberValue> v1 =
          new THashSet<PsiAnnotationMemberValue>(Arrays.asList(values));
      Set<PsiAnnotationMemberValue> v2 =
          new THashSet<PsiAnnotationMemberValue>(Arrays.asList(a2.values));
      if (v1.size() != v2.size()) {
        return false;
      }
      for (PsiAnnotationMemberValue value : v1) {
        for (PsiAnnotationMemberValue value2 : v2) {
          if (same(value, value2, value.getManager())) {
            v2.remove(value2);
            break;
          }
        }
      }
      return v2.isEmpty();
    }
  @Nullable
  private PsiAnnotation findNullabilityAnnotation(
      @NotNull PsiModifierListOwner owner, boolean checkBases, boolean nullable) {
    Set<String> qNames = ContainerUtil.newHashSet(nullable ? getNullables() : getNotNulls());
    PsiAnnotation annotation =
        checkBases && (owner instanceof PsiClass || owner instanceof PsiMethod)
            ? AnnotationUtil.findAnnotationInHierarchy(owner, qNames)
            : AnnotationUtil.findAnnotation(owner, qNames);
    if (annotation != null) {
      return annotation;
    }

    if (owner instanceof PsiParameter
        && !TypeConversionUtil.isPrimitiveAndNotNull(((PsiParameter) owner).getType())) {
      // even if javax.annotation.Nullable is not configured, it should still take precedence over
      // ByDefault annotations
      if (AnnotationUtil.isAnnotated(
          owner,
          nullable ? Arrays.asList(DEFAULT_NOT_NULLS) : Arrays.asList(DEFAULT_NULLABLES),
          checkBases,
          false)) {
        return null;
      }
      return findContainerAnnotation(
          owner,
          nullable
              ? "javax.annotation.ParametersAreNullableByDefault"
              : "javax.annotation.ParametersAreNonnullByDefault");
    }
    return null;
  }
  public static SafeDeleteProcessor createInstance(
      Project project,
      @Nullable Runnable prepareSuccessfulCallBack,
      PsiElement[] elementsToDelete,
      boolean isSearchInComments,
      boolean isSearchNonJava,
      boolean askForAccessors) {
    ArrayList<PsiElement> elements = new ArrayList<PsiElement>(Arrays.asList(elementsToDelete));
    HashSet<PsiElement> elementsToDeleteSet =
        new HashSet<PsiElement>(Arrays.asList(elementsToDelete));

    for (PsiElement psiElement : elementsToDelete) {
      for (SafeDeleteProcessorDelegate delegate :
          Extensions.getExtensions(SafeDeleteProcessorDelegate.EP_NAME)) {
        if (delegate.handlesElement(psiElement)) {
          Collection<PsiElement> addedElements =
              delegate.getAdditionalElementsToDelete(
                  psiElement, elementsToDeleteSet, askForAccessors);
          if (addedElements != null) {
            elements.addAll(addedElements);
          }
          break;
        }
      }
    }

    return new SafeDeleteProcessor(
        project,
        prepareSuccessfulCallBack,
        PsiUtilCore.toPsiElementArray(elements),
        isSearchInComments,
        isSearchNonJava);
  }
  public Collection<Module> getValidModules() {
    if (TEST_PACKAGE.equals(myData.TEST_OBJECT) || TEST_PATTERN.equals(myData.TEST_OBJECT)) {
      return Arrays.asList(ModuleManager.getInstance(getProject()).getModules());
    }
    try {
      myData.getTestObject(getProject(), this).checkConfiguration();
    } catch (RuntimeConfigurationError e) {
      return Arrays.asList(ModuleManager.getInstance(getProject()).getModules());
    } catch (RuntimeConfigurationException e) {
      // ignore
    }

    return JavaRunConfigurationModule.getModulesForClass(getProject(), myData.getMainClassName());
  }
    public MultiMap<PsiElement, String> findConflicts(Ref<UsageInfo[]> refUsages) {
      MultiMap<PsiElement, String> conflictDescriptions = new MultiMap<PsiElement, String>();
      addMethodConflicts(conflictDescriptions);
      Set<UsageInfo> usagesSet = new HashSet<UsageInfo>(Arrays.asList(refUsages.get()));
      RenameUtil.removeConflictUsages(usagesSet);
      if (myChangeInfo.isVisibilityChanged()) {
        try {
          addInaccessibilityDescriptions(usagesSet, conflictDescriptions);
        } catch (IncorrectOperationException e) {
          LOG.error(e);
        }
      }

      for (UsageInfo usageInfo : usagesSet) {
        if (usageInfo instanceof OverriderUsageInfo) {
          final PsiMethod method = (PsiMethod) usageInfo.getElement();
          final PsiMethod baseMethod = ((OverriderUsageInfo) usageInfo).getBaseMethod();
          final int delta =
              baseMethod.getParameterList().getParametersCount()
                  - method.getParameterList().getParametersCount();
          if (delta > 0) {
            final boolean[] toRemove = myChangeInfo.toRemoveParm();
            if (toRemove[
                toRemove.length - 1]) { // todo check if implicit parameter is not the last one
              conflictDescriptions.putValue(
                  baseMethod, "Implicit last parameter should not be deleted");
            }
          }
        }
      }

      return conflictDescriptions;
    }
  /**
   * Adds all code methods of clazz add its super classes to signatures. Doesn't walk into
   * interfaces because all methods from them will be overloaded in any case. Besides Some of
   * interfaces came from delegates and they should be visited during the following processing.
   *
   * @param clazz current class
   * @param substitutor super class substitutor of clazz
   * @param signatures map to initialize
   * @param classes already visited classes
   */
  private static void initializeSignatures(
      PsiClass clazz,
      PsiSubstitutor substitutor,
      Map<MethodSignature, PsiMethod> signatures,
      Set<PsiClass> classes) {
    if (clazz.isInterface()) return;

    if (classes.add(clazz)) {
      final List<PsiMethod> methods;
      if (clazz instanceof GrTypeDefinition) {
        methods = new ArrayList<PsiMethod>();
        GrClassImplUtil.collectMethodsFromBody((GrTypeDefinition) clazz, methods);
      } else {
        methods = Arrays.asList(clazz.getMethods());
      }

      for (PsiMethod method : methods) {
        addMethodChecked(signatures, method, substitutor, null);
      }

      for (PsiClassType type : getSuperTypes(clazz)) {
        final PsiClassType.ClassResolveResult result = type.resolveGenerics();
        final PsiClass superClass = result.getElement();
        if (superClass == null) continue;
        final PsiSubstitutor superClassSubstitutor =
            TypeConversionUtil.getSuperClassSubstitutor(superClass, clazz, substitutor);
        initializeSignatures(superClass, superClassSubstitutor, signatures, classes);
      }
    }
  }
예제 #8
0
 @NotNull
 public static PsiElement[] findSuperElements(@NotNull PsiElement element) {
   if (element instanceof PsiClass) {
     PsiClass aClass = (PsiClass) element;
     List<PsiClass> allSupers = new ArrayList<>(Arrays.asList(aClass.getSupers()));
     for (Iterator<PsiClass> iterator = allSupers.iterator(); iterator.hasNext(); ) {
       PsiClass superClass = iterator.next();
       if (CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName()))
         iterator.remove();
     }
     return allSupers.toArray(new PsiClass[allSupers.size()]);
   }
   if (element instanceof PsiMethod) {
     PsiMethod method = (PsiMethod) element;
     if (method.isConstructor()) {
       PsiMethod constructorInSuper = PsiSuperMethodUtil.findConstructorInSuper(method);
       if (constructorInSuper != null) {
         return new PsiMethod[] {constructorInSuper};
       }
     } else {
       PsiMethod[] superMethods = method.findSuperMethods(false);
       if (superMethods.length == 0) {
         PsiMethod superMethod = getSiblingInheritedViaSubClass(method);
         if (superMethod != null) {
           superMethods = new PsiMethod[] {superMethod};
         }
       }
       return superMethods;
     }
   }
   return PsiElement.EMPTY_ARRAY;
 }
예제 #9
0
  @NotNull
  public UsageInfo[] findUsages() {
    myRenamers.clear();
    ArrayList<UsageInfo> result = new ArrayList<UsageInfo>();

    List<PsiElement> elements = new ArrayList<PsiElement>(myAllRenames.keySet());
    //noinspection ForLoopReplaceableByForEach
    for (int i = 0; i < elements.size(); i++) {
      PsiElement element = elements.get(i);
      final String newName = myAllRenames.get(element);
      final UsageInfo[] usages =
          RenameUtil.findUsages(
              element, newName, mySearchInComments, mySearchTextOccurrences, myAllRenames);
      final List<UsageInfo> usagesList = Arrays.asList(usages);
      result.addAll(usagesList);

      for (AutomaticRenamerFactory factory : myRenamerFactories) {
        if (factory.isApplicable(element)) {
          myRenamers.add(factory.createRenamer(element, newName, usagesList));
        }
      }

      for (AutomaticRenamerFactory factory :
          Extensions.getExtensions(AutomaticRenamerFactory.EP_NAME)) {
        if (factory.getOptionName() == null && factory.isApplicable(element)) {
          myRenamers.add(factory.createRenamer(element, newName, usagesList));
        }
      }
    }
    UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]);
    usageInfos = UsageViewUtil.removeDuplicatedUsages(usageInfos);
    return usageInfos;
  }
  private static void collectMethods(
      PsiClass currentClass,
      PsiSubstitutor currentClassSubstitutor,
      boolean shouldProcessDeprecated,
      GrTypeDefinition classToDelegateTo,
      Collection<PsiMethod> collector,
      boolean keepParameterAnnotations) {
    final List<PsiMethod> methods;
    if (currentClass instanceof GrTypeDefinition) {
      methods = new ArrayList<PsiMethod>();
      GrClassImplUtil.collectMethodsFromBody((GrTypeDefinition) currentClass, methods);
    } else {
      methods = Arrays.asList(currentClass.getMethods());
    }

    for (PsiMethod method : methods) {
      if (method.isConstructor() || method.hasModifierProperty(PsiModifier.STATIC)) continue;
      if (overridesObjectOrGroovyObject(method)) continue;
      if (!shouldProcessDeprecated
          && PsiImplUtil.getAnnotation(method, CommonClassNames.JAVA_LANG_DEPRECATED) != null)
        continue;
      collector.add(
          generateDelegateMethod(
              method, classToDelegateTo, currentClassSubstitutor, keepParameterAnnotations));
    }
  }
예제 #11
0
  @Override
  @Nullable
  public Collection<PsiImportStatementBase> findRedundantImports(final PsiJavaFile file) {
    final PsiImportList importList = file.getImportList();
    if (importList == null) return null;
    final PsiImportStatementBase[] imports = importList.getAllImportStatements();
    if (imports.length == 0) return null;

    Set<PsiImportStatementBase> allImports =
        new THashSet<PsiImportStatementBase>(Arrays.asList(imports));
    final Collection<PsiImportStatementBase> redundant;
    if (FileTypeUtils.isInServerPageFile(file)) {
      // remove only duplicate imports
      redundant = ContainerUtil.newIdentityTroveSet();
      ContainerUtil.addAll(redundant, imports);
      redundant.removeAll(allImports);
      for (PsiImportStatementBase importStatement : imports) {
        if (importStatement instanceof JspxImportStatement
            && importStatement.isForeignFileImport()) {
          redundant.remove(importStatement);
        }
      }
    } else {
      redundant = allImports;
      final List<PsiFile> roots = file.getViewProvider().getAllFiles();
      for (PsiElement root : roots) {
        root.accept(
            new JavaRecursiveElementWalkingVisitor() {
              @Override
              public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
                if (!reference.isQualified()) {
                  final JavaResolveResult resolveResult = reference.advancedResolve(false);
                  if (!inTheSamePackage(file, resolveResult.getElement())) {
                    final PsiElement resolveScope = resolveResult.getCurrentFileResolveScope();
                    if (resolveScope instanceof PsiImportStatementBase) {
                      final PsiImportStatementBase importStatementBase =
                          (PsiImportStatementBase) resolveScope;
                      redundant.remove(importStatementBase);
                    }
                  }
                }
                super.visitReferenceElement(reference);
              }

              private boolean inTheSamePackage(PsiJavaFile file, PsiElement element) {
                if (element instanceof PsiClass
                    && ((PsiClass) element).getContainingClass() == null) {
                  final PsiFile containingFile = element.getContainingFile();
                  if (containingFile instanceof PsiJavaFile) {
                    return Comparing.strEqual(
                        file.getPackageName(), ((PsiJavaFile) containingFile).getPackageName());
                  }
                }
                return false;
              }
            });
      }
    }
    return redundant;
  }
  /**
   * Begins the in-place refactoring operation.
   *
   * @return true if the in-place refactoring was successfully started, false if it failed to start
   *     and a dialog should be shown instead.
   */
  public boolean startInplaceIntroduceTemplate() {
    final boolean replaceAllOccurrences = isReplaceAllOccurrences();
    final Ref<Boolean> result = new Ref<>();
    CommandProcessor.getInstance()
        .executeCommand(
            myProject,
            () -> {
              final String[] names = suggestNames(replaceAllOccurrences, getLocalVariable());
              final V variable = createFieldToStartTemplateOn(replaceAllOccurrences, names);
              boolean started = false;
              if (variable != null) {
                int caretOffset = getCaretOffset();
                myEditor.getCaretModel().moveToOffset(caretOffset);
                myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);

                final LinkedHashSet<String> nameSuggestions = new LinkedHashSet<>();
                nameSuggestions.add(variable.getName());
                nameSuggestions.addAll(Arrays.asList(names));
                initOccurrencesMarkers();
                setElementToRename(variable);
                updateTitle(getVariable());
                started = super.performInplaceRefactoring(nameSuggestions);
                if (started) {
                  onRenameTemplateStarted();
                  myDocumentAdapter =
                      new DocumentAdapter() {
                        @Override
                        public void documentChanged(DocumentEvent e) {
                          if (myPreview == null) return;
                          final TemplateState templateState =
                              TemplateManagerImpl.getTemplateState(myEditor);
                          if (templateState != null) {
                            final TextResult value =
                                templateState.getVariableValue(
                                    InplaceRefactoring.PRIMARY_VARIABLE_NAME);
                            if (value != null) {
                              updateTitle(getVariable(), value.getText());
                            }
                          }
                        }
                      };
                  myEditor.getDocument().addDocumentListener(myDocumentAdapter);
                  updateTitle(getVariable());
                  if (TemplateManagerImpl.getTemplateState(myEditor) != null) {
                    myEditor.putUserData(ACTIVE_INTRODUCE, this);
                  }
                }
              }
              result.set(started);
              if (!started) {
                finish(true);
              }
            },
            getCommandName(),
            getCommandName());
    return result.get();
  }
 public static void addExpandingReflectedMethods(List<PsiMethod> result, PsiMethod method) {
   if (method instanceof GrMethod) {
     final GrReflectedMethod[] reflectedMethods = ((GrMethod) method).getReflectedMethods();
     if (reflectedMethods.length > 0) {
       result.addAll(Arrays.asList(reflectedMethods));
       return;
     }
   }
   result.add(method);
 }
 public ExtractClassProcessor(
     PsiClass sourceClass,
     List<PsiField> fields,
     List<PsiMethod> methods,
     List<PsiClass> classes,
     String packageName,
     MoveDestination moveDestination,
     String newClassName,
     String newVisibility,
     boolean generateAccessors,
     List<MemberInfo> enumConstants) {
   super(sourceClass.getProject());
   this.sourceClass = sourceClass;
   this.newPackageName = packageName;
   myMoveDestination = moveDestination;
   myNewVisibility = newVisibility;
   myGenerateAccessors = generateAccessors;
   this.enumConstants = new ArrayList<PsiField>();
   for (MemberInfo constant : enumConstants) {
     if (constant.isChecked()) {
       this.enumConstants.add((PsiField) constant.getMember());
     }
   }
   this.fields = new ArrayList<PsiField>(fields);
   this.methods = new ArrayList<PsiMethod>(methods);
   this.innerClasses = new ArrayList<PsiClass>(classes);
   this.newClassName = newClassName;
   delegateFieldName = calculateDelegateFieldName();
   requiresBackpointer =
       new BackpointerUsageVisitor(fields, innerClasses, methods, sourceClass)
           .backpointerRequired();
   if (requiresBackpointer) {
     ContainerUtil.addAll(typeParams, sourceClass.getTypeParameters());
   } else {
     final Set<PsiTypeParameter> typeParamSet = new HashSet<PsiTypeParameter>();
     final TypeParametersVisitor visitor = new TypeParametersVisitor(typeParamSet);
     for (PsiField field : fields) {
       field.accept(visitor);
     }
     for (PsiMethod method : methods) {
       method.accept(visitor);
       // do not include method's type parameters in class signature
       typeParamSet.removeAll(Arrays.asList(method.getTypeParameters()));
     }
     typeParams.addAll(typeParamSet);
   }
   myClass =
       new WriteCommandAction<PsiClass>(myProject, getCommandName()) {
         @Override
         protected void run(@NotNull Result<PsiClass> result) throws Throwable {
           result.setResult(buildClass());
         }
       }.execute().getResultObject();
   myExtractEnumProcessor = new ExtractEnumProcessor(myProject, this.enumConstants, myClass);
 }
  @Override
  @NotNull
  public Object[] getVariants() {
    Set<PsiPackage> subPackages = new HashSet<>();
    for (PsiPackage psiPackage : getContext()) {
      subPackages.addAll(
          Arrays.asList(psiPackage.getSubPackages(myReferenceSet.getResolveScope())));
    }

    return subPackages.toArray();
  }
  @Nullable
  private static Condition<PsiElement> findMethodUsages(
      final PsiMethod psiMethod, final PsiElement[] allElementsToDelete, List<UsageInfo> usages) {
    final Collection<PsiReference> references = ReferencesSearch.search(psiMethod).findAll();

    if (psiMethod.isConstructor()) {
      return findConstructorUsages(psiMethod, references, usages, allElementsToDelete);
    }
    final PsiMethod[] overridingMethods =
        removeDeletedMethods(
            OverridingMethodsSearch.search(psiMethod).toArray(PsiMethod.EMPTY_ARRAY),
            allElementsToDelete);

    findFunctionalExpressions(usages, ArrayUtil.prepend(psiMethod, overridingMethods));

    final HashMap<PsiMethod, Collection<PsiReference>> methodToReferences = new HashMap<>();
    for (PsiMethod overridingMethod : overridingMethods) {
      final Collection<PsiReference> overridingReferences =
          ReferencesSearch.search(overridingMethod).findAll();
      methodToReferences.put(overridingMethod, overridingReferences);
    }
    final Set<PsiMethod> validOverriding =
        validateOverridingMethods(
            psiMethod,
            references,
            Arrays.asList(overridingMethods),
            methodToReferences,
            usages,
            allElementsToDelete);
    for (PsiReference reference : references) {
      final PsiElement element = reference.getElement();
      if (!isInside(element, allElementsToDelete) && !isInside(element, validOverriding)) {
        usages.add(
            new SafeDeleteReferenceJavaDeleteUsageInfo(
                element,
                psiMethod,
                PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class) != null));
      }
    }

    final List<PsiMethod> calleesSafeToDelete =
        SafeDeleteJavaCalleeChooser.computeCalleesSafeToDelete(psiMethod);
    if (calleesSafeToDelete != null) {
      for (PsiMethod method : calleesSafeToDelete) {
        usages.add(new SafeDeleteMethodCalleeUsageInfo(method, psiMethod));
      }
    }

    return usage -> {
      if (usage instanceof PsiFile) return false;
      return isInside(usage, allElementsToDelete) || isInside(usage, validOverriding);
    };
  }
  @NotNull
  private static List<PsiClass> getInnerClassesForResolve(
      @NotNull final GrTypeDefinition grType,
      @Nullable final PsiElement lastParent,
      @NotNull final PsiElement place) {
    if (lastParent instanceof GrReferenceList
        || PsiTreeUtil.getParentOfType(place, GrReferenceList.class) != null) {
      return Arrays.asList(grType.getInnerClasses());
    }

    List<PsiClass> classes =
        RecursionManager.doPreventingRecursion(
            grType,
            true,
            new Computable<List<PsiClass>>() {
              @Override
              public List<PsiClass> compute() {
                List<PsiClass> result = new ArrayList<PsiClass>();
                for (CandidateInfo info :
                    CollectClassMembersUtil.getAllInnerClasses(grType, false).values()) {
                  final PsiClass inner = (PsiClass) info.getElement();
                  final PsiClass containingClass = inner.getContainingClass();
                  assert containingClass != null;

                  if (lastParent == null
                      || !containingClass.isInterface()
                      || PsiTreeUtil.isAncestor(containingClass, place, false)) {
                    ContainerUtil.addIfNotNull(result, inner);
                  }
                }
                return result;
              }
            });

    if (classes == null) {
      return Arrays.asList(grType.getInnerClasses());
    }

    return classes;
  }
예제 #18
0
  @Nullable
  private List<? extends LocalQuickFix> registerFixes(final HighlightInfo info) {

    final List<LocalQuickFix> list =
        OrderEntryFix.registerFixes(new QuickFixActionRegistrarImpl(info), this);

    final String[] extendClasses = getExtendClassNames();
    final String extendClass =
        extendClasses != null && extendClasses.length > 0 ? extendClasses[0] : null;

    final JavaClassReference[] references = getJavaClassReferenceSet().getAllReferences();
    PsiPackage contextPackage = null;
    for (int i = myIndex; i >= 0; i--) {
      final PsiElement context = references[i].getContext();
      if (context != null) {
        if (context instanceof PsiPackage) {
          contextPackage = (PsiPackage) context;
        }
        break;
      }
    }

    boolean createJavaClass = !canReferencePackage();
    ClassKind kind = createJavaClass ? getClassKind() : null;
    if (createJavaClass && kind == null) kind = ClassKind.CLASS;
    final String templateName = JavaClassReferenceProvider.CLASS_TEMPLATE.getValue(getOptions());
    final TextRange range =
        new TextRange(
            references[0].getRangeInElement().getStartOffset(), getRangeInElement().getEndOffset());
    final String qualifiedName = range.substring(getElement().getText());
    final CreateClassOrPackageFix action =
        CreateClassOrPackageFix.createFix(
            qualifiedName,
            getScope(),
            getElement(),
            contextPackage,
            kind,
            extendClass,
            templateName);
    if (action != null) {
      QuickFixAction.registerQuickFixAction(info, action);
      if (list == null) {
        return Arrays.asList(action);
      } else {
        final ArrayList<LocalQuickFix> fixes = new ArrayList<LocalQuickFix>(list.size() + 1);
        fixes.addAll(list);
        fixes.add(action);
        return fixes;
      }
    }
    return list;
  }
 private static ArrayList<PsiMethod> filterConstructorsIfFieldAlreadyAssigned(
     PsiMethod[] constructors, PsiField field) {
   final ArrayList<PsiMethod> result = new ArrayList<PsiMethod>(Arrays.asList(constructors));
   for (PsiReference reference :
       ReferencesSearch.search(field, new LocalSearchScope(constructors))) {
     final PsiElement element = reference.getElement();
     if (element instanceof PsiReferenceExpression
         && PsiUtil.isOnAssignmentLeftHand((PsiExpression) element)) {
       result.remove(PsiTreeUtil.getParentOfType(element, PsiMethod.class));
     }
   }
   return result;
 }
  @Override
  public List<RefEntity> getChildren() {
    List<RefEntity> superChildren = super.getChildren();
    if (myParameters == null) return superChildren;
    if (superChildren == null || superChildren.isEmpty())
      return Arrays.<RefEntity>asList(myParameters);

    List<RefEntity> allChildren =
        new ArrayList<RefEntity>(superChildren.size() + myParameters.length);
    allChildren.addAll(superChildren);
    Collections.addAll(allChildren, myParameters);
    return allChildren;
  }
  private static void processCallerMethod(
      JavaChangeInfo changeInfo,
      PsiMethod caller,
      PsiMethod baseMethod,
      boolean toInsertParams,
      boolean toInsertThrows)
      throws IncorrectOperationException {
    LOG.assertTrue(toInsertParams || toInsertThrows);
    if (toInsertParams) {
      List<PsiParameter> newParameters = new ArrayList<PsiParameter>();
      ContainerUtil.addAll(newParameters, caller.getParameterList().getParameters());
      final JavaParameterInfo[] primaryNewParms = changeInfo.getNewParameters();
      PsiSubstitutor substitutor =
          baseMethod == null
              ? PsiSubstitutor.EMPTY
              : ChangeSignatureProcessor.calculateSubstitutor(caller, baseMethod);
      for (JavaParameterInfo info : primaryNewParms) {
        if (info.getOldIndex() < 0)
          newParameters.add(createNewParameter(changeInfo, info, substitutor));
      }
      PsiParameter[] arrayed = newParameters.toArray(new PsiParameter[newParameters.size()]);
      boolean[] toRemoveParm = new boolean[arrayed.length];
      Arrays.fill(toRemoveParm, false);
      resolveParameterVsFieldsConflicts(arrayed, caller, caller.getParameterList(), toRemoveParm);
    }

    if (toInsertThrows) {
      List<PsiJavaCodeReferenceElement> newThrowns = new ArrayList<PsiJavaCodeReferenceElement>();
      final PsiReferenceList throwsList = caller.getThrowsList();
      ContainerUtil.addAll(newThrowns, throwsList.getReferenceElements());
      final ThrownExceptionInfo[] primaryNewExns = changeInfo.getNewExceptions();
      for (ThrownExceptionInfo thrownExceptionInfo : primaryNewExns) {
        if (thrownExceptionInfo.getOldIndex() < 0) {
          final PsiClassType type =
              (PsiClassType) thrownExceptionInfo.createType(caller, caller.getManager());
          final PsiJavaCodeReferenceElement ref =
              JavaPsiFacade.getInstance(caller.getProject())
                  .getElementFactory()
                  .createReferenceElementByType(type);
          newThrowns.add(ref);
        }
      }
      PsiJavaCodeReferenceElement[] arrayed =
          newThrowns.toArray(new PsiJavaCodeReferenceElement[newThrowns.size()]);
      boolean[] toRemoveParm = new boolean[arrayed.length];
      Arrays.fill(toRemoveParm, false);
      ChangeSignatureUtil.synchronizeList(
          throwsList, Arrays.asList(arrayed), ThrowsList.INSTANCE, toRemoveParm);
    }
  }
  private static HighlightVisitor[] filterVisitors(
      HighlightVisitor[] highlightVisitors, final PsiFile file) {
    final List<HighlightVisitor> visitors =
        new ArrayList<HighlightVisitor>(highlightVisitors.length);
    List<HighlightVisitor> list = Arrays.asList(highlightVisitors);
    for (HighlightVisitor visitor :
        DumbService.getInstance(file.getProject()).filterByDumbAwareness(list)) {
      if (visitor.suitableForFile(file)) visitors.add(visitor);
    }
    LOG.assertTrue(!visitors.isEmpty(), list);

    HighlightVisitor[] visitorArray = visitors.toArray(new HighlightVisitor[visitors.size()]);
    Arrays.sort(visitorArray, VISITOR_ORDER_COMPARATOR);
    return visitorArray;
  }
 @Nullable
 public static DuplicatesFinder createDuplicatesFinder(PsiMember member) {
   PsiElement[] pattern;
   ReturnValue matchedReturnValue = null;
   if (member instanceof PsiMethod) {
     final PsiCodeBlock body = ((PsiMethod) member).getBody();
     LOG.assertTrue(body != null);
     final PsiStatement[] statements = body.getStatements();
     pattern = statements;
     matchedReturnValue = null;
     if (statements.length != 1 || !(statements[0] instanceof PsiReturnStatement)) {
       final PsiStatement lastStatement =
           statements.length > 0 ? statements[statements.length - 1] : null;
       if (lastStatement instanceof PsiReturnStatement) {
         final PsiExpression returnValue = ((PsiReturnStatement) lastStatement).getReturnValue();
         if (returnValue instanceof PsiReferenceExpression) {
           final PsiElement resolved = ((PsiReferenceExpression) returnValue).resolve();
           if (resolved instanceof PsiVariable) {
             pattern = new PsiElement[statements.length - 1];
             System.arraycopy(statements, 0, pattern, 0, statements.length - 1);
             matchedReturnValue = new VariableReturnValue((PsiVariable) resolved);
           }
         }
       }
     } else {
       final PsiExpression returnValue = ((PsiReturnStatement) statements[0]).getReturnValue();
       if (returnValue != null) {
         pattern = new PsiElement[] {returnValue};
       }
     }
   } else {
     pattern = new PsiElement[] {((PsiField) member).getInitializer()};
   }
   if (pattern.length == 0) {
     return null;
   }
   final List<? extends PsiVariable> inputVariables =
       member instanceof PsiMethod
           ? Arrays.asList(((PsiMethod) member).getParameterList().getParameters())
           : new ArrayList<>();
   return new DuplicatesFinder(
       pattern,
       new InputVariables(
           inputVariables, member.getProject(), new LocalSearchScope(pattern), false),
       matchedReturnValue,
       new ArrayList<>());
 }
  private static void getImplementListsInner(
      GrTypeDefinition grType, List<PsiClassType> result, Set<PsiClass> visited) {
    if (!visited.add(grType)) return;

    final PsiClassType[] implementsTypes = getReferenceListTypes(grType.getImplementsClause());
    List<PsiClassType> fromDelegates = getImplementsFromDelegate(grType, visited);
    if (fromDelegates != null) {
      result.addAll(fromDelegates);
    }
    result.addAll(Arrays.asList(implementsTypes));

    if (!grType.isInterface()
        && !ContainerUtil.or(implementsTypes, IS_GROOVY_OBJECT)
        && !ContainerUtil.or(getReferenceListTypes(grType.getExtendsClause()), IS_GROOVY_OBJECT)) {
      result.add(getGroovyObjectType(grType));
    }
  }
 private static void resolveParameterVsFieldsConflicts(
     final PsiParameter[] newParms,
     final PsiMethod method,
     final PsiParameterList list,
     boolean[] toRemoveParm)
     throws IncorrectOperationException {
   List<FieldConflictsResolver> conflictResolvers = new ArrayList<FieldConflictsResolver>();
   for (PsiParameter parameter : newParms) {
     conflictResolvers.add(new FieldConflictsResolver(parameter.getName(), method.getBody()));
   }
   ChangeSignatureUtil.synchronizeList(
       list, Arrays.asList(newParms), ParameterList.INSTANCE, toRemoveParm);
   JavaCodeStyleManager.getInstance(list.getProject()).shortenClassReferences(list);
   for (FieldConflictsResolver fieldConflictsResolver : conflictResolvers) {
     fieldConflictsResolver.fix();
   }
 }
  @NotNull
  public PsiVariable[] getOutputVariables(boolean collectVariablesAtExitPoints) {
    PsiVariable[] myOutputVariables =
        ControlFlowUtil.getOutputVariables(
            myControlFlow, myFlowStart, myFlowEnd, myExitPoints.toArray());
    if (collectVariablesAtExitPoints) {
      // variables declared in selected block used in return statements are to be considered output
      // variables when extracting guard methods
      final Set<PsiVariable> outputVariables = new HashSet<>(Arrays.asList(myOutputVariables));
      for (PsiStatement statement : myExitStatements) {
        statement.accept(
            new JavaRecursiveElementVisitor() {

              @Override
              public void visitReferenceExpression(PsiReferenceExpression expression) {
                super.visitReferenceExpression(expression);
                final PsiElement resolved = expression.resolve();
                if (resolved instanceof PsiVariable) {
                  final PsiVariable variable = (PsiVariable) resolved;
                  if (isWrittenInside(variable)) {
                    outputVariables.add(variable);
                  }
                }
              }

              private boolean isWrittenInside(final PsiVariable variable) {
                final List<Instruction> instructions = myControlFlow.getInstructions();
                for (int i = myFlowStart; i < myFlowEnd; i++) {
                  Instruction instruction = instructions.get(i);
                  if (instruction instanceof WriteVariableInstruction
                      && variable.equals(((WriteVariableInstruction) instruction).variable)) {
                    return true;
                  }
                }

                return false;
              }
            });
      }

      myOutputVariables = outputVariables.toArray(new PsiVariable[outputVariables.size()]);
    }
    Arrays.sort(myOutputVariables, PsiUtil.BY_POSITION);
    return myOutputVariables;
  }
  private void analyzeCodeBlock(
      @Nullable final PsiElement scope, ProblemsHolder holder, final boolean onTheFly) {
    if (scope == null) return;

    PsiClass containingClass = PsiTreeUtil.getParentOfType(scope, PsiClass.class);
    if (containingClass != null && PsiUtil.isLocalOrAnonymousClass(containingClass)) return;

    final StandardDataFlowRunner dfaRunner =
        new StandardDataFlowRunner(scope) {
          @Override
          protected boolean shouldCheckTimeLimit() {
            if (!onTheFly) return false;
            return super.shouldCheckTimeLimit();
          }
        };
    analyzeDfaWithNestedClosures(
        scope, holder, dfaRunner, Arrays.asList(dfaRunner.createMemoryState()));
  }
  public static boolean isMethodWithFirstString(PsiElement psiElement, String... methodName) {

    // filter out method calls without parameter
    // $this->methodName('service_name')
    // withName is not working, so simulate it in a hack
    if (!PlatformPatterns.psiElement(PhpElementTypes.METHOD_REFERENCE)
        .withChild(
            PlatformPatterns.psiElement(PhpElementTypes.PARAMETER_LIST)
                .withFirstChild(PlatformPatterns.psiElement(PhpElementTypes.STRING)))
        .accepts(psiElement)) {

      return false;
    }

    // cant we move it up to PlatformPatterns? withName condition dont looks working
    String methodRefName = ((MethodReference) psiElement).getName();

    return null != methodRefName && Arrays.asList(methodName).contains(methodRefName);
  }
  private static class StrictBindingReference extends SetterReferenceEx<PsiElement> {
    private static List<String> EXTRA_VALUES = Arrays.asList("*", "**");

    public StrictBindingReference(
        TextRange range, Boolean supportBraces, StripesReferenceSetBase referenceSet, int index) {
      super(range, supportBraces, referenceSet, index);
    }

    @Override
    protected List<String> getVariantsEx() {
      return EXTRA_VALUES;
    }

    @Override
    protected PsiElement resolveEx() {
      if (getIndex() == 0) return getReferenceSet().getActionBeanPsiClass();
      PsiMethod method = (PsiMethod) getReferenceSet().getReference(getIndex() - 1).resolve();
      return null == method ? null : method.getContainingClass();
    }
  }
  private void analyzeCodeBlock(
      @Nullable final PsiElement scope, ProblemsHolder holder, final boolean onTheFly) {
    if (scope == null) return;

    PsiClass containingClass = PsiTreeUtil.getParentOfType(scope, PsiClass.class);
    if (containingClass != null
        && PsiUtil.isLocalOrAnonymousClass(containingClass)
        && !(containingClass instanceof PsiEnumConstantInitializer)) return;

    final StandardDataFlowRunner dfaRunner =
        new StandardDataFlowRunner(
            TREAT_UNKNOWN_MEMBERS_AS_NULLABLE, !isInsideConstructorOrInitializer(scope)) {
          @Override
          protected boolean shouldCheckTimeLimit() {
            if (!onTheFly) return false;
            return super.shouldCheckTimeLimit();
          }
        };
    analyzeDfaWithNestedClosures(
        scope, holder, dfaRunner, Arrays.asList(dfaRunner.createMemoryState()), onTheFly);
  }