private boolean isIteratorNext(
   PsiElement element, String iteratorName, PsiType contentType) {
   if (element == null) {
     return false;
   }
   if (element instanceof PsiTypeCastExpression) {
     final PsiTypeCastExpression castExpression =
       (PsiTypeCastExpression)element;
     final PsiType type = castExpression.getType();
     if (type == null) {
       return false;
     }
     if (!type.equals(contentType)) {
       return false;
     }
     final PsiExpression operand =
       castExpression.getOperand();
     return isIteratorNext(operand, iteratorName, contentType);
   }
   if (!(element instanceof PsiMethodCallExpression)) {
     return false;
   }
   final PsiMethodCallExpression callExpression =
     (PsiMethodCallExpression)element;
   final PsiExpressionList argumentList =
     callExpression.getArgumentList();
   final PsiExpression[] args = argumentList.getExpressions();
   if (args.length != 0) {
     return false;
   }
   final PsiReferenceExpression reference =
     callExpression.getMethodExpression();
   final PsiExpression qualifier = reference.getQualifierExpression();
   if (qualifier == null) {
     return false;
   }
   if (!iteratorName.equals(qualifier.getText())) {
     return false;
   }
   final String referenceName = reference.getReferenceName();
   return HardcodedMethodConstants.NEXT.equals(referenceName);
 }
