/** Create fields for injections inside main class */
  protected void generateFields() {
    for (Iterator<Element> iterator = mElements.iterator(); iterator.hasNext(); ) {
      Element element = iterator.next();

      if (!element.used) {
        iterator.remove();
        continue;
      }

      // remove duplicate field
      PsiField[] fields = mClass.getFields();
      boolean duplicateField = false;
      for (PsiField field : fields) {
        String name = field.getName();
        if (name != null && name.equals(element.getFieldName())) {
          duplicateField = true;
          break;
        }
      }

      if (duplicateField) {
        iterator.remove();
        continue;
      }

      mClass.add(
          mFactory.createFieldFromText(
              "private " + element.name + " " + element.getFieldName() + ";", mClass));
    }
  }
Esempio n. 2
0
  public void buildReferences() {
    PsiClass psiClass = getElement();

    if (psiClass != null) {
      for (PsiClassInitializer classInitializer : psiClass.getInitializers()) {
        RefJavaUtil.getInstance().addReferences(psiClass, this, classInitializer.getBody());
      }

      RefJavaUtil.getInstance().addReferences(psiClass, this, psiClass.getModifierList());

      PsiField[] psiFields = psiClass.getFields();
      for (PsiField psiField : psiFields) {
        getRefManager().getReference(psiField);
        final PsiExpression initializer = psiField.getInitializer();
        if (initializer != null) {
          RefJavaUtil.getInstance().addReferences(psiClass, this, initializer);
        }
      }

      PsiMethod[] psiMethods = psiClass.getMethods();
      for (PsiMethod psiMethod : psiMethods) {
        getRefManager().getReference(psiMethod);
      }
      getRefManager().fireBuildReferences(this);
    }
  }
  @NotNull
  @Override
  public PsiField createField(@NotNull final String name, @NotNull final PsiType type)
      throws IncorrectOperationException {
    PsiUtil.checkIsIdentifier(myManager, name);
    if (PsiType.NULL.equals(type)) {
      throw new IncorrectOperationException("Cannot create field with type \"null\".");
    }

    @NonNls
    final String text = "class _Dummy_ { private " + type.getCanonicalText() + " " + name + "; }";
    final PsiJavaFile aFile = createDummyJavaFile(text);
    final PsiClass[] classes = aFile.getClasses();
    if (classes.length < 1) {
      throw new IncorrectOperationException("Class was not created " + text);
    }
    final PsiClass psiClass = classes[0];
    final PsiField[] fields = psiClass.getFields();
    if (fields.length < 1) {
      throw new IncorrectOperationException("Field was not created " + text);
    }
    PsiField field = fields[0];
    field =
        (PsiField)
            JavaCodeStyleManager.getInstance(myManager.getProject()).shortenClassReferences(field);
    return (PsiField) CodeStyleManager.getInstance(myManager.getProject()).reformat(field);
  }
  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()]);
  }
