blob: 272cbfb281b4cc998fed5198db23ca9495871982 [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.ipp.forloop;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import com.siyeh.ipp.base.Intention;
import com.siyeh.ipp.base.PsiElementPredicate;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class ReplaceForEachLoopWithIteratorForLoopIntention extends Intention {
@Override
@NotNull
public PsiElementPredicate getElementPredicate() {
return new IterableForEachLoopPredicate();
}
@Override
public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException {
final PsiForeachStatement statement = (PsiForeachStatement)element.getParent();
if (statement == null) {
return;
}
final PsiExpression iteratedValue = statement.getIteratedValue();
if (iteratedValue == null) {
return;
}
final PsiType iteratedValueType = iteratedValue.getType();
if (!(iteratedValueType instanceof PsiClassType)) {
return;
}
@NonNls final StringBuilder methodCall = new StringBuilder();
if (ParenthesesUtils.getPrecedence(iteratedValue) > ParenthesesUtils.METHOD_CALL_PRECEDENCE) {
methodCall.append('(').append(iteratedValue.getText()).append(')');
}
else {
methodCall.append(iteratedValue.getText());
}
methodCall.append(".iterator()");
final Project project = statement.getProject();
final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
final PsiExpression iteratorCall = factory.createExpressionFromText(methodCall.toString(), iteratedValue);
final PsiType variableType = GenericsUtil.getVariableTypeByExpressionType(iteratorCall.getType());
if (variableType == null) {
return;
}
@NonNls final StringBuilder newStatement = new StringBuilder();
newStatement.append("for(").append(variableType.getCanonicalText()).append(' ');
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
final String iterator = codeStyleManager.suggestUniqueVariableName("iterator", statement, true);
newStatement.append(iterator).append("=").append(iteratorCall.getText()).append(';');
newStatement.append(iterator).append(".hasNext();) {");
final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
newStatement.append("final ");
}
final PsiParameter iterationParameter = statement.getIterationParameter();
final PsiType parameterType = iterationParameter.getType();
final String typeText = parameterType.getCanonicalText();
newStatement.append(typeText).append(' ').append(iterationParameter.getName()).append(" = ").append(iterator).append(".next();");
final PsiStatement body = statement.getBody();
if (body == null) {
return;
}
if (body instanceof PsiBlockStatement) {
final PsiCodeBlock block = ((PsiBlockStatement)body).getCodeBlock();
final PsiElement[] children = block.getChildren();
for (int i = 1; i < children.length - 1; i++) {
//skip the braces
newStatement.append(children[i].getText());
}
}
else {
newStatement.append(body.getText());
}
newStatement.append('}');
PsiReplacementUtil.replaceStatementAndShortenClassNames(statement, newStatement.toString());
}
}