Skip to content

Commit

Permalink
Propagate variable lower bounds for patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
jaskarth committed Apr 15, 2024
1 parent ce9cd92 commit 08ee555
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ private static boolean identifyRecordPatternMatch(IfStatement stat, Statement br

toDestroy.add(branch.getBasichead());

PatternExprent pattern = new PatternExprent(type, new ArrayList<>(vars.values()));
PatternExprent pattern = new PatternExprent(PatternExprent.recordData(cl), type, new ArrayList<>(vars.values()));

instOf.getLstOperands().add(2, pattern);
stat.setPatternMatched(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,9 +438,9 @@ else if (type2.type == CodeType.BOOLEAN) {
break;
}
case INSTANCEOF:
if (lstOperands.size() > 2) { // pattern matching instanceof
if (lstOperands.size() > 2 && lstOperands.get(2) instanceof VarExprent var) { // pattern matching instanceof
// The type of the defined var must be the type being tested
result.addMinTypeExprent(lstOperands.get(2), lstOperands.get(1).getExprType());
result.addMinTypeExprent(var, lstOperands.get(1).getExprType());
}
break;
case STR_CONCAT:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.java.decompiler.modules.decompiler.DecHelper;
import org.jetbrains.java.decompiler.modules.decompiler.ValidationHelper;
import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult;
import org.jetbrains.java.decompiler.struct.StructClass;
import org.jetbrains.java.decompiler.struct.StructRecordComponent;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.TextBuffer;

Expand All @@ -11,11 +14,13 @@
import java.util.List;

public class PatternExprent extends Exprent implements Pattern {
private final PatternData data;
private final VarType varType;
private final List<Exprent> exprents;

public PatternExprent(VarType type, List<Exprent> exprents) {
public PatternExprent(PatternData data, VarType type, List<Exprent> exprents) {
super(Type.PATTERN);
this.data = data;
varType = type;
this.exprents = exprents;

Expand All @@ -39,7 +44,7 @@ public VarType getExprType() {

@Override
public Exprent copy() {
return new PatternExprent(varType, DecHelper.copyExprentList(exprents));
return new PatternExprent(data, varType, DecHelper.copyExprentList(exprents));
}

@Override
Expand All @@ -61,6 +66,25 @@ public TextBuffer toJava(int indent) {
return buf;
}

@Override
public CheckTypesResult checkExprTypeBounds() {
if (this.data instanceof PatternData.RecordPatternData record) {
CheckTypesResult res = new CheckTypesResult();

ValidationHelper.assertTrue(record.cl.getRecordComponents() != null, "Must not be null!");
ValidationHelper.assertTrue(record.cl.getRecordComponents().size() == exprents.size(), "Record component size and expr list size must be equal!");

// The type lower bound must be
for (int i = 0; i < exprents.size(); i++) {
res.addMinTypeExprent(exprents.get(i), new VarType(record.cl.getRecordComponents().get(i).getDescriptor()));
}

return res;
}

return super.checkExprTypeBounds();
}

@Override
public void getBytecodeRange(BitSet values) {
measureBytecode(values, exprents);
Expand All @@ -82,4 +106,14 @@ public List<VarExprent> getPatternVars() {

return vars;
}

public static PatternData recordData(StructClass cl) {
return new PatternData.RecordPatternData(cl);
}

public sealed interface PatternData {
record RecordPatternData(StructClass cl) implements PatternData {

}
}
}
8 changes: 4 additions & 4 deletions testData/results/pkg/TestRecordPatterns1.dec
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@ package pkg;

public class TestRecordPatterns1 {
public void test1(TestRecordPatterns1.R r) {
if (r instanceof TestRecordPatterns1.R(byte var5, Object var8)) {// 7
if (r instanceof TestRecordPatterns1.R(int var5, Object var8)) {// 7
System.out.println(var5);// 8
System.out.println(var8);// 9
}
}// 11

public void test2(TestRecordPatterns1.R r) {
if (r instanceof TestRecordPatterns1.R(byte var5, <unknown> var11) && var11 instanceof String s) {// 14
if (r instanceof TestRecordPatterns1.R(int var5, Object var11) && var11 instanceof String s) {// 14
System.out.println(var5);// 15
System.out.println(s);// 16
}
}// 18

public void test3(TestRecordPatterns1.R r) {
if (r instanceof TestRecordPatterns1.R(byte var5, <unknown> var11) && var11 instanceof String s && s.length() > 10) {// 21
if (r instanceof TestRecordPatterns1.R(int var5, Object var11) && var11 instanceof String s && s.length() > 10) {// 21
System.out.println(var5);// 22
System.out.println(s);// 23
}
}// 25

public void test4(TestRecordPatterns1.R r) {
if (r instanceof TestRecordPatterns1.R(byte var5, Object var8)) {// 28
if (r instanceof TestRecordPatterns1.R(int var5, Object var8)) {// 28
System.out.println(var5);// 29
System.out.println(var8);// 30
}
Expand Down
2 changes: 1 addition & 1 deletion testData/results/pkg/TestRecordPatterns2.dec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package pkg;

public class TestRecordPatterns2 {
public void test1(TestRecordPatterns2.R r) {
if (r instanceof TestRecordPatterns2.R(byte var4)) {// 9
if (r instanceof TestRecordPatterns2.R(int var4)) {// 9
System.out.println(var4);// 10
}
}// 12
Expand Down

0 comments on commit 08ee555

Please sign in to comment.