diff --git a/plugins/IntentionPowerPak/src/META-INF/plugin.xml b/plugins/IntentionPowerPak/src/META-INF/plugin.xml index ba2dfad06f36..e050f7b14371 100644 --- a/plugins/IntentionPowerPak/src/META-INF/plugin.xml +++ b/plugins/IntentionPowerPak/src/META-INF/plugin.xml @@ -277,6 +277,10 @@ com.siyeh.ipp.forloop.ReplaceForEachLoopWithIndexedForLoopIntention intention.category.control.flow + + com.siyeh.ipp.forloop.ReplaceForEachLoopWithOptimizedIndexedForLoopIntention + intention.category.control.flow + com.siyeh.ipp.forloop.ReplaceForEachLoopWithIteratorForLoopIntention intention.category.control.flow diff --git a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties index 6c8da6aeb7f1..8c489ff40f09 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties +++ b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties @@ -18,6 +18,8 @@ replace.equality.with.safe.equals.intention.family.name=Replace Equality with Sa replace.for.each.loop.with.indexed.for.loop.intention.name=Replace 'for each' loop with indexed 'for' loop replace.for.each.loop.with.iterator.for.loop.intention.name=Replace 'for each' loop with iterator 'for' loop replace.for.each.loop.with.indexed.for.loop.intention.family.name=Replace For-each Loop with Indexed For Loop +replace.for.each.loop.with.optimized.indexed.for.loop.intention.name=Replace 'for each' loop with optimized indexed 'for' loop +replace.for.each.loop.with.optimized.indexed.for.loop.intention.family.name=Replace For-each Loop with Optimized Indexed For Loop replace.for.each.loop.with.iterator.for.loop.intention.family.name=Replace For-each Loop with Iterator For Loop replace.for.loop.with.while.loop.intention.name=Replace 'for' loop with 'while' loop replace.for.loop.with.while.loop.intention.family.name=Replace For Loop with While Loop diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReplaceForEachLoopWithIndexedForLoopIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReplaceForEachLoopWithIndexedForLoopIntention.java index cf41ae7358ab..7252a3ef2343 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReplaceForEachLoopWithIndexedForLoopIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReplaceForEachLoopWithIndexedForLoopIntention.java @@ -60,42 +60,9 @@ public class ReplaceForEachLoopWithIndexedForLoopIntention extends Intention { context = statement; } final String iteratedValueText = getReferenceToIterate(iteratedValue, context); - final String lengthText; - if (isArray) { - lengthText = createVariableName(iteratedValueText + "Length", PsiType.INT, statement); - } - else { - lengthText = createVariableName(iteratedValueText + "Size", PsiType.INT, statement); - } @NonNls final StringBuilder newStatement = new StringBuilder(); - newStatement.append("for(int "); - final String indexText = - createVariableName("i", PsiType.INT, statement); - newStatement.append(indexText); - newStatement.append(" = 0, "); - newStatement.append(lengthText); - newStatement.append(" = "); - if (iteratedValue instanceof PsiTypeCastExpression) { - newStatement.append('('); - newStatement.append(iteratedValueText); - newStatement.append(')'); - } - else { - newStatement.append(iteratedValueText); - } - if (isArray) { - newStatement.append(".length;"); - } - else { - newStatement.append(".size();"); - } - newStatement.append(indexText); - newStatement.append('<'); - newStatement.append(lengthText); - newStatement.append(';'); - newStatement.append(indexText); - newStatement.append("++)"); - newStatement.append("{ "); + final String indexText = createVariableName("i", PsiType.INT, statement); + createForLoopDeclaration(statement, iteratedValue, isArray, iteratedValueText, newStatement, indexText); final Project project = statement.getProject(); final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project); @@ -136,6 +103,36 @@ public class ReplaceForEachLoopWithIndexedForLoopIntention extends Intention { replaceStatementAndShorten(newStatement.toString(), statement); } + protected void createForLoopDeclaration(PsiForeachStatement statement, + PsiExpression iteratedValue, + boolean array, + String iteratedValueText, StringBuilder newStatement, + final String indexText) { + newStatement.append("for(int "); + newStatement.append(indexText); + newStatement.append(" = 0; "); + newStatement.append(indexText); + newStatement.append('<'); + if (iteratedValue instanceof PsiTypeCastExpression) { + newStatement.append('('); + newStatement.append(iteratedValueText); + newStatement.append(')'); + } + else { + newStatement.append(iteratedValueText); + } + if (array) { + newStatement.append(".length"); + } + else { + newStatement.append(".size()"); + } + newStatement.append(';'); + newStatement.append(indexText); + newStatement.append("++)"); + newStatement.append("{ "); + } + private static String getVariableName(PsiExpression expression) { if (expression instanceof PsiMethodCallExpression) { final PsiMethodCallExpression methodCallExpression = diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReplaceForEachLoopWithOptimizedIndexedForLoopIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReplaceForEachLoopWithOptimizedIndexedForLoopIntention.java new file mode 100644 index 000000000000..26a836f83694 --- /dev/null +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReplaceForEachLoopWithOptimizedIndexedForLoopIntention.java @@ -0,0 +1,70 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * 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.psi.PsiExpression; +import com.intellij.psi.PsiForeachStatement; +import com.intellij.psi.PsiType; +import com.intellij.psi.PsiTypeCastExpression; + +/** + * User: anna + * Date: 8/1/12 + */ +public class ReplaceForEachLoopWithOptimizedIndexedForLoopIntention extends ReplaceForEachLoopWithIndexedForLoopIntention { + @Override + protected void createForLoopDeclaration(PsiForeachStatement statement, + PsiExpression iteratedValue, + boolean isArray, + String iteratedValueText, + StringBuilder newStatement, final String indexText) { + + final String lengthText; + if (isArray) { + lengthText = createVariableName(iteratedValueText + "Length", PsiType.INT, statement); + } + else { + lengthText = createVariableName(iteratedValueText + "Size", PsiType.INT, statement); + } + + newStatement.append("for(int "); + newStatement.append(indexText); + newStatement.append(" = 0, "); + newStatement.append(lengthText); + newStatement.append(" = "); + if (iteratedValue instanceof PsiTypeCastExpression) { + newStatement.append('('); + newStatement.append(iteratedValueText); + newStatement.append(')'); + } + else { + newStatement.append(iteratedValueText); + } + if (isArray) { + newStatement.append(".length;"); + } + else { + newStatement.append(".size();"); + } + newStatement.append(indexText); + newStatement.append('<'); + newStatement.append(lengthText); + newStatement.append(';'); + newStatement.append(indexText); + newStatement.append("++)"); + newStatement.append("{ "); + } +} diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/ReplaceForEachLoopWithOptimizedIndexedForLoopIntention/after.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/ReplaceForEachLoopWithOptimizedIndexedForLoopIntention/after.java.template new file mode 100644 index 000000000000..341ceb323542 --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/ReplaceForEachLoopWithOptimizedIndexedForLoopIntention/after.java.template @@ -0,0 +1,9 @@ +public class X { + void f() { + String[] array = new String[]{"foo", "bar", "baz"}; + for (int i = 0, arrayLength = array.length; i < arrayLength; i++) { + String content = array[i]; + System.out.println(content); + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/ReplaceForEachLoopWithOptimizedIndexedForLoopIntention/before.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/ReplaceForEachLoopWithOptimizedIndexedForLoopIntention/before.java.template new file mode 100644 index 000000000000..c5a2d1775d99 --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/ReplaceForEachLoopWithOptimizedIndexedForLoopIntention/before.java.template @@ -0,0 +1,8 @@ +public class X { + void f() { + String[] array = new String[]{"foo", "bar", "baz"}; + for (String content : array) { + System.out.println(content); + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/ReplaceForEachLoopWithOptimizedIndexedForLoopIntention/description.html b/plugins/IntentionPowerPak/src/intentionDescriptions/ReplaceForEachLoopWithOptimizedIndexedForLoopIntention/description.html new file mode 100644 index 000000000000..c78773006ae5 --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/ReplaceForEachLoopWithOptimizedIndexedForLoopIntention/description.html @@ -0,0 +1,7 @@ + + +This intention replaces a JDK 5.0 for-each loop which +iterates over a collection or array with an equivalent for loop that uses an index to +iterate over the collection or array and the size or length is stored in local variable. + + diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/forloop/ReplaceForEachLoopWithIndexedForLoopIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/forloop/ReplaceForEachLoopWithIndexedForLoopIntentionTest.java index 4155af65f527..68d9202d4666 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/forloop/ReplaceForEachLoopWithIndexedForLoopIntentionTest.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/forloop/ReplaceForEachLoopWithIndexedForLoopIntentionTest.java @@ -25,7 +25,7 @@ public class ReplaceForEachLoopWithIndexedForLoopIntentionTest extends IPPTestCa @Override protected String getIntentionName() { - return IntentionPowerPackBundle.message("replace.for.each.loop.with.indexed.for.loop.intention.name"); + return IntentionPowerPackBundle.message("replace.for.each.loop.with.optimized.indexed.for.loop.intention.name"); } @Override