public Collection<PsiElement> getAdditionalElementsToDelete(
      @NotNull final PsiElement element,
      @NotNull final Collection<PsiElement> allElementsToDelete,
      final boolean askUser) {
    if (element instanceof PsiField) {
      PsiField field = (PsiField) element;
      final Project project = element.getProject();
      String propertyName =
          JavaCodeStyleManager.getInstance(project)
              .variableNameToPropertyName(field.getName(), VariableKind.FIELD);

      PsiClass aClass = field.getContainingClass();
      if (aClass != null) {
        boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
        PsiMethod[] getters =
            GetterSetterPrototypeProvider.findGetters(aClass, propertyName, isStatic);
        if (getters != null) {
          final List<PsiMethod> validGetters = new ArrayList<>(1);
          for (PsiMethod getter : getters) {
            if (!allElementsToDelete.contains(getter) && (getter != null && getter.isPhysical())) {
              validGetters.add(getter);
            }
          }
          getters =
              validGetters.isEmpty()
                  ? null
                  : validGetters.toArray(new PsiMethod[validGetters.size()]);
        }

        PsiMethod setter = PropertyUtil.findPropertySetter(aClass, propertyName, isStatic, false);
        if (allElementsToDelete.contains(setter) || setter != null && !setter.isPhysical())
          setter = null;
        if (askUser && (getters != null || setter != null)) {
          final String message =
              RefactoringMessageUtil.getGetterSetterMessage(
                  field.getName(),
                  RefactoringBundle.message("delete.title"),
                  getters != null ? getters[0] : null,
                  setter);
          if (!ApplicationManager.getApplication().isUnitTestMode()
              && Messages.showYesNoDialog(
                      project,
                      message,
                      RefactoringBundle.message("safe.delete.title"),
                      Messages.getQuestionIcon())
                  != Messages.YES) {
            getters = null;
            setter = null;
          }
        }
        List<PsiElement> elements = new ArrayList<>();
        if (setter != null) elements.add(setter);
        if (getters != null) Collections.addAll(elements, getters);
        return elements;
      }
    }
    return null;
  }
  @Override
  protected boolean preprocessUsages(@NotNull final Ref<UsageInfo[]> refUsages) {
    final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
    myExtractEnumProcessor.findEnumConstantConflicts(refUsages);
    if (!DestinationFolderComboBox.isAccessible(
        myProject,
        sourceClass.getContainingFile().getVirtualFile(),
        myClass.getContainingFile().getContainingDirectory().getVirtualFile())) {
      conflicts.putValue(
          sourceClass,
          "Extracted class won't be accessible in "
              + RefactoringUIUtil.getDescription(sourceClass, true));
    }
    ApplicationManager.getApplication()
        .runWriteAction(
            new Runnable() {
              public void run() {
                myClass.delete();
              }
            });
    final Project project = sourceClass.getProject();
    final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
    final PsiClass existingClass =
        JavaPsiFacade.getInstance(project).findClass(getQualifiedName(), scope);
    if (existingClass != null) {
      conflicts.putValue(
          existingClass,
          RefactorJBundle.message("cannot.perform.the.refactoring")
              + RefactorJBundle.message("there.already.exists.a.class.with.the.chosen.name"));
    }

    if (!myGenerateAccessors) {
      calculateInitializersConflicts(conflicts);
      final NecessaryAccessorsVisitor visitor = checkNecessaryGettersSetters4ExtractedClass();
      final NecessaryAccessorsVisitor srcVisitor = checkNecessaryGettersSetters4SourceClass();
      final Set<PsiField> fieldsNeedingGetter = new LinkedHashSet<PsiField>();
      fieldsNeedingGetter.addAll(visitor.getFieldsNeedingGetter());
      fieldsNeedingGetter.addAll(srcVisitor.getFieldsNeedingGetter());
      for (PsiField field : fieldsNeedingGetter) {
        conflicts.putValue(field, "Field \'" + field.getName() + "\' needs getter");
      }
      final Set<PsiField> fieldsNeedingSetter = new LinkedHashSet<PsiField>();
      fieldsNeedingSetter.addAll(visitor.getFieldsNeedingSetter());
      fieldsNeedingSetter.addAll(srcVisitor.getFieldsNeedingSetter());
      for (PsiField field : fieldsNeedingSetter) {
        conflicts.putValue(field, "Field \'" + field.getName() + "\' needs setter");
      }
    }
    checkConflicts(refUsages, conflicts);
    return showConflicts(conflicts, refUsages.get());
  }
 private static PsiField convertFieldToLanguage(PsiField field, Language language) {
   if (field.getLanguage().equals(language)) {
     return field;
   }
   return JVMElementFactories.getFactory(language, field.getProject())
       .createField(field.getName(), field.getType());
 }
  private static PsiAnnotationMemberValue[] readFromClass(
      @NonNls String attributeName, @NotNull PsiAnnotation magic, PsiType type) {
    PsiAnnotationMemberValue fromClassAttr = magic.findAttributeValue(attributeName);
    PsiType fromClassType =
        fromClassAttr instanceof PsiClassObjectAccessExpression
            ? ((PsiClassObjectAccessExpression) fromClassAttr).getOperand().getType()
            : null;
    PsiClass fromClass =
        fromClassType instanceof PsiClassType ? ((PsiClassType) fromClassType).resolve() : null;
    if (fromClass == null) return null;
    String fqn = fromClass.getQualifiedName();
    if (fqn == null) return null;
    List<PsiAnnotationMemberValue> constants = new ArrayList<PsiAnnotationMemberValue>();
    for (PsiField field : fromClass.getFields()) {
      if (!field.hasModifierProperty(PsiModifier.PUBLIC)
          || !field.hasModifierProperty(PsiModifier.STATIC)
          || !field.hasModifierProperty(PsiModifier.FINAL)) continue;
      PsiType fieldType = field.getType();
      if (!Comparing.equal(fieldType, type)) continue;
      PsiAssignmentExpression e =
          (PsiAssignmentExpression)
              JavaPsiFacade.getElementFactory(field.getProject())
                  .createExpressionFromText("x=" + fqn + "." + field.getName(), field);
      PsiReferenceExpression refToField = (PsiReferenceExpression) e.getRExpression();
      constants.add(refToField);
    }
    if (constants.isEmpty()) return null;

    return constants.toArray(new PsiAnnotationMemberValue[constants.size()]);
  }
 private boolean existsFieldWithName(String name) {
   final PsiField[] allFields = sourceClass.getAllFields();
   for (PsiField field : allFields) {
     if (name.equals(field.getName()) && !fields.contains(field)) {
       return true;
     }
   }
   return false;
 }
