diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java
index 0bade66..f23fc78 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java
@@ -178,7 +178,7 @@ public class SimplifyExprentsHelper {
}
// expr++ and expr--
- if (isIPPorIMM(current, next)) {
+ if (isIPPorIMM(current, next) || isIPPorIMM2(current, next)) {
list.remove(index + 1);
res = true;
continue;
@@ -458,6 +458,48 @@ public class SimplifyExprentsHelper {
return false;
}
+ private static boolean isIPPorIMM2(Exprent first, Exprent second) {
+
+ if (first.type != Exprent.EXPRENT_ASSIGNMENT || second.type != Exprent.EXPRENT_ASSIGNMENT) {
+ return false;
+ }
+
+ AssignmentExprent af = (AssignmentExprent)first;
+ AssignmentExprent as = (AssignmentExprent)second;
+
+ if(as.getRight().type != Exprent.EXPRENT_FUNCTION) {
+ return false;
+ }
+
+ FunctionExprent func = (FunctionExprent)as.getRight();
+
+ if(func.getFuncType() != FunctionExprent.FUNCTION_ADD && func.getFuncType() != FunctionExprent.FUNCTION_SUB) {
+ return false;
+ }
+
+ Exprent econd = func.getLstOperands().get(0);
+ Exprent econst = func.getLstOperands().get(1);
+
+ if(econst.type != Exprent.EXPRENT_CONST && econd.type == Exprent.EXPRENT_CONST && func.getFuncType() == FunctionExprent.FUNCTION_ADD) {
+ econd = econst;
+ econst = func.getLstOperands().get(0);
+ }
+
+ if(econst.type == Exprent.EXPRENT_CONST && ((ConstExprent)econst).hasValueOne()) {
+ if(af.getLeft().equals(econd) && af.getRight().equals(as.getLeft()) && (af.getLeft().getExprentUse() & Exprent.MULTIPLE_USES) != 0) {
+ int type = func.getFuncType() == FunctionExprent.FUNCTION_ADD ? FunctionExprent.FUNCTION_IPP : FunctionExprent.FUNCTION_IMM;
+
+ FunctionExprent ret = new FunctionExprent(type, af.getRight(), func.bytecode);
+ ret.setImplicitType(VarType.VARTYPE_INT);
+
+ af.setRight(ret);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
private static boolean isMonitorExit(Exprent first) {
if (first.type == Exprent.EXPRENT_MONITOR) {
MonitorExprent expr = (MonitorExprent)first;
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorTreeExceptionFilter.java b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorTreeExceptionFilter.java
index 89babeb..d8b587f 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorTreeExceptionFilter.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorTreeExceptionFilter.java
@@ -134,8 +134,9 @@ public class DominatorTreeExceptionFilter {
exit = childid;
}
else {
- // exit = map.containsKey(handler)?-1:mapChild.get(handler); FIXME: Eclipse bug?
- exit = map.containsKey(handler) ? -1 : mapChild.get(handler);
+ // after replacing 'new Integer(-1)' with '-1' Eclipse throws a NullPointerException on the following line
+ // could be a bug in Eclipse or some obscure specification glitch, FIXME: needs further investigation
+ exit = map.containsKey(handler) ? new Integer(-1) : mapChild.get(handler);
}
if (exit != null) {
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java
index 264347e..642a86b 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java
@@ -54,7 +54,7 @@ public class FieldExprent extends Exprent {
@Override
public int getExprentUse() {
- return instance == null ? Exprent.MULTIPLE_USES : instance.getExprentUse() & Exprent.MULTIPLE_USES;
+ return 0; // multiple references to a field considered dangerous in a multithreaded environment, thus no Exprent.MULTIPLE_USES set here
}
@Override
diff --git a/testData/classes/pkg/TestFieldSingleAccess.class b/testData/classes/pkg/TestFieldSingleAccess.class
new file mode 100644
index 0000000..edc30ab
Binary files /dev/null and b/testData/classes/pkg/TestFieldSingleAccess.class differ
diff --git a/testData/results/TestFieldSingleAccess.dec b/testData/results/TestFieldSingleAccess.dec
new file mode 100644
index 0000000..268c866
--- /dev/null
+++ b/testData/results/TestFieldSingleAccess.dec
@@ -0,0 +1,40 @@
+package pkg;
+
+public final class TestFieldSingleAccess {
+ public Integer field;
+
+ public final void test() {
+ Integer var10000 = this.field;
+ if (var10000 != null) {
+ System.out.println(var10000);
+ }
+
+ }
+
+ public final void test1() {
+ synchronized(this.field) {
+ System.out.println('1');
+ }
+ }
+}
+
+class 'pkg/TestFieldSingleAccess' {
+ method 'test ()V' {
+ 1 6
+ 5 7
+ 8 8
+ c 8
+ f 11
+ }
+
+ method 'test1 ()V' {
+ 1 14
+ 6 14
+ 7 15
+ a 15
+ c 15
+ 19 17
+ }
+}
+
+Lines mapping:
diff --git a/testData/results/TestMethodReferenceSameName.dec b/testData/results/TestMethodReferenceSameName.dec
index 3449a8c..2592d18 100644
--- a/testData/results/TestMethodReferenceSameName.dec
+++ b/testData/results/TestMethodReferenceSameName.dec
@@ -3,7 +3,6 @@ public class TestMethodReferenceSameName {
private void foo() {
TestMethodReferenceSameName.R1 var10000 = this.r;// 5
- this.r.getClass();
(var10000::foo).run();
}// 6
@@ -16,19 +15,18 @@ public class TestMethodReferenceSameName {
class 'TestMethodReferenceSameName' {
method 'foo ()V' {
1 4
- 5 5
- e 6
- 13 7
+ e 5
+ 13 6
}
}
class 'TestMethodReferenceSameName$R1' {
method 'foo ()V' {
- 0 11
+ 0 10
}
}
Lines mapping:
5 <-> 5
-6 <-> 8
-9 <-> 12
+6 <-> 7
+9 <-> 11
diff --git a/testData/src/pkg/TestFieldSingleAccess.jasm b/testData/src/pkg/TestFieldSingleAccess.jasm
new file mode 100644
index 0000000..57b203c
--- /dev/null
+++ b/testData/src/pkg/TestFieldSingleAccess.jasm
@@ -0,0 +1,67 @@
+/**
+ * This code can be assembled with asmtools
+ * using asmtools jasm -g *.jasm command line.
+ */
+package pkg;
+
+super public final class TestFieldSingleAccess
+ version 52:0
+{
+
+public Field field:"Ljava/lang/Integer;";
+
+public Method "":"()V"
+ stack 1 locals 1
+{
+ aload_0;
+ invokespecial Method java/lang/Object."":"()V";
+ return;
+}
+
+public final Method test:"()V"
+ stack 2 locals 1
+{
+ aload_0;
+ getfield Field field:"Ljava/lang/Integer;";
+ dup;
+ ifnull L17;
+ getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
+ swap;
+ invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/Object;)V";
+ L17: stack_frame_type same;
+ return;
+}
+
+public final Method test1:"()V"
+ stack 2 locals 3
+{
+ aload_0;
+ getfield Field field:"Ljava/lang/Integer;";
+ dup;
+ astore_1;
+ monitorenter;
+ try t0;
+ getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
+ bipush 49;
+ invokevirtual Method java/io/PrintStream.println:"(C)V";
+ aload_1;
+ monitorexit;
+ endtry t0;
+ goto L25;
+ catch t0 #0;
+ catch t1 #0;
+ try t1;
+ stack_frame_type full;
+ locals_map class TestFieldSingleAccess, class java/lang/Object;
+ stack_map class java/lang/Throwable;
+ astore_2;
+ aload_1;
+ monitorexit;
+ endtry t1;
+ aload_2;
+ athrow;
+ L25: stack_frame_type chop1;
+ return;
+}
+
+} // end Class TestFieldSingleAccess