[java-decompiler] Patch 0041 from ForgeFlower. Fix compound assignments

Binary files are changed
Co-authored-by: Mikhail Pyltsin <mikhail.pyltsin@jetbrains.com>

GitOrigin-RevId: 1588124bb6662061a2a46fc3e9180e4645f8ccdc
This commit is contained in:
SuperCoder79
2024-10-10 09:55:49 +00:00
committed by intellij-monorepo-bot
parent 7f93c11ebc
commit aac5c6da2a
6 changed files with 493 additions and 378 deletions
@@ -243,6 +243,7 @@ public class MethodProcessorRunnable implements Runnable {
varProc.setVarDefinitions(root);
cancellationManager.checkCanceled();
SecondaryFunctionsHelper.updateAssignments(root);
// must be the last invocation, because it makes the statement structure inconsistent
// FIXME: new edge type needed
@@ -417,4 +417,46 @@ public final class SecondaryFunctionsHelper {
return null;
}
// Updates assignments to make them compound assignments if possible
public static void updateAssignments(Statement stat) {
List<Object> objects = new ArrayList<>(stat.getExprents() == null ? stat.getSequentialObjects() : stat.getExprents());
for (Object obj : objects) {
if (obj instanceof Statement) {
updateAssignments((Statement) obj);
} else if (obj instanceof Exprent) {
Exprent exprent = (Exprent) obj;
if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) {
AssignmentExprent assignment = (AssignmentExprent) exprent;
List<Exprent> params = exprent.getAllExprents();
Exprent lhs = params.get(0);
Exprent rhs = params.get(1);
// Check for expressions that are standard assignments where the left hand side is a variable and the right hand side is a function
if (assignment.getCondType() == -1 && lhs.type == Exprent.EXPRENT_VAR && rhs.type == Exprent.EXPRENT_FUNCTION) {
VarExprent lhsVar = (VarExprent) lhs;
FunctionExprent rhsFunc = (FunctionExprent) rhs;
List<Exprent> funcParams = rhsFunc.getAllExprents();
// Make sure that the function is a mathematical or bitwise function and function's lhs is a variable
if (rhsFunc.getFuncType() <= FunctionExprent.FUNCTION_USHR && funcParams.get(0).type == Exprent.EXPRENT_VAR) {
VarExprent lhsVarFunc = (VarExprent) funcParams.get(0);
// Check if the left hand side of the assignment and the left hand side of the function are the same variable
if (lhsVar.getIndex() == lhsVarFunc.getIndex()) {
// If all the checks succeed, set the assignment to be a compound assignment and set the right to the right hand side of the function
assignment.setCondType(rhsFunc.getFuncType());
assignment.setRight(funcParams.get(1));
}
}
}
}
}
}
}
}
@@ -242,9 +242,8 @@ public class SingleClassesTest extends SingleClassesTestBase {
@Test(expected = ClassFormatException.class)
public void testUnsupportedConstantPoolEntry() { doTest("java11/TestUnsupportedConstantPoolEntry"); }
@Test public void testSwitchOnStatic() { doTest("pkg/SwitchOnStatic"); }
@Test public void testCompoundAssignment() { doTest("pkg/TestCompoundAssignment"); }
@Test public void testTryToPreserveCast() { doTest("pkg/TryToPreserveCast"); }
@Test public void testPreserveAssignmentToRecord() { doTest("pkg/PreserveAssignmentToRecord"); }
@@ -1,74 +1,69 @@
package pkg;
public class TestCompoundAssignment {
public int testSimple(int i, int j) {
i += j;// 5
i -= j;// 6
i *= j;// 7
i /= j;// 8
i &= j;// 9
i |= j;// 10
i ^= j;// 11
i >>= j;// 12
i <<= j;// 13
i >>>= j;// 14
return i;// 16
public int testSimple(int var1, int var2) {
var1 += var2;// 5
var1 -= var2;// 6
var1 *= var2;// 7
var1 /= var2;// 8
var1 &= var2;// 9
var1 |= var2;// 10
var1 ^= var2;// 11
var1 >>= var2;// 12
var1 <<= var2;// 13
return var1 >>> var2;// 14 16
}
public int testComplex(int i, int j, int k) {
i += j + k;// 20
i -= j + k;// 21
i *= j + k;// 22
i /= j + k;// 23
i &= j + k;// 24
i |= j + k;// 25
i ^= j + k;// 26
i >>= j + k;// 27
i <<= j + k;// 28
i >>>= j + k;// 29
return i;// 31
public int testComplex(int var1, int var2, int var3) {
var1 += var2 + var3;// 20
var1 -= var2 + var3;// 21
var1 *= var2 + var3;// 22
var1 /= var2 + var3;// 23
var1 &= var2 + var3;// 24
var1 |= var2 + var3;// 25
var1 ^= var2 + var3;// 26
var1 >>= var2 + var3;// 27
var1 <<= var2 + var3;// 28
return var1 >>> var2 + var3;// 29 31
}
public int testComplexParens(int i, int j, int k, int m) {
i += (j + k) * m;// 35
i -= (j + k) * m;// 36
i *= (j + k) * m;// 37
i /= (j + k) * m;// 38
i &= (j + k) * m;// 39
i |= (j + k) * m;// 40
i ^= (j + k) * m;// 41
i >>= (j + k) * m;// 42
i <<= (j + k) * m;// 43
i >>>= (j + k) * m;// 44
return i;// 46
public int testComplexParens(int var1, int var2, int var3, int var4) {
var1 += (var2 + var3) * var4;// 35
var1 -= (var2 + var3) * var4;// 36
var1 *= (var2 + var3) * var4;// 37
var1 /= (var2 + var3) * var4;// 38
var1 &= (var2 + var3) * var4;// 39
var1 |= (var2 + var3) * var4;// 40
var1 ^= (var2 + var3) * var4;// 41
var1 >>= (var2 + var3) * var4;// 42
var1 <<= (var2 + var3) * var4;// 43
return var1 >>> (var2 + var3) * var4;// 44 46
}
public int testComplexTernary(int i, int j, int k, int m, boolean b) {
i += b ? j : k * m;// 50
i -= b ? j : k * m;// 51
i *= b ? j : k * m;// 52
i /= b ? j : k * m;// 53
i &= b ? j : k * m;// 54
i |= b ? j : k * m;// 55
i ^= b ? j : k * m;// 56
i >>= b ? j : k * m;// 57
i <<= b ? j : k * m;// 58
i >>>= b ? j : k * m;// 59
return i;// 61
public int testComplexTernary(int var1, int var2, int var3, int var4, boolean var5) {
var1 += var5 ? var2 : var3 * var4;// 50
var1 -= var5 ? var2 : var3 * var4;// 51
var1 *= var5 ? var2 : var3 * var4;// 52
var1 /= var5 ? var2 : var3 * var4;// 53
var1 &= var5 ? var2 : var3 * var4;// 54
var1 |= var5 ? var2 : var3 * var4;// 55
var1 ^= var5 ? var2 : var3 * var4;// 56
var1 >>= var5 ? var2 : var3 * var4;// 57
var1 <<= var5 ? var2 : var3 * var4;// 58
return var1 >>> (var5 ? var2 : var3 * var4);// 59 61
}
public int testArrayOp(int i, int j, int[] a, int b) {
i += a[b] = j;// 65
i -= a[b] = j;// 66
i *= a[b] = j;// 67
i /= a[b] = j;// 68
i &= a[b] = j;// 69
i |= a[b] = j;// 70
i ^= a[b] = j;// 71
i >>= a[b] = j;// 72
i <<= a[b] = j;// 73
i >>>= a[b] = j;// 74
return i;// 76
public int testArrayOp(int var1, int var2, int[] var3, int var4) {
var1 += var3[var4] = var2;// 65
var1 -= var3[var4] = var2;// 66
var1 *= var3[var4] = var2;// 67
var1 /= var3[var4] = var2;// 68
var1 &= var3[var4] = var2;// 69
var1 |= var3[var4] = var2;// 70
var1 ^= var3[var4] = var2;// 71
var1 >>= var3[var4] = var2;// 72
var1 <<= var3[var4] = var2;// 73
return var1 >>> (var3[var4] = var2);// 74 76
}
}
@@ -92,290 +87,290 @@ class 'pkg/TestCompoundAssignment' {
1f 11
21 12
23 12
24 13
25 13
27 13
28 14
29 14
26 13
29 13
}
method 'testComplex (III)I' {
1 18
2 18
3 18
5 18
7 19
8 19
9 19
b 19
d 20
e 20
f 20
11 20
13 21
14 21
15 21
17 21
19 22
1a 22
1b 22
1d 22
1f 23
20 23
21 23
23 23
25 24
26 24
27 24
29 24
2b 25
2c 25
2d 25
2f 25
31 26
32 26
33 26
35 26
37 27
38 27
39 27
3b 27
3c 28
3d 28
1 17
2 17
3 17
5 17
7 18
8 18
9 18
b 18
d 19
e 19
f 19
11 19
13 20
14 20
15 20
17 20
19 21
1a 21
1b 21
1d 21
1f 22
20 22
21 22
23 22
25 23
26 23
27 23
29 23
2b 24
2c 24
2d 24
2f 24
31 25
32 25
33 25
35 25
36 26
37 26
38 26
39 26
3a 26
3d 26
}
method 'testComplexParens (IIII)I' {
1 32
2 32
3 32
4 32
5 32
6 32
8 32
a 33
b 33
c 33
d 33
e 33
f 33
11 33
13 34
14 34
15 34
16 34
17 34
18 34
1a 34
1c 35
1d 35
1e 35
1f 35
20 35
21 35
23 35
25 36
26 36
27 36
28 36
29 36
2a 36
2c 36
2e 37
2f 37
30 37
31 37
32 37
33 37
35 37
37 38
38 38
39 38
3a 38
3b 38
3c 38
3e 38
40 39
41 39
42 39
43 39
44 39
45 39
47 39
49 40
4a 40
4b 40
4c 40
4d 40
4e 40
50 40
52 41
53 41
54 41
55 41
56 41
57 41
59 41
5a 42
5b 42
1 30
2 30
3 30
4 30
5 30
6 30
8 30
a 31
b 31
c 31
d 31
e 31
f 31
11 31
13 32
14 32
15 32
16 32
17 32
18 32
1a 32
1c 33
1d 33
1e 33
1f 33
20 33
21 33
23 33
25 34
26 34
27 34
28 34
29 34
2a 34
2c 34
2e 35
2f 35
30 35
31 35
32 35
33 35
35 35
37 36
38 36
39 36
3a 36
3b 36
3c 36
3e 36
40 37
41 37
42 37
43 37
44 37
45 37
47 37
49 38
4a 38
4b 38
4c 38
4d 38
4e 38
50 38
51 39
52 39
53 39
54 39
55 39
56 39
57 39
58 39
5b 39
}
method 'testComplexTernary (IIIIZ)I' {
1 46
2 46
3 46
6 46
a 46
b 46
c 46
d 46
f 46
11 47
12 47
13 47
16 47
1a 47
1b 47
1c 47
1d 47
1f 47
21 48
22 48
23 48
26 48
2a 48
2b 48
2c 48
2d 48
2f 48
31 49
32 49
33 49
36 49
3a 49
3b 49
3c 49
3d 49
3f 49
41 50
42 50
43 50
46 50
4a 50
4b 50
4c 50
4d 50
4f 50
51 51
52 51
53 51
56 51
5a 51
5b 51
5c 51
5d 51
5f 51
61 52
62 52
63 52
66 52
6a 52
6b 52
6c 52
6d 52
6f 52
71 53
72 53
73 53
76 53
7a 53
7b 53
7c 53
7d 53
7f 53
81 54
82 54
83 54
86 54
8a 54
8b 54
8c 54
8d 54
8f 54
91 55
92 55
93 55
96 55
9a 55
9b 55
9c 55
9d 55
9f 55
a0 56
a1 56
1 43
2 43
3 43
6 43
a 43
b 43
c 43
d 43
f 43
11 44
12 44
13 44
16 44
1a 44
1b 44
1c 44
1d 44
1f 44
21 45
22 45
23 45
26 45
2a 45
2b 45
2c 45
2d 45
2f 45
31 46
32 46
33 46
36 46
3a 46
3b 46
3c 46
3d 46
3f 46
41 47
42 47
43 47
46 47
4a 47
4b 47
4c 47
4d 47
4f 47
51 48
52 48
53 48
56 48
5a 48
5b 48
5c 48
5d 48
5f 48
61 49
62 49
63 49
66 49
6a 49
6b 49
6c 49
6d 49
6f 49
71 50
72 50
73 50
76 50
7a 50
7b 50
7c 50
7d 50
7f 50
81 51
82 51
83 51
86 51
8a 51
8b 51
8c 51
8d 51
8f 51
90 52
91 52
92 52
93 52
96 52
9a 52
9b 52
9c 52
9d 52
9e 52
a1 52
}
method 'testArrayOp (II[II)I' {
1 60
2 60
3 60
4 60
6 60
8 60
a 61
b 61
c 61
d 61
f 61
11 61
13 62
14 62
15 62
16 62
18 62
1a 62
1c 63
1d 63
1e 63
1f 63
21 63
23 63
25 64
26 64
27 64
28 64
2a 64
2c 64
2e 65
2f 65
30 65
31 65
33 65
35 65
37 66
38 66
39 66
3a 66
3c 66
3e 66
40 67
41 67
42 67
43 67
45 67
47 67
49 68
4a 68
4b 68
4c 68
4e 68
50 68
52 69
53 69
54 69
55 69
57 69
59 69
5a 70
5b 70
1 56
2 56
3 56
4 56
6 56
8 56
a 57
b 57
c 57
d 57
f 57
11 57
13 58
14 58
15 58
16 58
18 58
1a 58
1c 59
1d 59
1e 59
1f 59
21 59
23 59
25 60
26 60
27 60
28 60
2a 60
2c 60
2e 61
2f 61
30 61
31 61
33 61
35 61
37 62
38 62
39 62
3a 62
3c 62
3e 62
40 63
41 63
42 63
43 63
45 63
47 63
49 64
4a 64
4b 64
4c 64
4e 64
50 64
51 65
52 65
53 65
54 65
55 65
57 65
58 65
5b 65
}
}
@@ -390,48 +385,48 @@ Lines mapping:
12 <-> 12
13 <-> 13
14 <-> 14
16 <-> 15
20 <-> 19
21 <-> 20
22 <-> 21
23 <-> 22
24 <-> 23
25 <-> 24
26 <-> 25
27 <-> 26
28 <-> 27
29 <-> 28
31 <-> 29
35 <-> 33
36 <-> 34
37 <-> 35
38 <-> 36
39 <-> 37
40 <-> 38
41 <-> 39
42 <-> 40
43 <-> 41
44 <-> 42
46 <-> 43
50 <-> 47
51 <-> 48
52 <-> 49
53 <-> 50
54 <-> 51
55 <-> 52
56 <-> 53
57 <-> 54
58 <-> 55
59 <-> 56
61 <-> 57
65 <-> 61
66 <-> 62
67 <-> 63
68 <-> 64
69 <-> 65
70 <-> 66
71 <-> 67
72 <-> 68
73 <-> 69
74 <-> 70
76 <-> 71
16 <-> 14
20 <-> 18
21 <-> 19
22 <-> 20
23 <-> 21
24 <-> 22
25 <-> 23
26 <-> 24
27 <-> 25
28 <-> 26
29 <-> 27
31 <-> 27
35 <-> 31
36 <-> 32
37 <-> 33
38 <-> 34
39 <-> 35
40 <-> 36
41 <-> 37
42 <-> 38
43 <-> 39
44 <-> 40
46 <-> 40
50 <-> 44
51 <-> 45
52 <-> 46
53 <-> 47
54 <-> 48
55 <-> 49
56 <-> 50
57 <-> 51
58 <-> 52
59 <-> 53
61 <-> 53
65 <-> 57
66 <-> 58
67 <-> 59
68 <-> 60
69 <-> 61
70 <-> 62
71 <-> 63
72 <-> 64
73 <-> 65
74 <-> 66
76 <-> 66
@@ -0,0 +1,78 @@
package pkg;
public class TestCompoundAssignment {
public int testSimple(int i, int j) {
i += j;
i -= j;
i *= j;
i /= j;
i &= j;
i |= j;
i ^= j;
i >>= j;
i <<= j;
i >>>= j;
return i;
}
public int testComplex(int i, int j, int k) {
i += j + k;
i -= j + k;
i *= j + k;
i /= j + k;
i &= j + k;
i |= j + k;
i ^= j + k;
i >>= j + k;
i <<= j + k;
i >>>= j + k;
return i;
}
public int testComplexParens(int i, int j, int k, int m) {
i += (j + k) * m;
i -= (j + k) * m;
i *= (j + k) * m;
i /= (j + k) * m;
i &= (j + k) * m;
i |= (j + k) * m;
i ^= (j + k) * m;
i >>= (j + k) * m;
i <<= (j + k) * m;
i >>>= (j + k) * m;
return i;
}
public int testComplexTernary(int i, int j, int k, int m, boolean b) {
i += b ? j : k * m;
i -= b ? j : k * m;
i *= b ? j : k * m;
i /= b ? j : k * m;
i &= b ? j : k * m;
i |= b ? j : k * m;
i ^= b ? j : k * m;
i >>= b ? j : k * m;
i <<= b ? j : k * m;
i >>>= b ? j : k * m;
return i;
}
public int testArrayOp(int i, int j, int[] a, int b) {
i += a[b] = j;
i -= a[b] = j;
i *= a[b] = j;
i /= a[b] = j;
i &= a[b] = j;
i |= a[b] = j;
i ^= a[b] = j;
i >>= a[b] = j;
i <<= a[b] = j;
i >>>= a[b] = j;
return i;
}
}