diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java index 5467955..4cd7b67 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -267,6 +267,12 @@ public class InvocationExprent extends Exprent { else if (instance != null) { 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 leftType = new VarType(CodeConstants.TYPE_OBJECT, 0, classname); @@ -460,6 +466,24 @@ public class InvocationExprent extends Exprent { return null; } + private static final Map 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() { StructClass cl = DecompilerContext.getStructContext().getClass(classname); if (cl == null) return EMPTY_BIT_SET; diff --git a/testData/classes/pkg/TestPrimitives.class b/testData/classes/pkg/TestPrimitives.class index e0e83c7..fa6cc59 100644 Binary files a/testData/classes/pkg/TestPrimitives.class and b/testData/classes/pkg/TestPrimitives.class differ diff --git a/testData/obfuscated/aj.java b/testData/obfuscated/aj.java index 4ced9b7..f0d84c1 100644 --- a/testData/obfuscated/aj.java +++ b/testData/obfuscated/aj.java @@ -105,7 +105,7 @@ public class aj implements am { Entry var6 = (Entry)var5.next(); Long var7 = (Long)this.b.get(var6.getKey()); 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))); } } diff --git a/testData/obfuscated/o.java b/testData/obfuscated/o.java index 226c629..8e00c49 100644 --- a/testData/obfuscated/o.java +++ b/testData/obfuscated/o.java @@ -154,7 +154,7 @@ public class o { try { if (this.a instanceof Boolean) { - return ((Boolean)this.a).booleanValue(); + return (Boolean)this.a; } } catch (IllegalArgumentException var3) { throw var3; diff --git a/testData/results/TestClassLambda.dec b/testData/results/TestClassLambda.dec index bc12180..daeb7e1 100644 --- a/testData/results/TestClassLambda.dec +++ b/testData/results/TestClassLambda.dec @@ -18,7 +18,7 @@ public class TestClassLambda { List var1 = Arrays.asList(1, 2, 3, 4, 5, 6, 7);// 29 int var2 = (int)Math.random();// 30 var1.forEach((var2x) -> {// 32 - int var3 = 2 * var2x.intValue();// 33 + int var3 = 2 * var2x;// 33 System.out.println(var3 + var2 + this.field);// 34 });// 35 }// 36 diff --git a/testData/results/TestPrimitives.dec b/testData/results/TestPrimitives.dec index 3a590f4..043ed9f 100644 --- a/testData/results/TestPrimitives.dec +++ b/testData/results/TestPrimitives.dec @@ -19,124 +19,143 @@ public class TestPrimitives { this.printFloatBoxed(1.23F);// 21 this.printDoubleBoxed(1.23D);// 22 this.printCharBoxed('Z');// 23 - System.out.printf("%b, %d, %d, %d, %c, %d", true, 1, 213, 40000, 'c', 42L);// 25 - System.out.printf("%b, %d, %d, %d", this.getBoolean(), this.getByte(), this.getShort(), this.getInt());// 26 - new TestPrimitives(false, (byte)123, (short)257, 40000, 123L, 3.14F, 1.618D, 'A');// 28 - new TestPrimitives('A', 1.618D, 3.14F, 123L, 40000, (short)257, (byte)123, false);// 29 - }// 30 + this.printBoolean(Boolean.valueOf("true"));// 25 + this.printByte(Byte.valueOf("123"));// 26 + this.printShort(Short.valueOf("257"));// 27 + this.printInt(Integer.valueOf("123"));// 28 + 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) { - System.out.printf("%b, %d, %d, %d, %d, %.2f, %.2f, %c", bool, b, s, i, l, f, d, c);// 33 - }// 34 + System.out.printf("%b, %d, %d, %d, %d, %.2f, %.2f, %c", bool, b, s, i, l, f, d, c);// 47 + }// 48 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 - }// 38 + System.out.printf("%b, %d, %d, %d, %d, %.2f, %.2f, %c", bool, b, s, i, l, f, d, c);// 51 + }// 52 public void printBoolean(boolean b) { - System.out.printf("%b", b);// 41 - }// 42 + System.out.printf("%b", b);// 55 + }// 56 public void printByte(byte b) { - System.out.printf("%d", b);// 45 - }// 46 + System.out.printf("%d", b);// 59 + }// 60 public void printShort(short s) { - System.out.printf("%d", s);// 49 - }// 50 + System.out.printf("%d", s);// 63 + }// 64 public void printInt(int i) { - System.out.printf("%d", i);// 53 - }// 54 + System.out.printf("%d", i);// 67 + }// 68 public void printLong(long l) { - System.out.printf("%d", l);// 57 - }// 58 + System.out.printf("%d", l);// 71 + }// 72 public void printFloat(float f) { - System.out.printf("%f", f);// 61 - }// 62 + System.out.printf("%f", f);// 75 + }// 76 public void printDouble(double d) { - System.out.printf("%f", d);// 65 - }// 66 + System.out.printf("%f", d);// 79 + }// 80 public void printChar(char c) { - System.out.printf("%c", c);// 69 - }// 70 + System.out.printf("%c", c);// 83 + }// 84 public void printBooleanBoxed(Boolean b) { - System.out.printf("%b", b);// 74 - }// 75 + System.out.printf("%b", b);// 88 + }// 89 public void printByteBoxed(Byte b) { - System.out.printf("%d", b);// 78 - }// 79 + System.out.printf("%d", b);// 92 + }// 93 public void printShortBoxed(Short s) { - System.out.printf("%d", s);// 82 - }// 83 + System.out.printf("%d", s);// 96 + }// 97 public void printIntBoxed(Integer i) { - System.out.printf("%d", i);// 86 - }// 87 + System.out.printf("%d", i);// 100 + }// 101 public void printLongBoxed(Long l) { - System.out.printf("%d", l);// 90 - }// 91 + System.out.printf("%d", l);// 104 + }// 105 public void printFloatBoxed(Float f) { - System.out.printf("%f", f);// 94 - }// 95 + System.out.printf("%f", f);// 108 + }// 109 public void printDoubleBoxed(Double d) { - System.out.printf("%f", d);// 98 - }// 99 + System.out.printf("%f", d);// 112 + }// 113 public void printCharBoxed(Character c) { - System.out.printf("%c", c);// 102 - }// 103 + System.out.printf("%c", c);// 116 + }// 117 public boolean getBoolean() { - return false;// 107 + return false;// 121 } public byte getByte() { - return -128;// 111 + return -128;// 125 } public short getShort() { - return -32768;// 115 + return -32768;// 129 } public int getInt() { - return 42;// 119 + return 42;// 133 + } + + public Integer getInteger() { + return 40000;// 137 + } + + public Character getCharacter() { + return 'Z';// 141 } public void printNarrowed() { - this.printByte((byte)this.getInt());// 123 - this.printShort((short)this.getInt());// 124 - }// 125 + this.printByte((byte)this.getInt());// 145 + this.printShort((short)this.getInt());// 146 + }// 147 public void constructor() { - new Byte((byte)1);// 128 - }// 129 + new Byte((byte)1);// 150 + }// 151 private boolean compare(char c) { - boolean res = c > -1;// 132 - res = c > 0;// 133 - res = c > 1;// 134 - res = c > '\b';// 135 - res = c > '\t';// 136 - res = c > '\n';// 137 - res = c > '\f';// 138 - res = c > '\r';// 139 - res = c > ' ';// 140 - res = c > 'a';// 141 - res = c > 'Z';// 142 - res = c > 127;// 143 - res = c > 255;// 144 - return res;// 145 + boolean res = c > -1;// 154 + res = c > 0;// 155 + res = c > 1;// 156 + res = c > '\b';// 157 + res = c > '\t';// 158 + res = c > '\n';// 159 + res = c > '\f';// 160 + res = c > '\r';// 161 + res = c > ' ';// 162 + res = c > 'a';// 163 + res = c > 'Z';// 164 + res = c > 127;// 165 + res = c > 255;// 166 + return res;// 167 } } @@ -176,268 +195,340 @@ class 'pkg/TestPrimitives' { 78 19 7c 20 81 20 - 84 21 + 85 21 87 21 - 90 21 - 91 21 - 97 21 - 98 21 - 9e 21 - a1 21 - a7 21 - a9 21 - af 21 - b1 21 - b7 21 - ba 21 - be 21 - c2 22 - c5 22 - ce 22 - d1 22 - d8 22 - db 22 - e2 22 - e5 22 - ec 22 - ef 22 - f3 22 - fb 23 - fc 23 - fe 23 - 101 23 - 103 23 - 106 23 - 108 23 - 10b 23 - 115 24 - 11a 24 - 120 24 - 125 24 - 12b 24 - 130 24 - 136 24 - 13b 24 - 143 25 + 8a 21 + 8d 21 + 91 22 + 93 22 + 96 22 + 99 22 + 9d 23 + 9f 23 + a2 23 + a5 23 + a9 24 + ab 24 + ae 24 + b1 24 + b5 25 + b7 25 + ba 25 + bd 25 + c1 26 + c3 26 + c6 26 + c9 26 + cd 27 + cf 27 + d2 27 + d5 27 + dd 28 + e2 28 + e5 28 + ea 29 + ed 29 + f0 29 + f5 30 + f8 30 + fb 30 + fe 31 + 101 31 + 10a 31 + 10b 31 + 111 31 + 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 ' (ZBSIJFDC)V' { - 4 28 - 7 28 - 11 28 - 18 28 - 1f 28 - 27 28 - 2f 28 - 37 28 - 40 28 - 49 28 - 4d 28 - 51 29 + 4 39 + 7 39 + 11 39 + 18 39 + 1f 39 + 27 39 + 2f 39 + 37 39 + 40 39 + 49 39 + 4d 39 + 51 40 } method ' (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 - 7 32 - 35 32 - 39 33 + 4 43 + 7 43 + 35 43 + 39 44 } method 'printBoolean (Z)V' { - 0 36 - 3 36 - c 36 - 10 36 - 14 37 + 0 47 + 3 47 + c 47 + 10 47 + 14 48 } method 'printByte (B)V' { - 0 40 - 3 40 - c 40 - 10 40 - 14 41 + 0 51 + 3 51 + c 51 + 10 51 + 14 52 } method 'printShort (S)V' { - 0 44 - 3 44 - c 44 - 10 44 - 14 45 + 0 55 + 3 55 + c 55 + 10 55 + 14 56 } method 'printInt (I)V' { - 0 48 - 3 48 - c 48 - 10 48 - 14 49 + 0 59 + 3 59 + c 59 + 10 59 + 14 60 } method 'printLong (J)V' { - 0 52 - 3 52 - c 52 - 10 52 - 14 53 + 0 63 + 3 63 + c 63 + 10 63 + 14 64 } method 'printFloat (F)V' { - 0 56 - 3 56 - c 56 - 10 56 - 14 57 + 0 67 + 3 67 + c 67 + 10 67 + 14 68 } method 'printDouble (D)V' { - 0 60 - 3 60 - c 60 - 10 60 - 14 61 + 0 71 + 3 71 + c 71 + 10 71 + 14 72 } method 'printChar (C)V' { - 0 64 - 3 64 - c 64 - 10 64 - 14 65 + 0 75 + 3 75 + c 75 + 10 75 + 14 76 } method 'printBooleanBoxed (Ljava/lang/Boolean;)V' { - 0 68 - 3 68 - d 68 - 11 69 + 0 79 + 3 79 + d 79 + 11 80 } method 'printByteBoxed (Ljava/lang/Byte;)V' { - 0 72 - 3 72 - d 72 - 11 73 + 0 83 + 3 83 + d 83 + 11 84 } method 'printShortBoxed (Ljava/lang/Short;)V' { - 0 76 - 3 76 - d 76 - 11 77 + 0 87 + 3 87 + d 87 + 11 88 } method 'printIntBoxed (Ljava/lang/Integer;)V' { - 0 80 - 3 80 - d 80 - 11 81 + 0 91 + 3 91 + d 91 + 11 92 } method 'printLongBoxed (Ljava/lang/Long;)V' { - 0 84 - 3 84 - d 84 - 11 85 + 0 95 + 3 95 + d 95 + 11 96 } method 'printFloatBoxed (Ljava/lang/Float;)V' { - 0 88 - 3 88 - d 88 - 11 89 + 0 99 + 3 99 + d 99 + 11 100 } method 'printDoubleBoxed (Ljava/lang/Double;)V' { - 0 92 - 3 92 - d 92 - 11 93 + 0 103 + 3 103 + d 103 + 11 104 } method 'printCharBoxed (Ljava/lang/Character;)V' { - 0 96 - 3 96 - d 96 - 11 97 + 0 107 + 3 107 + d 107 + 11 108 } method 'getBoolean ()Z' { - 0 100 - 1 100 + 0 111 + 1 111 } method 'getByte ()B' { - 0 104 - 2 104 + 0 115 + 2 115 } method 'getShort ()S' { - 0 108 - 3 108 + 0 119 + 3 119 } method 'getInt ()I' { - 0 112 - 2 112 + 0 123 + 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' { - 2 116 - 5 116 - 6 116 - b 117 - e 117 - f 117 - 12 118 + 2 135 + 5 135 + 6 135 + b 136 + e 136 + f 136 + 12 137 } method 'constructor ()V' { - 4 121 - 9 122 + 4 140 + 9 141 } method 'compare (C)Z' { - 1 125 - 2 125 - a 125 - c 126 - 14 126 - 16 127 - 17 127 - 1f 127 - 21 128 - 23 128 - 2b 128 - 2d 129 - 2f 129 - 37 129 - 39 130 - 3b 130 - 43 130 - 45 131 - 47 131 - 4f 131 - 51 132 - 53 132 - 5b 132 - 5d 133 - 5f 133 - 67 133 - 69 134 - 6b 134 - 73 134 - 75 135 - 77 135 - 7f 135 - 81 136 - 83 136 - 8b 136 - 8d 137 - 90 137 - 98 137 - 9a 138 + 1 144 + 2 144 + a 144 + c 145 + 14 145 + 16 146 + 17 146 + 1f 146 + 21 147 + 23 147 + 2b 147 + 2d 148 + 2f 148 + 37 148 + 39 149 + 3b 149 + 43 149 + 45 150 + 47 150 + 4f 150 + 51 151 + 53 151 + 5b 151 + 5d 152 + 5f 152 + 67 152 + 69 153 + 6b 153 + 73 153 + 75 154 + 77 154 + 7f 154 + 81 155 + 83 155 + 8b 155 + 8d 156 + 90 156 + 98 156 + 9a 157 } } @@ -461,68 +552,82 @@ Lines mapping: 23 <-> 21 25 <-> 22 26 <-> 23 -28 <-> 24 -29 <-> 25 -30 <-> 26 -33 <-> 29 +27 <-> 24 +28 <-> 25 +29 <-> 26 +30 <-> 27 +31 <-> 28 +32 <-> 29 34 <-> 30 -37 <-> 33 -38 <-> 34 -41 <-> 37 -42 <-> 38 -45 <-> 41 -46 <-> 42 -49 <-> 45 -50 <-> 46 -53 <-> 49 -54 <-> 50 -57 <-> 53 -58 <-> 54 -61 <-> 57 -62 <-> 58 -65 <-> 61 -66 <-> 62 -69 <-> 65 -70 <-> 66 -74 <-> 69 -75 <-> 70 -78 <-> 73 -79 <-> 74 -82 <-> 77 -83 <-> 78 -86 <-> 81 -87 <-> 82 -90 <-> 85 -91 <-> 86 -94 <-> 89 -95 <-> 90 -98 <-> 93 -99 <-> 94 -102 <-> 97 -103 <-> 98 -107 <-> 101 -111 <-> 105 -115 <-> 109 -119 <-> 113 -123 <-> 117 -124 <-> 118 -125 <-> 119 -128 <-> 122 -129 <-> 123 -132 <-> 126 -133 <-> 127 -134 <-> 128 -135 <-> 129 -136 <-> 130 -137 <-> 131 -138 <-> 132 -139 <-> 133 -140 <-> 134 -141 <-> 135 -142 <-> 136 -143 <-> 137 -144 <-> 138 -145 <-> 139 +35 <-> 31 +37 <-> 32 +38 <-> 33 +40 <-> 34 +41 <-> 35 +42 <-> 36 +43 <-> 36 +44 <-> 37 +47 <-> 40 +48 <-> 41 +51 <-> 44 +52 <-> 45 +55 <-> 48 +56 <-> 49 +59 <-> 52 +60 <-> 53 +63 <-> 56 +64 <-> 57 +67 <-> 60 +68 <-> 61 +71 <-> 64 +72 <-> 65 +75 <-> 68 +76 <-> 69 +79 <-> 72 +80 <-> 73 +83 <-> 76 +84 <-> 77 +88 <-> 80 +89 <-> 81 +92 <-> 84 +93 <-> 85 +96 <-> 88 +97 <-> 89 +100 <-> 92 +101 <-> 93 +104 <-> 96 +105 <-> 97 +108 <-> 100 +109 <-> 101 +112 <-> 104 +113 <-> 105 +116 <-> 108 +117 <-> 109 +121 <-> 112 +125 <-> 116 +129 <-> 120 +133 <-> 124 +137 <-> 128 +141 <-> 132 +145 <-> 136 +146 <-> 137 +147 <-> 138 +150 <-> 141 +151 <-> 142 +154 <-> 145 +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: -32 -36 +46 +50 diff --git a/testData/src/pkg/TestPrimitives.java b/testData/src/pkg/TestPrimitives.java index 99b4fa1..8167339 100644 --- a/testData/src/pkg/TestPrimitives.java +++ b/testData/src/pkg/TestPrimitives.java @@ -22,11 +22,25 @@ public class TestPrimitives { printDoubleBoxed(1.23); 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", getBoolean(), getByte(), getShort(), getInt()); 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(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) { @@ -119,6 +133,14 @@ public class TestPrimitives { return 42; } + public Integer getInteger() { + return 40_000; + } + + public Character getCharacter() { + return 'Z'; + } + public void printNarrowed() { printByte((byte)getInt()); printShort((short)getInt());