示例#6
0
 @NotNull
 private Field fieldToField(@NotNull PsiField field, PsiClass psiClass) {
   Set<String> modifiers = modifiersListToModifiersSet(field.getModifierList());
   if (field instanceof PsiEnumConstant) // TODO: remove instanceof
   {
     return new EnumConstant(
         new IdentifierImpl(field.getName()), // TODO
         modifiers,
         typeToType(field.getType()),
         elementToElement(((PsiEnumConstant) field).getArgumentList()));
   }
   return new Field(
       new IdentifierImpl(field.getName()), // TODO
       modifiers,
       typeToType(field.getType(), ConverterUtil.isAnnotatedAsNotNull(field.getModifierList())),
       createSureCallOnlyForChain(field.getInitializer(), field.getType()), // TODO: add modifiers
       countWritingAccesses(field, psiClass));
 }
示例#7
0
  public static PsiMethod generateSetterPrototype(
      PsiField field, final PsiClass containingClass, boolean returnSelf) {
    Project project = field.getProject();
    JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
    PsiElementFactory factory = JavaPsiFacade.getInstance(field.getProject()).getElementFactory();

    String name = field.getName();
    boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
    VariableKind kind = codeStyleManager.getVariableKind(field);
    String propertyName = codeStyleManager.variableNameToPropertyName(name, kind);
    String setName = suggestSetterName(project, field);
    try {
      PsiMethod setMethod =
          factory.createMethod(
              setName, returnSelf ? factory.createType(containingClass) : PsiType.VOID);
      String parameterName =
          codeStyleManager.propertyNameToVariableName(propertyName, VariableKind.PARAMETER);
      PsiParameter param = factory.createParameter(parameterName, field.getType());

      annotateWithNullableStuff(field, factory, param);

      setMethod.getParameterList().add(param);
      PsiUtil.setModifierProperty(setMethod, PsiModifier.PUBLIC, true);
      PsiUtil.setModifierProperty(setMethod, PsiModifier.STATIC, isStatic);

      @NonNls StringBuffer buffer = new StringBuffer();
      buffer.append("{\n");
      if (name.equals(parameterName)) {
        if (!isStatic) {
          buffer.append("this.");
        } else {
          String className = containingClass.getName();
          if (className != null) {
            buffer.append(className);
            buffer.append(".");
          }
        }
      }
      buffer.append(name);
      buffer.append("=");
      buffer.append(parameterName);
      buffer.append(";\n");
      if (returnSelf) {
        buffer.append("return this;\n");
      }
      buffer.append("}");
      PsiCodeBlock body = factory.createCodeBlockFromText(buffer.toString(), null);
      setMethod.getBody().replace(body);
      setMethod = (PsiMethod) CodeStyleManager.getInstance(project).reformat(setMethod);
      return setMethod;
    } catch (IncorrectOperationException e) {
      LOG.error(e);
      return null;
    }
  }
  public static boolean isFieldEquivalentTo(@NotNull PsiField field, PsiElement another) {
    if (!(another instanceof PsiField)) return false;
    String name1 = field.getName();
    if (name1 == null) return false;
    if (!another.isValid()) return false;

    String name2 = ((PsiField) another).getName();
    if (!name1.equals(name2)) return false;
    PsiClass aClass1 = field.getContainingClass();
    PsiClass aClass2 = ((PsiField) another).getContainingClass();
    return aClass1 != null
        && aClass2 != null
        && field.getManager().areElementsEquivalent(aClass1, aClass2);
  }
  @Nullable
  public static PsiField findFieldByName(
      GrTypeDefinition grType, String name, boolean checkBases, boolean includeSynthetic) {
    if (!checkBases) {
      for (PsiField field : CollectClassMembersUtil.getFields(grType, includeSynthetic)) {
        if (name.equals(field.getName())) return field;
      }

      return null;
    }

    Map<String, CandidateInfo> fieldsMap =
        CollectClassMembersUtil.getAllFields(grType, includeSynthetic);
    final CandidateInfo info = fieldsMap.get(name);
    return info == null ? null : (PsiField) info.getElement();
  }
 private static void addFieldsUsages(
     final PsiClass aClass,
     final Processor<UsageInfo> results,
     final JavaClassFindUsagesOptions options) {
   if (options.isIncludeInherited) {
     final PsiManager manager = aClass.getManager();
     PsiField[] fields = aClass.getAllFields();
     FieldsLoop:
     for (int i = 0; i < fields.length; i++) {
       final PsiField field = fields[i];
       // filter hidden fields
       for (int j = 0; j < i; j++) {
         if (Comparing.strEqual(field.getName(), fields[j].getName())) continue FieldsLoop;
       }
       final PsiClass fieldClass = field.getContainingClass();
       if (manager.areElementsEquivalent(fieldClass, aClass)) {
         addElementUsages(fields[i], results, options);
       } else {
         ReferencesSearch.search(
                 new ReferencesSearch.SearchParameters(
                     field, options.searchScope, false, options.fastTrack))
             .forEach(
                 new ReadActionProcessor<PsiReference>() {
                   @Override
                   public boolean processInReadAction(final PsiReference reference) {
                     addResultFromReference(
                         reference, fieldClass, manager, aClass, results, options);
                     return true;
                   }
                 });
       }
     }
   } else {
     PsiField[] fields =
         ApplicationManager.getApplication()
             .runReadAction(
                 new Computable<PsiField[]>() {
                   @Override
                   public PsiField[] compute() {
                     return aClass.getFields();
                   }
                 });
     for (PsiField field : fields) {
       addElementUsages(field, results, options);
     }
   }
 }
