diff --git a/sootup.jimple.frontend/pom.xml b/sootup.jimple.frontend/pom.xml
index 88f68c5dd0b..95f91c55ba8 100644
--- a/sootup.jimple.frontend/pom.xml
+++ b/sootup.jimple.frontend/pom.xml
@@ -50,13 +50,17 @@
org.soot-oss
sootup.java.core
-
org.antlr
antlr4-runtime
+
+ org.soot-oss
+ sootup.interceptors
+
+
org.junit.jupiter
junit-jupiter-api
diff --git a/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleAnalysisInputLocation.java b/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleAnalysisInputLocation.java
index 4cbef4bcb89..6d558b20f6e 100644
--- a/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleAnalysisInputLocation.java
+++ b/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleAnalysisInputLocation.java
@@ -120,13 +120,13 @@ List walkDirectory(
@Nonnull
public Collection getClassSources(@Nonnull View view) {
return walkDirectory(
- path, view.getIdentifierFactory(), new JimpleClassProvider(bodyInterceptors));
+ path, view.getIdentifierFactory(), new JimpleClassProvider(bodyInterceptors, view));
}
@Override
@Nonnull
public Optional getClassSource(@Nonnull ClassType type, @Nonnull View view) {
- final JimpleClassProvider classProvider = new JimpleClassProvider(bodyInterceptors);
+ final JimpleClassProvider classProvider = new JimpleClassProvider(bodyInterceptors, view);
final String ext = classProvider.getHandledFileType().toString().toLowerCase();
diff --git a/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleClassProvider.java b/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleClassProvider.java
index cc3d8245720..4c3f0702dd0 100644
--- a/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleClassProvider.java
+++ b/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleClassProvider.java
@@ -37,16 +37,19 @@
import sootup.core.inputlocation.FileType;
import sootup.core.transform.BodyInterceptor;
import sootup.core.types.ClassType;
+import sootup.core.views.View;
/** @author Markus Schmidt */
public class JimpleClassProvider implements ClassProvider {
@Nonnull private final List bodyInterceptors;
+ @Nonnull private final View view;
private static final @Nonnull Logger logger = LoggerFactory.getLogger(JimpleClassProvider.class);
- public JimpleClassProvider(List bodyInterceptors) {
+ public JimpleClassProvider(List bodyInterceptors, @Nonnull View view) {
this.bodyInterceptors = bodyInterceptors;
+ this.view = view;
}
@Override
@@ -57,7 +60,7 @@ public Optional createClassSource(
final JimpleConverter jimpleConverter = new JimpleConverter();
return Optional.of(
jimpleConverter.run(
- CharStreams.fromPath(sourcePath), inputlocation, sourcePath, bodyInterceptors));
+ CharStreams.fromPath(sourcePath), inputlocation, sourcePath, bodyInterceptors, view));
} catch (IOException | ResolveException e) {
logger.warn(
"The jimple file of "
diff --git a/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleConverter.java b/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleConverter.java
index 29d53d070d5..dc423ead704 100644
--- a/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleConverter.java
+++ b/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleConverter.java
@@ -49,6 +49,7 @@
import sootup.core.signatures.SootClassMemberSubSignature;
import sootup.core.transform.BodyInterceptor;
import sootup.core.types.*;
+import sootup.core.views.View;
import sootup.java.core.JavaIdentifierFactory;
import sootup.java.core.language.JavaJimple;
import sootup.jimple.JimpleBaseVisitor;
@@ -56,44 +57,30 @@
public class JimpleConverter {
- public OverridingClassSource run(
- @Nonnull CharStream charStream,
- @Nonnull AnalysisInputLocation inputlocation,
- @Nonnull Path sourcePath) {
- return run(charStream, inputlocation, sourcePath, Collections.emptyList());
- }
-
public OverridingClassSource run(
@Nonnull CharStream charStream,
@Nonnull AnalysisInputLocation inputlocation,
@Nonnull Path sourcePath,
- @Nonnull List bodyInterceptors) {
+ @Nonnull List bodyInterceptors,
+ @Nonnull View view) {
final JimpleParser jimpleParser =
JimpleConverterUtil.createJimpleParser(charStream, sourcePath);
jimpleParser.setErrorHandler(new BailErrorStrategy());
- return run(jimpleParser, inputlocation, sourcePath, bodyInterceptors);
- }
-
- public OverridingClassSource run(
- @Nonnull JimpleParser parser,
- @Nonnull AnalysisInputLocation inputlocation,
- @Nonnull Path sourcePath) {
- return run(parser, inputlocation, sourcePath, Collections.emptyList());
+ return run(jimpleParser, inputlocation, sourcePath, bodyInterceptors, view);
}
public OverridingClassSource run(
@Nonnull JimpleParser parser,
@Nonnull AnalysisInputLocation inputlocation,
@Nonnull Path sourcePath,
- @Nonnull List bodyInterceptors) {
-
- // FIXME: [ms] apply bodyInterceptors or better: move that logic into View itself!
+ @Nonnull List bodyInterceptors,
+ @Nonnull View view) {
ClassVisitor classVisitor;
try {
- classVisitor = new ClassVisitor(sourcePath);
+ classVisitor = new ClassVisitor(sourcePath, bodyInterceptors, view);
classVisitor.visit(parser.file());
} catch (ParseCancellationException ex) {
throw new ResolveException("Syntax Error", sourcePath, ex);
@@ -119,10 +106,15 @@ private static class ClassVisitor extends JimpleBaseVisitor {
@Nonnull private final JimpleConverterUtil util;
@Nonnull private final Path path;
+ @Nonnull private final List bodyInterceptors;
+ @Nonnull private final View view;
- public ClassVisitor(@Nonnull Path path) {
+ public ClassVisitor(
+ @Nonnull Path path, @Nonnull List bodyInterceptors, @Nonnull View view) {
this.path = path;
util = new JimpleConverterUtil(path);
+ this.bodyInterceptors = bodyInterceptors;
+ this.view = view;
}
private ClassType clazz = null;
@@ -197,8 +189,31 @@ public Boolean visitFile(@Nonnull JimpleParser.FileContext ctx) {
throw new ResolveException(
"Method with the same Signature does already exist.", path, m.getPosition());
}
- methods.add(m);
-
+ if (m.isConcrete()) {
+ Body.BodyBuilder bodyBuilder = Body.builder(m.getBody(), m.getModifiers());
+ for (BodyInterceptor bodyInterceptor : bodyInterceptors) {
+ try {
+ bodyInterceptor.interceptBody(bodyBuilder, view);
+ bodyBuilder
+ .getStmtGraph()
+ .validateStmtConnectionsInGraph(); // TODO: remove in the future ;-)
+ } catch (Exception e) {
+ throw new IllegalStateException(
+ "Failed to apply " + bodyInterceptor + " to " + m.getSignature(), e);
+ }
+ }
+ Body modifiedBody = bodyBuilder.build();
+ SootMethod sm =
+ new SootMethod(
+ new OverridingBodySource(m.getBodySource()).withBody(modifiedBody),
+ m.getSignature(),
+ m.getModifiers(),
+ m.getExceptionSignatures(),
+ m.getPosition());
+ methods.add(sm);
+ } else {
+ methods.add(m);
+ }
} else {
final JimpleParser.FieldContext fieldCtx = ctx.member(i).field();
EnumSet modifier = getFieldModifiers(fieldCtx.field_modifier());
diff --git a/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleStringAnalysisInputLocation.java b/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleStringAnalysisInputLocation.java
index 392628b41e1..ff3fac31a46 100644
--- a/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleStringAnalysisInputLocation.java
+++ b/sootup.jimple.frontend/src/main/java/sootup/jimple/frontend/JimpleStringAnalysisInputLocation.java
@@ -37,6 +37,7 @@
import sootup.core.transform.BodyInterceptor;
import sootup.core.types.ClassType;
import sootup.core.views.View;
+import sootup.interceptors.BytecodeBodyInterceptors;
/**
* This AnalysisInputLocation encapsulates and represents a single Jimple "file" - the contents of
@@ -48,41 +49,51 @@ public class JimpleStringAnalysisInputLocation implements AnalysisInputLocation
@Nonnull final Path path = Paths.get("only-in-memory.jimple");
@Nonnull final List bodyInterceptors;
- @Nonnull private final OverridingClassSource classSource;
@Nonnull final SourceType sourceType;
+ private String jimpleFileContents;
public JimpleStringAnalysisInputLocation(@Nonnull String jimpleFileContents) {
- this(jimpleFileContents, SourceType.Application, Collections.emptyList());
+ this(
+ jimpleFileContents,
+ SourceType.Application,
+ BytecodeBodyInterceptors.Default.getBodyInterceptors());
}
public JimpleStringAnalysisInputLocation(
@Nonnull String jimpleFileContents,
@Nonnull SourceType sourceType,
@Nonnull List bodyInterceptors) {
+ this.jimpleFileContents = jimpleFileContents;
this.bodyInterceptors = bodyInterceptors;
this.sourceType = sourceType;
+ }
+ private OverridingClassSource getOverridingClassSource(
+ String jimpleFileContents, List bodyInterceptors, View view) {
+ final @Nonnull OverridingClassSource classSource;
try {
JimpleConverter jimpleConverter = new JimpleConverter();
classSource =
jimpleConverter.run(
- CharStreams.fromString(jimpleFileContents), this, path, bodyInterceptors);
+ CharStreams.fromString(jimpleFileContents), this, path, bodyInterceptors, view);
} catch (Exception e) {
throw new IllegalArgumentException("No valid Jimple given.", e);
}
+ return classSource;
}
@Nonnull
@Override
public Optional extends SootClassSource> getClassSource(
@Nonnull ClassType type, @Nonnull View view) {
- return Optional.of(classSource);
+ return Optional.of(getOverridingClassSource(jimpleFileContents, bodyInterceptors, view));
}
@Nonnull
@Override
public Collection extends SootClassSource> getClassSources(@Nonnull View view) {
- return Collections.singletonList(classSource);
+ return Collections.singletonList(
+ getOverridingClassSource(jimpleFileContents, bodyInterceptors, view));
}
@Nonnull
@@ -96,9 +107,4 @@ public SourceType getSourceType() {
public List getBodyInterceptors() {
return bodyInterceptors;
}
-
- @Nonnull
- public ClassType getClassType() {
- return classSource.getClassType();
- }
}
diff --git a/sootup.jimple.frontend/src/test/java/resources/jimple/testbodyinterceptorsinjimpleinputlocation/JB_CP.jimple b/sootup.jimple.frontend/src/test/java/resources/jimple/testbodyinterceptorsinjimpleinputlocation/JB_CP.jimple
new file mode 100644
index 00000000000..398c2d92981
--- /dev/null
+++ b/sootup.jimple.frontend/src/test/java/resources/jimple/testbodyinterceptorsinjimpleinputlocation/JB_CP.jimple
@@ -0,0 +1,51 @@
+public class JB_CP extends java.lang.Object
+{
+ public void ()
+ {
+ JB_CP r0;
+
+
+ r0 := @this: JB_CP;
+ specialinvoke r0.()>();
+
+ return;
+ }
+
+ int tc1()
+ {
+ byte b0, b1;
+ java.io.PrintStream r0;
+ JB_CP r1;
+
+
+ r1 := @this: JB_CP;
+ b0 = 5;
+ b1 = b0;
+ r0 = ;
+ virtualinvoke r0.(b1);
+
+ return b1;
+ }
+
+ public static void main(java.lang.String[])
+ {
+ int i0;
+ java.io.PrintStream r0;
+ java.lang.String r1;
+ java.lang.String[] r2;
+ JB_CP r3, r4;
+
+
+ r2 := @parameter0: java.lang.String[];
+ r3 = new JB_CP;
+ specialinvoke r3.()>();
+ r4 = r3;
+ r0 = ;
+ i0 = virtualinvoke r4.();
+ r1 = dynamicinvoke "makeConcatWithConstants" (i0) ("tc1: \u0001");
+ virtualinvoke r0.(r1);
+
+ return;
+ }
+}
+
diff --git a/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleAnalysisInputLocationTest.java b/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleAnalysisInputLocationTest.java
index 006e051b0a5..1f37a6f673f 100644
--- a/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleAnalysisInputLocationTest.java
+++ b/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleAnalysisInputLocationTest.java
@@ -4,12 +4,17 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
import java.util.Optional;
+import java.util.stream.Collectors;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import sootup.core.model.SootClass;
+import sootup.core.model.SourceType;
import sootup.core.signatures.PackageName;
import sootup.core.types.ClassType;
+import sootup.interceptors.CopyPropagator;
@Tag("Java8")
public class JimpleAnalysisInputLocationTest {
@@ -97,4 +102,27 @@ public PackageName getPackageName() {
final Optional classSource4 = jv2.getClass(classType);
assertTrue(classSource4.isPresent());
}
+
+ @Test
+ public void testIfBodyInterceptorsApplied() {
+ final String resourceDir = "src/test/java/resources/";
+ final JimpleAnalysisInputLocation inputLocation =
+ new JimpleAnalysisInputLocation(
+ Paths.get(resourceDir + "/jimple/testbodyinterceptorsinjimpleinputlocation"),
+ SourceType.Application,
+ Arrays.asList(new CopyPropagator()));
+ JimpleView jv1 = new JimpleView(inputLocation);
+ List applicationClasses = jv1.getClasses().collect(Collectors.toList());
+ applicationClasses.forEach(
+ cls -> {
+ cls.getMethods()
+ .forEach(
+ m -> {
+ if (m.getSignature().getName().contains("tc1")) {
+ String s = m.getBody().toString();
+ System.out.println(s);
+ }
+ });
+ });
+ }
}
diff --git a/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleConverterTest.java b/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleConverterTest.java
index 37fa00efb42..2c10cad184e 100644
--- a/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleConverterTest.java
+++ b/sootup.jimple.frontend/src/test/java/sootup/jimple/frontend/JimpleConverterTest.java
@@ -30,8 +30,14 @@ public class JimpleConverterTest {
private SootClass parseJimpleClass(CharStream cs) throws ResolveException {
JimpleConverter jimpleVisitor = new JimpleConverter();
+ EagerInputLocation eagerInputLocation = new EagerInputLocation();
final OverridingClassSource scs =
- jimpleVisitor.run(cs, new EagerInputLocation(), Paths.get(""));
+ jimpleVisitor.run(
+ cs,
+ eagerInputLocation,
+ Paths.get(""),
+ Collections.emptyList(),
+ new JimpleView(eagerInputLocation));
return new SootClass(scs, SourceType.Application);
}
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 5e37cfffbd2..b5ca885c431 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
@@ -22,15 +22,16 @@
* #L%
*/
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.*;
import java.util.Collections;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
+import sootup.core.model.SourceType;
import sootup.core.signatures.MethodSignature;
import sootup.core.types.VoidType;
import sootup.core.views.View;
+import sootup.interceptors.DeadAssignmentEliminator;
@Tag("Java8")
public class JimpleStringAnalysisInputLocationTest {
@@ -39,7 +40,13 @@ public class JimpleStringAnalysisInputLocationTest {
public void testInvalidInput() {
String methodStr = "This is not Jimple its just a Sentence.";
assertThrows(
- IllegalArgumentException.class, () -> new JimpleStringAnalysisInputLocation(methodStr));
+ IllegalArgumentException.class,
+ () -> {
+ JimpleStringAnalysisInputLocation analysisInputLocation =
+ new JimpleStringAnalysisInputLocation(methodStr);
+ JimpleView view = new JimpleView(analysisInputLocation);
+ analysisInputLocation.getClassSources(view);
+ });
}
@Test
@@ -54,15 +61,18 @@ public void test() {
+ "}";
JimpleStringAnalysisInputLocation analysisInputLocation =
- new JimpleStringAnalysisInputLocation(methodStr);
+ new JimpleStringAnalysisInputLocation(
+ methodStr,
+ SourceType.Application,
+ Collections.singletonList(new DeadAssignmentEliminator()));
View view = new JimpleView(Collections.singletonList(analysisInputLocation));
- assertTrue(view.getClass(analysisInputLocation.getClassType()).isPresent());
+ assertNotNull(view.getIdentifierFactory().getClassType("DummyClass"));
MethodSignature methodSig =
view.getIdentifierFactory()
.getMethodSignature(
- analysisInputLocation.getClassType(),
+ view.getIdentifierFactory().getClassType("DummyClass"),
"banana",
VoidType.getInstance(),
Collections.emptyList());