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;
|
||||
|
||||
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
|
||||
}
|
||||
@@ -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 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
|
||||
|
||||
Reference in New Issue
Block a user