示例#11
0
  @NotNull
  private Set<String> addAllRestrictedProperties() {
    if (myRefExpr.getQualifier() != null) {
      return Collections.emptySet();
    }

    Set<String> propertyNames = new HashSet<String>();
    for (GrTypeDefinition containingClass =
            PsiTreeUtil.getParentOfType(myRefExpr, GrTypeDefinition.class);
        containingClass != null;
        containingClass = PsiTreeUtil.getParentOfType(containingClass, GrTypeDefinition.class)) {
      for (PsiField field : containingClass.getFields()) {
        propertyNames.add(field.getName());
      }
    }
    return propertyNames;
  }
  private static void addParameters(
      @NotNull PsiClass psiClass,
      GrLightMethodBuilder fieldsConstructor,
      boolean includeProperties,
      boolean includeFields,
      boolean optional,
      Set<String> excludes) {

    PsiMethod[] methods = CollectClassMembersUtil.getMethods(psiClass, false);
    if (includeProperties) {
      for (PsiMethod method : methods) {
        if (!method.hasModifierProperty(PsiModifier.STATIC)
            && PropertyUtil.isSimplePropertySetter(method)) {
          final String name = PropertyUtil.getPropertyNameBySetter(method);
          if (!excludes.contains(name)) {
            final PsiType type = PropertyUtil.getPropertyType(method);
            assert type != null : method;
            fieldsConstructor.addParameter(
                new GrLightParameter(name, type, fieldsConstructor).setOptional(optional));
          }
        }
      }
    }

    final Map<String, PsiMethod> properties = PropertyUtil.getAllProperties(true, false, methods);
    for (PsiField field : CollectClassMembersUtil.getFields(psiClass, false)) {
      final String name = field.getName();
      if (includeFields
          || includeProperties && field instanceof GrField && ((GrField) field).isProperty()) {
        if (!excludes.contains(name)
            && !field.hasModifierProperty(PsiModifier.STATIC)
            && !properties.containsKey(name)) {
          fieldsConstructor.addParameter(
              new GrLightParameter(name, field.getType(), fieldsConstructor).setOptional(optional));
        }
      }
    }
  }
