diff --git a/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleToJavaCodeBuilder.java b/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleToJavaCodeBuilder.java new file mode 100644 index 0000000000..1b3c7e0137 --- /dev/null +++ b/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleToJavaCodeBuilder.java @@ -0,0 +1,111 @@ +package sootup.jimple.frontend; + +import java.util.*; + +public class JimpleToJavaCodeBuilder { + + private final List jimpleToJavaCodeObjects = new ArrayList<>(); + + public static JimpleToJavaCodeBuilder builder() { + return new JimpleToJavaCodeBuilder(); + } + + public List build() { + return jimpleToJavaCodeObjects; + } + + public JimpleToJavaCodeBuilder initObjects(String thisRefClassType) { + InitObjects initObjects = new InitObjects(thisRefClassType); + jimpleToJavaCodeObjects.add(initObjects); + return this; + } + + public JimpleToJavaCodeBuilder addLocal(String name, String type) { + Local local = new Local(name, type); + jimpleToJavaCodeObjects.add(local); + return this; + } + + public JimpleToJavaCodeBuilder addAssignStmt(String localName, String value) { + AssignStmt assignStmt = new AssignStmt(localName, value); + jimpleToJavaCodeObjects.add(assignStmt); + return this; + } + + public JimpleToJavaCodeBuilder addIdentityStmt(String localName, String type) { + IdentityStmt identityStmt = new IdentityStmt(localName, type); + jimpleToJavaCodeObjects.add(identityStmt); + return this; + } + + // Base JavaObject interface for all elements + public interface JavaCode { + String generateCode(); + } + + // Represents a local variable + public static class Local implements JavaCode { + private final String name; + private final String type; + + public Local(String name, String type) { + this.name = name; + this.type = type; + } + + @Override + public String generateCode() { + return "Local " + name + " = JavaJimple.newLocal(\"" + name + "\", factory.getClassType(\"" + type + "\"));"; + } + } + + // Represents an identity statement + public static class IdentityStmt implements JavaCode { + private final String localName; + private final String type; + + public IdentityStmt(String localName, String type) { + this.localName = localName; + this.type = type; + } + + @Override + public String generateCode() { + return "FallsThroughStmt startingStmt = JavaJimple.newIdentityStmt(" + + localName + ", JavaJimple.newThisRef(factory.getClassType(\"" + type + "\")), noStmtPositionInfo);"; + } + } + + // Represents an assignment statement + public static class AssignStmt implements JavaCode { + private final String localName; + private final String value; + + public AssignStmt(String localName, String value) { + this.localName = localName; + this.value = value; + } + + @Override + public String generateCode() { + return "FallsThroughStmt stmt = JavaJimple.newAssignStmt(" + + localName + ", " + value + ", noStmtPositionInfo);"; + } + } + + private static class InitObjects implements JavaCode { + + private final String thisRefClassType; + + private InitObjects(String thisRefClassType) { + this.thisRefClassType = thisRefClassType; + } + + @Override + public String generateCode() { + return "JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance();\n" + + "StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.getNoStmtPositionInfo();\n" + + "IdentityRef identityRef = JavaJimple.newThisRef(factory.getClassType(\"" + thisRefClassType + "\");"; + } + } +} diff --git a/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleStringAnalysisInputLocationTest.java b/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleStringAnalysisInputLocationTest.java index b5ca885c43..e4fe69050b 100644 --- a/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleStringAnalysisInputLocationTest.java +++ b/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleStringAnalysisInputLocationTest.java @@ -24,14 +24,23 @@ import static org.junit.jupiter.api.Assertions.*; -import java.util.Collections; +import java.util.*; + import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import sootup.core.graph.BasicBlock; +import sootup.core.graph.StmtGraph; +import sootup.core.jimple.common.stmt.Stmt; +import sootup.core.model.Body; +import sootup.core.model.SootClass; +import sootup.core.model.SootMethod; import sootup.core.model.SourceType; import sootup.core.signatures.MethodSignature; +import sootup.core.types.ClassType; import sootup.core.types.VoidType; import sootup.core.views.View; import sootup.interceptors.DeadAssignmentEliminator; +import sootup.java.core.JavaIdentifierFactory; @Tag("Java8") public class JimpleStringAnalysisInputLocationTest { @@ -78,4 +87,52 @@ public void test() { Collections.emptyList()); assertTrue(view.getMethod(methodSig).isPresent()); } + + + @Test + public void testJimpleJavaObjectPrinter() { + String jimpleString = "public class JimpleJavaObjectPrinter extends java.lang.Object\n" + + "{\n" + + " int tc1()\n" + + " {\n" + + " byte b0, b1;\n" + + " java.io.PrintStream r0;\n" + + " JB_CP r1;\n" + + "\n" + + " r1 := @this: JB_CP;\n" + + " b0 = 5;\n" + + " b1 = b0;\n" + + " r0 = ;\n" + + " virtualinvoke r0.(b1);\n" + + "\n" + + " return b1;\n" + + " }\n" + + "}"; + + JimpleStringAnalysisInputLocation analysisInputLocation = + new JimpleStringAnalysisInputLocation( + jimpleString, + SourceType.Application, + Collections.singletonList(new DeadAssignmentEliminator())); + + View view = new JimpleView(Collections.singletonList(analysisInputLocation)); + ClassType jimpleJavaObjectPrinter = view.getIdentifierFactory().getClassType("JimpleJavaObjectPrinter"); + assertNotNull(jimpleJavaObjectPrinter); + if (view.getClass(jimpleJavaObjectPrinter).isPresent()) { + SootClass sc = view.getClass(jimpleJavaObjectPrinter).get(); + MethodSignature methodSignature = JavaIdentifierFactory.getInstance().getMethodSignature(jimpleJavaObjectPrinter, "tc1", "int", Collections.emptyList()); + Optional method = sc.getMethod(methodSignature.getSubSignature()); + if (method.isPresent()) { + Body body = method.get().getBody(); + StmtGraph bodyStmtGraph = body.getStmtGraph(); + Iterator> bodyStmtGraphBlkIt = bodyStmtGraph.getBlockIterator(); + while (bodyStmtGraphBlkIt.hasNext()) { + BasicBlock block = bodyStmtGraphBlkIt.next(); + List blockStmts = block.getStmts(); + + } + + } + } + } } diff --git a/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleToJavaCodeBuilderTest.java b/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleToJavaCodeBuilderTest.java new file mode 100644 index 0000000000..132fda6091 --- /dev/null +++ b/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleToJavaCodeBuilderTest.java @@ -0,0 +1,43 @@ +package sootup.jimple.frontend; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +public class JimpleToJavaCodeBuilderTest { + + @Test + public void testJimpleToJavaCode() { + // Example Input + String input = "r0 := @this: Test;\n" + + "i1 = 5;\n" + + "i2 = 0;"; + + // Using the builder + List javaObjects = JimpleToJavaCodeBuilder.builder() + .initObjects("Test") + .addLocal("r0", "Test") + .addIdentityStmt("r0", "Test") + .addLocal("i1", "int") + .addAssignStmt("i1", "IntConstant.getInstance(5)") + .addLocal("i2", "int") + .addAssignStmt("i2", "IntConstant.getInstance(0)") + .build(); + + // Generate the code + for (JimpleToJavaCodeBuilder.JavaCode javaCode : javaObjects) { + System.out.println(javaCode.generateCode()); + } + } + + @Test + public void testJimpleToJavaCode2() { + String input = "\"r0 := @this: AbstractClass\",\n" + + " \"r1 = new AbstractClass\",\n" + + " \"specialinvoke r1.()>()\",\n" + + " \"virtualinvoke r1.()\",\n" + + " \"return\""; + + + } +}