Fix conversion of assignment as expression in J2K

Blockless if's and so with assignment as expression inside
should turn into blockful
 #KT-16816 fixed
This commit is contained in:
Simon Ogorodnik
2017-03-31 14:16:10 +03:00
parent 86137e1f65
commit 57c1d8eda4
13 changed files with 136 additions and 5 deletions
@@ -33,6 +33,8 @@ class ArrayAccessExpression(val expression: Expression, val index: Expression, v
open class AssignmentExpression(val left: Expression, val right: Expression, val op: Operator) : Expression() {
fun isMultiAssignment() = right is AssignmentExpression
fun appendAssignment(builder: CodeBuilder, left: Expression, right: Expression) {
builder.appendOperand(this, left).append(" ").append(op).append(" ").appendOperand(this, right)
}
@@ -65,9 +65,9 @@ class IfStatement(
private val brAfterElse = if (singleLine || elseStatement is IfStatement) " " else "\n"
override fun generateCode(builder: CodeBuilder) {
builder append "if (" append condition append ")" append br append thenStatement
builder append "if (" append condition append ")" append br append thenStatement.wrapToBlockIfRequired()
if (!elseStatement.isEmpty) {
builder append br append "else" append brAfterElse append elseStatement
builder append br append "else" append brAfterElse append elseStatement.wrapToBlockIfRequired()
}
}
}
@@ -78,7 +78,7 @@ class WhileStatement(val condition: Expression, val body: Element, singleLine: B
private val br = if (singleLine) " " else "\n"
override fun generateCode(builder: CodeBuilder) {
builder append "while (" append condition append ")" append br append body
builder append "while (" append condition append ")" append br append body.wrapToBlockIfRequired()
}
}
@@ -86,7 +86,7 @@ class DoWhileStatement(val condition: Expression, val body: Element, singleLine:
private val br = if (singleLine) " " else "\n"
override fun generateCode(builder: CodeBuilder) {
builder append "do" append br append body append br append "while (" append condition append ")"
builder append "do" append br append body.wrapToBlockIfRequired() append br append "while (" append condition append ")"
}
}
@@ -105,7 +105,7 @@ class ForeachStatement(
if (explicitVariableType != null) {
builder append ":" append explicitVariableType
}
builder append " in " append collection append ")" append br append body
builder append " in " append collection append ")" append br append body.wrapToBlockIfRequired()
}
}
@@ -32,6 +32,12 @@ fun CodeBuilder.appendOperand(expression: Expression, operand: Expression, paren
return this
}
fun Element.wrapToBlockIfRequired(): Element = when (this) {
is AssignmentExpression -> if (isMultiAssignment()) Block.of(this).assignNoPrototype() else this
else -> this
}
private fun Expression.precedence(): Int? {
return when (this) {
is QualifiedExpression, is MethodCallExpression, is ArrayAccessExpression, is PostfixExpression, is BangBangExpression, is StarExpression -> 0
@@ -0,0 +1,7 @@
public class SomeClass {
int a;
int b;
void doSomeWhile(int i) {
do a = b = i; while (i < 0)
}
}
@@ -0,0 +1,10 @@
class SomeClass {
internal var a: Int = 0
internal var b: Int = 0
internal fun doSomeWhile(i: Int) {
do {
b = i
a = b
} while (i < 0)
}
}
@@ -0,0 +1,7 @@
public class SomeClass {
void doSomeFor() {
int a,b;
for (int i = 0; i < 10; i++)
a = b = i;
}
}
@@ -0,0 +1,10 @@
class SomeClass {
internal fun doSomeFor() {
var a: Int
var b: Int
for (i in 0..9) {
b = i
a = b
}
}
}
@@ -0,0 +1,9 @@
public class SomeClass {
void doSomeIf(int i) {
int a,b,c
if (i < 0)
a = b = i;
else
b = c = i;
}
}
@@ -0,0 +1,14 @@
class SomeClass {
internal fun doSomeIf(i: Int) {
val a: Int
val b: Int
val c: Int
if (i < 0) {
b = i
a = b
} else {
c = i
b = c
}
}
}
@@ -0,0 +1,8 @@
public class SomeClass {
int a;
int b;
void doSomeWhile(int i) {
while (i < 0)
a = b = i;
}
}
@@ -0,0 +1,10 @@
class SomeClass {
internal var a: Int = 0
internal var b: Int = 0
internal fun doSomeWhile(i: Int) {
while (i < 0) {
b = i
a = b
}
}
}
@@ -1733,6 +1733,12 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/testData/fileOrElement/doWhileStatement"), Pattern.compile("^(.+)\\.java$"), TargetBackend.ANY, true);
}
@TestMetadata("whileWithAssignmentAsExpression.java")
public void testWhileWithAssignmentAsExpression() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/doWhileStatement/whileWithAssignmentAsExpression.java");
doTest(fileName);
}
@TestMetadata("whileWithBlock.java")
public void testWhileWithBlock() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/doWhileStatement/whileWithBlock.java");
@@ -2108,6 +2114,12 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
doTest(fileName);
}
@TestMetadata("assignmentAsExpressionInBody.java")
public void testAssignmentAsExpressionInBody() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/for/assignmentAsExpressionInBody.java");
doTest(fileName);
}
@TestMetadata("commonCaseForTest.java")
public void testCommonCaseForTest() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/for/commonCaseForTest.java");
@@ -2699,6 +2711,12 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/testData/fileOrElement/ifStatement"), Pattern.compile("^(.+)\\.java$"), TargetBackend.ANY, true);
}
@TestMetadata("assignmentAsExpressionInIf.java")
public void testAssignmentAsExpressionInIf() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/ifStatement/assignmentAsExpressionInIf.java");
doTest(fileName);
}
@TestMetadata("elseIf.java")
public void testElseIf() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/ifStatement/elseIf.java");
@@ -5018,6 +5036,12 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/testData/fileOrElement/whileStatement"), Pattern.compile("^(.+)\\.java$"), TargetBackend.ANY, true);
}
@TestMetadata("whileWithAssignmentAsExpression.java")
public void testWhileWithAssignmentAsExpression() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/whileStatement/whileWithAssignmentAsExpression.java");
doTest(fileName);
}
@TestMetadata("whileWithBlock.java")
public void testWhileWithBlock() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/whileStatement/whileWithBlock.java");
@@ -1733,6 +1733,12 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/testData/fileOrElement/doWhileStatement"), Pattern.compile("^(.+)\\.java$"), TargetBackend.ANY, true);
}
@TestMetadata("whileWithAssignmentAsExpression.java")
public void testWhileWithAssignmentAsExpression() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/doWhileStatement/whileWithAssignmentAsExpression.java");
doTest(fileName);
}
@TestMetadata("whileWithBlock.java")
public void testWhileWithBlock() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/doWhileStatement/whileWithBlock.java");
@@ -2108,6 +2114,12 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
doTest(fileName);
}
@TestMetadata("assignmentAsExpressionInBody.java")
public void testAssignmentAsExpressionInBody() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/for/assignmentAsExpressionInBody.java");
doTest(fileName);
}
@TestMetadata("commonCaseForTest.java")
public void testCommonCaseForTest() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/for/commonCaseForTest.java");
@@ -2699,6 +2711,12 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/testData/fileOrElement/ifStatement"), Pattern.compile("^(.+)\\.java$"), TargetBackend.ANY, true);
}
@TestMetadata("assignmentAsExpressionInIf.java")
public void testAssignmentAsExpressionInIf() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/ifStatement/assignmentAsExpressionInIf.java");
doTest(fileName);
}
@TestMetadata("elseIf.java")
public void testElseIf() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/ifStatement/elseIf.java");
@@ -5018,6 +5036,12 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/testData/fileOrElement/whileStatement"), Pattern.compile("^(.+)\\.java$"), TargetBackend.ANY, true);
}
@TestMetadata("whileWithAssignmentAsExpression.java")
public void testWhileWithAssignmentAsExpression() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/whileStatement/whileWithAssignmentAsExpression.java");
doTest(fileName);
}
@TestMetadata("whileWithBlock.java")
public void testWhileWithBlock() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/whileStatement/whileWithBlock.java");