Omit unnecessary unboxing calls in decompiled code

master
Dmitry Cherniachenko 7 years ago committed by Egor.Ushakov
parent aa78b7df28
commit 39db41ee8b
  1. 24
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java
  2. BIN
      testData/classes/pkg/TestPrimitives.class
  3. 2
      testData/obfuscated/aj.java
  4. 2
      testData/obfuscated/o.java
  5. 2
      testData/results/TestClassLambda.dec
  6. 731
      testData/results/TestPrimitives.dec
  7. 22
      testData/src/pkg/TestPrimitives.java

@ -267,6 +267,12 @@ public class InvocationExprent extends Exprent {
else if (instance != null) { else if (instance != null) {
TextBuffer res = instance.toJava(indent, tracer); TextBuffer res = instance.toJava(indent, tracer);
if (isUnboxingCall()) {
// we don't print the unboxing call - no need to bother with the instance wrapping / casting
buf.append(res);
return buf;
}
VarType rightType = instance.getExprType(); VarType rightType = instance.getExprType();
VarType leftType = new VarType(CodeConstants.TYPE_OBJECT, 0, classname); VarType leftType = new VarType(CodeConstants.TYPE_OBJECT, 0, classname);
@ -460,6 +466,24 @@ public class InvocationExprent extends Exprent {
return null; return null;
} }
private static final Map<String, String> UNBOXING_METHODS;
static {
UNBOXING_METHODS = new HashMap<>();
UNBOXING_METHODS.put("booleanValue", "java/lang/Boolean");
UNBOXING_METHODS.put("byteValue", "java/lang/Byte");
UNBOXING_METHODS.put("shortValue", "java/lang/Short");
UNBOXING_METHODS.put("intValue", "java/lang/Integer");
UNBOXING_METHODS.put("longValue", "java/lang/Long");
UNBOXING_METHODS.put("floatValue", "java/lang/Float");
UNBOXING_METHODS.put("doubleValue", "java/lang/Double");
UNBOXING_METHODS.put("charValue", "java/lang/Character");
}
private boolean isUnboxingCall() {
return !isStatic && lstParameters.size() == 0 && classname.equals(UNBOXING_METHODS.get(name));
}
private BitSet getAmbiguousParameters() { private BitSet getAmbiguousParameters() {
StructClass cl = DecompilerContext.getStructContext().getClass(classname); StructClass cl = DecompilerContext.getStructContext().getClass(classname);
if (cl == null) return EMPTY_BIT_SET; if (cl == null) return EMPTY_BIT_SET;

@ -105,7 +105,7 @@ public class aj implements am {
Entry var6 = (Entry)var5.next(); Entry var6 = (Entry)var5.next();
Long var7 = (Long)this.b.get(var6.getKey()); Long var7 = (Long)this.b.get(var6.getKey());
if (var7 != null) { if (var7 != null) {
double var8 = (double)((((Long)var6.getValue()).longValue() - var7.longValue()) * 10L) / (double)var3; double var8 = (double)(((Long)var6.getValue() - var7) * 10L) / (double)var3;
var1.a((Object)(new ar(h[1], (String)var6.getKey(), "%", var8 * 100.0D))); var1.a((Object)(new ar(h[1], (String)var6.getKey(), "%", var8 * 100.0D)));
} }
} }

@ -154,7 +154,7 @@ public class o {
try { try {
if (this.a instanceof Boolean) { if (this.a instanceof Boolean) {
return ((Boolean)this.a).booleanValue(); return (Boolean)this.a;
} }
} catch (IllegalArgumentException var3) { } catch (IllegalArgumentException var3) {
throw var3; throw var3;

@ -18,7 +18,7 @@ public class TestClassLambda {
List var1 = Arrays.asList(1, 2, 3, 4, 5, 6, 7);// 29 List var1 = Arrays.asList(1, 2, 3, 4, 5, 6, 7);// 29
int var2 = (int)Math.random();// 30 int var2 = (int)Math.random();// 30
var1.forEach((var2x) -> {// 32 var1.forEach((var2x) -> {// 32
int var3 = 2 * var2x.intValue();// 33 int var3 = 2 * var2x;// 33
System.out.println(var3 + var2 + this.field);// 34 System.out.println(var3 + var2 + this.field);// 34
});// 35 });// 35
}// 36 }// 36

@ -19,124 +19,143 @@ public class TestPrimitives {
this.printFloatBoxed(1.23F);// 21 this.printFloatBoxed(1.23F);// 21
this.printDoubleBoxed(1.23D);// 22 this.printDoubleBoxed(1.23D);// 22
this.printCharBoxed('Z');// 23 this.printCharBoxed('Z');// 23
System.out.printf("%b, %d, %d, %d, %c, %d", true, 1, 213, 40000, 'c', 42L);// 25 this.printBoolean(Boolean.valueOf("true"));// 25
System.out.printf("%b, %d, %d, %d", this.getBoolean(), this.getByte(), this.getShort(), this.getInt());// 26 this.printByte(Byte.valueOf("123"));// 26
new TestPrimitives(false, (byte)123, (short)257, 40000, 123L, 3.14F, 1.618D, 'A');// 28 this.printShort(Short.valueOf("257"));// 27
new TestPrimitives('A', 1.618D, 3.14F, 123L, 40000, (short)257, (byte)123, false);// 29 this.printInt(Integer.valueOf("123"));// 28
}// 30 this.printLong(Long.valueOf("123"));// 29
this.printFloat(Float.valueOf("1.23"));// 30
this.printDouble(Double.valueOf("1.23"));// 31
this.printChar(new Character('Z'));// 32
this.printInt(this.getInteger());// 34
this.printChar(this.getCharacter());// 35
System.out.printf("%b, %d, %d, %d, %c, %d", true, 1, 213, 40000, 'c', 42L);// 37
System.out.printf("%b, %d, %d, %d", this.getBoolean(), this.getByte(), this.getShort(), this.getInt());// 38
new TestPrimitives(false, (byte)123, (short)257, 40000, 123L, 3.14F, 1.618D, 'A');// 40
new TestPrimitives('A', 1.618D, 3.14F, 123L, 40000, (short)257, (byte)123, false);// 41
new TestPrimitives(Boolean.valueOf("false"), Byte.valueOf("123"), Short.valueOf("257"), Integer.valueOf("40000"), Long.valueOf("123"), Float.valueOf("3.14"), Double.valueOf("1.618"), new Character('A'));// 42 43
}// 44
private TestPrimitives(boolean bool, byte b, short s, int i, long l, float f, double d, char c) { private TestPrimitives(boolean bool, byte b, short s, int i, long l, float f, double d, char c) {
System.out.printf("%b, %d, %d, %d, %d, %.2f, %.2f, %c", bool, b, s, i, l, f, d, c);// 33 System.out.printf("%b, %d, %d, %d, %d, %.2f, %.2f, %c", bool, b, s, i, l, f, d, c);// 47
}// 34 }// 48
private TestPrimitives(Character c, Double d, Float f, Long l, Integer i, Short s, Byte b, Boolean bool) { private TestPrimitives(Character c, Double d, Float f, Long l, Integer i, Short s, Byte b, Boolean bool) {
System.out.printf("%b, %d, %d, %d, %d, %.2f, %.2f, %c", bool, b, s, i, l, f, d, c);// 37 System.out.printf("%b, %d, %d, %d, %d, %.2f, %.2f, %c", bool, b, s, i, l, f, d, c);// 51
}// 38 }// 52
public void printBoolean(boolean b) { public void printBoolean(boolean b) {
System.out.printf("%b", b);// 41 System.out.printf("%b", b);// 55
}// 42 }// 56
public void printByte(byte b) { public void printByte(byte b) {
System.out.printf("%d", b);// 45 System.out.printf("%d", b);// 59
}// 46 }// 60
public void printShort(short s) { public void printShort(short s) {
System.out.printf("%d", s);// 49 System.out.printf("%d", s);// 63
}// 50 }// 64
public void printInt(int i) { public void printInt(int i) {
System.out.printf("%d", i);// 53 System.out.printf("%d", i);// 67
}// 54 }// 68
public void printLong(long l) { public void printLong(long l) {
System.out.printf("%d", l);// 57 System.out.printf("%d", l);// 71
}// 58 }// 72
public void printFloat(float f) { public void printFloat(float f) {
System.out.printf("%f", f);// 61 System.out.printf("%f", f);// 75
}// 62 }// 76
public void printDouble(double d) { public void printDouble(double d) {
System.out.printf("%f", d);// 65 System.out.printf("%f", d);// 79
}// 66 }// 80
public void printChar(char c) { public void printChar(char c) {
System.out.printf("%c", c);// 69 System.out.printf("%c", c);// 83
}// 70 }// 84
public void printBooleanBoxed(Boolean b) { public void printBooleanBoxed(Boolean b) {
System.out.printf("%b", b);// 74 System.out.printf("%b", b);// 88
}// 75 }// 89
public void printByteBoxed(Byte b) { public void printByteBoxed(Byte b) {
System.out.printf("%d", b);// 78 System.out.printf("%d", b);// 92
}// 79 }// 93
public void printShortBoxed(Short s) { public void printShortBoxed(Short s) {
System.out.printf("%d", s);// 82 System.out.printf("%d", s);// 96
}// 83 }// 97
public void printIntBoxed(Integer i) { public void printIntBoxed(Integer i) {
System.out.printf("%d", i);// 86 System.out.printf("%d", i);// 100
}// 87 }// 101
public void printLongBoxed(Long l) { public void printLongBoxed(Long l) {
System.out.printf("%d", l);// 90 System.out.printf("%d", l);// 104
}// 91 }// 105
public void printFloatBoxed(Float f) { public void printFloatBoxed(Float f) {
System.out.printf("%f", f);// 94 System.out.printf("%f", f);// 108
}// 95 }// 109
public void printDoubleBoxed(Double d) { public void printDoubleBoxed(Double d) {
System.out.printf("%f", d);// 98 System.out.printf("%f", d);// 112
}// 99 }// 113
public void printCharBoxed(Character c) { public void printCharBoxed(Character c) {
System.out.printf("%c", c);// 102 System.out.printf("%c", c);// 116
}// 103 }// 117
public boolean getBoolean() { public boolean getBoolean() {
return false;// 107 return false;// 121
} }
public byte getByte() { public byte getByte() {
return -128;// 111 return -128;// 125
} }
public short getShort() { public short getShort() {
return -32768;// 115 return -32768;// 129
} }
public int getInt() { public int getInt() {
return 42;// 119 return 42;// 133
}
public Integer getInteger() {
return 40000;// 137
}
public Character getCharacter() {
return 'Z';// 141
} }
public void printNarrowed() { public void printNarrowed() {
this.printByte((byte)this.getInt());// 123 this.printByte((byte)this.getInt());// 145
this.printShort((short)this.getInt());// 124 this.printShort((short)this.getInt());// 146
}// 125 }// 147
public void constructor() { public void constructor() {
new Byte((byte)1);// 128 new Byte((byte)1);// 150
}// 129 }// 151
private boolean compare(char c) { private boolean compare(char c) {
boolean res = c > -1;// 132 boolean res = c > -1;// 154
res = c > 0;// 133 res = c > 0;// 155
res = c > 1;// 134 res = c > 1;// 156
res = c > '\b';// 135 res = c > '\b';// 157
res = c > '\t';// 136 res = c > '\t';// 158
res = c > '\n';// 137 res = c > '\n';// 159
res = c > '\f';// 138 res = c > '\f';// 160
res = c > '\r';// 139 res = c > '\r';// 161
res = c > ' ';// 140 res = c > ' ';// 162
res = c > 'a';// 141 res = c > 'a';// 163
res = c > 'Z';// 142 res = c > 'Z';// 164
res = c > 127;// 143 res = c > 127;// 165
res = c > 255;// 144 res = c > 255;// 166
return res;// 145 return res;// 167
} }
} }
@ -176,268 +195,340 @@ class 'pkg/TestPrimitives' {
78 19 78 19
7c 20 7c 20
81 20 81 20
84 21 85 21
87 21 87 21
90 21 8a 21
91 21 8d 21
97 21 91 22
98 21 93 22
9e 21 96 22
a1 21 99 22
a7 21 9d 23
a9 21 9f 23
af 21 a2 23
b1 21 a5 23
b7 21 a9 24
ba 21 ab 24
be 21 ae 24
c2 22 b1 24
c5 22 b5 25
ce 22 b7 25
d1 22 ba 25
d8 22 bd 25
db 22 c1 26
e2 22 c3 26
e5 22 c6 26
ec 22 c9 26
ef 22 cd 27
f3 22 cf 27
fb 23 d2 27
fc 23 d5 27
fe 23 dd 28
101 23 e2 28
103 23 e5 28
106 23 ea 29
108 23 ed 29
10b 23 f0 29
115 24 f5 30
11a 24 f8 30
120 24 fb 30
125 24 fe 31
12b 24 101 31
130 24 10a 31
136 24 10b 31
13b 24 111 31
143 25 112 31
118 31
11b 31
121 31
123 31
129 31
12b 31
131 31
134 31
138 31
13c 32
13f 32
148 32
14b 32
152 32
155 32
15c 32
15f 32
166 32
169 32
16d 32
175 33
176 33
178 33
17b 33
17d 33
180 33
182 33
185 33
18f 34
194 34
19a 34
19f 34
1a5 34
1aa 34
1b0 34
1b5 34
1c1 35
1c3 35
1c6 35
1c9 35
1cb 35
1ce 35
1d1 35
1d3 35
1d6 35
1d9 35
1db 35
1de 35
1e1 35
1e3 35
1e6 35
1e9 35
1eb 35
1ee 35
1f1 35
1f3 35
1f6 35
1fd 35
202 35
209 36
} }
method '<init> (ZBSIJFDC)V' { method '<init> (ZBSIJFDC)V' {
4 28 4 39
7 28 7 39
11 28 11 39
18 28 18 39
1f 28 1f 39
27 28 27 39
2f 28 2f 39
37 28 37 39
40 28 40 39
49 28 49 39
4d 28 4d 39
51 29 51 40
} }
method '<init> (Ljava/lang/Character;Ljava/lang/Double;Ljava/lang/Float;Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Short;Ljava/lang/Byte;Ljava/lang/Boolean;)V' { method '<init> (Ljava/lang/Character;Ljava/lang/Double;Ljava/lang/Float;Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Short;Ljava/lang/Byte;Ljava/lang/Boolean;)V' {
4 32 4 43
7 32 7 43
35 32 35 43
39 33 39 44
} }
method 'printBoolean (Z)V' { method 'printBoolean (Z)V' {
0 36 0 47
3 36 3 47
c 36 c 47
10 36 10 47
14 37 14 48
} }
method 'printByte (B)V' { method 'printByte (B)V' {
0 40 0 51
3 40 3 51
c 40 c 51
10 40 10 51
14 41 14 52
} }
method 'printShort (S)V' { method 'printShort (S)V' {
0 44 0 55
3 44 3 55
c 44 c 55
10 44 10 55
14 45 14 56
} }
method 'printInt (I)V' { method 'printInt (I)V' {
0 48 0 59
3 48 3 59
c 48 c 59
10 48 10 59
14 49 14 60
} }
method 'printLong (J)V' { method 'printLong (J)V' {
0 52 0 63
3 52 3 63
c 52 c 63
10 52 10 63
14 53 14 64
} }
method 'printFloat (F)V' { method 'printFloat (F)V' {
0 56 0 67
3 56 3 67
c 56 c 67
10 56 10 67
14 57 14 68
} }
method 'printDouble (D)V' { method 'printDouble (D)V' {
0 60 0 71
3 60 3 71
c 60 c 71
10 60 10 71
14 61 14 72
} }
method 'printChar (C)V' { method 'printChar (C)V' {
0 64 0 75
3 64 3 75
c 64 c 75
10 64 10 75
14 65 14 76
} }
method 'printBooleanBoxed (Ljava/lang/Boolean;)V' { method 'printBooleanBoxed (Ljava/lang/Boolean;)V' {
0 68 0 79
3 68 3 79
d 68 d 79
11 69 11 80
} }
method 'printByteBoxed (Ljava/lang/Byte;)V' { method 'printByteBoxed (Ljava/lang/Byte;)V' {
0 72 0 83
3 72 3 83
d 72 d 83
11 73 11 84
} }
method 'printShortBoxed (Ljava/lang/Short;)V' { method 'printShortBoxed (Ljava/lang/Short;)V' {
0 76 0 87
3 76 3 87
d 76 d 87
11 77 11 88
} }
method 'printIntBoxed (Ljava/lang/Integer;)V' { method 'printIntBoxed (Ljava/lang/Integer;)V' {
0 80 0 91
3 80 3 91
d 80 d 91
11 81 11 92
} }
method 'printLongBoxed (Ljava/lang/Long;)V' { method 'printLongBoxed (Ljava/lang/Long;)V' {
0 84 0 95
3 84 3 95
d 84 d 95
11 85 11 96
} }
method 'printFloatBoxed (Ljava/lang/Float;)V' { method 'printFloatBoxed (Ljava/lang/Float;)V' {
0 88 0 99
3 88 3 99
d 88 d 99
11 89 11 100
} }
method 'printDoubleBoxed (Ljava/lang/Double;)V' { method 'printDoubleBoxed (Ljava/lang/Double;)V' {
0 92 0 103
3 92 3 103
d 92 d 103
11 93 11 104
} }
method 'printCharBoxed (Ljava/lang/Character;)V' { method 'printCharBoxed (Ljava/lang/Character;)V' {
0 96 0 107
3 96 3 107
d 96 d 107
11 97 11 108
} }
method 'getBoolean ()Z' { method 'getBoolean ()Z' {
0 100 0 111
1 100 1 111
} }
method 'getByte ()B' { method 'getByte ()B' {
0 104 0 115
2 104 2 115
} }
method 'getShort ()S' { method 'getShort ()S' {
0 108 0 119
3 108 3 119
} }
method 'getInt ()I' { method 'getInt ()I' {
0 112 0 123
2 112 2 123
}
method 'getInteger ()Ljava/lang/Integer;' {
0 127
2 127
5 127
}
method 'getCharacter ()Ljava/lang/Character;' {
0 131
2 131
5 131
} }
method 'printNarrowed ()V' { method 'printNarrowed ()V' {
2 116 2 135
5 116 5 135
6 116 6 135
b 117 b 136
e 117 e 136
f 117 f 136
12 118 12 137
} }
method 'constructor ()V' { method 'constructor ()V' {
4 121 4 140
9 122 9 141
} }
method 'compare (C)Z' { method 'compare (C)Z' {
1 125 1 144
2 125 2 144
a 125 a 144
c 126 c 145
14 126 14 145
16 127 16 146
17 127 17 146
1f 127 1f 146
21 128 21 147
23 128 23 147
2b 128 2b 147
2d 129 2d 148
2f 129 2f 148
37 129 37 148
39 130 39 149
3b 130 3b 149
43 130 43 149
45 131 45 150
47 131 47 150
4f 131 4f 150
51 132 51 151
53 132 53 151
5b 132 5b 151
5d 133 5d 152
5f 133 5f 152
67 133 67 152
69 134 69 153
6b 134 6b 153
73 134 73 153
75 135 75 154
77 135 77 154
7f 135 7f 154
81 136 81 155
83 136 83 155
8b 136 8b 155
8d 137 8d 156
90 137 90 156
98 137 98 156
9a 138 9a 157
} }
} }
@ -461,68 +552,82 @@ Lines mapping:
23 <-> 21 23 <-> 21
25 <-> 22 25 <-> 22
26 <-> 23 26 <-> 23
28 <-> 24 27 <-> 24
29 <-> 25 28 <-> 25
30 <-> 26 29 <-> 26
33 <-> 29 30 <-> 27
31 <-> 28
32 <-> 29
34 <-> 30 34 <-> 30
37 <-> 33 35 <-> 31
38 <-> 34 37 <-> 32
41 <-> 37 38 <-> 33
42 <-> 38 40 <-> 34
45 <-> 41 41 <-> 35
46 <-> 42 42 <-> 36
49 <-> 45 43 <-> 36
50 <-> 46 44 <-> 37
53 <-> 49 47 <-> 40
54 <-> 50 48 <-> 41
57 <-> 53 51 <-> 44
58 <-> 54 52 <-> 45
61 <-> 57 55 <-> 48
62 <-> 58 56 <-> 49
65 <-> 61 59 <-> 52
66 <-> 62 60 <-> 53
69 <-> 65 63 <-> 56
70 <-> 66 64 <-> 57
74 <-> 69 67 <-> 60
75 <-> 70 68 <-> 61
78 <-> 73 71 <-> 64
79 <-> 74 72 <-> 65
82 <-> 77 75 <-> 68
83 <-> 78 76 <-> 69
86 <-> 81 79 <-> 72
87 <-> 82 80 <-> 73
90 <-> 85 83 <-> 76
91 <-> 86 84 <-> 77
94 <-> 89 88 <-> 80
95 <-> 90 89 <-> 81
98 <-> 93 92 <-> 84
99 <-> 94 93 <-> 85
102 <-> 97 96 <-> 88
103 <-> 98 97 <-> 89
107 <-> 101 100 <-> 92
111 <-> 105 101 <-> 93
115 <-> 109 104 <-> 96
119 <-> 113 105 <-> 97
123 <-> 117 108 <-> 100
124 <-> 118 109 <-> 101
125 <-> 119 112 <-> 104
128 <-> 122 113 <-> 105
129 <-> 123 116 <-> 108
132 <-> 126 117 <-> 109
133 <-> 127 121 <-> 112
134 <-> 128 125 <-> 116
135 <-> 129 129 <-> 120
136 <-> 130 133 <-> 124
137 <-> 131 137 <-> 128
138 <-> 132 141 <-> 132
139 <-> 133 145 <-> 136
140 <-> 134 146 <-> 137
141 <-> 135 147 <-> 138
142 <-> 136 150 <-> 141
143 <-> 137 151 <-> 142
144 <-> 138 154 <-> 145
145 <-> 139 155 <-> 146
156 <-> 147
157 <-> 148
158 <-> 149
159 <-> 150
160 <-> 151
161 <-> 152
162 <-> 153
163 <-> 154
164 <-> 155
165 <-> 156
166 <-> 157
167 <-> 158
Not mapped: Not mapped:
32 46
36 50

@ -22,11 +22,25 @@ public class TestPrimitives {
printDoubleBoxed(1.23); printDoubleBoxed(1.23);
printCharBoxed('Z'); printCharBoxed('Z');
printBoolean(Boolean.valueOf("true"));
printByte(Byte.valueOf("123"));
printShort(Short.valueOf("257"));
printInt(Integer.valueOf("123"));
printLong(Long.valueOf("123"));
printFloat(Float.valueOf("1.23"));
printDouble(Double.valueOf("1.23"));
printChar(new Character('Z'));
printInt(getInteger());
printChar(getCharacter());
System.out.printf("%b, %d, %d, %d, %c, %d", true, 1, 213, 40_000, 'c', 42L); System.out.printf("%b, %d, %d, %d, %c, %d", true, 1, 213, 40_000, 'c', 42L);
System.out.printf("%b, %d, %d, %d", getBoolean(), getByte(), getShort(), getInt()); System.out.printf("%b, %d, %d, %d", getBoolean(), getByte(), getShort(), getInt());
new TestPrimitives(false, (byte) 123, (short) 257, 40_000, 123L, 3.14f, 1.618, 'A'); new TestPrimitives(false, (byte) 123, (short) 257, 40_000, 123L, 3.14f, 1.618, 'A');
new TestPrimitives('A', 1.618, 3.14f, 123L, 40_000, (short) 257, (byte) 123, false); new TestPrimitives('A', 1.618, 3.14f, 123L, 40_000, (short) 257, (byte) 123, false);
new TestPrimitives(Boolean.valueOf("false"), Byte.valueOf("123"), Short.valueOf("257"), Integer.valueOf("40000"), Long.valueOf("123"),
Float.valueOf("3.14"), Double.valueOf("1.618"), new Character('A'));
} }
private TestPrimitives(boolean bool, byte b, short s, int i, long l, float f, double d, char c) { private TestPrimitives(boolean bool, byte b, short s, int i, long l, float f, double d, char c) {
@ -119,6 +133,14 @@ public class TestPrimitives {
return 42; return 42;
} }
public Integer getInteger() {
return 40_000;
}
public Character getCharacter() {
return 'Z';
}
public void printNarrowed() { public void printNarrowed() {
printByte((byte)getInt()); printByte((byte)getInt());
printShort((short)getInt()); printShort((short)getInt());

Loading…
Cancel
Save