protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
    final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();

    checkExistingMethods(conflicts, true);
    checkExistingMethods(conflicts, false);
    final Collection<PsiClass> classes = ClassInheritorsSearch.search(myClass).findAll();
    for (FieldDescriptor fieldDescriptor : myFieldDescriptors) {
      final Set<PsiMethod> setters = new HashSet<PsiMethod>();
      final Set<PsiMethod> getters = new HashSet<PsiMethod>();

      for (PsiClass aClass : classes) {
        final PsiMethod getterOverrider =
            myDescriptor.isToEncapsulateGet()
                ? aClass.findMethodBySignature(fieldDescriptor.getGetterPrototype(), false)
                : null;
        if (getterOverrider != null) {
          getters.add(getterOverrider);
        }
        final PsiMethod setterOverrider =
            myDescriptor.isToEncapsulateSet()
                ? aClass.findMethodBySignature(fieldDescriptor.getSetterPrototype(), false)
                : null;
        if (setterOverrider != null) {
          setters.add(setterOverrider);
        }
      }
      if (!getters.isEmpty() || !setters.isEmpty()) {
        final PsiField field = fieldDescriptor.getField();
        for (PsiReference reference : ReferencesSearch.search(field)) {
          final PsiElement place = reference.getElement();
          if (place instanceof PsiReferenceExpression) {
            final PsiExpression qualifierExpression =
                ((PsiReferenceExpression) place).getQualifierExpression();
            final PsiClass ancestor;
            if (qualifierExpression == null) {
              ancestor = PsiTreeUtil.getParentOfType(place, PsiClass.class, false);
            } else {
              ancestor = PsiUtil.resolveClassInType(qualifierExpression.getType());
            }

            final boolean isGetter = !PsiUtil.isAccessedForWriting((PsiExpression) place);
            for (PsiMethod overridden : isGetter ? getters : setters) {
              if (InheritanceUtil.isInheritorOrSelf(myClass, ancestor, true)) {
                conflicts.putValue(
                    overridden,
                    "There is already a "
                        + RefactoringUIUtil.getDescription(overridden, true)
                        + " which would hide generated "
                        + (isGetter ? "getter" : "setter")
                        + " for "
                        + place.getText());
                break;
              }
            }
          }
        }
      }
    }
    return showConflicts(conflicts, refUsages.get());
  }
 public static void registerQuickFix(
     PsiMember refElement,
     PsiJavaCodeReferenceElement place,
     PsiClass accessObjectClass,
     HighlightInfo error) {
   if (refElement instanceof PsiField && place instanceof PsiReferenceExpression) {
     final PsiField psiField = (PsiField) refElement;
     final PsiClass containingClass = psiField.getContainingClass();
     if (containingClass != null) {
       if (PsiUtil.isOnAssignmentLeftHand((PsiExpression) place)) {
         final PsiMethod setterPrototype = PropertyUtil.generateSetterPrototype(psiField);
         final PsiMethod setter = containingClass.findMethodBySignature(setterPrototype, true);
         if (setter != null && PsiUtil.isAccessible(setter, place, accessObjectClass)) {
           QuickFixAction.registerQuickFixAction(
               error, new ReplaceInaccessibleFieldWithGetterSetterFix(place, setter, true));
         }
       } else if (PsiUtil.isAccessedForReading((PsiExpression) place)) {
         final PsiMethod getterPrototype = PropertyUtil.generateGetterPrototype(psiField);
         final PsiMethod getter = containingClass.findMethodBySignature(getterPrototype, true);
         if (getter != null && PsiUtil.isAccessible(getter, place, accessObjectClass)) {
           QuickFixAction.registerQuickFixAction(
               error, new ReplaceInaccessibleFieldWithGetterSetterFix(place, getter, false));
         }
       }
     }
   }
 }
 @Override
 public PsiElement getOriginalElement() {
   final PsiClass containingClass = getContainingClass();
   if (containingClass == null) return this;
   PsiClass originalClass = (PsiClass) containingClass.getOriginalElement();
   final PsiMethod originalMethod = originalClass.findMethodBySignature(this, false);
   return originalMethod != null ? originalMethod : this;
 }
 private boolean existsInSuperClass(PsiElement classMember) {
   if (!(classMember instanceof PsiMethod)) return false;
   final PsiMethod method = ((PsiMethod) classMember);
   if (myInterfaceContainmentVerifier.checkedInterfacesContain(method)) return true;
   if (mySuperClass == null) return false;
   final PsiMethod methodBySignature = mySuperClass.findMethodBySignature(method, true);
   return methodBySignature != null;
 }
