KT-584 Convert C-style for statement more correctly

This commit is contained in:
Sergey Ignatov
2011-11-23 13:22:33 +04:00
parent d7e06aeb6a
commit 75a4d34da7
10 changed files with 109 additions and 42 deletions
@@ -0,0 +1,29 @@
package org.jetbrains.jet.j2k.ast;
import org.jetbrains.annotations.NotNull;
/**
* @author ignatov
*/
public class ForeachWithRangeStatement extends Statement {
private Expression myStart;
private IdentifierImpl myIdentifier;
private Expression myEnd;
private Statement myBody;
public ForeachWithRangeStatement(IdentifierImpl identifier, Expression start, Expression end, Statement body) {
myStart = start;
myIdentifier = identifier;
myEnd = end;
myBody = body;
}
@NotNull
@Override
public String toKotlin() {
return "for" + SPACE + "(" +
myIdentifier.toKotlin() + SPACE + "in" + SPACE + myStart.toKotlin() + ".." + myEnd.toKotlin() +
")" + SPACE +
myBody.toKotlin();
}
}
@@ -1,6 +1,9 @@
package org.jetbrains.jet.j2k.visitors;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.j2k.ast.*;
@@ -93,17 +96,66 @@ public class StatementVisitor extends ElementVisitor {
}
@Override
public void visitForStatement(PsiForStatement statement) {
public void visitForStatement(@NotNull PsiForStatement statement) {
super.visitForStatement(statement);
List<Statement> forStatements = new LinkedList<Statement>();
forStatements.add(statementToStatement(statement.getInitialization()));
forStatements.add(new WhileStatement(
expressionToExpression(statement.getCondition()),
new Block(
Arrays.asList(statementToStatement(statement.getBody()),
new Block(Arrays.asList(statementToStatement(statement.getUpdate())))))));
myResult = new Block(forStatements);
final PsiStatement initialization = statement.getInitialization();
final PsiStatement update = statement.getUpdate();
final PsiExpression condition = statement.getCondition();
final PsiLocalVariable firstChild = initialization != null && initialization.getFirstChild() instanceof PsiLocalVariable ?
(PsiLocalVariable) initialization.getFirstChild() : null;
final IElementType operationTokenType = condition != null && condition instanceof PsiBinaryExpression ?
((PsiBinaryExpression) condition).getOperationTokenType() : null;
if (
initialization != null &&
initialization instanceof PsiDeclarationStatement
&& initialization.getFirstChild() == initialization.getLastChild()
&& condition != null
&& update != null
&& update.getChildren().length == 1
&& update.getChildren()[0] instanceof PsiPostfixExpression
&& ((PsiPostfixExpression) update.getChildren()[0]).getOperationTokenType() == JavaTokenType.PLUSPLUS
&& operationTokenType != null
&& (operationTokenType == JavaTokenType.LT || operationTokenType == JavaTokenType.LE)
&& initialization.getFirstChild() != null
&& initialization.getFirstChild() instanceof PsiLocalVariable
&& firstChild != null
&& firstChild.getNameIdentifier() != null
&& isOnceWritableIterator(firstChild)
) {
final Expression end = expressionToExpression(((PsiBinaryExpression) condition).getROperand());
final Expression endExpression = operationTokenType == JavaTokenType.LT ?
new BinaryExpression(end, new IdentifierImpl("1"), "-"):
end;
myResult = new ForeachWithRangeStatement(
new IdentifierImpl(firstChild.getName()),
expressionToExpression(firstChild.getInitializer()),
endExpression,
statementToStatement(statement.getBody())
);
} else { // common case: while loop instead of for loop
List<Statement> forStatements = new LinkedList<Statement>();
forStatements.add(statementToStatement(initialization));
forStatements.add(new WhileStatement(
expressionToExpression(condition),
new Block(
Arrays.asList(statementToStatement(statement.getBody()),
new Block(Arrays.asList(statementToStatement(update)))))));
myResult = new Block(forStatements);
}
}
private static boolean isOnceWritableIterator(PsiLocalVariable firstChild) {
int counter = 0;
if (firstChild != null)
for (PsiReference r : (ReferencesSearch.search(firstChild))) {
if (r instanceof PsiExpression) {
if (PsiUtil.isAccessedForWriting((PsiExpression) r))
counter++;
}
}
return counter == 1; // only increment usage
}
@Override
@@ -0,0 +1,2 @@
int[] array = new int[10];
for (int i = 0; i <= 10; i++) {array[i] = i;}
@@ -0,0 +1,4 @@
var array : IntArray? = IntArray?(10, {null})
for (i in 0..10) {
array[i] = i
}
@@ -0,0 +1,2 @@
int[] array = new int[10];
for (int i = 0; i < 10; i++) {array[i] = i;}
@@ -0,0 +1,4 @@
var array : IntArray? = IntArray?(10, {null})
for (i in 0..(10 - 1)) {
array[i] = i
}
+2 -1
View File
@@ -1 +1,2 @@
for (int i = 0; i < 0; i++) {int i = 1; i++;}
int[] array = new int[10];
for (int i = 0; i < 10; i++) {array[i] = i;}
+3 -12
View File
@@ -1,13 +1,4 @@
{
var i : Int = 0
while ((i < 0))
{
{
var i : Int = 1
(i++)
}
{
(i++)
}
}
var array : IntArray? = IntArray?(10, {null})
for (i in 0..(10 - 1)) {
array[i] = i
}
@@ -1,10 +1 @@
{
var i : Int = 0
while ((i < 0))
{
(t++)
{
(i++)
}
}
}
for (i in 0..(0 - 1)) (t++)
@@ -1,8 +1,4 @@
@test {
var i : Int = 0
while ((i <= max))
{
{
@test for (i in 0..max) {
var n : Int = substring.length()
var j : Int = i
var k : Int = 0
@@ -16,11 +12,6 @@ continue@test
foundIt = true
break@test
}
{
(i++)
}
}
}
System.out?.println((if (foundIt)
"Found it"
else