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 static boolean onTheLeftSideOfConditionalAssignment(final PsiElement psiAnchor) {
   final PsiElement parent = psiAnchor.getParent();
   if (parent instanceof PsiAssignmentExpression) {
     final PsiAssignmentExpression expression = (PsiAssignmentExpression) parent;
     if (expression.getLExpression() == psiAnchor) return true;
   }
   return false;
 }
 private static boolean writtenInside(PsiVariable variable, PsiElement element) {
   if (element instanceof PsiAssignmentExpression) {
     PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) element;
     PsiExpression lExpression = assignmentExpression.getLExpression();
     if (lExpression instanceof PsiReferenceExpression
         && ((PsiReferenceExpression) lExpression).resolve() == variable) return true;
   } else if (PsiUtil.isIncrementDecrementOperation(element)) {
     PsiElement operand =
         element instanceof PsiPostfixExpression
             ? ((PsiPostfixExpression) element).getOperand()
             : ((PsiPrefixExpression) element).getOperand();
     if (operand instanceof PsiReferenceExpression
         && ((PsiReferenceExpression) operand).resolve() == variable) return true;
   }
   PsiElement[] children = element.getChildren();
   for (PsiElement child : children) {
     if (writtenInside(variable, child)) return true;
   }
   return false;
 }
    public void visitAssignmentExpression(PsiAssignmentExpression expression) {
      super.visitAssignmentExpression(expression);

      final PsiExpression lhs = expression.getLExpression();
      if (isProhibitedReference(lhs)) {
        final PsiField field = getReferencedField(lhs);
        if (!hasGetter(field)
            && !isStaticFinal(field)
            && !field.getModifierList().hasModifierProperty(PsiModifier.PUBLIC)) {
          fieldsNeedingSetter.add(field);
        }
      }
    }
 /**
  * @param sideEffects if null, delete usages, otherwise collect side effects
  * @return true if there are at least one unrecoverable side effect found, false if no side
  *     effects, null if read usage found (may happen if interval between fix creation in invoke()
  *     call was long enough)
  * @throws com.intellij.util.IncorrectOperationException
  */
 static Boolean processUsage(
     PsiElement element, PsiVariable variable, List<PsiElement> sideEffects, int deleteMode)
     throws IncorrectOperationException {
   if (!element.isValid()) return null;
   PsiElementFactory factory =
       JavaPsiFacade.getInstance(variable.getProject()).getElementFactory();
   while (element != null) {
     if (element instanceof PsiAssignmentExpression) {
       PsiAssignmentExpression expression = (PsiAssignmentExpression) element;
       PsiExpression lExpression = expression.getLExpression();
       // there should not be read access to the variable, otherwise it is not unused
       if (!(lExpression instanceof PsiReferenceExpression)
           || variable != ((PsiReferenceExpression) lExpression).resolve()) {
         return null;
       }
       PsiExpression rExpression = expression.getRExpression();
       rExpression = PsiUtil.deparenthesizeExpression(rExpression);
       if (rExpression == null) return true;
       // replace assignment with expression and resimplify
       boolean sideEffectFound = checkSideEffects(rExpression, variable, sideEffects);
       if (!(element.getParent() instanceof PsiExpressionStatement)
           || PsiUtil.isStatement(rExpression)) {
         if (deleteMode == MAKE_STATEMENT
             || deleteMode == DELETE_ALL
                 && !(element.getParent() instanceof PsiExpressionStatement)) {
           element = replaceElementWithExpression(rExpression, factory, element);
           while (element.getParent() instanceof PsiParenthesizedExpression) {
             element = element.getParent().replace(element);
           }
           List<PsiElement> references = new ArrayList<PsiElement>();
           collectReferences(element, variable, references);
           deleteReferences(variable, references, deleteMode);
         } else if (deleteMode == DELETE_ALL) {
           deleteWholeStatement(element, factory);
         }
         return true;
       } else {
         if (deleteMode != CANCEL) {
           deleteWholeStatement(element, factory);
         }
         return !sideEffectFound;
       }
     } else if (element instanceof PsiExpressionStatement && deleteMode != CANCEL) {
       final PsiElement parent = element.getParent();
       if (parent instanceof PsiIfStatement
           || parent instanceof PsiLoopStatement
               && ((PsiLoopStatement) parent).getBody() == element) {
         element.replace(
             JavaPsiFacade.getElementFactory(element.getProject())
                 .createStatementFromText(";", element));
       } else {
         element.delete();
       }
       break;
     } else if (element instanceof PsiVariable && element == variable) {
       PsiExpression expression = variable.getInitializer();
       if (expression != null) {
         expression = PsiUtil.deparenthesizeExpression(expression);
       }
       boolean sideEffectsFound = checkSideEffects(expression, variable, sideEffects);
       if (expression != null
           && PsiUtil.isStatement(expression)
           && variable instanceof PsiLocalVariable
           && !(variable.getParent() instanceof PsiDeclarationStatement
               && ((PsiDeclarationStatement) variable.getParent()).getDeclaredElements().length
                   > 1)) {
         if (deleteMode == MAKE_STATEMENT) {
           element = element.replace(createStatementIfNeeded(expression, factory, element));
           List<PsiElement> references = new ArrayList<PsiElement>();
           collectReferences(element, variable, references);
           deleteReferences(variable, references, deleteMode);
         } else if (deleteMode == DELETE_ALL) {
           element.delete();
         }
         return true;
       } else {
         if (deleteMode != CANCEL) {
           if (element instanceof PsiField) {
             ((PsiField) element).normalizeDeclaration();
           }
           element.delete();
         }
         return !sideEffectsFound;
       }
     }
     element = element.getParent();
   }
   return true;
 }
  @Nullable
  private PsiStatement hasCommonInitializer(
      PsiStatement commonInitializer,
      PsiMethod subConstructor,
      PsiField field,
      ArrayList<PsiElement> statementsToRemove) {
    final PsiCodeBlock body = subConstructor.getBody();
    if (body == null) return null;
    final PsiStatement[] statements = body.getStatements();

    // Algorithm: there should be only one write usage of field in a subConstructor,
    // and in that usage field must be a target of top-level assignment, and RHS of assignment
    // should be the same as commonInitializer if latter is non-null.
    //
    // There should be no usages before that initializer, and there should be
    // no write usages afterwards.
    PsiStatement commonInitializerCandidate = null;
    for (PsiStatement statement : statements) {
      final HashSet<PsiStatement> collectedStatements = new HashSet<PsiStatement>();
      collectPsiStatements(statement, collectedStatements);
      boolean doLookup = true;
      for (PsiStatement collectedStatement : collectedStatements) {
        if (collectedStatement instanceof PsiExpressionStatement) {
          final PsiExpression expression =
              ((PsiExpressionStatement) collectedStatement).getExpression();
          if (expression instanceof PsiAssignmentExpression) {
            final PsiAssignmentExpression assignmentExpression =
                (PsiAssignmentExpression) expression;
            final PsiExpression lExpression = assignmentExpression.getLExpression();
            if (lExpression instanceof PsiReferenceExpression) {
              final PsiReferenceExpression lRef = (PsiReferenceExpression) lExpression;
              if (lRef.getQualifierExpression() == null
                  || lRef.getQualifierExpression() instanceof PsiThisExpression) {
                final PsiElement resolved = lRef.resolve();
                if (resolved == field) {
                  doLookup = false;
                  if (commonInitializerCandidate == null) {
                    final PsiExpression initializer = assignmentExpression.getRExpression();
                    if (initializer == null) return null;
                    if (commonInitializer == null) {
                      final IsMovableInitializerVisitor visitor = new IsMovableInitializerVisitor();
                      statement.accept(visitor);
                      if (visitor.isMovable()) {
                        ChangeContextUtil.encodeContextInfo(statement, true);
                        PsiStatement statementCopy = (PsiStatement) statement.copy();
                        ChangeContextUtil.clearContextInfo(statement);
                        statementsToRemove.add(statement);
                        commonInitializerCandidate = statementCopy;
                      } else {
                        return null;
                      }
                    } else {
                      if (PsiEquivalenceUtil.areElementsEquivalent(commonInitializer, statement)) {
                        statementsToRemove.add(statement);
                        commonInitializerCandidate = commonInitializer;
                      } else {
                        return null;
                      }
                    }
                  } else if (!PsiEquivalenceUtil.areElementsEquivalent(
                      commonInitializerCandidate, statement)) {
                    return null;
                  }
                }
              }
            }
          }
        }
      }
      if (doLookup) {
        final PsiReference[] references =
            ReferencesSearch.search(field, new LocalSearchScope(statement), false)
                .toArray(new PsiReference[0]);
        if (commonInitializerCandidate == null && references.length > 0) {
          return null;
        }

        for (PsiReference reference : references) {
          if (RefactoringUtil.isAssignmentLHS(reference.getElement())) return null;
        }
      }
    }
    return commonInitializerCandidate;
  }
