KT-584 Convert C-style for statement more correctly
This commit is contained in:
@@ -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;
|
package org.jetbrains.jet.j2k.visitors;
|
||||||
|
|
||||||
import com.intellij.psi.*;
|
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.annotations.NotNull;
|
||||||
import org.jetbrains.jet.j2k.ast.*;
|
import org.jetbrains.jet.j2k.ast.*;
|
||||||
|
|
||||||
@@ -93,17 +96,66 @@ public class StatementVisitor extends ElementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitForStatement(PsiForStatement statement) {
|
public void visitForStatement(@NotNull PsiForStatement statement) {
|
||||||
super.visitForStatement(statement);
|
super.visitForStatement(statement);
|
||||||
|
|
||||||
List<Statement> forStatements = new LinkedList<Statement>();
|
final PsiStatement initialization = statement.getInitialization();
|
||||||
forStatements.add(statementToStatement(statement.getInitialization()));
|
final PsiStatement update = statement.getUpdate();
|
||||||
forStatements.add(new WhileStatement(
|
final PsiExpression condition = statement.getCondition();
|
||||||
expressionToExpression(statement.getCondition()),
|
final PsiLocalVariable firstChild = initialization != null && initialization.getFirstChild() instanceof PsiLocalVariable ?
|
||||||
new Block(
|
(PsiLocalVariable) initialization.getFirstChild() : null;
|
||||||
Arrays.asList(statementToStatement(statement.getBody()),
|
|
||||||
new Block(Arrays.asList(statementToStatement(statement.getUpdate())))))));
|
final IElementType operationTokenType = condition != null && condition instanceof PsiBinaryExpression ?
|
||||||
myResult = new Block(forStatements);
|
((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
|
@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
|
||||||
|
}
|
||||||
@@ -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;}
|
||||||
@@ -1,13 +1,4 @@
|
|||||||
{
|
var array : IntArray? = IntArray?(10, {null})
|
||||||
var i : Int = 0
|
for (i in 0..(10 - 1)) {
|
||||||
while ((i < 0))
|
array[i] = i
|
||||||
{
|
|
||||||
{
|
|
||||||
var i : Int = 1
|
|
||||||
(i++)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
(i++)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1 @@
|
|||||||
{
|
for (i in 0..(0 - 1)) (t++)
|
||||||
var i : Int = 0
|
|
||||||
while ((i < 0))
|
|
||||||
{
|
|
||||||
(t++)
|
|
||||||
{
|
|
||||||
(i++)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
@test {
|
@test for (i in 0..max) {
|
||||||
var i : Int = 0
|
|
||||||
while ((i <= max))
|
|
||||||
{
|
|
||||||
{
|
|
||||||
var n : Int = substring.length()
|
var n : Int = substring.length()
|
||||||
var j : Int = i
|
var j : Int = i
|
||||||
var k : Int = 0
|
var k : Int = 0
|
||||||
@@ -16,11 +12,6 @@ continue@test
|
|||||||
foundIt = true
|
foundIt = true
|
||||||
break@test
|
break@test
|
||||||
}
|
}
|
||||||
{
|
|
||||||
(i++)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out?.println((if (foundIt)
|
System.out?.println((if (foundIt)
|
||||||
"Found it"
|
"Found it"
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user