From 02fdbec13231c16a8f8479a464327c57cd1a8681 Mon Sep 17 00:00:00 2001 From: temp1011 <34900092+temp1011@users.noreply.github.com> Date: Tue, 31 Jul 2018 13:26:13 +0300 Subject: [PATCH] fix extra semicolon in decompiled empty blocks IDEA-196314 #843 --- .../decompiler/stats/CatchStatement.java | 6 +- .../modules/decompiler/stats/DoStatement.java | 12 ++- .../modules/decompiler/stats/IfStatement.java | 18 ++--- .../java/decompiler/SingleClassesTest.java | 1 + testData/classes/pkg/TestEmptyBlocks.class | Bin 0 -> 544 bytes testData/obfuscated/bc.java | 1 - testData/obfuscated/bd.java | 2 - testData/results/TestClassVar.dec | 15 ++-- testData/results/TestEmptyBlocks.dec | 47 +++++++++++ .../results/TestMissingConstructorCallBad.dec | 5 +- .../TestMissingConstructorCallGood.dec | 5 +- testData/results/TestTryCatchFinally.dec | 75 +++++++++--------- testData/src/pkg/TestEmptyBlocks.java | 48 +++++++++++ 13 files changed, 160 insertions(+), 75 deletions(-) create mode 100644 testData/classes/pkg/TestEmptyBlocks.class create mode 100644 testData/results/TestEmptyBlocks.dec create mode 100644 testData/src/pkg/TestEmptyBlocks.java diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java index 87b9bd9..2c32d4c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java @@ -1,6 +1,4 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - */ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.java.decompiler.modules.decompiler.stats; import org.jetbrains.java.decompiler.code.CodeConstants; @@ -171,7 +169,7 @@ public class CatchStatement extends Statement { buf.append(vars.get(i - 1).toJava(indent, tracer)); buf.append(") {").appendLineSeparator(); tracer.incrementCurrentSourceLine(); - buf.append(ExprProcessor.jmpWrapper(stat, indent + 1, true, tracer)).appendIndent(indent) + buf.append(ExprProcessor.jmpWrapper(stat, indent + 1, false, tracer)).appendIndent(indent) .append("}"); } buf.appendLineSeparator(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java index 06a3a80..8abfc29 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java @@ -1,6 +1,4 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - */ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.java.decompiler.modules.decompiler.stats; import org.jetbrains.java.decompiler.util.TextBuffer; @@ -93,21 +91,21 @@ public class DoStatement extends Statement { case LOOP_DO: buf.appendIndent(indent).append("while(true) {").appendLineSeparator(); tracer.incrementCurrentSourceLine(); - buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true, tracer)); + buf.append(ExprProcessor.jmpWrapper(first, indent + 1, false, tracer)); buf.appendIndent(indent).append("}").appendLineSeparator(); tracer.incrementCurrentSourceLine(); break; case LOOP_DOWHILE: buf.appendIndent(indent).append("do {").appendLineSeparator(); tracer.incrementCurrentSourceLine(); - buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true, tracer)); + buf.append(ExprProcessor.jmpWrapper(first, indent + 1, false, tracer)); buf.appendIndent(indent).append("} while(").append(conditionExprent.get(0).toJava(indent, tracer)).append(");").appendLineSeparator(); tracer.incrementCurrentSourceLine(); break; case LOOP_WHILE: buf.appendIndent(indent).append("while(").append(conditionExprent.get(0).toJava(indent, tracer)).append(") {").appendLineSeparator(); tracer.incrementCurrentSourceLine(); - buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true, tracer)); + buf.append(ExprProcessor.jmpWrapper(first, indent + 1, false, tracer)); buf.appendIndent(indent).append("}").appendLineSeparator(); tracer.incrementCurrentSourceLine(); break; @@ -120,7 +118,7 @@ public class DoStatement extends Statement { .append(conditionExprent.get(0).toJava(indent, tracer)).append("; ").append(incExprent.get(0).toJava(indent, tracer)).append(") {") .appendLineSeparator(); tracer.incrementCurrentSourceLine(); - buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true, tracer)); + buf.append(ExprProcessor.jmpWrapper(first, indent + 1, false, tracer)); buf.appendIndent(indent).append("}").appendLineSeparator(); tracer.incrementCurrentSourceLine(); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java index 7962bb1..46fba5e 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java @@ -1,6 +1,4 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - */ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.java.decompiler.modules.decompiler.stats; import org.jetbrains.java.decompiler.util.TextBuffer; @@ -204,24 +202,26 @@ public class IfStatement extends Statement { tracer.incrementCurrentSourceLine(); if (ifstat == null) { - buf.appendIndent(indent + 1); - + boolean semicolon = false; if (ifedge.explicit) { + semicolon = true; if (ifedge.getType() == StatEdge.TYPE_BREAK) { // break - buf.append("break"); + buf.appendIndent(indent + 1).append("break"); } else { // continue - buf.append("continue"); + buf.appendIndent(indent + 1).append("continue"); } if (ifedge.labeled) { buf.append(" label").append(ifedge.closure.id.toString()); } } - buf.append(";").appendLineSeparator(); - tracer.incrementCurrentSourceLine(); + if(semicolon) { + buf.append(";").appendLineSeparator(); + tracer.incrementCurrentSourceLine(); + } } else { buf.append(ExprProcessor.jmpWrapper(ifstat, indent + 1, true, tracer)); diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 68cb460..eb0cc2a 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -107,6 +107,7 @@ public class SingleClassesTest { @Test public void testSuperInner() { doTest("pkg/TestSuperInner", "pkg/TestSuperInnerBase"); } @Test public void testMissingConstructorCallGood() { doTest("pkg/TestMissingConstructorCallGood"); } @Test public void testMissingConstructorCallBad() { doTest("pkg/TestMissingConstructorCallBad"); } + @Test public void testEmptyBlocks() { doTest("pkg/TestEmptyBlocks"); } // TODO: fix all below diff --git a/testData/classes/pkg/TestEmptyBlocks.class b/testData/classes/pkg/TestEmptyBlocks.class new file mode 100644 index 0000000000000000000000000000000000000000..2f7e391dacb46a50d0668094bfa725dc4b18383e GIT binary patch literal 544 zcmZ8dO-oxr6g@XDc`tcM%$LS$s-*~}?V_pRF5@0sftCM8x#I*BXj5%)N8Y+ z6@tC00%g_+*82}lLi~%~mxNqH1#+w3ZprSBX!*<(8`=|oQ*>2`|B-QXqwedh8!A+vej)JbSo{dB5#Iw0gDwr`YQ{UL&V-Ok`O7TEany>(Q%ri9g#(3c%S)OfGnmMrI4F6pGRWAvQ--( z{?)3@CohpY0}aOaH?Vd`h+iRb0edk1{Xe#bkz@=B7O)UrxEQ%BGoE91mJL);!W%5{ i{ET-KBT25#qre?SUU}GchwC0e^Z+*(TAgM-hM7M%<7cD* literal 0 HcmV?d00001 diff --git a/testData/obfuscated/bc.java b/testData/obfuscated/bc.java index ee3c7f5..468d25f 100644 --- a/testData/obfuscated/bc.java +++ b/testData/obfuscated/bc.java @@ -150,7 +150,6 @@ public class bc extends DefaultHandler { var4.setContentHandler(this); var4.parse(new InputSource(var1)); } catch (a_ var8) { - ; } finally { var1.close(); } diff --git a/testData/obfuscated/bd.java b/testData/obfuscated/bd.java index af46c04..5368353 100644 --- a/testData/obfuscated/bd.java +++ b/testData/obfuscated/bd.java @@ -236,7 +236,6 @@ public class bd { try { b.update(var0.getBytes(j)); } catch (UnsupportedEncodingException var4) { - ; } byte[] var2 = b.digest(); @@ -260,7 +259,6 @@ public class bd { try { var2 = (var0 + a).getBytes(j); } catch (UnsupportedEncodingException var9) { - ; } b.update(var2); diff --git a/testData/results/TestClassVar.dec b/testData/results/TestClassVar.dec index fb7cb0f..14e8b9e 100644 --- a/testData/results/TestClassVar.dec +++ b/testData/results/TestClassVar.dec @@ -28,7 +28,6 @@ public class TestClassVar { while(var1 < 10) {// 47 int var2; for(var2 = var1; var1 < 10 && var1 == 0; ++var1) {// 49 51 - ; } if (var2 != var1) {// 54 @@ -72,10 +71,10 @@ class 'pkg/TestClassVar' { d 29 11 29 14 29 - 1c 33 - 1f 34 - 22 34 - 28 38 + 1c 32 + 1f 33 + 22 33 + 28 37 } } @@ -90,8 +89,8 @@ Lines mapping: 47 <-> 28 49 <-> 30 51 <-> 30 -54 <-> 34 -55 <-> 35 -58 <-> 39 +54 <-> 33 +55 <-> 34 +58 <-> 38 Not mapped: 57 diff --git a/testData/results/TestEmptyBlocks.dec b/testData/results/TestEmptyBlocks.dec new file mode 100644 index 0000000..72a39b6 --- /dev/null +++ b/testData/results/TestEmptyBlocks.dec @@ -0,0 +1,47 @@ +import java.util.Random; + +public class TestEmptyBlocks { + public static void foo() { + try { + boolean var0 = false;// 22 + } catch (Exception var1) {// 23 + } + + for(int i = 0; i < 5; ++i) {// 27 + } + + while((new Random()).nextBoolean()) {// 31 + } + + if ((new Random()).nextBoolean()) {// 35 + } + + }// 38 +} + +class 'TestEmptyBlocks' { + method 'foo ()V' { + 0 5 + 1 5 + 5 6 + 6 9 + 7 9 + 9 9 + a 9 + d 9 + 1a 12 + 2a 15 + 2d 15 + 30 18 + } +} + +Lines mapping: +22 <-> 6 +23 <-> 7 +27 <-> 10 +31 <-> 13 +35 <-> 16 +38 <-> 19 +Not mapped: +25 diff --git a/testData/results/TestMissingConstructorCallBad.dec b/testData/results/TestMissingConstructorCallBad.dec index a540d62..c4bec2b 100644 --- a/testData/results/TestMissingConstructorCallBad.dec +++ b/testData/results/TestMissingConstructorCallBad.dec @@ -10,7 +10,6 @@ public class TestMissingConstructorCallBad { try { new TestMissingConstructorCallBad(); } catch (Throwable var2) {// 37 - ; } }// 39 @@ -28,7 +27,7 @@ class 'pkg/TestMissingConstructorCallBad' { method 'main ([Ljava/lang/String;)V' { b 11 - c 15 + c 14 } } @@ -40,7 +39,7 @@ Lines mapping: 20 <-> 6 21 <-> 7 37 <-> 12 -39 <-> 16 +39 <-> 15 Not mapped: 18 28 diff --git a/testData/results/TestMissingConstructorCallGood.dec b/testData/results/TestMissingConstructorCallGood.dec index 43af112..2173f97 100644 --- a/testData/results/TestMissingConstructorCallGood.dec +++ b/testData/results/TestMissingConstructorCallGood.dec @@ -13,7 +13,6 @@ public class TestMissingConstructorCallGood { try { new TestMissingConstructorCallGood(); } catch (Throwable var2) {// 45 - ; } }// 47 @@ -35,7 +34,7 @@ class 'pkg/TestMissingConstructorCallGood' { method 'main ([Ljava/lang/String;)V' { b 14 - c 18 + c 17 } } @@ -48,7 +47,7 @@ Lines mapping: 28 <-> 9 29 <-> 10 45 <-> 15 -47 <-> 19 +47 <-> 18 Not mapped: 14 15 diff --git a/testData/results/TestTryCatchFinally.dec b/testData/results/TestTryCatchFinally.dec index 092564e..2af717c 100644 --- a/testData/results/TestTryCatchFinally.dec +++ b/testData/results/TestTryCatchFinally.dec @@ -8,7 +8,6 @@ public class TestTryCatchFinally { try { System.out.println("sout2");// 27 } catch (Exception var8) {// 28 - ; } } finally { System.out.println("finally");// 34 @@ -49,36 +48,36 @@ class 'pkg/TestTryCatchFinally' { 17 8 19 8 1f 9 - 2b 13 - 2d 13 - 30 13 - 38 16 + 2b 12 + 2d 12 + 30 12 + 38 15 } method 'foo (I)I' { - 1 19 - 2 19 - c 20 - e 21 - f 21 - 13 22 - 1b 24 + 1 18 + 2 18 + c 19 + e 20 + f 20 + 13 21 + 1b 23 } method 'test (Ljava/lang/String;)I' { - 1 30 - 4 30 - e 31 - f 32 - 10 33 - 1a 33 - 23 33 - 26 33 - 31 38 - 34 35 - 35 35 - 38 35 - 3f 38 + 1 29 + 4 29 + e 30 + f 31 + 10 32 + 1a 32 + 23 32 + 26 32 + 31 37 + 34 34 + 35 34 + 38 34 + 3f 37 } } @@ -86,19 +85,19 @@ Lines mapping: 24 <-> 6 27 <-> 9 28 <-> 10 -34 <-> 14 -36 <-> 17 -39 <-> 20 -40 <-> 21 -41 <-> 22 -42 <-> 23 -45 <-> 25 -51 <-> 31 -52 <-> 33 -53 <-> 34 -55 <-> 36 -56 <-> 39 -57 <-> 39 +34 <-> 13 +36 <-> 16 +39 <-> 19 +40 <-> 20 +41 <-> 21 +42 <-> 22 +45 <-> 24 +51 <-> 30 +52 <-> 32 +53 <-> 33 +55 <-> 35 +56 <-> 38 +57 <-> 38 Not mapped: 25 32 diff --git a/testData/src/pkg/TestEmptyBlocks.java b/testData/src/pkg/TestEmptyBlocks.java new file mode 100644 index 0000000..30e196f --- /dev/null +++ b/testData/src/pkg/TestEmptyBlocks.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2016 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. + */ +import java.util.Random; + +public class TestEmptyBlocks { + + public static void foo() { + try { + int a = 0; //make sure whole try/catch not removed by compiler + } catch(Exception e) { + + } + + for(int i = 0; i < 5; i++) { + + } + + while(new Random().nextBoolean()) { + + } + + if(new Random().nextBoolean()) { + + } + } + + + + + + + + + +} \ No newline at end of file