@Override
 @Nullable
 public PsiMethod generateMethodPrototype(
     @NotNull PsiField field, @NotNull String methodName, boolean isGetter) {
   PsiMethod prototype =
       isGetter
           ? GenerateMembersUtil.generateGetterPrototype(field)
           : GenerateMembersUtil.generateSetterPrototype(field);
   try {
     prototype.setName(methodName);
     return prototype;
   } catch (IncorrectOperationException e) {
     return null;
   }
 }
 private void processUsagesForMethod(
     final boolean deleteMethodHierarchy,
     PsiMethod method,
     int[] paramPermutation,
     String getterName,
     PsiMethod delegatedMethod,
     List<FixableUsageInfo> usages) {
   for (PsiReference reference : ReferencesSearch.search(method)) {
     final PsiElement referenceElement = reference.getElement();
     final PsiMethodCallExpression call = (PsiMethodCallExpression) referenceElement.getParent();
     final String access;
     if (call.getMethodExpression().getQualifierExpression() == null) {
       access = field.getName();
     } else {
       access = getterName + "()";
       if (getter == null) {
         getter = GenerateMembersUtil.generateGetterPrototype(field);
       }
     }
     usages.add(
         new InlineDelegatingCall(call, paramPermutation, access, delegatedMethod.getName()));
   }
   if (deleteMethodHierarchy) {
     usages.add(new DeleteMethod(method));
   }
 }
 private void appendAccessors(final Set<PsiParameter> params, boolean isGetter) {
   final PsiElement element = getElement();
   if (element != null) {
     for (PsiParameter parameter : params) {
       final IntroduceParameterObjectProcessor.ParameterChunk parameterChunk =
           IntroduceParameterObjectProcessor.ParameterChunk.getChunkByParameter(
               parameter, parameters);
       LOGGER.assertTrue(parameterChunk != null);
       final PsiField field = parameterChunk.getField();
       if (field != null) {
         element.add(
             isGetter
                 ? GenerateMembersUtil.generateGetterPrototype(field)
                 : GenerateMembersUtil.generateSetterPrototype(field));
       }
     }
   }
 }
 public void findUsages(@NotNull List<FixableUsageInfo> usages) {
   for (final MemberInfo memberInfo : myDelegateMethodInfos) {
     if (!memberInfo.isChecked()) continue;
     final PsiMethod method = (PsiMethod) memberInfo.getMember();
     final String getterName = GenerateMembersUtil.suggestGetterName(field);
     final int[] paramPermutation = DelegationUtils.getParameterPermutation(method);
     final PsiMethod delegatedMethod = DelegationUtils.getDelegatedMethod(method);
     LOG.assertTrue(!DelegationUtils.isAbstract(method));
     processUsagesForMethod(
         memberInfo.isToAbstract(), method, paramPermutation, getterName, delegatedMethod, usages);
   }
 }
 public void applyFix(final Project project, final PsiFile file, final Editor editor) {
   if (!CodeInsightUtilBase.prepareFileForWrite(myClass.getContainingFile())) return;
   PsiCodeBlock body;
   if (myClass.isInterface() && (body = myMethod.getBody()) != null) body.delete();
   for (String exception : myExceptions) {
     PsiUtil.addException(myMethod, exception);
   }
   PsiMethod method = (PsiMethod) myClass.add(myMethod);
   method = (PsiMethod) method.replace(reformat(project, method));
   if (editor != null) {
     GenerateMembersUtil.positionCaret(editor, method, true);
   }
 }
    @Nullable
    private static PsiMethod generateDummyMethod(Editor editor, PsiFile file)
        throws IncorrectOperationException {
      final PsiMethod method = TestIntegrationUtils.createDummyMethod(file);
      final PsiGenerationInfo<PsiMethod> info = OverrideImplementUtil.createGenerationInfo(method);

      int offset = findOffsetToInsertMethodTo(editor, file);
      GenerateMembersUtil.insertMembersAtOffset(file, offset, Collections.singletonList(info));

      final PsiMethod member = info.getPsiMember();
      return member != null
          ? CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(member)
          : null;
    }
 @Override
 public void invoke(
     @NotNull Project project,
     @NotNull PsiFile file,
     @Nullable("is null when called from inspection") Editor editor,
     @NotNull PsiElement startElement,
     @NotNull PsiElement endElement) {
   final PsiClass myClass = (PsiClass) startElement;
   if (!CodeInsightUtilBase.prepareFileForWrite(myClass.getContainingFile())) return;
   PsiCodeBlock body;
   if (myClass.isInterface() && (body = myMethodPrototype.getBody()) != null) body.delete();
   for (String exception : myExceptions) {
     PsiUtil.addException(myMethodPrototype, exception);
   }
   PsiMethod method = (PsiMethod) myClass.add(myMethodPrototype);
   method = (PsiMethod) method.replace(reformat(project, method));
   if (editor != null) {
     GenerateMembersUtil.positionCaret(editor, method, true);
   }
 }
  private static void insertGenerationInfos(
      InsertionContext context, List<PsiGenerationInfo<PsiMethod>> infos) {
    List<PsiGenerationInfo<PsiMethod>> newInfos =
        GenerateMembersUtil.insertMembersAtOffset(
            context.getFile(), context.getStartOffset(), infos);
    if (!newInfos.isEmpty()) {
      final List<PsiElement> elements = new ArrayList<PsiElement>();
      for (GenerationInfo member : newInfos) {
        if (!(member instanceof TemplateGenerationInfo)) {
          final PsiMember psiMember = member.getPsiMember();
          if (psiMember != null) {
            elements.add(psiMember);
          }
        }
      }

      GlobalInspectionContextBase.cleanupElements(
          context.getProject(), null, elements.toArray(new PsiElement[elements.size()]));
      newInfos.get(0).positionCaret(context.getEditor(), true);
    }
  }
  private void findUsagesForMethod(
      PsiMethod overridingMethod, List<FixableUsageInfo> usages, boolean changeSignature) {
    final PsiCodeBlock body = overridingMethod.getBody();
    final String baseParameterName = StringUtil.decapitalize(className);
    final String fixedParamName =
        body != null
            ? JavaCodeStyleManager.getInstance(myProject)
                .suggestUniqueVariableName(baseParameterName, body.getLBrace(), true)
            : JavaCodeStyleManager.getInstance(myProject)
                .propertyNameToVariableName(baseParameterName, VariableKind.PARAMETER);

    usages.add(
        new MergeMethodArguments(
            overridingMethod,
            className,
            packageName,
            fixedParamName,
            paramsToMerge,
            typeParams,
            keepMethodAsDelegate,
            myCreateInnerClass ? method.getContainingClass() : null,
            changeSignature));

    final ParamUsageVisitor visitor = new ParamUsageVisitor(overridingMethod, paramsToMerge);
    overridingMethod.accept(visitor);
    final Set<PsiReferenceExpression> values = visitor.getParameterUsages();
    for (PsiReferenceExpression paramUsage : values) {
      final PsiParameter parameter = (PsiParameter) paramUsage.resolve();
      assert parameter != null;
      final PsiMethod containingMethod = (PsiMethod) parameter.getDeclarationScope();
      final int index = containingMethod.getParameterList().getParameterIndex(parameter);
      final PsiParameter replacedParameter = method.getParameterList().getParameters()[index];
      final ParameterChunk parameterChunk =
          ParameterChunk.getChunkByParameter(parameter, parameters);

      @NonNls String getter = parameterChunk != null ? parameterChunk.getter : null;
      final String paramName =
          parameterChunk != null ? parameterChunk.parameter.name : replacedParameter.getName();
      final PsiType paramType =
          parameterChunk != null ? parameterChunk.parameter.type : replacedParameter.getType();
      if (getter == null) {
        getter = GenerateMembersUtil.suggestGetterName(paramName, paramType, myProject);
        paramsNeedingGetters.add(replacedParameter);
      }
      @NonNls String setter = parameterChunk != null ? parameterChunk.setter : null;
      if (setter == null) {
        setter = GenerateMembersUtil.suggestSetterName(paramName, paramType, myProject);
      }
      if (RefactoringUtil.isPlusPlusOrMinusMinus(paramUsage.getParent())) {
        usages.add(
            new ReplaceParameterIncrementDecrement(paramUsage, fixedParamName, setter, getter));
        if (parameterChunk == null || parameterChunk.setter == null) {
          paramsNeedingSetters.add(replacedParameter);
        }
      } else if (RefactoringUtil.isAssignmentLHS(paramUsage)) {
        usages.add(
            new ReplaceParameterAssignmentWithCall(paramUsage, fixedParamName, setter, getter));
        if (parameterChunk == null || parameterChunk.setter == null) {
          paramsNeedingSetters.add(replacedParameter);
        }
      } else {
        usages.add(new ReplaceParameterReferenceWithCall(paramUsage, fixedParamName, getter));
      }
    }
  }
 private boolean hasSetter(final PsiField field) {
   return hasGetterOrSetter(
       sourceClass.findMethodsBySignature(
           GenerateMembersUtil.generateSetterPrototype(field), false));
 }
  private void findUsagesForField(PsiField field, List<FixableUsageInfo> usages) {
    final PsiManager psiManager = field.getManager();
    final Project project = psiManager.getProject();
    final GlobalSearchScope scope = GlobalSearchScope.allScope(project);

    final String qualifiedName = getQualifiedName();
    @NonNls String getter = null;
    if (myGenerateAccessors) {
      getter = GenerateMembersUtil.suggestGetterName(field);
    } else {
      final PsiMethod fieldGetter =
          PropertyUtil.findPropertyGetter(sourceClass, field.getName(), false, false);
      if (fieldGetter != null && isInMovedElement(fieldGetter)) {
        getter = fieldGetter.getName();
      }
    }

    @NonNls String setter = null;
    if (myGenerateAccessors) {
      setter = GenerateMembersUtil.suggestSetterName(field);
    } else {
      final PsiMethod fieldSetter =
          PropertyUtil.findPropertySetter(sourceClass, field.getName(), false, false);
      if (fieldSetter != null && isInMovedElement(fieldSetter)) {
        setter = fieldSetter.getName();
      }
    }
    final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);

    for (PsiReference reference : ReferencesSearch.search(field, scope)) {
      final PsiElement element = reference.getElement();
      if (isInMovedElement(element)) {
        continue;
      }

      if (element instanceof PsiReferenceExpression) {
        final PsiReferenceExpression exp = (PsiReferenceExpression) element;
        if (RefactoringUtil.isPlusPlusOrMinusMinus(exp.getParent())) {
          usages.add(
              isStatic
                  ? new ReplaceStaticVariableIncrementDecrement(exp, qualifiedName)
                  : new ReplaceInstanceVariableIncrementDecrement(
                      exp, delegateFieldName, setter, getter, field.getName()));
        } else if (RefactoringUtil.isAssignmentLHS(exp)) {
          usages.add(
              isStatic
                  ? new ReplaceStaticVariableAssignment(exp, qualifiedName)
                  : new ReplaceInstanceVariableAssignment(
                      PsiTreeUtil.getParentOfType(exp, PsiAssignmentExpression.class),
                      delegateFieldName,
                      setter,
                      getter,
                      field.getName()));

        } else {
          usages.add(
              isStatic
                  ? new ReplaceStaticVariableAccess(
                      exp, qualifiedName, enumConstants.contains(field))
                  : new ReplaceInstanceVariableAccess(
                      exp, delegateFieldName, getter, field.getName()));
        }

        if (!isStatic) {
          delegationRequired = true;
        }
      } else if (element instanceof PsiDocTagValue) {
        usages.add(new BindJavadocReference(element, qualifiedName, field.getName()));
      }
    }
  }
  protected void performRefactoring(@NotNull UsageInfo[] usageInfos) {
    final PsiClass psiClass = buildClass();
    if (psiClass == null) return;
    if (delegationRequired) {
      buildDelegate();
    }
    myExtractEnumProcessor.performEnumConstantTypeMigration(usageInfos);
    final Set<PsiMember> members = new HashSet<PsiMember>();
    for (PsiMethod method : methods) {
      final PsiMethod member = psiClass.findMethodBySignature(method, false);
      if (member != null) {
        members.add(member);
      }
    }
    for (PsiField field : fields) {
      final PsiField member = psiClass.findFieldByName(field.getName(), false);
      if (member != null) {
        members.add(member);
        final PsiExpression initializer = member.getInitializer();
        if (initializer != null) {
          final boolean[] moveInitializerToConstructor = new boolean[1];
          initializer.accept(
              new JavaRecursiveElementWalkingVisitor() {
                @Override
                public void visitReferenceExpression(PsiReferenceExpression expression) {
                  super.visitReferenceExpression(expression);
                  final PsiElement resolved = expression.resolve();
                  if (resolved instanceof PsiField && !members.contains(resolved)) {
                    moveInitializerToConstructor[0] = true;
                  }
                }
              });

          if (moveInitializerToConstructor[0]) {
            final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
            PsiMethod[] constructors = psiClass.getConstructors();
            if (constructors.length == 0) {
              final PsiMethod constructor =
                  (PsiMethod) elementFactory.createConstructor().setName(psiClass.getName());
              constructors = new PsiMethod[] {(PsiMethod) psiClass.add(constructor)};
            }
            for (PsiMethod constructor : constructors) {
              MoveInstanceMembersUtil.moveInitializerToConstructor(
                  elementFactory, constructor, member);
            }
          }
        }
      }
    }

    if (myGenerateAccessors) {
      final NecessaryAccessorsVisitor visitor = checkNecessaryGettersSetters4SourceClass();
      for (PsiField field : visitor.getFieldsNeedingGetter()) {
        sourceClass.add(GenerateMembersUtil.generateGetterPrototype(field));
      }

      for (PsiField field : visitor.getFieldsNeedingSetter()) {
        sourceClass.add(GenerateMembersUtil.generateSetterPrototype(field));
      }
    }
    super.performRefactoring(usageInfos);
    if (myNewVisibility == null) return;
    for (PsiMember member : members) {
      VisibilityUtil.fixVisibility(UsageViewUtil.toElements(usageInfos), member, myNewVisibility);
    }
  }
 @Override
 @NotNull
 public String suggestGetterName(@NotNull PsiField field) {
   return GenerateMembersUtil.suggestGetterName(field);
 }