示例#13
0
  public static PsiMethod generateGetterPrototype(PsiField field) {
    PsiElementFactory factory = JavaPsiFacade.getInstance(field.getProject()).getElementFactory();
    Project project = field.getProject();
    String name = field.getName();
    String getName = suggestGetterName(project, field);
    try {
      PsiMethod getMethod = factory.createMethod(getName, field.getType());
      PsiUtil.setModifierProperty(getMethod, PsiModifier.PUBLIC, true);
      if (field.hasModifierProperty(PsiModifier.STATIC)) {
        PsiUtil.setModifierProperty(getMethod, PsiModifier.STATIC, true);
      }

      annotateWithNullableStuff(field, factory, getMethod);

      PsiCodeBlock body = factory.createCodeBlockFromText("{\nreturn " + name + ";\n}", null);
      getMethod.getBody().replace(body);
      getMethod = (PsiMethod) CodeStyleManager.getInstance(project).reformat(getMethod);
      return getMethod;
    } catch (IncorrectOperationException e) {
      LOG.error(e);
      return null;
    }
  }
  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 PsiElement[] getSecondaryElements() {
   PsiElement element = getPsiElement();
   if (ApplicationManager.getApplication().isUnitTestMode()) return PsiElement.EMPTY_ARRAY;
   if (element instanceof PsiField) {
     final PsiField field = (PsiField) element;
     PsiClass containingClass = field.getContainingClass();
     if (containingClass != null) {
       String fieldName = field.getName();
       final String propertyName =
           JavaCodeStyleManager.getInstance(getProject())
               .variableNameToPropertyName(fieldName, VariableKind.FIELD);
       Set<PsiMethod> accessors = new THashSet<PsiMethod>();
       boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
       PsiMethod getter =
           PropertyUtil.findPropertyGetterWithType(
               propertyName,
               isStatic,
               field.getType(),
               ContainerUtil.iterate(containingClass.getMethods()));
       if (getter != null) accessors.add(getter);
       PsiMethod setter =
           PropertyUtil.findPropertySetterWithType(
               propertyName,
               isStatic,
               field.getType(),
               ContainerUtil.iterate(containingClass.getMethods()));
       if (setter != null) accessors.add(setter);
       accessors.addAll(PropertyUtil.getAccessors(containingClass, fieldName));
       if (!accessors.isEmpty()) {
         final boolean doSearch;
         boolean containsPhysical =
             ContainerUtil.find(
                     accessors,
                     new Condition<PsiMethod>() {
                       @Override
                       public boolean value(PsiMethod psiMethod) {
                         return psiMethod.isPhysical();
                       }
                     })
                 != null;
         if (!containsPhysical) {
           doSearch = true;
         } else {
           doSearch =
               Messages.showOkCancelDialog(
                       FindBundle.message("find.field.accessors.prompt", fieldName),
                       FindBundle.message("find.field.accessors.title"),
                       CommonBundle.getYesButtonText(),
                       CommonBundle.getNoButtonText(),
                       Messages.getQuestionIcon())
                   == DialogWrapper.OK_EXIT_CODE;
         }
         if (doSearch) {
           final Set<PsiElement> elements = new THashSet<PsiElement>();
           for (PsiMethod accessor : accessors) {
             ContainerUtil.addAll(
                 elements, SuperMethodWarningUtil.checkSuperMethods(accessor, ACTION_STRING));
           }
           return PsiUtilBase.toPsiElementArray(elements);
         }
       }
     }
   }
   return super.getSecondaryElements();
 }
  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()));
      }
    }
  }
示例#17
0
 public static String suggestPropertyName(Project project, PsiField field) {
   JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
   VariableKind kind = codeStyleManager.getVariableKind(field);
   return codeStyleManager.variableNameToPropertyName(field.getName(), kind);
 }