Beispiel #7
0
  private NamesByExprInfo suggestVariableNameByExpressionPlace(
      PsiExpression expr, final VariableKind variableKind, boolean correctKeywords) {
    if (expr.getParent() instanceof PsiExpressionList) {
      PsiExpressionList list = (PsiExpressionList) expr.getParent();
      PsiElement listParent = list.getParent();
      PsiSubstitutor subst = PsiSubstitutor.EMPTY;
      PsiMethod method = null;
      if (listParent instanceof PsiMethodCallExpression) {
        final JavaResolveResult resolveResult =
            ((PsiMethodCallExpression) listParent).getMethodExpression().advancedResolve(false);
        method = (PsiMethod) resolveResult.getElement();
        subst = resolveResult.getSubstitutor();
      } else {
        if (listParent instanceof PsiAnonymousClass) {
          listParent = listParent.getParent();
        }
        if (listParent instanceof PsiNewExpression) {
          method = ((PsiNewExpression) listParent).resolveConstructor();
        }
      }

      if (method != null) {
        final PsiElement navElement = method.getNavigationElement();
        if (navElement instanceof PsiMethod) {
          method = (PsiMethod) navElement;
        }
        PsiExpression[] expressions = list.getExpressions();
        int index = -1;
        for (int i = 0; i < expressions.length; i++) {
          if (expressions[i] == expr) {
            index = i;
            break;
          }
        }
        PsiParameter[] parameters = method.getParameterList().getParameters();
        if (index < parameters.length) {
          String name = parameters[index].getName();
          if (name != null
              && TypeConversionUtil.areTypesAssignmentCompatible(
                  subst.substitute(parameters[index].getType()), expr)) {
            name = variableNameToPropertyName(name, VariableKind.PARAMETER);
            String[] names = getSuggestionsByName(name, variableKind, false, correctKeywords);
            if (expressions.length == 1) {
              final String methodName = method.getName();
              String[] words = NameUtil.nameToWords(methodName);
              if (words.length > 0) {
                final String firstWord = words[0];
                if (SET_PREFIX.equals(firstWord)) {
                  final String propertyName = methodName.substring(firstWord.length());
                  final String[] setterNames =
                      getSuggestionsByName(propertyName, variableKind, false, correctKeywords);
                  names = ArrayUtil.mergeArrays(names, setterNames);
                }
              }
            }
            return new NamesByExprInfo(name, names);
          }
        }
      }
    } else if (expr.getParent() instanceof PsiAssignmentExpression
        && variableKind == VariableKind.PARAMETER) {
      final PsiAssignmentExpression assignmentExpression =
          (PsiAssignmentExpression) expr.getParent();
      if (expr == assignmentExpression.getRExpression()) {
        final PsiExpression leftExpression = assignmentExpression.getLExpression();
        if (leftExpression instanceof PsiReferenceExpression
            && ((PsiReferenceExpression) leftExpression).getQualifier() == null) {
          String name = leftExpression.getText();
          if (name != null) {
            final PsiElement resolve = ((PsiReferenceExpression) leftExpression).resolve();
            if (resolve instanceof PsiVariable) {
              name = variableNameToPropertyName(name, getVariableKind((PsiVariable) resolve));
            }
            String[] names = getSuggestionsByName(name, variableKind, false, correctKeywords);
            return new NamesByExprInfo(name, names);
          }
        }
      }
    }

    return new NamesByExprInfo(null, ArrayUtil.EMPTY_STRING_ARRAY);
  }