Exemple #5
0
  public static void checkMethodConflicts(
      @Nullable PsiClass aClass,
      PsiMethod refactoredMethod,
      PsiMethod prototype,
      final MultiMap<PsiElement, String> conflicts) {
    if (prototype == null) return;

    PsiMethod method = aClass != null ? aClass.findMethodBySignature(prototype, true) : null;

    if (method != null && method != refactoredMethod) {
      if (aClass.equals(method.getContainingClass())) {
        final String classDescr =
            aClass instanceof PsiAnonymousClass
                ? RefactoringBundle.message("current.class")
                : RefactoringUIUtil.getDescription(aClass, false);
        conflicts.putValue(
            method,
            RefactoringBundle.message(
                "method.0.is.already.defined.in.the.1",
                getMethodPrototypeString(prototype),
                classDescr));
      } else { // method somewhere in base class
        if (JavaPsiFacade.getInstance(method.getProject())
            .getResolveHelper()
            .isAccessible(method, aClass, null)) {
          String protoMethodInfo = getMethodPrototypeString(prototype);
          String className =
              CommonRefactoringUtil.htmlEmphasize(
                  UsageViewUtil.getDescriptiveName(method.getContainingClass()));
          if (PsiUtil.getAccessLevel(prototype.getModifierList())
              >= PsiUtil.getAccessLevel(method.getModifierList())) {
            boolean isMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
            boolean isMyMethodAbstract =
                refactoredMethod != null
                    && refactoredMethod.hasModifierProperty(PsiModifier.ABSTRACT);
            final String conflict =
                isMethodAbstract != isMyMethodAbstract
                    ? RefactoringBundle.message(
                        "method.0.will.implement.method.of.the.base.class",
                        protoMethodInfo,
                        className)
                    : RefactoringBundle.message(
                        "method.0.will.override.a.method.of.the.base.class",
                        protoMethodInfo,
                        className);
            conflicts.putValue(method, conflict);
          } else { // prototype is private, will be compile-error
            conflicts.putValue(
                method,
                RefactoringBundle.message(
                    "method.0.will.hide.method.of.the.base.class", protoMethodInfo, className));
          }
        }
      }
    }
  }
 private static List<? extends GenerationInfo> filterOutAlreadyInsertedConstructors(
     PsiClass aClass, List<? extends GenerationInfo> constructors) {
   boolean alreadyExist = true;
   for (GenerationInfo constructor : constructors) {
     alreadyExist &=
         aClass.findMethodBySignature((PsiMethod) constructor.getPsiMember(), false) != null;
   }
   if (alreadyExist) {
     return Collections.emptyList();
   }
   return constructors;
 }
 public static boolean isUsedInExistingAccessor(
     PsiClass aClass, PsiMethod prototype, PsiElement element) {
   PsiMethod existingAccessor = aClass.findMethodBySignature(prototype, false);
   if (existingAccessor != null) {
     PsiElement parent = element;
     while (parent != null) {
       if (existingAccessor.equals(parent)) return true;
       parent = parent.getParent();
     }
   }
   return false;
 }
  protected void performRefactoring(@NotNull UsageInfo[] usageInfos) {
    if (getter != null) {
      try {
        if (containingClass.findMethodBySignature(getter, false) == null) {
          containingClass.add(getter);
        }
      } catch (IncorrectOperationException e) {
        LOG.error(e);
      }
    }

    super.performRefactoring(usageInfos);
  }
