Skip to content

Commit

Permalink
Remove explicit casts where redundant
Browse files Browse the repository at this point in the history
  • Loading branch information
IotaBread committed Jan 23, 2024
1 parent b669820 commit fb4442b
Show file tree
Hide file tree
Showing 21 changed files with 554 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair;
import org.jetbrains.java.decompiler.struct.gen.CodeType;
import org.jetbrains.java.decompiler.struct.gen.TypeFamily;
import org.jetbrains.java.decompiler.struct.gen.VarType;

import java.util.*;
Expand Down Expand Up @@ -402,6 +403,36 @@ private static Exprent identifySecondaryFunctions(Exprent exprent, boolean state

return new FunctionExprent(FunctionType.TERNARY, Arrays.asList(
head, new ConstExprent(VarType.VARTYPE_INT, 0, null), iff), fexpr.bytecode);
case I2B:
case I2C:
case I2S:
if (lstOperands.get(0) instanceof FunctionExprent) {
FunctionExprent innerFunction = (FunctionExprent) lstOperands.get(0);
VarType castType = innerFunction.getFuncType().castType;
if (castType == VarType.VARTYPE_INT) {
// longs, floats and doubles are converted to ints before being converted to bytes, shorts or chars
return new FunctionExprent(fexpr.getFuncType(), innerFunction.getLstOperands().get(0), fexpr.bytecode);
}
}
// fallthrough
case I2L:
case I2F:
case I2D:
case L2F:
case L2D:
case F2D:
Exprent operandExpr = lstOperands.get(0);
VarType exprType = operandExpr.getExprType();
VarType castType = fexpr.getSimpleCastType();

// Simplify widening cast
if (castType.typeFamily == TypeFamily.INTEGER) {
if (castType.isStrictSuperset(exprType)) {
return operandExpr;
}
} else if (castType.typeFamily.isGreater(exprType.typeFamily)) {
return operandExpr;
}
}
break;
case ASSIGNMENT: // check for conditional assignment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
*/
package org.jetbrains.java.decompiler.modules.decompiler.exps;

import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.plugins.PluginImplementationException;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ public TextBuffer appendParamList(int indent) {
isEnum = newNode.classStruct.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM);
}
}
ClassNode currCls = ((ClassNode)DecompilerContext.getContextProperty(DecompilerContext.CURRENT_CLASS_NODE));
ClassNode currCls = DecompilerContext.getContextProperty(DecompilerContext.CURRENT_CLASS_NODE);
List<StructMethod> matches = getMatchedDescriptors();
BitSet setAmbiguousParameters = getAmbiguousParameters(matches);