Ejemplo n.º 2
0
  private NamesByExprInfo suggestVariableNameByExpressionOnly(
      PsiExpression expr,
      final VariableKind variableKind,
      boolean correctKeywords,
      boolean useAllMethodNames) {
    if (expr instanceof PsiMethodCallExpression) {
      PsiReferenceExpression methodExpr = ((PsiMethodCallExpression) expr).getMethodExpression();
      String methodName = methodExpr.getReferenceName();
      if (methodName != null) {
        if ("of".equals(methodName) || "ofNullable".equals(methodName)) {
          if (isJavaUtilMethodCall((PsiMethodCallExpression) expr)) {
            PsiExpression[] expressions =
                ((PsiMethodCallExpression) expr).getArgumentList().getExpressions();
            if (expressions.length > 0) {
              return suggestVariableNameByExpressionOnly(
                  expressions[0], variableKind, correctKeywords, useAllMethodNames);
            }
          }
        }
        if ("map".equals(methodName)
            || "flatMap".equals(methodName)
            || "filter".equals(methodName)) {
          if (isJavaUtilMethodCall((PsiMethodCallExpression) expr)) {
            return new NamesByExprInfo(null);
          }
        }

        String[] words = NameUtil.nameToWords(methodName);
        if (words.length > 0) {
          final String firstWord = words[0];
          if (GET_PREFIX.equals(firstWord)
              || IS_PREFIX.equals(firstWord)
              || FIND_PREFIX.equals(firstWord)
              || CREATE_PREFIX.equals(firstWord)) {
            if (words.length > 1) {
              final String propertyName = methodName.substring(firstWord.length());
              String[] names =
                  getSuggestionsByName(propertyName, variableKind, false, correctKeywords);
              final PsiExpression qualifierExpression = methodExpr.getQualifierExpression();
              if (qualifierExpression instanceof PsiReferenceExpression
                  && ((PsiReferenceExpression) qualifierExpression).resolve()
                      instanceof PsiVariable) {
                names =
                    ArrayUtil.append(
                        names,
                        StringUtil.sanitizeJavaIdentifier(
                            changeIfNotIdentifier(
                                qualifierExpression.getText()
                                    + StringUtil.capitalize(propertyName))));
              }
              return new NamesByExprInfo(propertyName, names);
            }
          } else if (words.length == 1 || useAllMethodNames) {
            return new NamesByExprInfo(
                methodName, getSuggestionsByName(methodName, variableKind, false, correctKeywords));
          }
        }
      }
    } else if (expr instanceof PsiReferenceExpression) {
      String propertyName = ((PsiReferenceExpression) expr).getReferenceName();
      PsiElement refElement = ((PsiReferenceExpression) expr).resolve();
      if (refElement instanceof PsiVariable) {
        VariableKind refVariableKind = getVariableKind((PsiVariable) refElement);
        propertyName = variableNameToPropertyName(propertyName, refVariableKind);
      }
      if (refElement != null && propertyName != null) {
        String[] names = getSuggestionsByName(propertyName, variableKind, false, correctKeywords);
        return new NamesByExprInfo(propertyName, names);
      }
    } else if (expr instanceof PsiArrayAccessExpression) {
      PsiExpression arrayExpr = ((PsiArrayAccessExpression) expr).getArrayExpression();
      if (arrayExpr instanceof PsiReferenceExpression) {
        String arrayName = ((PsiReferenceExpression) arrayExpr).getReferenceName();
        PsiElement refElement = ((PsiReferenceExpression) arrayExpr).resolve();
        if (refElement instanceof PsiVariable) {
          VariableKind refVariableKind = getVariableKind((PsiVariable) refElement);
          arrayName = variableNameToPropertyName(arrayName, refVariableKind);
        }

        if (arrayName != null) {
          String name = StringUtil.unpluralize(arrayName);
          if (name != null) {
            String[] names = getSuggestionsByName(name, variableKind, false, correctKeywords);
            return new NamesByExprInfo(name, names);
          }
        }
      }
    } else if (expr instanceof PsiLiteralExpression
        && variableKind == VariableKind.STATIC_FINAL_FIELD) {
      final PsiLiteralExpression literalExpression = (PsiLiteralExpression) expr;
      final Object value = literalExpression.getValue();
      if (value instanceof String) {
        final String stringValue = (String) value;
        String[] names = getSuggestionsByValue(stringValue);
        if (names.length > 0) {
          return new NamesByExprInfo(null, constantValueToConstantName(names));
        }
      }
    } else if (expr instanceof PsiParenthesizedExpression) {
      return suggestVariableNameByExpressionOnly(
          ((PsiParenthesizedExpression) expr).getExpression(),
          variableKind,
          correctKeywords,
          useAllMethodNames);
    } else if (expr instanceof PsiTypeCastExpression) {
      return suggestVariableNameByExpressionOnly(
          ((PsiTypeCastExpression) expr).getOperand(),
          variableKind,
          correctKeywords,
          useAllMethodNames);
    } else if (expr instanceof PsiLiteralExpression) {
      final String text = StringUtil.stripQuotesAroundValue(expr.getText());
      if (isIdentifier(text)) {
        return new NamesByExprInfo(
            text, getSuggestionsByName(text, variableKind, false, correctKeywords));
      }
    }

    return new NamesByExprInfo(null, ArrayUtil.EMPTY_STRING_ARRAY);
  }
 @Nullable
 private String createListIterationText(@NotNull PsiForStatement forStatement) {
   final PsiBinaryExpression condition =
       (PsiBinaryExpression) ParenthesesUtils.stripParentheses(forStatement.getCondition());
   if (condition == null) {
     return null;
   }
   final PsiExpression lhs = ParenthesesUtils.stripParentheses(condition.getLOperand());
   if (lhs == null) {
     return null;
   }
   final PsiExpression rhs = ParenthesesUtils.stripParentheses(condition.getROperand());
   if (rhs == null) {
     return null;
   }
   final IElementType tokenType = condition.getOperationTokenType();
   final String indexName;
   PsiExpression collectionSize;
   if (JavaTokenType.LT.equals(tokenType)) {
     indexName = lhs.getText();
     collectionSize = rhs;
   } else if (JavaTokenType.GT.equals(tokenType)) {
     indexName = rhs.getText();
     collectionSize = lhs;
   } else {
     return null;
   }
   if (collectionSize instanceof PsiReferenceExpression) {
     final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) collectionSize;
     final PsiElement target = referenceExpression.resolve();
     if (target instanceof PsiVariable) {
       final PsiVariable variable = (PsiVariable) target;
       collectionSize = ParenthesesUtils.stripParentheses(variable.getInitializer());
     }
   }
   if (!(collectionSize instanceof PsiMethodCallExpression)) {
     return null;
   }
   final PsiMethodCallExpression methodCallExpression =
       (PsiMethodCallExpression) ParenthesesUtils.stripParentheses(collectionSize);
   if (methodCallExpression == null) {
     return null;
   }
   final PsiReferenceExpression listLengthExpression =
       methodCallExpression.getMethodExpression();
   final PsiExpression qualifier =
       ParenthesesUtils.stripParentheses(listLengthExpression.getQualifierExpression());
   final PsiReferenceExpression listReference;
   if (qualifier instanceof PsiReferenceExpression) {
     listReference = (PsiReferenceExpression) qualifier;
   } else {
     listReference = null;
   }
   PsiType parameterType;
   if (listReference == null) {
     parameterType = extractListTypeFromContainingClass(forStatement);
   } else {
     final PsiType type = listReference.getType();
     if (type == null) {
       return null;
     }
     parameterType = extractContentTypeFromType(type);
   }
   if (parameterType == null) {
     parameterType = TypeUtils.getObjectType(forStatement);
   }
   final String typeString = parameterType.getCanonicalText();
   final PsiVariable listVariable;
   if (listReference == null) {
     listVariable = null;
   } else {
     final PsiElement target = listReference.resolve();
     if (!(target instanceof PsiVariable)) {
       return null;
     }
     listVariable = (PsiVariable) target;
   }
   final PsiStatement body = forStatement.getBody();
   final PsiStatement firstStatement = getFirstStatement(body);
   final boolean isDeclaration =
       isListElementDeclaration(firstStatement, listVariable, indexName, parameterType);
   final String contentVariableName;
   @NonNls final String finalString;
   final PsiStatement statementToSkip;
   if (isDeclaration) {
     final PsiDeclarationStatement declarationStatement =
         (PsiDeclarationStatement) firstStatement;
     assert declarationStatement != null;
     final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
     final PsiElement declaredElement = declaredElements[0];
     if (!(declaredElement instanceof PsiVariable)) {
       return null;
     }
     final PsiVariable variable = (PsiVariable) declaredElement;
     contentVariableName = variable.getName();
     statementToSkip = declarationStatement;
     if (variable.hasModifierProperty(PsiModifier.FINAL)) {
       finalString = "final ";
     } else {
       finalString = "";
     }
   } else {
     final String collectionName;
     if (listReference == null) {
       collectionName = null;
     } else {
       collectionName = listReference.getReferenceName();
     }
     contentVariableName = createNewVariableName(forStatement, parameterType, collectionName);
     finalString = "";
     statementToSkip = null;
   }
   @NonNls final StringBuilder out = new StringBuilder();
   out.append("for(");
   out.append(finalString);
   out.append(typeString);
   out.append(' ');
   out.append(contentVariableName);
   out.append(": ");
   @NonNls final String listName;
   if (listReference == null) {
     listName = "this";
   } else {
     listName = listReference.getText();
   }
   out.append(listName);
   out.append(')');
   if (body != null) {
     replaceCollectionGetAccess(
         body, contentVariableName, listVariable, indexName, statementToSkip, out);
   }
   return out.toString();
 }
 @Nullable
 private String createArrayIterationText(@NotNull PsiForStatement forStatement) {
   final PsiExpression condition = forStatement.getCondition();
   final PsiBinaryExpression strippedCondition =
       (PsiBinaryExpression) ParenthesesUtils.stripParentheses(condition);
   if (strippedCondition == null) {
     return null;
   }
   final PsiExpression lhs = ParenthesesUtils.stripParentheses(strippedCondition.getLOperand());
   if (lhs == null) {
     return null;
   }
   final PsiExpression rhs = ParenthesesUtils.stripParentheses(strippedCondition.getROperand());
   if (rhs == null) {
     return null;
   }
   final IElementType tokenType = strippedCondition.getOperationTokenType();
   final PsiReferenceExpression arrayLengthExpression;
   final String indexName;
   if (tokenType.equals(JavaTokenType.LT)) {
     arrayLengthExpression = (PsiReferenceExpression) ParenthesesUtils.stripParentheses(rhs);
     indexName = lhs.getText();
   } else if (tokenType.equals(JavaTokenType.GT)) {
     arrayLengthExpression = (PsiReferenceExpression) ParenthesesUtils.stripParentheses(lhs);
     indexName = rhs.getText();
   } else {
     return null;
   }
   if (arrayLengthExpression == null) {
     return null;
   }
   PsiReferenceExpression arrayReference =
       (PsiReferenceExpression) arrayLengthExpression.getQualifierExpression();
   if (arrayReference == null) {
     final PsiElement target = arrayLengthExpression.resolve();
     if (!(target instanceof PsiVariable)) {
       return null;
     }
     final PsiVariable variable = (PsiVariable) target;
     final PsiExpression initializer = variable.getInitializer();
     if (!(initializer instanceof PsiReferenceExpression)) {
       return null;
     }
     final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) initializer;
     arrayReference = (PsiReferenceExpression) referenceExpression.getQualifierExpression();
     if (arrayReference == null) {
       return null;
     }
   }
   final PsiType type = arrayReference.getType();
   if (!(type instanceof PsiArrayType)) {
     return null;
   }
   final PsiArrayType arrayType = (PsiArrayType) type;
   final PsiType componentType = arrayType.getComponentType();
   final String typeText = componentType.getCanonicalText();
   final PsiElement target = arrayReference.resolve();
   if (!(target instanceof PsiVariable)) {
     return null;
   }
   final PsiVariable arrayVariable = (PsiVariable) target;
   final PsiStatement body = forStatement.getBody();
   final PsiStatement firstStatement = getFirstStatement(body);
   final boolean isDeclaration =
       isArrayElementDeclaration(firstStatement, arrayVariable, indexName);
   final String contentVariableName;
   @NonNls final String finalString;
   final PsiStatement statementToSkip;
   if (isDeclaration) {
     final PsiDeclarationStatement declarationStatement =
         (PsiDeclarationStatement) firstStatement;
     assert declarationStatement != null;
     final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
     final PsiElement declaredElement = declaredElements[0];
     if (!(declaredElement instanceof PsiVariable)) {
       return null;
     }
     final PsiVariable variable = (PsiVariable) declaredElement;
     if (VariableAccessUtils.variableIsAssigned(variable, forStatement)) {
       final String collectionName = arrayReference.getReferenceName();
       contentVariableName = createNewVariableName(forStatement, componentType, collectionName);
       final Project project = forStatement.getProject();
       final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
       if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
         finalString = "final ";
       } else {
         finalString = "";
       }
       statementToSkip = null;
     } else {
       contentVariableName = variable.getName();
       statementToSkip = declarationStatement;
       if (variable.hasModifierProperty(PsiModifier.FINAL)) {
         finalString = "final ";
       } else {
         finalString = "";
       }
     }
   } else {
     final String collectionName = arrayReference.getReferenceName();
     contentVariableName = createNewVariableName(forStatement, componentType, collectionName);
     final Project project = forStatement.getProject();
     final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
     if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
       finalString = "final ";
     } else {
       finalString = "";
     }
     statementToSkip = null;
   }
   @NonNls final StringBuilder out = new StringBuilder();
   out.append("for(");
   out.append(finalString);
   out.append(typeText);
   out.append(' ');
   out.append(contentVariableName);
   out.append(": ");
   final String arrayName = arrayReference.getText();
   out.append(arrayName);
   out.append(')');
   if (body != null) {
     replaceArrayAccess(
         body, contentVariableName, arrayVariable, indexName, statementToSkip, out);
   }
   return out.toString();
 }
 @Nullable
 private String createCollectionIterationText(@NotNull PsiForStatement forStatement)
     throws IncorrectOperationException {
   final PsiStatement body = forStatement.getBody();
   final PsiStatement firstStatement = getFirstStatement(body);
   final PsiStatement initialization = forStatement.getInitialization();
   if (!(initialization instanceof PsiDeclarationStatement)) {
     return null;
   }
   final PsiDeclarationStatement declaration = (PsiDeclarationStatement) initialization;
   final PsiElement declaredIterator = declaration.getDeclaredElements()[0];
   if (!(declaredIterator instanceof PsiVariable)) {
     return null;
   }
   final PsiVariable iteratorVariable = (PsiVariable) declaredIterator;
   final PsiMethodCallExpression initializer =
       (PsiMethodCallExpression) iteratorVariable.getInitializer();
   if (initializer == null) {
     return null;
   }
   final PsiType iteratorType = initializer.getType();
   if (iteratorType == null) {
     return null;
   }
   final PsiType iteratorContentType = extractContentTypeFromType(iteratorType);
   final PsiType iteratorVariableType = iteratorVariable.getType();
   final PsiType contentType;
   final PsiClassType javaLangObject = TypeUtils.getObjectType(forStatement);
   if (iteratorContentType == null) {
     final PsiType iteratorVariableContentType =
         extractContentTypeFromType(iteratorVariableType);
     if (iteratorVariableContentType == null) {
       contentType = javaLangObject;
     } else {
       contentType = iteratorVariableContentType;
     }
   } else {
     contentType = iteratorContentType;
   }
   final PsiReferenceExpression methodExpression = initializer.getMethodExpression();
   final PsiExpression collection = methodExpression.getQualifierExpression();
   final String iteratorName = iteratorVariable.getName();
   final boolean isDeclaration =
       isIteratorNextDeclaration(firstStatement, iteratorName, contentType);
   final PsiStatement statementToSkip;
   @NonNls final String finalString;
   final String contentVariableName;
   if (isDeclaration) {
     final PsiDeclarationStatement declarationStatement =
         (PsiDeclarationStatement) firstStatement;
     assert declarationStatement != null;
     final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
     final PsiElement declaredElement = declaredElements[0];
     if (!(declaredElement instanceof PsiVariable)) {
       return null;
     }
     final PsiVariable variable = (PsiVariable) declaredElement;
     contentVariableName = variable.getName();
     statementToSkip = declarationStatement;
     if (variable.hasModifierProperty(PsiModifier.FINAL)) {
       finalString = "final ";
     } else {
       finalString = "";
     }
   } else {
     if (collection instanceof PsiReferenceExpression) {
       final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) collection;
       final String collectionName = referenceExpression.getReferenceName();
       contentVariableName = createNewVariableName(forStatement, contentType, collectionName);
     } else {
       contentVariableName = createNewVariableName(forStatement, contentType, null);
     }
     final Project project = forStatement.getProject();
     final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
     if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
       finalString = "final ";
     } else {
       finalString = "";
     }
     statementToSkip = null;
   }
   final String contentTypeString = contentType.getCanonicalText();
   @NonNls final StringBuilder out = new StringBuilder();
   out.append("for(");
   out.append(finalString);
   out.append(contentTypeString);
   out.append(' ');
   out.append(contentVariableName);
   out.append(": ");
   if (!contentType.equals(javaLangObject)) {
     @NonNls final String iterableTypeString = "java.lang.Iterable<" + contentTypeString + '>';
     if (iteratorContentType == null) {
       out.append('(');
       out.append(iterableTypeString);
       out.append(')');
     }
   }
   if (collection == null) {
     out.append("this");
   } else {
     out.append(collection.getText());
   }
   out.append(')');
   replaceIteratorNext(
       body, contentVariableName, iteratorName, statementToSkip, out, contentType);
   return out.toString();
 }