Exemple #9
0
 public static @Nullable PsiType resolveMethod(
     @Nullable PsiType type, String methodName, @NotNull PsiType... argTypes) {
   if (!(type instanceof PsiClassType) || methodName == null) return null;
   for (PsiType a : argTypes) if (a == null) return null;
   PsiClassType clas = (PsiClassType) type;
   PsiSubstitutor subst = clas.resolveGenerics().getSubstitutor();
   PsiClass psiClass = clas.resolve();
   if (psiClass == null) return null;
   LightMethodBuilder method =
       new LightMethodBuilder(psiClass.getManager(), JavaLanguage.INSTANCE, methodName);
   for (PsiType a : argTypes) method.addParameter("_", a);
   PsiMethod m = psiClass.findMethodBySignature(method, true);
   return m == null ? null : subst.substitute(m.getReturnType());
 }
 @Nullable
 public static PsiMethod findPsiMethod(PsiManager manager, String externalName) {
   final int spaceIdx = externalName.indexOf(' ');
   final String className = externalName.substring(0, spaceIdx);
   final PsiClass psiClass = ClassUtil.findPsiClass(manager, className);
   if (psiClass == null) return null;
   try {
     PsiElementFactory factory =
         JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory();
     String methodSignature = externalName.substring(spaceIdx + 1);
     PsiMethod patternMethod = factory.createMethodFromText(methodSignature, psiClass);
     return psiClass.findMethodBySignature(patternMethod, false);
   } catch (IncorrectOperationException e) {
     // Do nothing. Returning null is acceptable in this case.
     return null;
   }
 }
 private PsiMethod addOrChangeAccessor(
     PsiMethod prototype, HashMap<String, PsiMethod> nameToAncestor) {
   PsiMethod existing = myClass.findMethodBySignature(prototype, false);
   PsiMethod result = existing;
   try {
     if (existing == null) {
       PsiUtil.setModifierProperty(prototype, myDescriptor.getAccessorsVisibility(), true);
       result = (PsiMethod) myClass.add(prototype);
     } else {
       // TODO : change visibility
     }
     nameToAncestor.put(prototype.getName(), result);
     return result;
   } catch (IncorrectOperationException e) {
     LOG.error(e);
   }
   return null;
 }
 private void detectAccessibilityConflicts(
     final UsageInfo[] usageArray, MultiMap<PsiElement, String> conflicts) {
   if (myParameterInitializer != null) {
     final ReferencedElementsCollector collector = new ReferencedElementsCollector();
     myParameterInitializer.accept(collector);
     final Set<PsiElement> result = collector.myResult;
     if (!result.isEmpty()) {
       for (final UsageInfo usageInfo : usageArray) {
         if (usageInfo instanceof ExternalUsageInfo
             && IntroduceParameterUtil.isMethodUsage(usageInfo)) {
           final PsiElement place = usageInfo.getElement();
           for (PsiElement element : result) {
             if (element instanceof PsiField
                 && myReplaceFieldsWithGetters
                     != IntroduceParameterRefactoring
                         .REPLACE_FIELDS_WITH_GETTERS_NONE) { // check getter access instead
               final PsiClass psiClass = ((PsiField) element).getContainingClass();
               LOG.assertTrue(psiClass != null);
               final PsiMethod method =
                   psiClass.findMethodBySignature(
                       PropertyUtil.generateGetterPrototype((PsiField) element), true);
               if (method != null) {
                 element = method;
               }
             }
             if (element instanceof PsiMember
                 && !JavaPsiFacade.getInstance(myProject)
                     .getResolveHelper()
                     .isAccessible((PsiMember) element, place, null)) {
               String message =
                   RefactoringBundle.message(
                       "0.is.not.accessible.from.1.value.for.introduced.parameter.in.that.method.call.will.be.incorrect",
                       RefactoringUIUtil.getDescription(element, true),
                       RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(place), true));
               conflicts.putValue(element, message);
             }
           }
         }
       }
     }
   }
 }
 public static boolean containsMember(@Nullable PsiType qualifierType, @NotNull Object object) {
   if (qualifierType instanceof PsiArrayType
       && object instanceof PsiMember) { // length and clone()
     PsiFile file = ((PsiMember) object).getContainingFile();
     if (file == null || file.getVirtualFile() == null) { // yes, they're a bit dummy
       return true;
     }
   } else if (qualifierType instanceof PsiClassType) {
     PsiClass qualifierClass = ((PsiClassType) qualifierType).resolve();
     if (qualifierClass == null) return false;
     if (object instanceof PsiMethod
         && qualifierClass.findMethodBySignature((PsiMethod) object, false) != null) {
       return true;
     }
     if (object instanceof PsiMember) {
       return qualifierClass.equals(((PsiMember) object).getContainingClass());
     }
   }
   return false;
 }
  private static void addGetterSetterElements(
      CompletionResultSet result, PsiClass parent, Set<MethodSignature> addedSignatures) {
    int count = 0;
    for (PsiField field : parent.getFields()) {
      if (field instanceof PsiEnumConstant) continue;

      List<PsiMethod> prototypes = ContainerUtil.newSmartList();
      Collections.addAll(
          prototypes, GetterSetterPrototypeProvider.generateGetterSetters(field, true));
      Collections.addAll(
          prototypes, GetterSetterPrototypeProvider.generateGetterSetters(field, false));
      for (final PsiMethod prototype : prototypes) {
        if (parent.findMethodBySignature(prototype, false) == null
            && addedSignatures.add(prototype.getSignature(PsiSubstitutor.EMPTY))) {
          Icon icon = prototype.getIcon(Iconable.ICON_FLAG_VISIBILITY);
          result.addElement(
              createGenerateMethodElement(
                  prototype,
                  PsiSubstitutor.EMPTY,
                  icon,
                  "",
                  new InsertHandler<LookupElement>() {
                    @Override
                    public void handleInsert(InsertionContext context, LookupElement item) {
                      removeLookupString(context);

                      insertGenerationInfos(
                          context,
                          Collections.singletonList(new PsiGenerationInfo<PsiMethod>(prototype)));
                    }
                  }));

          if (count++ > 100) return;
        }
      }
    }
  }
  private static boolean areGroovyObjectMethodsOverridden(GrReferenceExpression ref) {
    PsiType qualifierType = GrReferenceResolveUtil.getQualifierType(ref);
    if (!(qualifierType instanceof PsiClassType)) return false;

    PsiClass resolved = ((PsiClassType) qualifierType).resolve();
    if (resolved == null) return false;

    PsiClass groovyObject =
        JavaPsiFacade.getInstance(ref.getProject())
            .findClass(GroovyCommonClassNames.GROOVY_OBJECT, ref.getResolveScope());
    if (groovyObject == null) return false;

    String methodName;
    if (ref.getParent() instanceof GrCall) {
      methodName = "invokeMethod";
    } else if (PsiUtil.isLValue(ref)) {
      methodName = "setProperty";
    } else {
      methodName = "getProperty";
    }

    PsiMethod[] patternMethods = groovyObject.findMethodsByName(methodName, false);
    if (patternMethods.length != 1) return false;

    PsiMethod patternMethod = patternMethods[0];
    PsiMethod found = resolved.findMethodBySignature(patternMethod, true);
    if (found == null) return false;

    PsiClass aClass = found.getContainingClass();
    if (aClass == null) return false;
    String qname = aClass.getQualifiedName();
    if (GroovyCommonClassNames.GROOVY_OBJECT.equals(qname)) return false;
    if (GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT.equals(qname)) return false;

    return true;
  }
  /** Should be invoked in command and write action */
  @SuppressWarnings({"HardCodedStringLiteral"})
  public static void generateDataBindingMethods(final WizardData data) throws MyException {
    if (data.myBindToNewBean) {
      data.myBeanClass = createBeanClass(data);
    } else {
      if (!CommonRefactoringUtil.checkReadOnlyStatus(
          data.myBeanClass.getProject(), data.myBeanClass)) {
        return;
      }
    }

    final HashMap<String, String> binding2beanGetter = new HashMap<String, String>();
    final HashMap<String, String> binding2beanSetter = new HashMap<String, String>();

    final FormProperty2BeanProperty[] bindings = data.myBindings;
    for (final FormProperty2BeanProperty form2bean : bindings) {
      if (form2bean == null || form2bean.myBeanProperty == null) {
        continue;
      }

      // check that bean contains the property, and if not, try to add the property to the bean
      {
        final String setterName = PropertyUtil.suggestSetterName(form2bean.myBeanProperty.myName);
        final PsiMethod[] methodsByName = data.myBeanClass.findMethodsByName(setterName, true);
        if (methodsByName.length < 1) {
          // bean does not contain this property
          // try to add...

          LOG.assertTrue(
              !data.myBindToNewBean); // just generated bean class should contain all necessary
                                      // properties

          if (!data.myBeanClass.isWritable()) {
            throw new MyException(
                "Cannot add property to non writable class " + data.myBeanClass.getQualifiedName());
          }

          final StringBuffer membersBuffer = new StringBuffer();
          final StringBuffer methodsBuffer = new StringBuffer();

          final Project project = data.myBeanClass.getProject();
          final CodeStyleManager formatter = CodeStyleManager.getInstance(project);
          final JavaCodeStyleManager styler = JavaCodeStyleManager.getInstance(project);

          generateProperty(
              styler,
              form2bean.myBeanProperty.myName,
              form2bean.myBeanProperty.myType,
              membersBuffer,
              methodsBuffer);

          final PsiClass fakeClass;
          try {
            fakeClass =
                JavaPsiFacade.getInstance(data.myBeanClass.getProject())
                    .getElementFactory()
                    .createClassFromText(membersBuffer.toString() + methodsBuffer.toString(), null);

            final PsiField[] fields = fakeClass.getFields();
            {
              final PsiElement result = data.myBeanClass.add(fields[0]);
              styler.shortenClassReferences(result);
              formatter.reformat(result);
            }

            final PsiMethod[] methods = fakeClass.getMethods();
            {
              final PsiElement result = data.myBeanClass.add(methods[0]);
              styler.shortenClassReferences(result);
              formatter.reformat(result);
            }
            {
              final PsiElement result = data.myBeanClass.add(methods[1]);
              styler.shortenClassReferences(result);
              formatter.reformat(result);
            }
          } catch (IncorrectOperationException e) {
            throw new MyException(e.getMessage());
          }
        }
      }

      final PsiMethod propertySetter =
          PropertyUtil.findPropertySetter(
              data.myBeanClass, form2bean.myBeanProperty.myName, false, true);
      final PsiMethod propertyGetter =
          PropertyUtil.findPropertyGetter(
              data.myBeanClass, form2bean.myBeanProperty.myName, false, true);

      if (propertyGetter == null) {
        // todo
        continue;
      }
      if (propertySetter == null) {
        // todo
        continue;
      }

      final String binding = form2bean.myFormProperty.getLwComponent().getBinding();
      binding2beanGetter.put(binding, propertyGetter.getName());
      binding2beanSetter.put(binding, propertySetter.getName());
    }

    final String dataBeanClassName = data.myBeanClass.getQualifiedName();

    final LwRootContainer[] rootContainer = new LwRootContainer[1];
    final FormProperty[] formProperties =
        exposeForm(data.myProject, data.myFormFile, rootContainer);

    final StringBuffer getDataBody = new StringBuffer();
    final StringBuffer setDataBody = new StringBuffer();
    final StringBuffer isModifiedBody = new StringBuffer();

    // iterate exposed formproperties

    for (final FormProperty formProperty : formProperties) {
      final String binding = formProperty.getLwComponent().getBinding();
      if (!binding2beanGetter.containsKey(binding)) {
        continue;
      }

      getDataBody.append("data.");
      getDataBody.append(binding2beanSetter.get(binding));
      getDataBody.append("(");
      getDataBody.append(binding);
      getDataBody.append(".");
      getDataBody.append(formProperty.getComponentPropertyGetterName());
      getDataBody.append("());\n");

      setDataBody.append(binding);
      setDataBody.append(".");
      setDataBody.append(formProperty.getComponentPropertySetterName());
      setDataBody.append("(data.");
      setDataBody.append(binding2beanGetter.get(binding));
      setDataBody.append("());\n");

      final String propertyClassName = formProperty.getComponentPropertyClassName();
      if ("boolean".equals(propertyClassName)) {
        isModifiedBody.append("if (");
        //
        isModifiedBody.append(binding);
        isModifiedBody.append(".");
        isModifiedBody.append(formProperty.getComponentPropertyGetterName());
        isModifiedBody.append("()");
        //
        isModifiedBody.append("!= ");
        //
        isModifiedBody.append("data.");
        isModifiedBody.append(binding2beanGetter.get(binding));
        isModifiedBody.append("()");
        //
        isModifiedBody.append(") return true;\n");
      } else {
        isModifiedBody.append("if (");
        //
        isModifiedBody.append(binding);
        isModifiedBody.append(".");
        isModifiedBody.append(formProperty.getComponentPropertyGetterName());
        isModifiedBody.append("()");
        //
        isModifiedBody.append("!= null ? ");
        //
        isModifiedBody.append("!");
        //
        isModifiedBody.append(binding);
        isModifiedBody.append(".");
        isModifiedBody.append(formProperty.getComponentPropertyGetterName());
        isModifiedBody.append("()");
        //
        isModifiedBody.append(".equals(");
        //
        isModifiedBody.append("data.");
        isModifiedBody.append(binding2beanGetter.get(binding));
        isModifiedBody.append("()");
        isModifiedBody.append(") : ");
        //
        isModifiedBody.append("data.");
        isModifiedBody.append(binding2beanGetter.get(binding));
        isModifiedBody.append("()");
        isModifiedBody.append("!= null");
        //
        isModifiedBody.append(") return true;\n");
      }
    }
    isModifiedBody.append("return false;\n");

    final String textOfMethods =
        "public void setData("
            + dataBeanClassName
            + " data){\n"
            + setDataBody.toString()
            + "}\n"
            + "\n"
            + "public void getData("
            + dataBeanClassName
            + " data){\n"
            + getDataBody.toString()
            + "}\n"
            + "\n"
            + "public boolean isModified("
            + dataBeanClassName
            + " data){\n"
            + isModifiedBody.toString()
            + "}\n";

    // put them to the bound class

    final Module module = ModuleUtil.findModuleForFile(data.myFormFile, data.myProject);
    LOG.assertTrue(module != null);
    final PsiClass boundClass =
        FormEditingUtil.findClassToBind(module, rootContainer[0].getClassToBind());
    LOG.assertTrue(boundClass != null);

    if (!CommonRefactoringUtil.checkReadOnlyStatus(module.getProject(), boundClass)) {
      return;
    }

    // todo: check that this method does not exist yet

    final PsiClass fakeClass;
    try {
      fakeClass =
          JavaPsiFacade.getInstance(data.myProject)
              .getElementFactory()
              .createClassFromText(textOfMethods, null);

      final PsiMethod methodSetData = fakeClass.getMethods()[0];
      final PsiMethod methodGetData = fakeClass.getMethods()[1];
      final PsiMethod methodIsModified = fakeClass.getMethods()[2];

      final PsiMethod existing1 = boundClass.findMethodBySignature(methodSetData, false);
      final PsiMethod existing2 = boundClass.findMethodBySignature(methodGetData, false);
      final PsiMethod existing3 = boundClass.findMethodBySignature(methodIsModified, false);

      // warning already shown
      if (existing1 != null) {
        existing1.delete();
      }
      if (existing2 != null) {
        existing2.delete();
      }
      if (existing3 != null) {
        existing3.delete();
      }

      final CodeStyleManager formatter = CodeStyleManager.getInstance(module.getProject());
      final JavaCodeStyleManager styler = JavaCodeStyleManager.getInstance(module.getProject());

      final PsiElement setData = boundClass.add(methodSetData);
      styler.shortenClassReferences(setData);
      formatter.reformat(setData);

      final PsiElement getData = boundClass.add(methodGetData);
      styler.shortenClassReferences(getData);
      formatter.reformat(getData);

      if (data.myGenerateIsModified) {
        final PsiElement isModified = boundClass.add(methodIsModified);
        styler.shortenClassReferences(isModified);
        formatter.reformat(isModified);
      }

      final OpenFileDescriptor descriptor =
          new OpenFileDescriptor(
              setData.getProject(),
              setData.getContainingFile().getVirtualFile(),
              setData.getTextOffset());
      FileEditorManager.getInstance(data.myProject).openTextEditor(descriptor, true);
    } catch (IncorrectOperationException e) {
      throw new MyException(e.getMessage());
    }
  }
  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);
    }
  }
  private void doMoveMethod(PsiSubstitutor substitutor, MemberInfo info) {
    PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
    PsiMethod method = (PsiMethod) info.getMember();
    PsiMethod sibling = method;
    PsiMethod anchor = null;
    while (sibling != null) {
      sibling = PsiTreeUtil.getNextSiblingOfType(sibling, PsiMethod.class);
      if (sibling != null) {
        anchor =
            MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(
                method.getContainingClass(),
                myTargetSuperClass,
                sibling.getSignature(PsiSubstitutor.EMPTY),
                false);
        if (anchor != null) {
          break;
        }
      }
    }
    PsiMethod methodCopy = (PsiMethod) method.copy();
    Language language = myTargetSuperClass.getLanguage();
    final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false);
    if (superClassMethod != null && superClassMethod.findDeepestSuperMethods().length == 0
        || method.findSuperMethods(myTargetSuperClass).length == 0) {
      deleteOverrideAnnotationIfFound(methodCopy);
    }
    boolean isOriginalMethodAbstract =
        method.hasModifierProperty(PsiModifier.ABSTRACT)
            || method.hasModifierProperty(PsiModifier.DEFAULT);
    boolean isOriginalMethodPrototype =
        method instanceof HaxeFunctionPrototypeDeclarationWithAttributes;
    if (myIsTargetInterface || info.isToAbstract()) {
      ChangeContextUtil.clearContextInfo(method);

      if (!info.isToAbstract()
          && !method.hasModifierProperty(PsiModifier.ABSTRACT)
          && PsiUtil.isLanguageLevel8OrHigher(myTargetSuperClass)) {
        // pull as default
        RefactoringUtil.makeMethodDefault(methodCopy);
        isOriginalMethodAbstract = true;
      } else {
        RefactoringUtil.makeMethodAbstract(myTargetSuperClass, methodCopy);
      }

      RefactoringUtil.replaceMovedMemberTypeParameters(
          methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);

      myJavaDocPolicy.processCopiedJavaDoc(
          methodCopy.getDocComment(), method.getDocComment(), isOriginalMethodAbstract);

      final PsiMember movedElement;
      if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
        movedElement =
            (PsiMember) superClassMethod.replace(convertMethodToLanguage(methodCopy, language));
      } else {
        methodCopy =
            HaxeElementGenerator.createFunctionPrototypeDeclarationWithAttributes(
                myProject, methodCopy.getText().trim() + ";");

        movedElement =
            anchor != null
                ? (PsiMember) myTargetSuperClass.addBefore(methodCopy, anchor)
                : (PsiMember)
                    myTargetSuperClass.addBefore(methodCopy, myTargetSuperClass.getRBrace());

        reformat(movedElement);
      }
      CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject());
      if (styleSettings.INSERT_OVERRIDE_ANNOTATION) {
        if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myIsTargetInterface
            || PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) {
          new AddAnnotationFix(Override.class.getName(), method)
              .invoke(method.getProject(), null, mySourceClass.getContainingFile());
        }
      }
      if (!PsiUtil.isLanguageLevel6OrHigher(mySourceClass) && myIsTargetInterface) {
        if (isOriginalMethodAbstract) {
          for (PsiMethod oMethod : OverridingMethodsSearch.search(method)) {
            deleteOverrideAnnotationIfFound(oMethod);
          }
        }
        deleteOverrideAnnotationIfFound(method);
      }
      myMembersAfterMove.add(movedElement);
      // if (isOriginalMethodAbstract) {
      method.delete();
      // }
    } else {
      if (isOriginalMethodAbstract) {
        PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true);
      }
      RefactoringUtil.replaceMovedMemberTypeParameters(
          methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
      fixReferencesToStatic(methodCopy);

      if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
        superClassMethod.replace(convertMethodToLanguage(methodCopy, language));
      } else {
        final PsiMember movedElement =
            anchor != null
                ? (PsiMember)
                    myTargetSuperClass.addBefore(
                        convertMethodToLanguage(methodCopy, language), anchor)
                : (PsiMember)
                    myTargetSuperClass.addBefore(
                        convertMethodToLanguage(methodCopy, language),
                        myTargetSuperClass.getRBrace());
        reformat(movedElement);
        myMembersAfterMove.add(movedElement);
      }
      method.delete();
    }
  }
  @NotNull
  private static LookupElement castQualifier(
      @NotNull LookupElement item,
      @Nullable final PsiTypeLookupItem castTypeItem,
      @Nullable PsiType plainQualifier,
      JavaCompletionProcessor processor) {
    if (castTypeItem == null) {
      return item;
    }
    if (plainQualifier != null) {
      Object o = item.getObject();
      if (o instanceof PsiMethod) {
        PsiType castType = castTypeItem.getType();
        if (plainQualifier instanceof PsiClassType && castType instanceof PsiClassType) {
          PsiMethod method = (PsiMethod) o;
          PsiClassType.ClassResolveResult plainResult =
              ((PsiClassType) plainQualifier).resolveGenerics();
          PsiClass plainClass = plainResult.getElement();
          if (plainClass != null && plainClass.findMethodBySignature(method, true) != null) {
            PsiClass castClass = ((PsiClassType) castType).resolveGenerics().getElement();

            if (castClass == null || !castClass.isInheritor(plainClass, true)) {
              return item;
            }

            PsiSubstitutor plainSub = plainResult.getSubstitutor();
            PsiSubstitutor castSub =
                TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType) castType);
            PsiType returnType = method.getReturnType();
            if (method.getSignature(plainSub).equals(method.getSignature(castSub))) {
              PsiType typeAfterCast = toRaw(castSub.substitute(returnType));
              PsiType typeDeclared = toRaw(plainSub.substitute(returnType));
              if (typeAfterCast != null
                  && typeDeclared != null
                  && typeAfterCast.isAssignableFrom(typeDeclared)
                  && processor.isAccessible(plainClass.findMethodBySignature(method, true))) {
                return item;
              }
            }
          }
        }
      } else if (containsMember(plainQualifier, o)) {
        return item;
      }
    }

    return LookupElementDecorator.withInsertHandler(
        item,
        new InsertHandlerDecorator<LookupElement>() {
          @Override
          public void handleInsert(
              InsertionContext context, LookupElementDecorator<LookupElement> item) {
            final Document document = context.getEditor().getDocument();
            context.commitDocument();
            final PsiFile file = context.getFile();
            final PsiJavaCodeReferenceElement ref =
                PsiTreeUtil.findElementOfClassAtOffset(
                    file, context.getStartOffset(), PsiJavaCodeReferenceElement.class, false);
            if (ref != null) {
              final PsiElement qualifier = ref.getQualifier();
              if (qualifier != null) {
                final CommonCodeStyleSettings settings = context.getCodeStyleSettings();

                final String parenSpace = settings.SPACE_WITHIN_PARENTHESES ? " " : "";
                document.insertString(qualifier.getTextRange().getEndOffset(), parenSpace + ")");

                final String spaceWithin = settings.SPACE_WITHIN_CAST_PARENTHESES ? " " : "";
                final String prefix = "(" + parenSpace + "(" + spaceWithin;
                final String spaceAfter = settings.SPACE_AFTER_TYPE_CAST ? " " : "";
                final int exprStart = qualifier.getTextRange().getStartOffset();
                document.insertString(exprStart, prefix + spaceWithin + ")" + spaceAfter);

                CompletionUtil.emulateInsertion(context, exprStart + prefix.length(), castTypeItem);
                PsiDocumentManager.getInstance(file.getProject())
                    .doPostponedOperationsAndUnblockDocument(document);
                context.getEditor().getCaretModel().moveToOffset(context.getTailOffset());
              }
            }

            item.getDelegate().handleInsert(context);
          }
        });
  }
  private void checkExistingMethods(MultiMap<PsiElement, String> conflicts, boolean isGetter) {
    if (isGetter) {
      if (!myDescriptor.isToEncapsulateGet()) return;
    } else {
      if (!myDescriptor.isToEncapsulateSet()) return;
    }

    for (FieldDescriptor descriptor : myFieldDescriptors) {
      PsiMethod prototype =
          isGetter ? descriptor.getGetterPrototype() : descriptor.getSetterPrototype();

      final PsiType prototypeReturnType = prototype.getReturnType();
      PsiMethod existing = myClass.findMethodBySignature(prototype, true);
      if (existing != null) {
        final PsiType returnType = existing.getReturnType();
        if (!RefactoringUtil.equivalentTypes(
            prototypeReturnType, returnType, myClass.getManager())) {
          final String descr =
              PsiFormatUtil.formatMethod(
                  existing,
                  PsiSubstitutor.EMPTY,
                  PsiFormatUtilBase.SHOW_NAME
                      | PsiFormatUtilBase.SHOW_PARAMETERS
                      | PsiFormatUtilBase.SHOW_TYPE,
                  PsiFormatUtilBase.SHOW_TYPE);
          String message =
              isGetter
                  ? RefactoringBundle.message(
                      "encapsulate.fields.getter.exists",
                      CommonRefactoringUtil.htmlEmphasize(descr),
                      CommonRefactoringUtil.htmlEmphasize(prototype.getName()))
                  : RefactoringBundle.message(
                      "encapsulate.fields.setter.exists",
                      CommonRefactoringUtil.htmlEmphasize(descr),
                      CommonRefactoringUtil.htmlEmphasize(prototype.getName()));
          conflicts.putValue(existing, message);
        }
      } else {
        PsiClass containingClass = myClass.getContainingClass();
        while (containingClass != null && existing == null) {
          existing = containingClass.findMethodBySignature(prototype, true);
          if (existing != null) {
            for (PsiReference reference : ReferencesSearch.search(existing)) {
              final PsiElement place = reference.getElement();
              LOG.assertTrue(place instanceof PsiReferenceExpression);
              final PsiExpression qualifierExpression =
                  ((PsiReferenceExpression) place).getQualifierExpression();
              final PsiClass inheritor;
              if (qualifierExpression == null) {
                inheritor = PsiTreeUtil.getParentOfType(place, PsiClass.class, false);
              } else {
                inheritor = PsiUtil.resolveClassInType(qualifierExpression.getType());
              }

              if (InheritanceUtil.isInheritorOrSelf(inheritor, myClass, true)) {
                conflicts.putValue(
                    existing,
                    "There is already a "
                        + RefactoringUIUtil.getDescription(existing, true)
                        + " which would be hidden by generated "
                        + (isGetter ? "getter" : "setter"));
                break;
              }
            }
          }
          containingClass = containingClass.getContainingClass();
        }
      }
    }
  }