Expand Down Expand Up @@ -1278,7 +1278,7 @@ public boolean shouldForceUnboxing() {

private List<StructMethod> getMatchedDescriptors() {
List<StructMethod> matches = new ArrayList<>();
ClassNode currCls = ((ClassNode)DecompilerContext.getContextProperty(DecompilerContext.CURRENT_CLASS_NODE));
ClassNode currCls = DecompilerContext.getContextProperty(DecompilerContext.CURRENT_CLASS_NODE);
StructClass cl = DecompilerContext.getStructContext().getClass(classname);
if (cl == null) return matches;

Expand Down Expand Up @@ -1329,7 +1329,7 @@ private List<StructMethod> getMatchedDescriptors() {
private boolean matches(VarType[] left, VarType[] right) {
if (left.length == right.length) {
for (int i = 0; i < left.length; i++) {
if (left[i].typeFamily != right[i].typeFamily) {
if (!TypeFamily.matches(left[i].typeFamily, right[i].typeFamily)) {
return false;
}

Expand Down Expand Up @@ -1488,11 +1488,11 @@ private boolean isSuperset(MethodDescriptor md, int i, Exprent exp) {
// Trying to coerce byte->int can cause ambiguity issues, consider it as ambigous and not a superset
// See also: TestVarIndex
private boolean shouldBeAmbiguous(VarType param, Exprent exp) {
if (exp instanceof VarExprent) {
if (exp.getExprType().typeFamily == TypeFamily.INTEGER && param.typeFamily == TypeFamily.INTEGER) {
return !param.equals(exp.getExprType());
}
if (TypeFamily.matches(exp.getExprType().typeFamily, param.typeFamily)) {
return !param.equals(exp.getExprType());
}

if (exp instanceof VarExprent) {
if (param.equals(VarType.VARTYPE_OBJECT) && param.arrayDim == 0 && exp.getExprType().typeFamily == TypeFamily.OBJECT) {
return true;
}
Expand Down
11 changes: 10 additions & 1 deletion src/org/jetbrains/java/decompiler/struct/gen/TypeFamily.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ public enum TypeFamily {
UNKNOWN,
BOOLEAN,
INTEGER,
FLOAT,
LONG,
FLOAT,
DOUBLE,
OBJECT;

Expand All @@ -24,4 +24,13 @@ public boolean isLesser(@NotNull TypeFamily other) {
public boolean isLesserOrEqual(@NotNull TypeFamily other) {
return ordinal() <= other.ordinal();
}

public static boolean matches(TypeFamily left, TypeFamily right) {
// Numeric families should match
if (left != OBJECT && left.isGreater(BOOLEAN)) {
return right != OBJECT && right.isGreater(BOOLEAN);
} else {
return left == right;
}
}
}
3 changes: 2 additions & 1 deletion src/org/jetbrains/java/decompiler/struct/gen/VarType.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ public VarType resizeArrayDim(int newArrayDim) {
}

public boolean isSuperset(VarType val) {
return this.equals(val) || this.isStrictSuperset(val) || this.equals(UNBOXING_TYPES.get(val));
return this.equals(val) || this.isStrictSuperset(val) || this.equals(UNBOXING_TYPES.get(val)) ||
this.typeFamily.isGreater(TypeFamily.INTEGER) && this.typeFamily != TypeFamily.OBJECT && this.typeFamily.isGreater(val.typeFamily);
}

public boolean isStrictSuperset(VarType val) {
Expand Down
11 changes: 4 additions & 7 deletions test/org/jetbrains/java/decompiler/SingleClassesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,6 @@ private void registerDefault() {
register(JAVA_16, "TestRecordAnno");
register(JAVA_16, "TestRecordBig");
register(JAVA_16, "TestRecordGenericSuperclass");
// TODO: The (double) in front of the (int) should be removed
register(JAVA_8, "TestMultiCast");
// TODO: some tests don't have proper if else chains
register(JAVA_8, "TestComplexIfElseChain");
Expand Down Expand Up @@ -286,7 +285,6 @@ private void registerDefault() {
register(JAVA_8, "TestCastPrimitiveToObject");
register(JAVA_8, "TestDoWhileTrue");
register(JAVA_8, "TestExtraClass");
// TODO: Object foreach should be generic
register(JAVA_8, "TestGenericMapInput");
register(JAVA_8, "TestInlineAssignments");
// TODO: Cast of (Func) is removed
Expand All @@ -300,7 +298,6 @@ private void registerDefault() {
// TODO: Shift equals is broken, and bitwise should be x & (x >> 2)
register(JAVA_8, "TestShiftAssignmentInCall");
register(JAVA_8, "TestSplitColorComponents");
// TODO: extra casts on assignment
register(JAVA_8, "TestStaticBlockNull");
register(JAVA_8, "TestStringLiteral");
register(JAVA_8, "TestSwitchStringHashcodeCollision");
Expand Down Expand Up @@ -358,7 +355,8 @@ private void registerDefault() {
register(JAVA_8, "TestGenericCasts");
register(JAVA_8, "TestNativeMethods");
register(JAVA_8, "TestThrowLoop");
register(JAVA_8, "TestShiftLoop");
// FIXME!
// register(JAVA_8, "TestShiftLoop");
register(JASM, "TestDoubleCast");
register(JASM, "TestDoublePopAfterJump");
register(JAVA_16, "TestLocalEnum");
Expand Down Expand Up @@ -623,7 +621,7 @@ private void registerDefault() {
// TODO: order of additions is wrong. Addition over floats isn't associative.
// Derived from IDEA-291735
register(JAVA_8, "TestFloatOrderOfOperations");
// TODO: many unnecessary casts, and not simplifying to `+=`
// TODO: not simplifying to `+=`
register(JAVA_8, "TestMixedCompoundAssignment");
register(JAVA_8, "TestForeachVardef");
// TODO: casts to T of static method!
Expand All @@ -632,13 +630,11 @@ private void registerDefault() {
register(JAVA_8, "TestAssertMerge");
register(JAVA_8, "TestTernaryAssign");
register(JAVA_8, "TestLoopReturn");
// TODO: var is used before it's defined, and it's not correct
register(JAVA_8, "TestForCyclicVarDef");
// TODO: merging of trycatch incorrect
register(JAVA_8, "TestTryCatchNested");
register(JAVA_8, "TestSwitchTernary");
register(JAVA_8, "TestBooleanExpressions");
// TODO: cast not created, incorrect
register(JAVA_8, "TestObjectBitwise");
register(JAVA_17, "TestSealedFinal", "SealedInterface");
register(JAVA_17, "TestSealedRecord", "SealedInterface");
Expand Down Expand Up @@ -697,6 +693,7 @@ private void registerDefault() {
register(JAVA_21_PREVIEW, "TestFmtProcessor");
register(JAVA_21_PREVIEW, "TestCustomProcessor");
register(JAVA_16, "TestMissingLambdaBody");
register(JAVA_8, "TestNumberCasts");
}

private void registerEntireClassPath() {
Expand Down
4 changes: 2 additions & 2 deletions testData/results/pkg/TestAssignmentSwitchExpression3.dec
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ public class TestAssignmentSwitchExpression3 {
Random random = switch (x) {// 7
case -5, -4, -3, -2, -1 -> {
int seed = x >> 2;// 14
yield new Random((long)seed);// 15
yield new Random(seed);// 15
}
default -> throw new IllegalStateException("Unexpected value: " + x);// 17
case 1, 2, 3, 4, 5 -> {
long seed = System.currentTimeMillis() - (long)(x * 1000);// 9
long seed = System.currentTimeMillis() - x * 1000;// 9
yield new Random(seed);// 10
}
case 6, 7, 8, 9, 10 -> new Random();
Expand Down
2 changes: 1 addition & 1 deletion testData/results/pkg/TestClassVar.dec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class TestClassVar {
}// 37

public Long testFieldSSAU1() {
return new Long((long)(this.field_int++));// 40
return new Long(this.field_int++);// 40
}

public void testComplexPropagation() {
Expand Down
2 changes: 1 addition & 1 deletion testData/results/pkg/TestDebugSymbols.dec
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class TestDebugSymbols {
String text = "text";// 21
long prolonged = 42L;// 22
float decimated = (float)prolonged / 10.0F;// 23
double doubled = (double)(2.0F * decimated);// 24
double doubled = 2.0F * decimated;// 24
return (text + ":" + prolonged + ":" + decimated + ":" + doubled).length();// 25
}
}
Expand Down
24 changes: 8 additions & 16 deletions testData/results/pkg/TestForCyclicVarDef.dec
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@ public class TestForCyclicVarDef {
public void test() {
short var2 = 12338;// 5
if (var2 != -8396) {
float var9 = 22.22F;
float var9 = 22.22F;// 9

while (var9 > 133.07F) {
float var3 = var9 - -15.01F;// 10
var9 -= -15.01F;// 10
System.out.println("Hi");// 11
var9 = var3 * 29.43F;// 9
var9 *= 29.43F;
}
}
}// 6 13

public void test1() {
short var9 = 12338;// 17
float var9x = 22.22F;
float var9x = 22.22F;// 20

while (var9x > 133.07F) {
float var3 = var9x - -15.01F;// 21
var9x -= -15.01F;// 21
System.out.println("Hi");// 22
var9x = var3 * 29.43F;// 20
var9x *= 29.43F;
}
}// 24

Expand Down Expand Up @@ -55,10 +55,8 @@ class 'pkg/TestForCyclicVarDef' {
10 8
11 8
12 8
16 9
17 9
18 9
19 9
1a 9
1b 10
1c 10
Expand All @@ -68,10 +66,8 @@ class 'pkg/TestForCyclicVarDef' {
20 10
21 10
22 10
23 11
24 11
25 11
26 11
27 11
2b 14
}
Expand All @@ -88,10 +84,8 @@ class 'pkg/TestForCyclicVarDef' {
8 20
9 20
a 20
e 21
f 21
10 21
11 21
12 21
13 22
14 22
Expand All @@ -101,10 +95,8 @@ class 'pkg/TestForCyclicVarDef' {
18 22
19 22
1a 22
1b 23
1c 23
1d 23
1e 23
1f 23
23 25
}
Expand Down Expand Up @@ -138,12 +130,12 @@ class 'pkg/TestForCyclicVarDef' {
Lines mapping:
5 <-> 5
6 <-> 15
9 <-> 12
9 <-> 7
10 <-> 10
11 <-> 11
13 <-> 15
17 <-> 18
20 <-> 24
20 <-> 19
21 <-> 22
22 <-> 23
24 <-> 26
Expand Down
2 changes: 1 addition & 1 deletion testData/results/pkg/TestLocalsNames.dec
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class TestLocalsNames {
}

long elapsed = System.currentTimeMillis() - start;// 31
System.out.println("took " + elapsed + "ms (" + elapsed / (long)files.length + "ms per dir)");// 32
System.out.println("took " + elapsed + "ms (" + elapsed / files.length + "ms per dir)");// 32
}
}// 34
}
Expand Down
10 changes: 5 additions & 5 deletions testData/results/pkg/TestMethodHandles.dec
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,33 @@ public class TestMethodHandles {
public void test1() throws Throwable {
MethodHandle abs = LOOKUP.findStatic(Math.class, "abs", MethodType.methodType(long.class, long.class));// 10
int a = -5;// 11
long b = (long)abs.invokeExact((long)a);// 12
long b = (long)abs.invokeExact(a);// 12
System.out.println(b);// 13
}// 14

public int test2() throws Throwable {
MethodHandle abs = LOOKUP.findStatic(Math.class, "abs", MethodType.methodType(long.class, long.class));// 17
int a = -5;// 18
return (int)(long)abs.invokeExact((long)a);// 19
return (int)(long)abs.invokeExact(a);// 19
}

public void test3() throws Throwable {
MethodHandle abs = LOOKUP.findStatic(Math.class, "abs", MethodType.methodType(long.class, long.class));// 23
int a = -5;// 24
long b = (long)abs.invoke((long)a);// 25
long b = (long)abs.invoke(a);// 25
System.out.println(b);// 26
}// 27

public int test4() throws Throwable {
MethodHandle abs = LOOKUP.findStatic(Math.class, "abs", MethodType.methodType(long.class, long.class));// 30
int a = -5;// 31
return (int)(long)abs.invoke((long)a);// 32
return (int)(long)abs.invoke(a);// 32
}

public void test5() throws Throwable {
MethodHandle println = LOOKUP.findVirtual(PrintStream.class, "println", MethodType.methodType(void.class, long.class));// 36
int a = -5;// 37
println.invokeExact(System.out, (long)a);// 38
println.invokeExact(System.out, a);// 38
}// 39
}

Expand Down
Loading

0 comments on commit fb4442b

Please sign in to comment.