diff --git a/py-visualise/out/diff.json b/py-visualise/out/diff.json index 82a8364..4e19239 100644 --- a/py-visualise/out/diff.json +++ b/py-visualise/out/diff.json @@ -1 +1 @@ -{"actions":[{"action":"Update","oldLine":-1,"newLine":-1,"oldCode":"","newCode":"","difference":{"message":null,"oldJimple":"this := @this: org.pdgdiff.testclasses.TestAdder1","newJimple":"this := @this: org.pdgdiff.testclasses.TestAdder2"}},{"action":"Insert","line":3,"code":"public class TestAdder2 {"},{"action":"Delete","line":3,"code":"public class TestAdder1 {"},{"action":"Update","oldLine":19,"newLine":21,"oldCode":" System.out.println(\"identical Result: \" + t);","newCode":" System.out.println(\"identical Result: \" + meep);","difference":{"message":null,"oldJimple":"$stack30 = virtualinvoke $stack29.()","newJimple":"$stack32 = virtualinvoke $stack31.()"}},{"action":"Update","oldLine":17,"newLine":20,"oldCode":" System.out.println(\"Detailed Computation Result: \" + complexRes);","newCode":" System.out.println(\"Complex Calculation Result: \" + complexResult);","difference":{"message":null,"oldJimple":"virtualinvoke $stack21.($stack24)","newJimple":"virtualinvoke $stack24.($stack27)"}},{"action":"Update","oldLine":12,"newLine":12,"oldCode":" System.out.println(\"Result: \" + result);","newCode":" System.out.println(\"Result: \" + result);","difference":{"message":null,"oldJimple":"virtualinvoke $stack9.($stack12)","newJimple":"virtualinvoke $stack11.($stack14)"}},{"action":"Update","oldLine":10,"newLine":8,"oldCode":" TestAdder1 test = new TestAdder1();","newCode":" TestAdder2 test = new TestAdder2();","difference":{"message":null,"oldJimple":"specialinvoke $stack6.()>()","newJimple":"specialinvoke $stack8.()>()"}},{"action":"Insert","line":20,"code":" System.out.println(\"Complex Calculation Result: \" + complexResult);"},{"action":"Update","oldLine":12,"newLine":12,"oldCode":" System.out.println(\"Result: \" + result);","newCode":" System.out.println(\"Result: \" + result);","difference":{"message":null,"oldJimple":"$stack11 = virtualinvoke $stack10.($stack7)","newJimple":"$stack13 = virtualinvoke $stack12.($stack9)"}},{"action":"Delete","line":19,"code":" System.out.println(\"identical Result: \" + t);"},{"action":"Update","oldLine":16,"newLine":18,"oldCode":" int complexRes = test.detailedComputation(5, 10);","newCode":" int complexResult = test.complexCalculation(number1, number2);","difference":{"message":null,"oldJimple":"$stack19 = virtualinvoke $stack6.(5, 10)","newJimple":"$stack21 = virtualinvoke $stack8.(5, 4)"}},{"action":"Update","oldLine":11,"newLine":11,"oldCode":" int result = test.addNumbers(5, 10);","newCode":" int result = test.addNumbers(number1, number2);","difference":{"message":null,"oldJimple":"$stack7 = virtualinvoke $stack6.(5, 10)","newJimple":"$stack9 = virtualinvoke $stack8.(5, 4)"}},{"action":"Update","oldLine":19,"newLine":21,"oldCode":" System.out.println(\"identical Result: \" + t);","newCode":" System.out.println(\"identical Result: \" + meep);","difference":{"message":null,"oldJimple":"virtualinvoke $stack27.($stack30)","newJimple":"virtualinvoke $stack29.($stack32)"}},{"action":"Update","oldLine":14,"newLine":14,"oldCode":" System.out.println(\"Result: \" + res);","newCode":" System.out.println(\"Product: \" + product);","difference":{"message":null,"oldJimple":"$stack17 = virtualinvoke $stack16.($stack13)","newJimple":"$stack19 = virtualinvoke $stack18.($stack15)"}},{"action":"Update","oldLine":13,"newLine":13,"oldCode":" int res = test.minus(10, 5);","newCode":" int product = test.multiplyNumbers(number1, number2);","difference":{"message":null,"oldJimple":"$stack13 = virtualinvoke $stack6.(10, 5)","newJimple":"$stack15 = virtualinvoke $stack8.(5, 4)"}},{"action":"Insert","line":21,"code":" System.out.println(\"identical Result: \" + meep);"},{"action":"Delete","line":14,"code":" System.out.println(\"Result: \" + res);"},{"action":"Update","oldLine":17,"newLine":20,"oldCode":" System.out.println(\"Detailed Computation Result: \" + complexRes);","newCode":" System.out.println(\"Complex Calculation Result: \" + complexResult);","difference":{"message":null,"oldJimple":"$stack23 = virtualinvoke $stack22.($stack19)","newJimple":"$stack26 = virtualinvoke $stack25.($stack21)"}},{"action":"Delete","line":-1,"code":""},{"action":"Insert","line":-1,"code":""},{"action":"Update","oldLine":19,"newLine":21,"oldCode":" System.out.println(\"identical Result: \" + t);","newCode":" System.out.println(\"identical Result: \" + meep);","difference":{"message":null,"oldJimple":"$stack29 = virtualinvoke $stack28.($stack25)","newJimple":"$stack31 = virtualinvoke $stack30.($stack22)"}},{"action":"Delete","line":12,"code":" System.out.println(\"Result: \" + result);"},{"action":"Insert","line":12,"code":" System.out.println(\"Result: \" + result);"},{"action":"Insert","line":14,"code":" System.out.println(\"Product: \" + product);"},{"action":"Update","oldLine":14,"newLine":14,"oldCode":" System.out.println(\"Result: \" + res);","newCode":" System.out.println(\"Product: \" + product);","difference":{"message":null,"oldJimple":"$stack18 = virtualinvoke $stack17.()","newJimple":"$stack20 = virtualinvoke $stack19.()"}},{"action":"Update","oldLine":18,"newLine":19,"oldCode":" int t = test.identical(5, 10);","newCode":" int meep = test.identical(3,10);","difference":{"message":null,"oldJimple":"$stack25 = virtualinvoke $stack6.(5, 10)","newJimple":"$stack22 = virtualinvoke $stack8.(3, 10)"}},{"action":"Update","oldLine":12,"newLine":12,"oldCode":" System.out.println(\"Result: \" + result);","newCode":" System.out.println(\"Result: \" + result);","difference":{"message":null,"oldJimple":"$stack12 = virtualinvoke $stack11.()","newJimple":"$stack14 = virtualinvoke $stack13.()"}},{"action":"Update","oldLine":14,"newLine":14,"oldCode":" System.out.println(\"Result: \" + res);","newCode":" System.out.println(\"Product: \" + product);","difference":{"message":null,"oldJimple":"virtualinvoke $stack15.($stack18)","newJimple":"virtualinvoke $stack17.($stack20)"}},{"action":"Delete","line":17,"code":" System.out.println(\"Detailed Computation Result: \" + complexRes);"},{"action":"Update","oldLine":17,"newLine":20,"oldCode":" System.out.println(\"Detailed Computation Result: \" + complexRes);","newCode":" System.out.println(\"Complex Calculation Result: \" + complexResult);","difference":{"message":null,"oldJimple":"$stack24 = virtualinvoke $stack23.()","newJimple":"$stack27 = virtualinvoke $stack26.()"}},{"action":"Insert","line":22,"code":" }"},{"action":"Delete","line":20,"code":" }"},{"action":"Update","oldLine":10,"newLine":8,"oldCode":" TestAdder1 test = new TestAdder1();","newCode":" TestAdder2 test = new TestAdder2();","difference":{"message":null,"oldJimple":"$stack6 = new org.pdgdiff.testclasses.TestAdder1","newJimple":"$stack8 = new org.pdgdiff.testclasses.TestAdder2"}},{"action":"Delete","line":-1,"code":""},{"action":"Insert","line":-1,"code":""},{"action":"Update","oldLine":39,"newLine":25,"oldCode":" int sum = toadd1 + toadd2;","newCode":" int sum = number - number2;","difference":{"message":null,"oldJimple":"sum = a + b","newJimple":"sum = number - number2"}},{"action":"Update","oldLine":-1,"newLine":-1,"oldCode":"","newCode":"","difference":{"message":null,"oldJimple":"a := @parameter0: int","newJimple":"number := @parameter0: int"}},{"action":"Update","oldLine":44,"newLine":30,"oldCode":" int sum = a - b;","newCode":" int product = number * number2;","difference":{"message":null,"oldJimple":"sum = a - b","newJimple":"product = number * number2"}},{"action":"Delete","line":-1,"code":""},{"action":"Insert","line":-1,"code":""},{"action":"Update","oldLine":43,"newLine":29,"oldCode":"public int minus(int, int)","newCode":"public int multiplyNumbers(int, int)","difference":"signature or class metadata change"},{"action":"Update","oldLine":45,"newLine":31,"oldCode":" return sum;","newCode":" return product;","difference":{"message":null,"oldJimple":"return sum","newJimple":"return product"}},{"action":"Update","oldLine":-1,"newLine":-1,"oldCode":"","newCode":"","difference":{"message":null,"oldJimple":"a := @parameter0: int","newJimple":"number := @parameter0: int"}},{"action":"Delete","line":68,"code":" result += i * 2;"},{"action":"Delete","line":-1,"code":""},{"action":"Insert","line":-1,"code":""},{"action":"Update","oldLine":57,"newLine":42,"oldCode":" result = num1 - num2;","newCode":" result = num1 + num2;","difference":{"message":null,"oldJimple":"result = num1 - num2","newJimple":"result = num1 + num2"}},{"action":"Update","oldLine":68,"newLine":53,"oldCode":" result += i * 2;","newCode":" result *= 3;","difference":{"message":null,"oldJimple":"result = result + $stack6","newJimple":"result = result * 3"}},{"action":"Update","oldLine":50,"newLine":35,"oldCode":"public int detailedComputation(int, int)","newCode":"public int complexCalculation(int, int)","difference":"signature or class metadata change"},{"action":"Delete","line":63,"code":" for (int i = 0; i < 4; i++) {"},{"action":"Update","oldLine":64,"newLine":49,"oldCode":" result -= i;","newCode":" result += i;","difference":{"message":null,"oldJimple":"result = result - i","newJimple":"result = result + i"}},{"action":"Update","oldLine":55,"newLine":40,"oldCode":" result = num1 + num2;","newCode":" result = num1 - num2;","difference":{"message":null,"oldJimple":"result = num1 + num2","newJimple":"result = num1 - num2"}},{"action":"Update","oldLine":66,"newLine":51,"oldCode":" result /= 3;","newCode":" result /= 2;","difference":{"message":null,"oldJimple":"result = result / 3","newJimple":"result = result / 2"}},{"action":"Update","oldLine":65,"newLine":50,"oldCode":" if (result % 3 == 0) {","newCode":" if (result % 2 == 0) {","difference":{"message":null,"oldJimple":"$stack5 = result % 3","newJimple":"$stack5 = result % 2"}},{"action":"Insert","line":48,"code":" for (int i = 0; i < 3; i++) {"},{"action":"Update","oldLine":65,"newLine":50,"oldCode":" if (result % 3 == 0) {","newCode":" if (result % 2 == 0) {","difference":{"message":null,"oldJimple":"if $stack5 != 0 goto $stack6 = i * 2","newJimple":"if $stack5 != 0 goto result = result * 3"}},{"action":"Delete","line":-1,"code":""},{"action":"Insert","line":-1,"code":""},{"action":"Update","oldLine":5,"newLine":5,"oldCode":"private int cheese;","newCode":"private int another;","difference":"signature or class metadata change"},{"action":"Delete","line":7,"code":"public String swag;"}]} \ No newline at end of file +{"actions":[{"action":"Update","oldLine":-1,"newLine":-1,"oldCode":"","newCode":"","difference":{"message":null,"oldJimple":"this := @this: org.pdgdiff.testclasses.TestAdder1","newJimple":"this := @this: org.pdgdiff.testclasses.TestAdder2"}},{"action":"Update","oldLine":17,"newLine":20,"oldCode":" System.out.println(\"Detailed Computation Result: \" + complexRes);","newCode":" System.out.println(\"Complex Calculation Result: \" + complexResult);","difference":{"message":null,"oldJimple":"virtualinvoke $stack21.($stack24)","newJimple":"virtualinvoke $stack24.($stack27)"}},{"action":"Update","oldLine":12,"newLine":12,"oldCode":" System.out.println(\"Result: \" + result);","newCode":" System.out.println(\"Result: \" + result);","difference":{"message":null,"oldJimple":"virtualinvoke $stack9.($stack12)","newJimple":"virtualinvoke $stack11.($stack14)"}},{"action":"Update","oldLine":19,"newLine":21,"oldCode":" System.out.println(\"identical Result: \" + t);","newCode":" System.out.println(\"identical Result: \" + meep);","difference":{"message":null,"oldJimple":"$stack30 = virtualinvoke $stack29.()","newJimple":"$stack32 = virtualinvoke $stack31.()"}},{"action":"Update","oldLine":10,"newLine":8,"oldCode":" TestAdder1 test = new TestAdder1();","newCode":" TestAdder2 test = new TestAdder2();","difference":{"message":null,"oldJimple":"specialinvoke $stack6.()>()","newJimple":"specialinvoke $stack8.()>()"}},{"action":"Update","oldLine":12,"newLine":12,"oldCode":" System.out.println(\"Result: \" + result);","newCode":" System.out.println(\"Result: \" + result);","difference":{"message":null,"oldJimple":"$stack8 = new java.lang.StringBuilder","newJimple":"$stack10 = new java.lang.StringBuilder"}},{"action":"Update","oldLine":14,"newLine":14,"oldCode":" System.out.println(\"Result: \" + res);","newCode":" System.out.println(\"Product: \" + product);","difference":{"message":null,"oldJimple":"$stack15 = ","newJimple":"$stack17 = "}},{"action":"Update","oldLine":12,"newLine":12,"oldCode":" System.out.println(\"Result: \" + result);","newCode":" System.out.println(\"Result: \" + result);","difference":{"message":null,"oldJimple":"$stack11 = virtualinvoke $stack10.($stack7)","newJimple":"$stack13 = virtualinvoke $stack12.($stack9)"}},{"action":"Update","oldLine":16,"newLine":18,"oldCode":" int complexRes = test.detailedComputation(5, 10);","newCode":" int complexResult = test.complexCalculation(number1, number2);","difference":{"message":null,"oldJimple":"$stack19 = virtualinvoke $stack6.(5, 10)","newJimple":"$stack21 = virtualinvoke $stack8.(5, 4)"}},{"action":"Update","oldLine":11,"newLine":11,"oldCode":" int result = test.addNumbers(5, 10);","newCode":" int result = test.addNumbers(number1, number2);","difference":{"message":null,"oldJimple":"$stack7 = virtualinvoke $stack6.(5, 10)","newJimple":"$stack9 = virtualinvoke $stack8.(5, 4)"}},{"action":"Update","oldLine":19,"newLine":21,"oldCode":" System.out.println(\"identical Result: \" + t);","newCode":" System.out.println(\"identical Result: \" + meep);","difference":{"message":null,"oldJimple":"virtualinvoke $stack27.($stack30)","newJimple":"virtualinvoke $stack29.($stack32)"}},{"action":"Update","oldLine":14,"newLine":14,"oldCode":" System.out.println(\"Result: \" + res);","newCode":" System.out.println(\"Product: \" + product);","difference":{"message":null,"oldJimple":"$stack17 = virtualinvoke $stack16.($stack13)","newJimple":"$stack19 = virtualinvoke $stack18.($stack15)"}},{"action":"Update","oldLine":17,"newLine":20,"oldCode":" System.out.println(\"Detailed Computation Result: \" + complexRes);","newCode":" System.out.println(\"Complex Calculation Result: \" + complexResult);","difference":{"message":null,"oldJimple":"$stack21 = ","newJimple":"$stack24 = "}},{"action":"Update","oldLine":13,"newLine":13,"oldCode":" int res = test.minus(10, 5);","newCode":" int product = test.multiplyNumbers(number1, number2);","difference":{"message":null,"oldJimple":"$stack13 = virtualinvoke $stack6.(10, 5)","newJimple":"$stack15 = virtualinvoke $stack8.(5, 4)"}},{"action":"Update","oldLine":14,"newLine":14,"oldCode":" System.out.println(\"Result: \" + res);","newCode":" System.out.println(\"Product: \" + product);","difference":{"message":null,"oldJimple":"$stack14 = new java.lang.StringBuilder","newJimple":"$stack16 = new java.lang.StringBuilder"}},{"action":"Update","oldLine":19,"newLine":21,"oldCode":" System.out.println(\"identical Result: \" + t);","newCode":" System.out.println(\"identical Result: \" + meep);","difference":{"message":null,"oldJimple":"$stack26 = new java.lang.StringBuilder","newJimple":"$stack28 = new java.lang.StringBuilder"}},{"action":"Update","oldLine":14,"newLine":14,"oldCode":" System.out.println(\"Result: \" + res);","newCode":" System.out.println(\"Product: \" + product);","difference":{"message":null,"oldJimple":"$stack16 = virtualinvoke $stack14.(\"Result: \")","newJimple":"$stack18 = virtualinvoke $stack16.(\"Product: \")"}},{"action":"Update","oldLine":17,"newLine":20,"oldCode":" System.out.println(\"Detailed Computation Result: \" + complexRes);","newCode":" System.out.println(\"Complex Calculation Result: \" + complexResult);","difference":{"message":null,"oldJimple":"$stack23 = virtualinvoke $stack22.($stack19)","newJimple":"$stack26 = virtualinvoke $stack25.($stack21)"}},{"action":"Update","oldLine":19,"newLine":21,"oldCode":" System.out.println(\"identical Result: \" + t);","newCode":" System.out.println(\"identical Result: \" + meep);","difference":{"message":null,"oldJimple":"$stack29 = virtualinvoke $stack28.($stack25)","newJimple":"$stack31 = virtualinvoke $stack30.($stack22)"}},{"action":"Update","oldLine":17,"newLine":20,"oldCode":" System.out.println(\"Detailed Computation Result: \" + complexRes);","newCode":" System.out.println(\"Complex Calculation Result: \" + complexResult);","difference":{"message":null,"oldJimple":"specialinvoke $stack20.()>()","newJimple":"specialinvoke $stack23.()>()"}},{"action":"Update","oldLine":14,"newLine":14,"oldCode":" System.out.println(\"Result: \" + res);","newCode":" System.out.println(\"Product: \" + product);","difference":{"message":null,"oldJimple":"specialinvoke $stack14.()>()","newJimple":"specialinvoke $stack16.()>()"}},{"action":"Update","oldLine":19,"newLine":21,"oldCode":" System.out.println(\"identical Result: \" + t);","newCode":" System.out.println(\"identical Result: \" + meep);","difference":{"message":null,"oldJimple":"specialinvoke $stack26.()>()","newJimple":"specialinvoke $stack28.()>()"}},{"action":"Update","oldLine":19,"newLine":21,"oldCode":" System.out.println(\"identical Result: \" + t);","newCode":" System.out.println(\"identical Result: \" + meep);","difference":{"message":null,"oldJimple":"$stack28 = virtualinvoke $stack26.(\"identical Result: \")","newJimple":"$stack30 = virtualinvoke $stack28.(\"identical Result: \")"}},{"action":"Update","oldLine":17,"newLine":20,"oldCode":" System.out.println(\"Detailed Computation Result: \" + complexRes);","newCode":" System.out.println(\"Complex Calculation Result: \" + complexResult);","difference":{"message":null,"oldJimple":"$stack22 = virtualinvoke $stack20.(\"Detailed Computation Result: \")","newJimple":"$stack25 = virtualinvoke $stack23.(\"Complex Calculation Result: \")"}},{"action":"Update","oldLine":14,"newLine":14,"oldCode":" System.out.println(\"Result: \" + res);","newCode":" System.out.println(\"Product: \" + product);","difference":{"message":null,"oldJimple":"$stack18 = virtualinvoke $stack17.()","newJimple":"$stack20 = virtualinvoke $stack19.()"}},{"action":"Update","oldLine":18,"newLine":19,"oldCode":" int t = test.identical(5, 10);","newCode":" int meep = test.identical(3,10);","difference":{"message":null,"oldJimple":"$stack25 = virtualinvoke $stack6.(5, 10)","newJimple":"$stack22 = virtualinvoke $stack8.(3, 10)"}},{"action":"Update","oldLine":14,"newLine":14,"oldCode":" System.out.println(\"Result: \" + res);","newCode":" System.out.println(\"Product: \" + product);","difference":{"message":null,"oldJimple":"virtualinvoke $stack15.($stack18)","newJimple":"virtualinvoke $stack17.($stack20)"}},{"action":"Update","oldLine":12,"newLine":12,"oldCode":" System.out.println(\"Result: \" + result);","newCode":" System.out.println(\"Result: \" + result);","difference":{"message":null,"oldJimple":"$stack12 = virtualinvoke $stack11.()","newJimple":"$stack14 = virtualinvoke $stack13.()"}},{"action":"Update","oldLine":17,"newLine":20,"oldCode":" System.out.println(\"Detailed Computation Result: \" + complexRes);","newCode":" System.out.println(\"Complex Calculation Result: \" + complexResult);","difference":{"message":null,"oldJimple":"$stack20 = new java.lang.StringBuilder","newJimple":"$stack23 = new java.lang.StringBuilder"}},{"action":"Update","oldLine":19,"newLine":21,"oldCode":" System.out.println(\"identical Result: \" + t);","newCode":" System.out.println(\"identical Result: \" + meep);","difference":{"message":null,"oldJimple":"$stack27 = ","newJimple":"$stack29 = "}},{"action":"Update","oldLine":17,"newLine":20,"oldCode":" System.out.println(\"Detailed Computation Result: \" + complexRes);","newCode":" System.out.println(\"Complex Calculation Result: \" + complexResult);","difference":{"message":null,"oldJimple":"$stack24 = virtualinvoke $stack23.()","newJimple":"$stack27 = virtualinvoke $stack26.()"}},{"action":"Update","oldLine":12,"newLine":12,"oldCode":" System.out.println(\"Result: \" + result);","newCode":" System.out.println(\"Result: \" + result);","difference":{"message":null,"oldJimple":"$stack9 = ","newJimple":"$stack11 = "}},{"action":"Update","oldLine":12,"newLine":12,"oldCode":" System.out.println(\"Result: \" + result);","newCode":" System.out.println(\"Result: \" + result);","difference":{"message":null,"oldJimple":"$stack10 = virtualinvoke $stack8.(\"Result: \")","newJimple":"$stack12 = virtualinvoke $stack10.(\"Result: \")"}},{"action":"Update","oldLine":10,"newLine":8,"oldCode":" TestAdder1 test = new TestAdder1();","newCode":" TestAdder2 test = new TestAdder2();","difference":{"message":null,"oldJimple":"$stack6 = new org.pdgdiff.testclasses.TestAdder1","newJimple":"$stack8 = new org.pdgdiff.testclasses.TestAdder2"}},{"action":"Update","oldLine":12,"newLine":12,"oldCode":" System.out.println(\"Result: \" + result);","newCode":" System.out.println(\"Result: \" + result);","difference":{"message":null,"oldJimple":"specialinvoke $stack8.()>()","newJimple":"specialinvoke $stack10.()>()"}},{"action":"Update","oldLine":-1,"newLine":-1,"oldCode":"","newCode":"","difference":{"message":null,"oldJimple":"this := @this: org.pdgdiff.testclasses.TestAdder1","newJimple":"this := @this: org.pdgdiff.testclasses.TestAdder2"}},{"action":"Update","oldLine":-1,"newLine":-1,"oldCode":"","newCode":"","difference":{"message":null,"oldJimple":"b := @parameter1: int","newJimple":"number2 := @parameter1: int"}},{"action":"Update","oldLine":39,"newLine":25,"oldCode":" int sum = toadd1 + toadd2;","newCode":" int sum = number - number2;","difference":{"message":null,"oldJimple":"sum = a + b","newJimple":"sum = number - number2"}},{"action":"Update","oldLine":-1,"newLine":-1,"oldCode":"","newCode":"","difference":{"message":null,"oldJimple":"a := @parameter0: int","newJimple":"number := @parameter0: int"}},{"action":"Update","oldLine":44,"newLine":30,"oldCode":" int sum = a - b;","newCode":" int product = number * number2;","difference":{"message":null,"oldJimple":"sum = a - b","newJimple":"product = number * number2"}},{"action":"Update","oldLine":43,"newLine":29,"oldCode":"public int minus(int, int)","newCode":"public int multiplyNumbers(int, int)","difference":"signature or class metadata change"},{"action":"Update","oldLine":-1,"newLine":-1,"oldCode":"","newCode":"","difference":{"message":null,"oldJimple":"this := @this: org.pdgdiff.testclasses.TestAdder1","newJimple":"this := @this: org.pdgdiff.testclasses.TestAdder2"}},{"action":"Update","oldLine":-1,"newLine":-1,"oldCode":"","newCode":"","difference":{"message":null,"oldJimple":"b := @parameter1: int","newJimple":"number2 := @parameter1: int"}},{"action":"Update","oldLine":45,"newLine":31,"oldCode":" return sum;","newCode":" return product;","difference":{"message":null,"oldJimple":"return sum","newJimple":"return product"}},{"action":"Update","oldLine":-1,"newLine":-1,"oldCode":"","newCode":"","difference":{"message":null,"oldJimple":"a := @parameter0: int","newJimple":"number := @parameter0: int"}},{"action":"Update","oldLine":-1,"newLine":-1,"oldCode":"","newCode":"","difference":{"message":null,"oldJimple":"this := @this: org.pdgdiff.testclasses.TestAdder1","newJimple":"this := @this: org.pdgdiff.testclasses.TestAdder2"}},{"action":"Update","oldLine":5,"newLine":5,"oldCode":"private int cheese;","newCode":"private int another;","difference":"signature or class metadata change"},{"action":"Delete","line":7,"code":"public String swag;"}]} \ No newline at end of file diff --git a/py-visualise/testclasses/TestAdder2.java b/py-visualise/testclasses/TestAdder2.java index 567c412..b0b5dc3 100644 --- a/py-visualise/testclasses/TestAdder2.java +++ b/py-visualise/testclasses/TestAdder2.java @@ -50,7 +50,7 @@ public int complexCalculation(int num1, int num2) { if (result % 2 == 0) { result /= 2; } else { - result *= 3; + result += 3; } } diff --git a/src/main/java/org/pdgdiff/Main.java b/src/main/java/org/pdgdiff/Main.java index f32eae9..1db94a9 100644 --- a/src/main/java/org/pdgdiff/Main.java +++ b/src/main/java/org/pdgdiff/Main.java @@ -2,6 +2,7 @@ import org.pdgdiff.graph.GraphExporter; import org.pdgdiff.graph.GraphGenerator; +import org.pdgdiff.graph.GraphTraversal; import org.pdgdiff.graph.PDG; import org.pdgdiff.matching.GraphMatcherFactory; import org.pdgdiff.matching.PDGComparator; @@ -10,9 +11,11 @@ import soot.SootClass; import soot.SootMethod; import soot.toolkits.graph.pdg.HashMutablePDG; +import soot.toolkits.graph.pdg.PDGNode; import java.util.ArrayList; import java.util.List; +import java.util.Set; public class Main { @@ -70,10 +73,47 @@ private static List generatePDGsForClass(SootClass sootClass) { try { // Retrieve the active body and generate the PDG method.retrieveActiveBody(); - System.out.println("Successfully retrieved active body for: " + method.getName() + " in " + sootClass.getName()); + System.out.println("\n\nSuccessfully retrieved active body for: " + method.getName() + " in " + sootClass.getName()); + + // print jimple body + System.out.println("Jimple body for function" + method.getName()); + System.out.println(method.getActiveBody().toString()); // Generate the PDG for the method PDG pdg = GraphGenerator.constructPdg(sootClass, method); + + List> connectedComponents = pdg.getConnectedComponents(); + int numComponents = connectedComponents.size(); + System.out.println("Number of connected components in method " + method.getName() + ": " + numComponents); + int componentIndex = 1; + for (Set component : connectedComponents) { + System.out.println(" Component " + componentIndex + " size: " + component.size()); + componentIndex++; + } + List isolatedNodes = pdg.getIsolatedNodes(); + if (!isolatedNodes.isEmpty()) { + System.out.println("Isolated nodes in method " + method.getName() + ":"); + for (PDGNode node : isolatedNodes) { + System.out.println(" " + node); + } + } else { + System.out.println("No isolated nodes in method " + method.getName()); + } + + connectedComponents.sort((c1, c2) -> Integer.compare(c2.size(), c1.size())); + Set largestComponent = connectedComponents.get(0); + System.out.println("Largest component size: " + largestComponent.size()); + +// +// List eg = GraphTraversal.collectNodesBFS(pdg); +// List eg2 = pdg.getNodes(); +// // find differences +// System.out.println("\npdg: Checking differences between entire graph and connected component for method " + pdg.getCFG().getBody().getMethod().getSignature() + ". BFS:" + eg.size() + "entire:" + eg2.size() ); +// for (PDGNode pdgNode : eg2) { +// if (!eg.contains(pdgNode)) { +// System.out.println("Node not found in BFS: " + pdgNode); +// } +// } if (pdg != null) { pdgList.add(pdg); System.out.println("PDG generated for method: " + method.getName()); diff --git a/src/main/java/org/pdgdiff/graph/CycleDetection.java b/src/main/java/org/pdgdiff/graph/CycleDetection.java index e835064..7164167 100644 --- a/src/main/java/org/pdgdiff/graph/CycleDetection.java +++ b/src/main/java/org/pdgdiff/graph/CycleDetection.java @@ -34,7 +34,7 @@ public static boolean hasCycle(PDG pdg) { stack.clear(); stronglyConnectedComponents.clear(); - List allNodes = GraphTraversal.collectNodesBFS(pdg); + List allNodes = new ArrayList<>(pdg.getNodes()); // Tarjan's algorithm starting from each node for (PDGNode node : allNodes) { diff --git a/src/main/java/org/pdgdiff/graph/GraphGenerator.java b/src/main/java/org/pdgdiff/graph/GraphGenerator.java index 75da18e..2b18324 100644 --- a/src/main/java/org/pdgdiff/graph/GraphGenerator.java +++ b/src/main/java/org/pdgdiff/graph/GraphGenerator.java @@ -12,6 +12,7 @@ import soot.toolkits.scalar.SimpleLocalUses; import soot.toolkits.scalar.UnitValueBoxPair; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -47,7 +48,7 @@ public static HashMutablePDG generatePDG(SootClass sootClass, SootMethod method) public static PDG constructPdg(SootClass sootClass, SootMethod method) { Body body = method.retrieveActiveBody(); - System.out.println("Generating PDG for method: " + method.getName()); + System.out.println("\n\nGenerating PDG for method: " + method.getName()); UnitGraph eug = new ExceptionalUnitGraph(body); //soot's api for creating postdominator tree @@ -62,6 +63,7 @@ public static PDG constructPdg(SootClass sootClass, SootMethod method) { SimpleLocalUses uses = new SimpleLocalUses(body, definitions); Map unitToNodeMap = new HashMap<>(); + List orderedNodes = new ArrayList<>(); // retrieve the start node of the PDG, which is the entry node of the CFG // List heads = eug.getHeads(); @@ -87,7 +89,9 @@ public static PDG constructPdg(SootClass sootClass, SootMethod method) { for (Unit unit : body.getUnits()) { + boolean connected = false; PDGNode node = addOrGetNode(pdg, unit, unitToNodeMap); + orderedNodes.add(node); //add control dependencies based on dominance frontier for (DominatorNode dode : dominanceFrontier.getDominanceFrontierOf(postdominatorTree.getDode(unit))) { @@ -101,7 +105,9 @@ public static PDG constructPdg(SootClass sootClass, SootMethod method) { pdg.startNode = startNode; } pdg.addEdge(frontierNode, node, DependencyTypes.CONTROL_DEPENDENCY); + connected = true; frontierNode.addDependent(node); + node.addBackDependent(frontierNode); System.out.println("Control Dependency: " + frontierNode + " -> " + node); } @@ -118,11 +124,17 @@ public static PDG constructPdg(SootClass sootClass, SootMethod method) { pdg.startNode = startNode; } pdg.addEdge(node, useNode, DependencyTypes.DATA_DEPENDENCY); + connected = true; node.addDependent(useNode); + useNode.addBackDependent(node); System.out.println("Data Dependency: " + node + " -> " + useNode); } } + + if (!connected) { + System.out.println("> No outgoing edges from: " + node); + } } // for (PDGNode node : pdg.getNodes()) { @@ -131,6 +143,7 @@ public static PDG constructPdg(SootClass sootClass, SootMethod method) { // System.out.println(" Dependent: " + dependent); // } // } + pdg.setOrderedNodes(orderedNodes); return pdg; } diff --git a/src/main/java/org/pdgdiff/graph/GraphTraversal.java b/src/main/java/org/pdgdiff/graph/GraphTraversal.java index 6bfd3b1..7bc2884 100644 --- a/src/main/java/org/pdgdiff/graph/GraphTraversal.java +++ b/src/main/java/org/pdgdiff/graph/GraphTraversal.java @@ -54,6 +54,7 @@ public static List collectNodesBFS(PDG pdg) { if (debug) System.out.println("[BFS] BFS Graph traversal complete."); return nodeList; +// return pdg.getNodes(); } // Method to traverse the graph using a depth-first search and collect all nodes @@ -96,8 +97,9 @@ public static List collectNodesDFS(PDG pdg) { } public static int getNodeCount(PDG pdg) { - List nodeList = collectNodesBFS(pdg); - return nodeList.size(); +// List nodeList = collectNodesBFS(pdg); +// return nodeList.size(); + return pdg.getNodes().size(); } // Optionally, if you have already collected nodes and want to avoid traversal: diff --git a/src/main/java/org/pdgdiff/graph/PDG.java b/src/main/java/org/pdgdiff/graph/PDG.java index ddfa4e3..b7d871f 100644 --- a/src/main/java/org/pdgdiff/graph/PDG.java +++ b/src/main/java/org/pdgdiff/graph/PDG.java @@ -1,34 +1,96 @@ -package org.pdgdiff.graph; + package org.pdgdiff.graph; -import soot.toolkits.graph.HashMutableEdgeLabelledDirectedGraph; -import soot.toolkits.graph.UnitGraph; -import soot.toolkits.graph.pdg.PDGNode; + import soot.toolkits.graph.HashMutableEdgeLabelledDirectedGraph; + import soot.toolkits.graph.UnitGraph; + import soot.toolkits.graph.pdg.PDGNode; -import java.util.List; + import java.util.*; -// TODO: this class will be my own version of the HashMutuablePDG that Soot presents, hopefully made slightly more accurate to -// TODO: the original literature. -public class PDG extends HashMutableEdgeLabelledDirectedGraph { - private UnitGraph cfg = null; - protected PDGNode startNode = null; + // TODO: this class will be my own version of the HashMutuablePDG that Soot presents, hopefully made slightly more accurate to + // TODO: the original literature. + public class PDG extends HashMutableEdgeLabelledDirectedGraph { + private UnitGraph cfg = null; + protected PDGNode startNode = null; + private List orderedNodes; - public PDG() { - super(); - } + public PDG() { + super(); + } - public void setCFG(UnitGraph cfg) { - this.cfg = cfg; - } + public void setCFG(UnitGraph cfg) { + this.cfg = cfg; + } - public UnitGraph getCFG() { - return cfg; - } + public UnitGraph getCFG() { + return cfg; + } - public PDGNode getStartNode() { - return startNode; - } + public PDGNode getStartNode() { + return startNode; + } -// public List getNodes() { -// return super.getNodes(); -// } -} + public void setOrderedNodes(List orderedNodes) { + this.orderedNodes = orderedNodes; + } + + + public List getNodes() { + // alternatively could use nodeToPreds method here, not sure + // order seems to be non-det which is a bit worrying. + return orderedNodes; + } + + public List> getConnectedComponents() { + Set visited = new HashSet<>(); + List> components = new ArrayList<>(); + + for (PDGNode node : this.getNodes()) { + if (!visited.contains(node)) { + Set component = new HashSet<>(); + exploreComponent(node, visited, component); + components.add(component); + } + } + return components; + } + + private void exploreComponent(PDGNode node, Set visited, Set component) { + Stack stack = new Stack<>(); + stack.push(node); + visited.add(node); + + while (!stack.isEmpty()) { + PDGNode current = stack.pop(); + component.add(current); + + for (PDGNode neighbor : this.getSuccsOf(current)) { + if (!visited.contains(neighbor)) { + visited.add(neighbor); + stack.push(neighbor); + } + } + + for (PDGNode neighbor : this.getPredsOf(current)) { + if (!visited.contains(neighbor)) { + visited.add(neighbor); + stack.push(neighbor); + } + } + } + } + + public List getIsolatedNodes() { + List isolatedNodes = new ArrayList<>(); + + for (PDGNode node : this.getNodes()) { + List successors = this.getSuccsOf(node); + List predecessors = this.getPredsOf(node); + + if ((successors == null || successors.isEmpty()) && (predecessors == null || predecessors.isEmpty())) { + isolatedNodes.add(node); + } + } + + return isolatedNodes; + } + } \ No newline at end of file diff --git a/src/main/java/org/pdgdiff/matching/PDGComparator.java b/src/main/java/org/pdgdiff/matching/PDGComparator.java index 84883f1..a0036d9 100644 --- a/src/main/java/org/pdgdiff/matching/PDGComparator.java +++ b/src/main/java/org/pdgdiff/matching/PDGComparator.java @@ -33,7 +33,13 @@ public static void compareAndPrintGraphSimilarity(List pdgList1, List GraphMatcher matcher = GraphMatcherFactory.createMatcher(strategy, pdgList1, pdgList2); // for each graph print the size of its nodes and if it has a cycle pdgList1.forEach(pdg -> { - System.out.println("------"); + System.out.println("FILE1 ------"); + System.out.println(pdg.getCFG().getBody().getMethod().getSignature()); + System.out.println(GraphTraversal.getNodeCount(pdg)); + CycleDetection.hasCycle(pdg); + }); + pdgList2.forEach(pdg -> { + System.out.println("FILE2 ------"); System.out.println(pdg.getCFG().getBody().getMethod().getSignature()); System.out.println(GraphTraversal.getNodeCount(pdg)); CycleDetection.hasCycle(pdg); @@ -49,10 +55,6 @@ public static void compareAndPrintGraphSimilarity(List pdgList1, List String method1 = srcPDG.getCFG().getBody().getMethod().getSignature(); String method2 = dstPDG.getCFG().getBody().getMethod().getSignature(); System.out.println("---\n> PDG from class 1: " + method1 + " is matched with PDG from class 2: " + method2); - System.out.println(GraphTraversal.getNodeCount(srcPDG)); - CycleDetection.hasCycle(srcPDG); - System.out.println(GraphTraversal.getNodeCount(dstPDG)); - CycleDetection.hasCycle(dstPDG); NodeMapping nodeMapping = graphMapping.getNodeMapping(srcPDG); if (nodeMapping != null) { System.out.println("--- Node Mapping:"); diff --git a/src/main/java/org/pdgdiff/matching/models/VF2GraphMatcher.java b/src/main/java/org/pdgdiff/matching/models/VF2GraphMatcher.java index 009d293..2d9f1f1 100644 --- a/src/main/java/org/pdgdiff/matching/models/VF2GraphMatcher.java +++ b/src/main/java/org/pdgdiff/matching/models/VF2GraphMatcher.java @@ -30,10 +30,12 @@ public GraphMapping matchPDGLists() { // for each pair of unmapped PDGs, compute similarity score for (PDG pdg1 : unmappedPDGs1) { for (PDG pdg2 : unmappedPDGs2) { + System.out.println("Matching PDG1: " + pdg1.getCFG().getBody().getMethod().getSignature() + ", PDG2: " + pdg2.getCFG().getBody().getMethod().getSignature()); VF2Matcher vf2Matcher = new VF2Matcher(pdg1, pdg2); NodeMapping nodeMapping = vf2Matcher.match(); - + System.out.println(nodeMapping); if (nodeMapping != null && !nodeMapping.isEmpty()) { + System.out.println(" >> Produced a mapping for " + pdg1.getCFG().getBody().getMethod().getSignature() + " and " + pdg2.getCFG().getBody().getMethod().getSignature()); int mappedNodes = nodeMapping.size(); int unmappedNodes1 = GraphTraversal.getNodeCount(pdg1) - mappedNodes; int unmappedNodes2 = GraphTraversal.getNodeCount(pdg2) - mappedNodes; @@ -42,8 +44,9 @@ public GraphMapping matchPDGLists() { // this might be to be improved. TODO look into other metrics/ measures. // TODO might want to add a threshold. possibly not all graphs should be mapped to all graphs! double score = (double) mappedNodes / (mappedNodes + unmappedNodes1 + unmappedNodes2); - + System.out.println(" >> Score: " + score + " for " + pdg1.getCFG().getBody().getMethod().getSignature() + " and " + pdg2.getCFG().getBody().getMethod().getSignature()); if (score > maxScore) { + System.out.println("!!!! >> New best score: " + score); maxScore = score; bestPdg1 = pdg1; bestPdg2 = pdg2; diff --git a/src/main/java/org/pdgdiff/matching/models/ullmann/UllmannMatcher.java b/src/main/java/org/pdgdiff/matching/models/ullmann/UllmannMatcher.java index 847bb48..9f69026 100644 --- a/src/main/java/org/pdgdiff/matching/models/ullmann/UllmannMatcher.java +++ b/src/main/java/org/pdgdiff/matching/models/ullmann/UllmannMatcher.java @@ -1,6 +1,5 @@ package org.pdgdiff.matching.models.ullmann; -import org.pdgdiff.graph.GraphTraversal; import org.pdgdiff.graph.PDG; import org.pdgdiff.matching.NodeMapping; import soot.toolkits.graph.pdg.HashMutablePDG; @@ -29,8 +28,9 @@ public UllmannMatcher(PDG pdg1, PDG pdg2) { this.pdg2 = pdg2; this.nodeMapping = new NodeMapping(); - this.nodes1 = new ArrayList<>(GraphTraversal.collectNodesBFS(pdg1)); - this.nodes2 = new ArrayList<>(GraphTraversal.collectNodesBFS(pdg2)); + this.nodes1 = new ArrayList<>(pdg1.getNodes()); + this.nodes2 = new ArrayList<>(pdg2.getNodes()); + this.n = nodes1.size(); this.m = nodes2.size(); this.M = new int[n][m]; diff --git a/src/main/java/org/pdgdiff/matching/models/vf2/VF2State.java b/src/main/java/org/pdgdiff/matching/models/vf2/VF2State.java index c629a62..8375b68 100644 --- a/src/main/java/org/pdgdiff/matching/models/vf2/VF2State.java +++ b/src/main/java/org/pdgdiff/matching/models/vf2/VF2State.java @@ -20,14 +20,24 @@ class VF2State { private Set unmapped1; // Unmapped nodes in PDG1 private Set unmapped2; // Unmapped nodes in PDG2 + private int pdg1Size; + private int pdg2Size; + public VF2State(PDG pdg1, PDG pdg2) { this.pdg1 = pdg1; this.pdg2 = pdg2; this.mapping = new LinkedHashMap<>(); - this.unmapped1 = new LinkedHashSet<>(GraphTraversal.collectNodesBFS(pdg1)); - this.unmapped2 = new LinkedHashSet<>(GraphTraversal.collectNodesBFS(pdg2)); + this.unmapped1 = new LinkedHashSet<>(pdg1.getNodes()); + this.unmapped2 = new LinkedHashSet<>(pdg2.getNodes()); + this.pdg1Size = pdg1.getNodes().size(); + this.pdg2Size = pdg2.getNodes().size(); + +// this.unmapped1 = new LinkedHashSet<>(GraphTraversal.collectNodesBFS(pdg1)); +// this.unmapped2 = new LinkedHashSet<>(GraphTraversal.collectNodesBFS(pdg2)); +// this.pdg1Size = unmapped1.size(); +// this.pdg2Size = unmapped2.size(); this.T1 = new LinkedHashSet<>(); this.T2 = new LinkedHashSet<>(); @@ -35,7 +45,7 @@ public VF2State(PDG pdg1, PDG pdg2) { public boolean isComplete() { // once one of the graphs is fully matched (hence this is subgraph isomorphism) - return mapping.size() >= Math.min(GraphTraversal.getNodeCount(pdg1), GraphTraversal.getNodeCount(pdg2)); + return mapping.size() >= Math.min(this.pdg1Size, this.pdg2Size); } public Map getMapping() { @@ -43,8 +53,6 @@ public Map getMapping() { } public List generateCandidates() { - // TODO: If non determinism prevails, consider implementing a sort on these candidates - // TODO: probably need to sort by id e.g. CFGNODE 1 sorta thing. should hopefully work, // If not implementing this here, possibly need to implement it in the matchRecursvie function. List candidates = new ArrayList<>();