Esempio n. 5
0
  private static void docheckClass(final PsiClass aClass, ProblemsHolder holder) {
    if (aClass.isInterface()) return;
    final PsiField[] fields = aClass.getFields();
    final Set<PsiField> candidates = new LinkedHashSet<PsiField>();
    for (PsiField field : fields) {
      if (field.hasModifierProperty(PsiModifier.PRIVATE)
          && !(field.hasModifierProperty(PsiModifier.STATIC)
              && field.hasModifierProperty(PsiModifier.FINAL))) {
        candidates.add(field);
      }
    }

    removeFieldsReferencedFromInitializers(aClass, candidates);
    if (candidates.isEmpty()) return;

    final Set<PsiField> usedFields = new THashSet<PsiField>();
    removeReadFields(aClass, candidates, usedFields);

    if (candidates.isEmpty()) return;
    final ImplicitUsageProvider[] implicitUsageProviders =
        Extensions.getExtensions(ImplicitUsageProvider.EP_NAME);

    for (PsiField field : candidates) {
      if (usedFields.contains(field)
          && !hasImplicitReadOrWriteUsage(field, implicitUsageProviders)) {
        final String message =
            InspectionsBundle.message("inspection.field.can.be.local.problem.descriptor");
        holder.registerProblem(field.getNameIdentifier(), message, new MyQuickFix(field));
      }
    }
  }
  @NotNull
  public Object[] getVariants() {
    PsiElement context = getContext();
    if (context == null) {
      context = JavaPsiFacade.getInstance(getElement().getProject()).findPackage("");
    }
    if (context instanceof PsiPackage) {
      final String[] extendClasses = getExtendClassNames();
      if (extendClasses != null) {
        return getSubclassVariants((PsiPackage) context, extendClasses);
      }
      return processPackage((PsiPackage) context);
    }
    if (context instanceof PsiClass) {
      final PsiClass aClass = (PsiClass) context;

      if (myInStaticImport) {
        return ArrayUtil.mergeArrays(aClass.getInnerClasses(), aClass.getFields(), Object.class);
      } else if (isDefinitelyStatic()) {
        final PsiClass[] psiClasses = aClass.getInnerClasses();
        final List<PsiClass> staticClasses = new ArrayList<PsiClass>(psiClasses.length);

        for (PsiClass c : psiClasses) {
          if (c.hasModifierProperty(PsiModifier.STATIC)) {
            staticClasses.add(c);
          }
        }
        return staticClasses.isEmpty()
            ? PsiClass.EMPTY_ARRAY
            : staticClasses.toArray(new PsiClass[staticClasses.size()]);
      }
    }
    return ArrayUtil.EMPTY_OBJECT_ARRAY;
  }
  private static boolean containsAllCases(GrSwitchStatement statement) {
    final GrCaseSection[] sections = statement.getCaseSections();
    for (GrCaseSection section : sections) {
      if (section.isDefault()) return true;
    }

    final GrExpression condition = statement.getCondition();
    if (!(condition instanceof GrReferenceExpression)) return false;

    PsiType type = TypesUtil.unboxPrimitiveTypeWrapper(getNominalTypeNoRecursion(condition));
    if (type == null) return false;

    if (type instanceof PsiPrimitiveType) {
      if (type == PsiType.BOOLEAN) return sections.length == 2;
      if (type == PsiType.BYTE || type == PsiType.CHAR) return sections.length == 128;
      return false;
    }

    if (type instanceof PsiClassType) {
      final PsiClass resolved = ((PsiClassType) type).resolve();
      if (resolved != null && resolved.isEnum()) {
        int enumConstantCount = 0;
        final PsiField[] fields = resolved.getFields();
        for (PsiField field : fields) {
          if (field instanceof PsiEnumConstant) enumConstantCount++;
        }

        if (sections.length == enumConstantCount) return true;
      }
    }

    return false;
  }
 private static boolean isFieldInitializedInOtherFieldInitializer(
     @NotNull PsiClass aClass, @NotNull PsiField field, final boolean fieldStatic) {
   PsiField[] fields = aClass.getFields();
   for (PsiField psiField : fields) {
     if (psiField != field
         && psiField.hasModifierProperty(PsiModifier.STATIC) == fieldStatic
         && variableDefinitelyAssignedIn(field, psiField)) {
       return true;
     }
   }
   return false;
 }
 private void checkEnumWithConstants(PsiClass enumClass, boolean okToLoadTree) {
   PsiField[] fields = enumClass.getFields();
   assertEquals(3, fields.length);
   checkEnumConstant("A", fields[0]);
   checkEnumConstant("B", fields[1]);
   checkEnumConstant("C", fields[2]);
   if (okToLoadTree) {
     assertEquals("A", fields[0].getText());
     assertEquals("B", fields[1].getText());
     assertEquals("C", fields[2].getText());
   }
 }
  public void testDeprecatedAnnotation() throws IOException {
    setupLoadingFilter();

    final PsiClass aClass =
        myJavaFacade.findClass(
            "annotations.DeprecatedAnnotation", GlobalSearchScope.moduleScope(myModule));
    assertNotNull(aClass);
    assertTrue(aClass.isDeprecated());
    PsiMethod method = aClass.getMethods()[0];
    assertTrue(method.isDeprecated());
    PsiField field = aClass.getFields()[0];
    assertTrue(field.isDeprecated());
    teardownLoadingFilter();
  }
 private void registerNestedClosures(DfaInstructionState instructionState, PsiClass nestedClass) {
   DfaMemoryStateImpl closureState = createClosureState(instructionState.getMemoryState());
   for (PsiMethod method : nestedClass.getMethods()) {
     PsiCodeBlock body = method.getBody();
     if (body != null) {
       myNestedClosures.putValue(body, closureState);
     }
   }
   for (PsiClassInitializer initializer : nestedClass.getInitializers()) {
     myNestedClosures.putValue(initializer.getBody(), closureState);
   }
   for (PsiField field : nestedClass.getFields()) {
     myNestedClosures.putValue(field, closureState);
   }
 }
  public void testEnumWithConstantsAndSastaticFields() throws Exception {
    setupLoadingFilter();
    PsiClass enumClass =
        myJavaFacade.findClass(
            "enums.OurEnumWithConstantsAndStaticFields", GlobalSearchScope.moduleScope(myModule));
    PsiField[] fields = enumClass.getFields();
    assertTrue(fields[0] instanceof PsiEnumConstant);
    assertTrue(fields[1] instanceof PsiEnumConstant);
    assertTrue(fields[2] instanceof PsiEnumConstant);
    assertFalse(fields[3] instanceof PsiEnumConstant);

    teardownLoadingFilter();

    assertEquals("public static final int A1 = 1;", fields[3].getText());
  }
 public void testEnumConstantOrdinal() throws Exception {
   PsiClass psiClass = getTestClass();
   PsiField field = psiClass.getFields()[0];
   final File htmlPath =
       new File(
           JavaTestUtil.getJavaTestDataPath()
               + "/codeInsight/javadocIG/"
               + getTestName(true)
               + ".html");
   String htmlText = FileUtil.loadFile(htmlPath);
   String docInfo = new JavaDocumentationProvider().getQuickNavigateInfo(field, field);
   assertNotNull(docInfo);
   assertEquals(
       StringUtil.convertLineSeparators(htmlText.trim()),
       StringUtil.convertLineSeparators(docInfo.trim()));
 }
 public boolean satisfiedBy(PsiElement element) {
   if (!(element instanceof PsiSwitchStatement)) {
     return false;
   }
   final PsiSwitchStatement switchStatement = (PsiSwitchStatement) element;
   final PsiCodeBlock body = switchStatement.getBody();
   if (body == null) {
     return false;
   }
   final PsiExpression expression = switchStatement.getExpression();
   if (expression == null) {
     return false;
   }
   final PsiType type = expression.getType();
   if (!(type instanceof PsiClassType)) {
     return false;
   }
   final PsiClass enumClass = ((PsiClassType) type).resolve();
   if (enumClass == null || !enumClass.isEnum()) {
     return false;
   }
   final PsiField[] fields = enumClass.getFields();
   final Set<String> enumElements = new HashSet<String>(fields.length);
   for (final PsiField field : fields) {
     final PsiType fieldType = field.getType();
     if (fieldType.equals(type)) {
       final String fieldName = field.getName();
       enumElements.add(fieldName);
     }
   }
   final PsiStatement[] statements = body.getStatements();
   for (PsiStatement statement : statements) {
     if (statement instanceof PsiSwitchLabelStatement) {
       final PsiSwitchLabelStatement labelStatement = (PsiSwitchLabelStatement) statement;
       final PsiExpression value = labelStatement.getCaseValue();
       if (value != null) {
         final String valueText = value.getText();
         enumElements.remove(valueText);
       }
     }
   }
   if (enumElements.isEmpty()) {
     return false;
   }
   return !ErrorUtil.containsError(element);
 }
  @Override
  protected ClassMember[] getAllOriginalMembers(PsiClass aClass) {
    PsiField[] fields = aClass.getFields();
    ArrayList<ClassMember> array = new ArrayList<ClassMember>();
    ImplicitUsageProvider[] implicitUsageProviders =
        Extensions.getExtensions(ImplicitUsageProvider.EP_NAME);
    fieldLoop:
    for (PsiField field : fields) {
      if (field.hasModifierProperty(PsiModifier.STATIC)) continue;

      if (field.hasModifierProperty(PsiModifier.FINAL) && field.getInitializer() != null) continue;

      for (ImplicitUsageProvider provider : implicitUsageProviders) {
        if (provider.isImplicitWrite(field)) continue fieldLoop;
      }
      array.add(new PsiFieldMember(field));
    }
    return array.toArray(new ClassMember[array.size()]);
  }
  // todo: inline
  private static void generateBean(
      final PsiClass aClass,
      final String[] properties,
      final HashMap<String, String> property2fqClassName)
      throws MyException {
    final StringBuffer membersBuffer = new StringBuffer();
    final StringBuffer methodsBuffer = new StringBuffer();

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

    for (final String property : properties) {
      LOG.assertTrue(property != null);
      final String type = property2fqClassName.get(property);
      LOG.assertTrue(type != null);

      generateProperty(styler, property, type, membersBuffer, methodsBuffer);
    }

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

      final PsiField[] fields = fakeClass.getFields();
      for (final PsiField field : fields) {
        aClass.add(field);
      }

      final PsiMethod[] methods = fakeClass.getMethods();
      for (final PsiMethod method : methods) {
        aClass.add(method);
      }

      styler.shortenClassReferences(aClass);
      formatter.reformat(aClass);
    } catch (IncorrectOperationException e) {
      throw new MyException(e.getMessage());
    }
  }
  @Override
  public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
    int offset = editor.getCaretModel().getOffset();
    final PsiMethod method = findMethod(file, offset);

    if (method == null || !method.isValid()) return false;
    setText(getIntentionName(method));

    if (!method.getManager().isInProject(method)) return false;

    PsiClass containingClass = method.getContainingClass();
    if (containingClass == null) return false;
    final boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
    if (isAbstract
        || !method.hasModifierProperty(PsiModifier.PRIVATE)
            && !method.hasModifierProperty(PsiModifier.STATIC)) {
      if (!isAbstract && !isOnIdentifier(file, offset)) return false;
      MyElementProcessor processor = new MyElementProcessor(method);
      if (containingClass.isEnum()) {
        for (PsiField field : containingClass.getFields()) {
          if (field instanceof PsiEnumConstant) {
            final PsiEnumConstantInitializer initializingClass =
                ((PsiEnumConstant) field).getInitializingClass();
            if (initializingClass == null) {
              processor.myHasMissingImplementations = true;
            } else {
              if (!processor.execute(initializingClass)) {
                break;
              }
            }
          }
        }
      }
      ClassInheritorsSearch.search(containingClass, false)
          .forEach(new PsiElementProcessorAdapter<PsiClass>(processor));
      return isAvailable(processor);
    }

    return false;
  }
  private static boolean containsOnlyPrivates(final PsiClass aClass) {
    final PsiField[] fields = aClass.getFields();
    for (PsiField field : fields) {
      if (!field.hasModifierProperty(PsiModifier.PRIVATE)) return false;
    }

    final PsiMethod[] methods = aClass.getMethods();
    for (PsiMethod method : methods) {
      if (!method.hasModifierProperty(PsiModifier.PRIVATE)) {
        if (method.isConstructor()) { // skip non-private constructors with call to super only
          final PsiCodeBlock body = method.getBody();
          if (body != null) {
            final PsiStatement[] statements = body.getStatements();
            if (statements.length == 0) continue;
            if (statements.length == 1 && statements[0] instanceof PsiExpressionStatement) {
              final PsiExpression expression =
                  ((PsiExpressionStatement) statements[0]).getExpression();
              if (expression instanceof PsiMethodCallExpression) {
                PsiReferenceExpression methodExpression =
                    ((PsiMethodCallExpression) expression).getMethodExpression();
                if (methodExpression.getText().equals(PsiKeyword.SUPER)) {
                  continue;
                }
              }
            }
          }
        }
        return false;
      }
    }

    final PsiClass[] inners = aClass.getInnerClasses();
    for (PsiClass inner : inners) {
      if (!inner.hasModifierProperty(PsiModifier.PRIVATE)) return false;
    }

    return true;
  }
  @NotNull
  private static List<PsiMember> findByMap(
      @NotNull PsiClass aClass, String name, boolean checkBases, @NotNull MemberType type) {
    if (name == null) return Collections.emptyList();

    if (checkBases) {
      Map<String, List<Pair<PsiMember, PsiSubstitutor>>> allMethodsMap = getMap(aClass, type);
      List<Pair<PsiMember, PsiSubstitutor>> list = allMethodsMap.get(name);
      if (list == null) return Collections.emptyList();
      List<PsiMember> ret = new ArrayList<PsiMember>(list.size());
      for (final Pair<PsiMember, PsiSubstitutor> info : list) {
        ret.add(info.getFirst());
      }

      return ret;
    } else {
      PsiMember[] members = null;
      switch (type) {
        case METHOD:
          members = aClass.getMethods();
          break;
        case CLASS:
          members = aClass.getInnerClasses();
          break;
        case FIELD:
          members = aClass.getFields();
          break;
      }

      List<PsiMember> list = new ArrayList<PsiMember>();
      for (PsiMember member : members) {
        if (name.equals(member.getName())) {
          list.add(member);
        }
      }
      return list;
    }
  }
  public void testEnumWithConstantsAndStaticFields2() throws Exception {
    setupLoadingFilter();
    PsiClass enumClass =
        myJavaFacade.findClass(
            "enums.OurEnumWithConstantsAndStaticFields2", GlobalSearchScope.moduleScope(myModule));
    PsiField[] fields = enumClass.getFields();
    assertTrue(fields[0] instanceof PsiEnumConstant);
    assertTrue(fields[1] instanceof PsiEnumConstant);
    assertTrue(fields[2] instanceof PsiEnumConstant);
    assertFalse(fields[3] instanceof PsiEnumConstant);

    teardownLoadingFilter();

    assertEquals("public static final int A1 = 10;", fields[3].getText());
    enumClass.accept(
        new JavaRecursiveElementWalkingVisitor() {
          @Override
          public void visitReferenceExpression(PsiReferenceExpression expression) {
            visitExpression(expression);
          }
        });
    enumClass.getText();
  }
  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;
        }
      }
    }
  }
  @Nullable
  public static HighlightInfo checkFinalVariableMightAlreadyHaveBeenAssignedTo(
      @NotNull PsiVariable variable,
      @NotNull PsiReferenceExpression expression,
      @NotNull Map<PsiElement, Collection<ControlFlowUtil.VariableInfo>> finalVarProblems) {
    if (!PsiUtil.isAccessedForWriting(expression)) return null;

    final PsiElement scope =
        variable instanceof PsiField
            ? variable.getParent()
            : variable.getParent() == null ? null : variable.getParent().getParent();
    PsiElement codeBlock = PsiUtil.getTopLevelEnclosingCodeBlock(expression, scope);
    if (codeBlock == null) return null;
    Collection<ControlFlowUtil.VariableInfo> codeBlockProblems =
        getFinalVariableProblemsInBlock(finalVarProblems, codeBlock);

    boolean alreadyAssigned = false;
    for (ControlFlowUtil.VariableInfo variableInfo : codeBlockProblems) {
      if (variableInfo.expression == expression) {
        alreadyAssigned = true;
        break;
      }
    }

    if (!alreadyAssigned) {
      if (!(variable instanceof PsiField)) return null;
      final PsiField field = (PsiField) variable;
      final PsiClass aClass = field.getContainingClass();
      if (aClass == null) return null;
      // field can get assigned in other field initializers
      final PsiField[] fields = aClass.getFields();
      boolean isFieldStatic = field.hasModifierProperty(PsiModifier.STATIC);
      for (PsiField psiField : fields) {
        PsiExpression initializer = psiField.getInitializer();
        if (psiField != field
            && psiField.hasModifierProperty(PsiModifier.STATIC) == isFieldStatic
            && initializer != null
            && initializer != codeBlock
            && !variableDefinitelyNotAssignedIn(field, initializer)) {
          alreadyAssigned = true;
          break;
        }
      }

      if (!alreadyAssigned) {
        // field can get assigned in class initializers
        final PsiMember enclosingConstructorOrInitializer =
            PsiUtil.findEnclosingConstructorOrInitializer(expression);
        if (enclosingConstructorOrInitializer == null
            || !aClass
                .getManager()
                .areElementsEquivalent(
                    enclosingConstructorOrInitializer.getContainingClass(), aClass)) {
          return null;
        }
        final PsiClassInitializer[] initializers = aClass.getInitializers();
        for (PsiClassInitializer initializer : initializers) {
          if (initializer.hasModifierProperty(PsiModifier.STATIC)
              == field.hasModifierProperty(PsiModifier.STATIC)) {
            final PsiCodeBlock body = initializer.getBody();
            if (body == codeBlock) return null;
            try {
              final ControlFlow controlFlow = getControlFlow(body);
              if (!ControlFlowUtil.isVariableDefinitelyNotAssigned(field, controlFlow)) {
                alreadyAssigned = true;
                break;
              }
            } catch (AnalysisCanceledException e) {
              // incomplete code
              return null;
            }
          }
        }
      }

      if (!alreadyAssigned && !field.hasModifierProperty(PsiModifier.STATIC)) {
        // then check if instance field already assigned in other constructor
        final PsiMethod ctr =
            codeBlock.getParent() instanceof PsiMethod ? (PsiMethod) codeBlock.getParent() : null;
        // assignment to final field in several constructors threatens us only if these are linked
        // (there is this() call in the beginning)
        final List<PsiMethod> redirectedConstructors =
            ctr != null && ctr.isConstructor()
                ? JavaHighlightUtil.getChainedConstructors(ctr)
                : null;
        for (int j = 0; redirectedConstructors != null && j < redirectedConstructors.size(); j++) {
          PsiMethod redirectedConstructor = redirectedConstructors.get(j);
          PsiCodeBlock body = redirectedConstructor.getBody();
          if (body != null && variableDefinitelyAssignedIn(variable, body)) {
            alreadyAssigned = true;
            break;
          }
        }
      }
    }

    if (alreadyAssigned) {
      String description =
          JavaErrorMessages.message("variable.already.assigned", variable.getName());
      final HighlightInfo highlightInfo =
          HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
              .range(expression)
              .descriptionAndTooltip(description)
              .create();
      QuickFixAction.registerQuickFixAction(
          highlightInfo,
          QUICK_FIX_FACTORY.createModifierListFix(variable, PsiModifier.FINAL, false, false));
      QuickFixAction.registerQuickFixAction(
          highlightInfo, QUICK_FIX_FACTORY.createDeferFinalAssignmentFix(variable, expression));
      return highlightInfo;
    }

    return null;
  }
  /** 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());
    }
  }
 @NotNull
 @Override
 public PsiField[] getApplicableFields(@NotNull PsiClass aClass) {
   return aClass.getFields();
 }
  public void testEnumWithInitializedConstants() throws Exception {
    setupLoadingFilter();
    final GlobalSearchScope moduleScope = GlobalSearchScope.moduleScope(myModule);
    PsiClass enumClass =
        myJavaFacade.findClass("enums.OurEnumWithInitializedConstants", moduleScope);
    assertNotNull(enumClass);
    assertTrue(enumClass.isEnum());
    PsiField[] fields = enumClass.getFields();
    assertEquals(3, fields.length);
    assertTrue(fields[0] instanceof PsiEnumConstant);
    assertTrue(fields[1] instanceof PsiEnumConstant);
    assertTrue(fields[2] instanceof PsiEnumConstant);
    PsiAnonymousClass initializingClass0 = ((PsiEnumConstant) fields[0]).getInitializingClass();
    PsiClass baseClass0 = initializingClass0.getBaseClassType().resolve();
    assertTrue(baseClass0 == enumClass);

    PsiAnonymousClass initializingClass1 = ((PsiEnumConstant) fields[1]).getInitializingClass();
    PsiClass baseClass1 = initializingClass1.getBaseClassType().resolve();
    assertTrue(baseClass1 == enumClass);

    PsiAnonymousClass initializingClass2 = ((PsiEnumConstant) fields[1]).getInitializingClass();
    PsiClass baseClass2 = initializingClass2.getBaseClassType().resolve();
    assertTrue(baseClass2 == enumClass);

    assertTrue(initializingClass0.isInheritor(enumClass, false));
    assertTrue(initializingClass1.isInheritor(enumClass, false));
    assertTrue(initializingClass2.isInheritor(enumClass, false));

    final PsiClass[] enumInheritors =
        ClassInheritorsSearch.search(enumClass, moduleScope, false).toArray(PsiClass.EMPTY_ARRAY);
    assertEquals(3, enumInheritors.length);
    assertTrue(Arrays.asList(enumInheritors).contains(initializingClass0));
    assertTrue(Arrays.asList(enumInheritors).contains(initializingClass1));
    assertTrue(Arrays.asList(enumInheritors).contains(initializingClass2));

    PsiMethod[] methods1 = initializingClass2.getMethods();
    assertEquals(1, methods1.length);
    assertEquals("foo", methods1[0].getName());

    final PsiClass baseInterfaceClass =
        myJavaFacade.findClass(
            "enums.OurBaseInterface", GlobalSearchScope.moduleWithLibrariesScope(myModule));
    assertNotNull(baseInterfaceClass);

    final PsiClass[] inheritors =
        ClassInheritorsSearch.search(baseInterfaceClass, moduleScope, false)
            .toArray(PsiClass.EMPTY_ARRAY);
    assertEquals(1, inheritors.length);
    assertTrue(inheritors[0] instanceof PsiAnonymousClass);

    teardownLoadingFilter();

    assertTrue(inheritors[0].getParent().getParent() instanceof PsiExpressionList);
    assertTrue(inheritors[0].getParent().getParent().getParent() == fields[2]);

    final PsiExpression[] expressions2 =
        ((PsiEnumConstant) fields[2]).getArgumentList().getExpressions();
    assertEquals(1, expressions2.length);
    assertTrue(expressions2[0] instanceof PsiNewExpression);
    final PsiAnonymousClass anonymousClass2 =
        ((PsiNewExpression) expressions2[0]).getAnonymousClass();
    assertTrue(anonymousClass2 != null);
    assertTrue(anonymousClass2.isInheritor(baseInterfaceClass, false));
  }
  private static boolean processDeclarationsInClassNotCached(
      @NotNull PsiClass aClass,
      @NotNull PsiScopeProcessor processor,
      @NotNull ResolveState state,
      @Nullable Set<PsiClass> visited,
      PsiElement last,
      @NotNull PsiElement place,
      boolean isRaw,
      @NotNull LanguageLevel languageLevel) {
    if (visited == null) visited = new THashSet<PsiClass>();
    if (!visited.add(aClass)) return true;
    processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
    final ElementClassHint classHint = processor.getHint(ElementClassHint.KEY);
    final NameHint nameHint = processor.getHint(NameHint.KEY);

    if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.FIELD)) {
      if (nameHint != null) {
        final PsiField fieldByName = aClass.findFieldByName(nameHint.getName(state), false);
        if (fieldByName != null && !processor.execute(fieldByName, state)) return false;
      } else {
        final PsiField[] fields = aClass.getFields();
        for (final PsiField field : fields) {
          if (!processor.execute(field, state)) return false;
        }
      }
    }

    PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();

    if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.METHOD)) {
      PsiSubstitutor baseSubstitutor = state.get(PsiSubstitutor.KEY);
      final PsiMethod[] methods =
          nameHint != null
              ? aClass.findMethodsByName(nameHint.getName(state), false)
              : aClass.getMethods();
      for (final PsiMethod method : methods) {
        PsiSubstitutor finalSubstitutor = checkRaw(isRaw, factory, method, baseSubstitutor);
        ResolveState methodState =
            finalSubstitutor == baseSubstitutor
                ? state
                : state.put(PsiSubstitutor.KEY, finalSubstitutor);
        if (!processor.execute(method, methodState)) return false;
      }
    }

    if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) {
      if (last != null && last.getParent() == aClass) {
        // Parameters
        final PsiTypeParameterList list = aClass.getTypeParameterList();
        if (list != null
            && !list.processDeclarations(processor, ResolveState.initial(), last, place))
          return false;
      }

      if (!(last instanceof PsiReferenceList) && !(last instanceof PsiModifierList)) {
        // Inners
        if (nameHint != null) {
          final PsiClass inner = aClass.findInnerClassByName(nameHint.getName(state), false);
          if (inner != null) {
            if (!processor.execute(inner, state)) return false;
          }
        } else {
          final PsiClass[] inners = aClass.getInnerClasses();
          for (final PsiClass inner : inners) {
            if (!processor.execute(inner, state)) return false;
          }
        }
      }
    }

    return last instanceof PsiReferenceList
        || processSuperTypes(
            aClass, processor, visited, last, place, state, isRaw, factory, languageLevel);
  }
Esempio n. 27
0
  protected void initialize() {
    myDefaultConstructor = null;

    final PsiClass psiClass = getElement();

    LOG.assertTrue(psiClass != null);

    PsiElement psiParent = psiClass.getParent();
    if (psiParent instanceof PsiFile) {
      if (isSyntheticJSP()) {
        final RefFileImpl refFile =
            (RefFileImpl) getRefManager().getReference(JspPsiUtil.getJspFile(psiClass));
        LOG.assertTrue(refFile != null);
        refFile.add(this);
      } else if (psiParent instanceof PsiJavaFile) {
        PsiJavaFile psiFile = (PsiJavaFile) psiParent;
        String packageName = psiFile.getPackageName();
        if (!"".equals(packageName)) {
          ((RefPackageImpl) getRefJavaManager().getPackage(packageName)).add(this);
        } else {
          ((RefPackageImpl) getRefJavaManager().getDefaultPackage()).add(this);
        }
      }
      final Module module = ModuleUtil.findModuleForPsiElement(psiClass);
      LOG.assertTrue(module != null);
      final RefModuleImpl refModule = ((RefModuleImpl) getRefManager().getRefModule(module));
      LOG.assertTrue(refModule != null);
      refModule.add(this);
    } else {
      while (!(psiParent instanceof PsiClass
          || psiParent instanceof PsiMethod
          || psiParent instanceof PsiField)) {
        psiParent = psiParent.getParent();
      }
      RefElement refParent = getRefManager().getReference(psiParent);
      LOG.assertTrue(refParent != null);
      ((RefElementImpl) refParent).add(this);
    }

    setAbstract(psiClass.hasModifierProperty(PsiModifier.ABSTRACT));

    setAnonymous(psiClass instanceof PsiAnonymousClass);
    setIsLocal(!(isAnonymous() || psiParent instanceof PsiClass || psiParent instanceof PsiFile));
    setInterface(psiClass.isInterface());

    initializeSuperReferences(psiClass);

    PsiMethod[] psiMethods = psiClass.getMethods();
    PsiField[] psiFields = psiClass.getFields();

    setUtilityClass(psiMethods.length > 0 || psiFields.length > 0);

    for (PsiField psiField : psiFields) {
      getRefManager().getReference(psiField);
    }

    if (!isApplet()) {
      final PsiClass servlet = getRefJavaManager().getServlet();
      setServlet(servlet != null && psiClass.isInheritor(servlet, true));
    }
    if (!isApplet() && !isServlet()) {
      setTestCase(TestUtil.isTestClass(psiClass));
      for (RefClass refBase : getBaseClasses()) {
        ((RefClassImpl) refBase).setTestCase(true);
      }
    }

    for (PsiMethod psiMethod : psiMethods) {
      RefMethod refMethod = (RefMethod) getRefManager().getReference(psiMethod);

      if (refMethod != null) {
        if (psiMethod.isConstructor()) {
          if (psiMethod.getParameterList().getParametersCount() > 0
              || !psiMethod.hasModifierProperty(PsiModifier.PRIVATE)) {
            setUtilityClass(false);
          }

          addConstructor(refMethod);
          if (psiMethod.getParameterList().getParametersCount() == 0) {
            setDefaultConstructor((RefMethodImpl) refMethod);
          }
        } else {
          if (!psiMethod.hasModifierProperty(PsiModifier.STATIC)) {
            setUtilityClass(false);
          }
        }
      }
    }

    if (getConstructors().size() == 0 && !isInterface() && !isAnonymous()) {
      RefImplicitConstructorImpl refImplicitConstructor = new RefImplicitConstructorImpl(this);
      setDefaultConstructor(refImplicitConstructor);
      addConstructor(refImplicitConstructor);
    }

    if (isInterface()) {
      for (int i = 0; i < psiFields.length && isUtilityClass(); i++) {
        PsiField psiField = psiFields[i];
        if (!psiField.hasModifierProperty(PsiModifier.STATIC)) {
          setUtilityClass(false);
        }
      }
    }

    final PsiClass applet = getRefJavaManager().getApplet();
    setApplet(applet != null && psiClass.isInheritor(applet, true));
    getRefManager().fireNodeInitialized(this);
  }
  public static Set<PsiField> getNonInitializedFields(PsiElement element) {
    final PsiStatement statement = PsiTreeUtil.getParentOfType(element, PsiStatement.class);
    final PsiMethod method =
        PsiTreeUtil.getParentOfType(element, PsiMethod.class, true, PsiClass.class);
    if (statement == null || method == null || !method.isConstructor()) {
      return Collections.emptySet();
    }

    PsiElement parent = element.getParent();
    while (parent != statement) {
      PsiElement next = parent.getParent();
      if (next instanceof PsiAssignmentExpression
          && parent == ((PsiAssignmentExpression) next).getLExpression()) {
        return Collections.emptySet();
      }
      if (parent instanceof PsiReferenceExpression && next instanceof PsiExpressionStatement) {
        return Collections.emptySet();
      }
      parent = next;
    }

    final Set<PsiField> fields = new HashSet<PsiField>();
    final PsiClass containingClass = method.getContainingClass();
    assert containingClass != null;
    for (PsiField field : containingClass.getFields()) {
      if (!field.hasModifierProperty(PsiModifier.STATIC)
          && field.getInitializer() == null
          && !isInitializedImplicitly(field)) {
        fields.add(field);
      }
    }

    method.accept(
        new JavaRecursiveElementWalkingVisitor() {
          @Override
          public void visitAssignmentExpression(PsiAssignmentExpression expression) {
            if (expression.getTextRange().getStartOffset()
                < statement.getTextRange().getStartOffset()) {
              final PsiExpression lExpression = expression.getLExpression();
              if (lExpression instanceof PsiReferenceExpression) {
                //noinspection SuspiciousMethodCalls
                fields.remove(((PsiReferenceExpression) lExpression).resolve());
              }
            }
            super.visitAssignmentExpression(expression);
          }

          @Override
          public void visitMethodCallExpression(PsiMethodCallExpression expression) {
            if (expression.getTextRange().getStartOffset()
                < statement.getTextRange().getStartOffset()) {
              final PsiReferenceExpression methodExpression = expression.getMethodExpression();
              if (methodExpression.textMatches("this")) {
                fields.clear();
              }
            }
            super.visitMethodCallExpression(expression);
          }
        });
    return fields;
  }
  private static String[] getFieldNames(final RadComponent component, final String currentName) {
    final ArrayList<String> result = new ArrayList<String>();
    if (currentName != null) {
      result.add(currentName);
    }

    final IRootContainer root = FormEditingUtil.getRoot(component);
    final String className = root.getClassToBind();
    if (className == null) {
      return ArrayUtil.toStringArray(result);
    }

    final PsiClass aClass = FormEditingUtil.findClassToBind(component.getModule(), className);
    if (aClass == null) {
      return ArrayUtil.toStringArray(result);
    }

    final PsiField[] fields = aClass.getFields();

    for (final PsiField field : fields) {
      if (field.hasModifierProperty(PsiModifier.STATIC)) {
        continue;
      }

      final String fieldName = field.getName();

      if (Comparing.equal(currentName, fieldName)) {
        continue;
      }

      if (!FormEditingUtil.isBindingUnique(component, fieldName, root)) {
        continue;
      }

      final String componentClassName;
      if (component instanceof RadErrorComponent) {
        componentClassName = component.getComponentClassName();
      } else if (component instanceof RadHSpacer || component instanceof RadVSpacer) {
        componentClassName = Spacer.class.getName();
      } else {
        componentClassName = component.getComponentClass().getName();
      }

      final PsiType componentType;
      try {
        componentType =
            JavaPsiFacade.getInstance(component.getProject())
                .getElementFactory()
                .createTypeFromText(componentClassName, null);
      } catch (IncorrectOperationException e) {
        continue;
      }

      final PsiType fieldType = field.getType();
      if (!fieldType.isAssignableFrom(componentType)) {
        continue;
      }

      result.add(fieldName);
    }

    String text = FormInspectionUtil.getText(component.getModule(), component);
    if (text != null) {
      String binding = BindingProperty.suggestBindingFromText(component, text);
      if (binding != null && !result.contains(binding)) {
        result.add(binding);
      }
    }

    final String[] names = ArrayUtil.toStringArray(result);
    Arrays.sort(names);
    return names;
  }
  @Override
  public void onReferencesBuild(RefElement refElement) {
    if (refElement instanceof RefClass) {
      final PsiClass psiClass = (PsiClass) refElement.getElement();
      if (psiClass != null) {

        if (refElement.isEntry()) {
          ((RefClassImpl) refElement).setFlag(false, CAN_BE_FINAL_MASK);
        }

        PsiMethod[] psiMethods = psiClass.getMethods();
        PsiField[] psiFields = psiClass.getFields();

        HashSet<PsiVariable> allFields = new HashSet<PsiVariable>();
        ContainerUtil.addAll(allFields, psiFields);
        ArrayList<PsiVariable> instanceInitializerInitializedFields = new ArrayList<PsiVariable>();
        boolean hasInitializers = false;
        for (PsiClassInitializer initializer : psiClass.getInitializers()) {
          PsiCodeBlock body = initializer.getBody();
          hasInitializers = true;
          ControlFlow flow;
          try {
            flow =
                ControlFlowFactory.getInstance(body.getProject())
                    .getControlFlow(
                        body, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance(), false);
          } catch (AnalysisCanceledException e) {
            flow = ControlFlow.EMPTY;
          }
          Collection<PsiVariable> writtenVariables = new ArrayList<PsiVariable>();
          ControlFlowUtil.getWrittenVariables(flow, 0, flow.getSize(), false, writtenVariables);
          for (PsiVariable psiVariable : writtenVariables) {
            if (allFields.contains(psiVariable)) {
              if (instanceInitializerInitializedFields.contains(psiVariable)) {
                allFields.remove(psiVariable);
                instanceInitializerInitializedFields.remove(psiVariable);
              } else {
                instanceInitializerInitializedFields.add(psiVariable);
              }
            }
          }
          for (PsiVariable psiVariable : writtenVariables) {
            if (!instanceInitializerInitializedFields.contains(psiVariable)) {
              allFields.remove(psiVariable);
            }
          }
        }

        for (PsiMethod psiMethod : psiMethods) {
          if (psiMethod.isConstructor()) {
            PsiCodeBlock body = psiMethod.getBody();
            if (body != null) {
              hasInitializers = true;
              ControlFlow flow;
              try {
                flow =
                    ControlFlowFactory.getInstance(body.getProject())
                        .getControlFlow(
                            body, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance(), false);
              } catch (AnalysisCanceledException e) {
                flow = ControlFlow.EMPTY;
              }

              Collection<PsiVariable> writtenVariables =
                  ControlFlowUtil.getWrittenVariables(flow, 0, flow.getSize(), false);
              for (PsiVariable psiVariable : writtenVariables) {
                if (instanceInitializerInitializedFields.contains(psiVariable)) {
                  allFields.remove(psiVariable);
                  instanceInitializerInitializedFields.remove(psiVariable);
                }
              }
              List<PsiMethod> redirectedConstructors =
                  HighlightControlFlowUtil.getChainedConstructors(psiMethod);
              if (redirectedConstructors == null || redirectedConstructors.isEmpty()) {
                List<PsiVariable> ssaVariables = ControlFlowUtil.getSSAVariables(flow);
                ArrayList<PsiVariable> good = new ArrayList<PsiVariable>(ssaVariables);
                good.addAll(instanceInitializerInitializedFields);
                allFields.retainAll(good);
              } else {
                allFields.removeAll(writtenVariables);
              }
            }
          }
        }

        for (PsiField psiField : psiFields) {
          if ((!hasInitializers || !allFields.contains(psiField))
              && psiField.getInitializer() == null) {
            final RefFieldImpl refField = (RefFieldImpl) myManager.getReference(psiField);
            if (refField != null) {
              refField.setFlag(false, CAN_BE_FINAL_MASK);
            }
          }
        }
      }
    } else if (refElement instanceof RefMethod) {
      final RefMethod refMethod = (RefMethod) refElement;
      if (refMethod.isEntry()) {
        ((RefMethodImpl) refMethod).setFlag(false, CAN_BE_FINAL_MASK);
      }
    }
  }