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