blob: c0a302710d55480727adfd67d52b8be58e7c40b6 [file] [log] [blame]
/*
* Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.migration;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.HardcodedMethodConstants;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import com.siyeh.ig.psiutils.StringUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import com.siyeh.ig.psiutils.VariableAccessUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public class ForCanBeForeachInspection extends ForCanBeForeachInspectionBase {
@Override
public InspectionGadgetsFix buildFix(Object... infos) {
return new ForCanBeForeachFix();
}
@Override
@Nullable
public JComponent createOptionsPanel() {
final MultipleCheckboxOptionsPanel panel =
new MultipleCheckboxOptionsPanel(this);
panel.addCheckbox(InspectionGadgetsBundle.message(
"for.can.be.foreach.option"), "REPORT_INDEXED_LOOP");
panel.addCheckbox(InspectionGadgetsBundle.message(
"for.can.be.foreach.option2"), "ignoreUntypedCollections");
return panel;
}
private class ForCanBeForeachFix extends InspectionGadgetsFix {
@Override
@NotNull
public String getFamilyName() {
return getName();
}
@Override
@NotNull
public String getName() {
return InspectionGadgetsBundle.message("foreach.replace.quickfix");
}
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
final PsiElement forElement = descriptor.getPsiElement();
final PsiElement parent = forElement.getParent();
if (!(parent instanceof PsiForStatement)) {
return;
}
final PsiForStatement forStatement = (PsiForStatement)parent;
final String newExpression;
if (isArrayLoopStatement(forStatement)) {
newExpression = createArrayIterationText(forStatement);
}
else if (isCollectionLoopStatement(forStatement, ignoreUntypedCollections)) {
newExpression = createCollectionIterationText(forStatement);
}
else if (isIndexedListLoopStatement(forStatement, ignoreUntypedCollections)) {
newExpression = createListIterationText(forStatement);
}
else {
return;
}
if (newExpression == null) {
return;
}
PsiReplacementUtil.replaceStatementAndShortenClassNames(forStatement, newExpression);
}
@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 = 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 PsiType extractContentTypeFromType(
PsiType collectionType) {
if (!(collectionType instanceof PsiClassType)) {
return null;
}
final PsiClassType classType = (PsiClassType)collectionType;
final PsiType[] parameterTypes = classType.getParameters();
if (parameterTypes.length == 0) {
return null;
}
final PsiType parameterType = parameterTypes[0];
if (parameterType == null) {
return null;
}
if (parameterType instanceof PsiWildcardType) {
final PsiWildcardType wildcardType =
(PsiWildcardType)parameterType;
return wildcardType.getExtendsBound();
}
else if (parameterType instanceof PsiCapturedWildcardType) {
final PsiCapturedWildcardType capturedWildcardType =
(PsiCapturedWildcardType)parameterType;
final PsiWildcardType wildcardType =
capturedWildcardType.getWildcard();
return wildcardType.getExtendsBound();
}
return parameterType;
}
@Nullable
private PsiType extractListTypeFromContainingClass(
PsiElement element) {
PsiClass listClass = PsiTreeUtil.getParentOfType(element,
PsiClass.class);
if (listClass == null) {
return null;
}
final PsiMethod[] getMethods =
listClass.findMethodsByName("get", true);
if (getMethods.length == 0) {
return null;
}
final PsiType type = getMethods[0].getReturnType();
if (!(type instanceof PsiClassType)) {
return null;
}
final PsiClassType classType = (PsiClassType)type;
final PsiClass parameterClass = classType.resolve();
if (parameterClass == null) {
return null;
}
PsiClass subClass = null;
while (listClass != null && !listClass.hasTypeParameters()) {
subClass = listClass;
listClass = listClass.getSuperClass();
}
if (listClass == null || subClass == null) {
return TypeUtils.getObjectType(element);
}
final PsiTypeParameter[] typeParameters =
listClass.getTypeParameters();
if (!parameterClass.equals(typeParameters[0])) {
return TypeUtils.getObjectType(element);
}
final PsiReferenceList extendsList = subClass.getExtendsList();
if (extendsList == null) {
return null;
}
final PsiJavaCodeReferenceElement[] referenceElements =
extendsList.getReferenceElements();
if (referenceElements.length == 0) {
return null;
}
final PsiType[] types =
referenceElements[0].getTypeParameters();
if (types.length == 0) {
return TypeUtils.getObjectType(element);
}
return types[0];
}
@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();
}
@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();
}
private void replaceArrayAccess(
PsiElement element, String contentVariableName,
PsiVariable arrayVariable, String indexName,
PsiElement childToSkip, StringBuilder out) {
if (isArrayLookup(element, indexName, arrayVariable)) {
out.append(contentVariableName);
}
else {
final PsiElement[] children = element.getChildren();
if (children.length == 0) {
final String text = element.getText();
if (PsiKeyword.INSTANCEOF.equals(text) &&
out.charAt(out.length() - 1) != ' ') {
out.append(' ');
}
out.append(text);
}
else {
boolean skippingWhiteSpace = false;
for (final PsiElement child : children) {
if (child.equals(childToSkip)) {
skippingWhiteSpace = true;
}
else if (child instanceof PsiWhiteSpace &&
skippingWhiteSpace) {
//don't do anything
}
else {
skippingWhiteSpace = false;
replaceArrayAccess(child, contentVariableName,
arrayVariable, indexName,
childToSkip, out);
}
}
}
}
}
private void replaceCollectionGetAccess(
PsiElement element, String contentVariableName,
PsiVariable listVariable, String indexName,
PsiElement childToSkip, StringBuilder out) {
if (isListGetLookup(element, indexName, listVariable)) {
out.append(contentVariableName);
}
else {
final PsiElement[] children = element.getChildren();
if (children.length == 0) {
final String text = element.getText();
if (PsiKeyword.INSTANCEOF.equals(text) &&
out.charAt(out.length() - 1) != ' ') {
out.append(' ');
}
out.append(text);
}
else {
boolean skippingWhiteSpace = false;
for (final PsiElement child : children) {
if (child.equals(childToSkip)) {
skippingWhiteSpace = true;
}
else if (child instanceof PsiWhiteSpace &&
skippingWhiteSpace) {
//don't do anything
}
else {
skippingWhiteSpace = false;
replaceCollectionGetAccess(child,
contentVariableName,
listVariable, indexName,
childToSkip, out);
}
}
}
}
}
private boolean isListGetLookup(PsiElement element,
String indexName,
PsiVariable listVariable) {
if (!(element instanceof PsiExpression)) {
return false;
}
final PsiExpression expression = (PsiExpression)element;
if (!expressionIsListGetLookup(expression)) {
return false;
}
final PsiMethodCallExpression methodCallExpression =
(PsiMethodCallExpression)
ParenthesesUtils.stripParentheses(expression);
if (methodCallExpression == null) {
return false;
}
final PsiReferenceExpression methodExpression =
methodCallExpression.getMethodExpression();
final PsiExpression qualifierExpression =
methodExpression.getQualifierExpression();
final PsiExpressionList argumentList =
methodCallExpression.getArgumentList();
final PsiExpression[] expressions = argumentList.getExpressions();
if (expressions.length != 1) {
return false;
}
if (!indexName.equals(expressions[0].getText())) {
return false;
}
if (qualifierExpression == null ||
qualifierExpression instanceof PsiThisExpression ||
qualifierExpression instanceof PsiSuperExpression) {
return listVariable == null;
}
if (!(qualifierExpression instanceof PsiReferenceExpression)) {
return false;
}
final PsiReferenceExpression referenceExpression =
(PsiReferenceExpression)qualifierExpression;
final PsiExpression qualifier =
referenceExpression.getQualifierExpression();
if (qualifier != null && !(qualifier instanceof PsiThisExpression) &&
!(qualifier instanceof PsiSuperExpression)) {
return false;
}
final PsiElement target = referenceExpression.resolve();
return listVariable.equals(target);
}
private void replaceIteratorNext(
PsiElement element, String contentVariableName,
String iteratorName, PsiElement childToSkip,
StringBuilder out, PsiType contentType) {
if (isIteratorNext(element, iteratorName, contentType)) {
out.append(contentVariableName);
}
else {
final PsiElement[] children = element.getChildren();
if (children.length == 0) {
final String text = element.getText();
if (PsiKeyword.INSTANCEOF.equals(text) &&
out.charAt(out.length() - 1) != ' ') {
out.append(' ');
}
out.append(text);
}
else {
boolean skippingWhiteSpace = false;
for (final PsiElement child : children) {
if (child.equals(childToSkip)) {
skippingWhiteSpace = true;
}
else if (child instanceof PsiWhiteSpace &&
skippingWhiteSpace) {
//don't do anything
}
else {
skippingWhiteSpace = false;
replaceIteratorNext(child, contentVariableName,
iteratorName, childToSkip, out, contentType);
}
}
}
}
}
private boolean isArrayElementDeclaration(
PsiStatement statement, PsiVariable arrayVariable,
String indexName) {
if (!(statement instanceof PsiDeclarationStatement)) {
return false;
}
final PsiDeclarationStatement declarationStatement =
(PsiDeclarationStatement)statement;
final PsiElement[] declaredElements =
declarationStatement.getDeclaredElements();
if (declaredElements.length != 1) {
return false;
}
final PsiElement declaredElement = declaredElements[0];
if (!(declaredElement instanceof PsiVariable)) {
return false;
}
final PsiVariable variable = (PsiVariable)declaredElement;
final PsiExpression initializer = variable.getInitializer();
return isArrayLookup(initializer, indexName, arrayVariable);
}
private boolean isListElementDeclaration(
PsiStatement statement, PsiVariable listVariable,
String indexName, PsiType type) {
if (!(statement instanceof PsiDeclarationStatement)) {
return false;
}
final PsiDeclarationStatement declarationStatement =
(PsiDeclarationStatement)statement;
final PsiElement[] declaredElements =
declarationStatement.getDeclaredElements();
if (declaredElements.length != 1) {
return false;
}
final PsiElement declaredElement = declaredElements[0];
if (!(declaredElement instanceof PsiVariable)) {
return false;
}
final PsiVariable variable = (PsiVariable)declaredElement;
final PsiExpression initializer = variable.getInitializer();
if (!isListGetLookup(initializer, indexName, listVariable)) {
return false;
}
return type != null && type.equals(variable.getType());
}
private boolean isIteratorNextDeclaration(
PsiStatement statement, String iteratorName,
PsiType contentType) {
if (!(statement instanceof PsiDeclarationStatement)) {
return false;
}
final PsiDeclarationStatement declarationStatement =
(PsiDeclarationStatement)statement;
final PsiElement[] declaredElements =
declarationStatement.getDeclaredElements();
if (declaredElements.length != 1) {
return false;
}
final PsiElement declaredElement = declaredElements[0];
if (!(declaredElement instanceof PsiVariable)) {
return false;
}
final PsiVariable variable = (PsiVariable)declaredElement;
final PsiExpression initializer = variable.getInitializer();
return isIteratorNext(initializer, iteratorName, contentType);
}
private boolean isArrayLookup(
PsiElement element, String indexName, PsiVariable arrayVariable) {
if (element == null) {
return false;
}
if (!(element instanceof PsiArrayAccessExpression)) {
return false;
}
final PsiArrayAccessExpression arrayAccess =
(PsiArrayAccessExpression)element;
final PsiExpression indexExpression =
arrayAccess.getIndexExpression();
if (indexExpression == null) {
return false;
}
if (!indexName.equals(indexExpression.getText())) {
return false;
}
final PsiExpression arrayExpression =
arrayAccess.getArrayExpression();
if (!(arrayExpression instanceof PsiReferenceExpression)) {
return false;
}
final PsiReferenceExpression referenceExpression =
(PsiReferenceExpression)arrayExpression;
final PsiExpression qualifier =
referenceExpression.getQualifierExpression();
if (qualifier != null && !(qualifier instanceof PsiThisExpression) &&
!(qualifier instanceof PsiSuperExpression)) {
return false;
}
final PsiElement target = referenceExpression.resolve();
return arrayVariable.equals(target);
}
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);
}
private String createNewVariableName(
@NotNull PsiForStatement scope, PsiType type,
@Nullable String containerName) {
final Project project = scope.getProject();
final JavaCodeStyleManager codeStyleManager =
JavaCodeStyleManager.getInstance(project);
@NonNls String baseName;
if (containerName != null) {
baseName = StringUtils.createSingularFromName(containerName);
}
else {
final SuggestedNameInfo suggestions =
codeStyleManager.suggestVariableName(
VariableKind.LOCAL_VARIABLE, null, null, type);
final String[] names = suggestions.names;
if (names != null && names.length > 0) {
baseName = names[0];
}
else {
baseName = "value";
}
}
if (baseName == null || baseName.isEmpty()) {
baseName = "value";
}
return codeStyleManager.suggestUniqueVariableName(baseName, scope,
true);
}
@Nullable
private PsiStatement getFirstStatement(PsiStatement body) {
if (!(body instanceof PsiBlockStatement)) {
return body;
}
final PsiBlockStatement block = (PsiBlockStatement)body;
final PsiCodeBlock codeBlock = block.getCodeBlock();
final PsiStatement[] statements = codeBlock.getStatements();
if (statements.length <= 0) {
return null;
}
return statements[0];
}
}
}