From 1fd2fe265b48fc03426004cbc8c5cafd5f63c774 Mon Sep 17 00:00:00 2001
From: Markus Schmidt
Date: Mon, 17 Jul 2023 12:30:16 +0200
Subject: [PATCH 01/36] fix off by one: iterating over a all type items; adapt
it according to old soots implementation
---
.../sootup/java/bytecode/frontend/AsmMethodSource.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
index 067aa461843..a9f06720a6e 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
@@ -1345,7 +1345,7 @@ private void convertInvokeDynamicInsn(@Nonnull InvokeDynamicInsnNode insn) {
// Generate parameters & returnType & parameterTypes
List types = AsmUtil.toJimpleSignatureDesc(insn.desc);
- int nrArgs = types.size() - 1;
+ int nrArgs = types.size() - 1; // don't handle the return type here
List parameterTypes = new ArrayList<>(nrArgs);
List methodArgs = new ArrayList<>(nrArgs);
@@ -1383,12 +1383,12 @@ private void convertInvokeDynamicInsn(@Nonnull InvokeDynamicInsnNode insn) {
AbstractInvokeExpr expr = (AbstractInvokeExpr) opr.value;
List types = expr.getMethodSignature().getParameterTypes();
Operand[] oprs;
- int nrArgs = types.size() - 1;
+ int nrArgs = types.size();
final boolean isStaticInvokeExpr = expr instanceof JStaticInvokeExpr;
if (isStaticInvokeExpr) {
- oprs = (nrArgs <= 0) ? null : new Operand[nrArgs];
+ oprs = (nrArgs == 0) ? null : new Operand[nrArgs];
} else {
- oprs = (nrArgs < 0) ? null : new Operand[nrArgs + 1];
+ oprs = new Operand[nrArgs + 1];
}
if (oprs != null) {
while (nrArgs-- > 0) {
From f5420790d9770eca114bb7d5114d2765364bd445 Mon Sep 17 00:00:00 2001
From: Markus Schmidt
Date: Mon, 17 Jul 2023 12:30:31 +0200
Subject: [PATCH 02/36] cleanup
---
.../bytecode/frontend/AsmMethodSource.java | 33 +++----------------
1 file changed, 4 insertions(+), 29 deletions(-)
diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
index a9f06720a6e..3fa2fdfdf04 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
@@ -1345,7 +1345,7 @@ private void convertInvokeDynamicInsn(@Nonnull InvokeDynamicInsnNode insn) {
// Generate parameters & returnType & parameterTypes
List types = AsmUtil.toJimpleSignatureDesc(insn.desc);
- int nrArgs = types.size() - 1; // don't handle the return type here
+ int nrArgs = types.size() - 1; // don't handle the return type here
List parameterTypes = new ArrayList<>(nrArgs);
List methodArgs = new ArrayList<>(nrArgs);
@@ -1353,8 +1353,9 @@ private void convertInvokeDynamicInsn(@Nonnull InvokeDynamicInsnNode insn) {
// Beware: Call stack is FIFO, Jimple is linear
for (int i = nrArgs - 1; i >= 0; i--) {
- parameterTypes.add(types.get(i));
- args[i] = operandStack.popImmediate(types.get(i));
+ final Type type = types.get(i);
+ parameterTypes.add(type);
+ args[i] = operandStack.popImmediate(type);
methodArgs.add((Immediate) args[i].stackOrValue());
}
if (methodArgs.size() > 1) {
@@ -1418,32 +1419,6 @@ private void convertInvokeDynamicInsn(@Nonnull InvokeDynamicInsnNode insn) {
addReadOperandAssignments();
}
- // private @Nonnull MethodRef toSootMethodRef(@Nonnull Handle methodHandle) {
- // String bsmClsName = AsmUtil.toQualifiedName(methodHandle.getOwner());
- // JavaClassType bsmCls = view.getIdentifierFactory().getClassSignature(bsmClsName);
- // List bsmSigTypes = AsmUtil.toJimpleSignatureDesc(methodHandle.getDesc(), view);
- // Type returnType = bsmSigTypes.remove(bsmSigTypes.size() - 1);
- // MethodSignature methodSignature =
- // view.getIdentifierFactory().getMethodSignature(methodHandle.getName(), bsmCls,
- // returnType, bsmSigTypes);
- // boolean isStatic = methodHandle.getTag() == MethodHandle.Kind.REF_INVOKE_STATIC.getValue();
- // return Jimple.createSymbolicMethodRef(methodSignature, isStatic);
- // }
- //
- // private JFieldRef toSootFieldRef(Handle methodHandle) {
- // String bsmClsName = AsmUtil.toQualifiedName(methodHandle.getOwner());
- // JavaClassType bsmCls = view.getIdentifierFactory().getClassSignature(bsmClsName);
- //
- // Type t = AsmUtil.toJimpleSignatureDesc(methodHandle.getDesc(), view).get(0);
- // int kind = methodHandle.getTag();
- // boolean isStatic = kind == MethodHandle.Kind.REF_GET_FIELD_STATIC.getValue()
- // || kind == MethodHandle.Kind.REF_PUT_FIELD_STATIC.getValue();
- //
- // FieldSignature fieldSignature =
- // view.getIdentifierFactory().getFieldSignature(methodHandle.getName(), bsmCls, t);
- // return Jimple.createSymbolicFieldRef(fieldSignature, isStatic);
- // }
-
private void convertMultiANewArrayInsn(@Nonnull MultiANewArrayInsnNode insn) {
StackFrame frame = operandStack.getOrCreateStackframe(insn);
Operand[] out = frame.getOut();
From bc479395925ec47fc41c869ed3ce29c699aca9c2 Mon Sep 17 00:00:00 2001
From: Markus Schmidt
Date: Wed, 2 Aug 2023 13:46:41 +0200
Subject: [PATCH 03/36] create ctor; use memory efficient variant to store just
line numbers
---
.../jimple/basic/FullStmtPositionInfo.java | 7 +++---
.../jimple/basic/SimpleStmtPositionInfo.java | 16 ++-----------
.../core/jimple/basic/StmtPositionInfo.java | 23 ++-----------------
.../java/sootup/core/model/LinePosition.java | 6 ++++-
4 files changed, 12 insertions(+), 40 deletions(-)
diff --git a/sootup.core/src/main/java/sootup/core/jimple/basic/FullStmtPositionInfo.java b/sootup.core/src/main/java/sootup/core/jimple/basic/FullStmtPositionInfo.java
index 058e4fdc1bc..dfa3a785388 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/basic/FullStmtPositionInfo.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/basic/FullStmtPositionInfo.java
@@ -23,7 +23,6 @@
*/
import javax.annotation.Nonnull;
-import sootup.core.model.FullPosition;
import sootup.core.model.Position;
import sootup.core.util.Copyable;
@@ -34,7 +33,7 @@
* @author Linghui Luo, Markus Schmidt
*/
public class FullStmtPositionInfo extends SimpleStmtPositionInfo implements Copyable {
- protected final FullPosition[] operandPositions;
+ @Nonnull protected final Position[] operandPositions;
/**
* Create an instance from given statement position and operand positions.
@@ -43,7 +42,7 @@ public class FullStmtPositionInfo extends SimpleStmtPositionInfo implements Copy
* @param operandPositions the operand positions
*/
public FullStmtPositionInfo(
- @Nonnull Position stmtPosition, @Nonnull FullPosition[] operandPositions) {
+ @Nonnull Position stmtPosition, @Nonnull Position[] operandPositions) {
super(stmtPosition);
this.operandPositions = operandPositions;
}
@@ -94,7 +93,7 @@ public StmtPositionInfo withStmtPosition(@Nonnull Position stmtPosition) {
}
@Nonnull
- public StmtPositionInfo withOperandPositions(@Nonnull FullPosition[] operandPositions) {
+ public StmtPositionInfo withOperandPositions(@Nonnull Position[] operandPositions) {
return new FullStmtPositionInfo(stmtPosition, operandPositions);
}
}
diff --git a/sootup.core/src/main/java/sootup/core/jimple/basic/SimpleStmtPositionInfo.java b/sootup.core/src/main/java/sootup/core/jimple/basic/SimpleStmtPositionInfo.java
index 10275f0fa13..7f30a58d2fa 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/basic/SimpleStmtPositionInfo.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/basic/SimpleStmtPositionInfo.java
@@ -24,7 +24,7 @@
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import sootup.core.model.FullPosition;
+import sootup.core.model.LinePosition;
import sootup.core.model.Position;
/**
@@ -47,7 +47,7 @@ public SimpleStmtPositionInfo(@Nonnull Position stmtPosition) {
* @param lineNumber the line number of the statement.
*/
public SimpleStmtPositionInfo(int lineNumber) {
- stmtPosition = new FullPosition(lineNumber, -1, lineNumber, -1);
+ stmtPosition = new LinePosition(lineNumber);
}
@Nonnull
@@ -67,16 +67,4 @@ public String toString() {
s.append("stmt at:").append(getStmtPosition()).append("\n");
return s.toString();
}
-
- @Nonnull
- @Override
- public StmtPositionInfo withStmtPosition(@Nonnull Position stmtPosition) {
- return null;
- }
-
- @Nonnull
- @Override
- public StmtPositionInfo withOperandPositions(@Nonnull FullPosition[] operandPositions) {
- return null;
- }
}
diff --git a/sootup.core/src/main/java/sootup/core/jimple/basic/StmtPositionInfo.java b/sootup.core/src/main/java/sootup/core/jimple/basic/StmtPositionInfo.java
index b65dddd380b..692732326e7 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/basic/StmtPositionInfo.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/basic/StmtPositionInfo.java
@@ -24,7 +24,6 @@
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import sootup.core.model.FullPosition;
import sootup.core.model.Position;
/**
@@ -34,7 +33,7 @@
*/
public abstract class StmtPositionInfo {
- protected static final StmtPositionInfo noPosition =
+ protected static final StmtPositionInfo NOPOSITION =
new StmtPositionInfo() {
@Nonnull
@Override
@@ -51,18 +50,6 @@ public Position getOperandPosition(int index) {
public String toString() {
return "No StmtPositionnfo";
}
-
- @Nonnull
- @Override
- public StmtPositionInfo withStmtPosition(@Nonnull Position stmtPosition) {
- return this;
- }
-
- @Nonnull
- @Override
- public StmtPositionInfo withOperandPositions(@Nonnull FullPosition[] operandPositions) {
- return this;
- }
};
/**
@@ -72,7 +59,7 @@ public StmtPositionInfo withOperandPositions(@Nonnull FullPosition[] operandPosi
*/
@Nonnull
public static StmtPositionInfo createNoStmtPositionInfo() {
- return noPosition;
+ return NOPOSITION;
}
/**
@@ -94,10 +81,4 @@ public static StmtPositionInfo createNoStmtPositionInfo() {
@Override
public abstract String toString();
-
- @Nonnull
- public abstract StmtPositionInfo withStmtPosition(@Nonnull Position stmtPosition);
-
- @Nonnull
- public abstract StmtPositionInfo withOperandPositions(@Nonnull FullPosition[] operandPositions);
}
diff --git a/sootup.core/src/main/java/sootup/core/model/LinePosition.java b/sootup.core/src/main/java/sootup/core/model/LinePosition.java
index 8dc130eadb2..624ffa88fb8 100644
--- a/sootup.core/src/main/java/sootup/core/model/LinePosition.java
+++ b/sootup.core/src/main/java/sootup/core/model/LinePosition.java
@@ -1,7 +1,11 @@
package sootup.core.model;
public class LinePosition extends Position {
- int lineNo;
+ private final int lineNo;
+
+ public LinePosition(int lineNo) {
+ this.lineNo = lineNo;
+ }
@Override
public int getFirstLine() {
From 70873efb680644b4a60a8dc4cb6c14f271c18881 Mon Sep 17 00:00:00 2001
From: Markus Schmidt
Date: Thu, 3 Aug 2023 17:53:50 +0200
Subject: [PATCH 04/36] fixed nonnull. dry toString
---
.../core/jimple/basic/FullStmtPositionInfo.java | 13 ++++---------
.../core/jimple/basic/SimpleStmtPositionInfo.java | 6 ------
.../sootup/core/jimple/basic/StmtPositionInfo.java | 6 +++++-
.../frontend/WalaIRToJimpleConverter.java | 2 +-
4 files changed, 10 insertions(+), 17 deletions(-)
diff --git a/sootup.core/src/main/java/sootup/core/jimple/basic/FullStmtPositionInfo.java b/sootup.core/src/main/java/sootup/core/jimple/basic/FullStmtPositionInfo.java
index dfa3a785388..98dab8e2641 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/basic/FullStmtPositionInfo.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/basic/FullStmtPositionInfo.java
@@ -64,7 +64,7 @@ public Position getStmtPosition() {
* @return the position of the given operand
*/
public Position getOperandPosition(int index) {
- if (this.operandPositions != null && index >= 0 && index < this.operandPositions.length) {
+ if (index >= 0 && index < this.operandPositions.length) {
return this.operandPositions[index];
} else {
return NoPositionInformation.getInstance();
@@ -74,15 +74,10 @@ public Position getOperandPosition(int index) {
@Override
public String toString() {
StringBuilder s = new StringBuilder();
- s.append("stmt at: ").append(getStmtPosition()).append("\n");
+ s.append(super.toString());
s.append("operands at: ");
- if (operandPositions != null) {
- s.append("\n");
- for (int i = 0; i < operandPositions.length; i++) {
- s.append(i).append(": ").append(operandPositions[i]).append(" ");
- }
- } else {
- s.append("No position info");
+ for (int i = 0; i < operandPositions.length; i++) {
+ s.append(i).append(": ").append(operandPositions[i]).append(" ");
}
return s.toString();
}
diff --git a/sootup.core/src/main/java/sootup/core/jimple/basic/SimpleStmtPositionInfo.java b/sootup.core/src/main/java/sootup/core/jimple/basic/SimpleStmtPositionInfo.java
index 7f30a58d2fa..546cbe7a110 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/basic/SimpleStmtPositionInfo.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/basic/SimpleStmtPositionInfo.java
@@ -61,10 +61,4 @@ public Position getStmtPosition() {
public Position getOperandPosition(int index) {
return null;
}
-
- public String toString() {
- StringBuilder s = new StringBuilder();
- s.append("stmt at:").append(getStmtPosition()).append("\n");
- return s.toString();
- }
}
diff --git a/sootup.core/src/main/java/sootup/core/jimple/basic/StmtPositionInfo.java b/sootup.core/src/main/java/sootup/core/jimple/basic/StmtPositionInfo.java
index 692732326e7..769eb1bdf1b 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/basic/StmtPositionInfo.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/basic/StmtPositionInfo.java
@@ -80,5 +80,9 @@ public static StmtPositionInfo createNoStmtPositionInfo() {
public abstract Position getOperandPosition(int index);
@Override
- public abstract String toString();
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ s.append("stmt at:").append(getStmtPosition());
+ return s.toString();
+ }
}
diff --git a/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaIRToJimpleConverter.java b/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaIRToJimpleConverter.java
index 4094732a53d..a204eec586d 100644
--- a/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaIRToJimpleConverter.java
+++ b/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaIRToJimpleConverter.java
@@ -645,7 +645,7 @@ public static StmtPositionInfo convertPositionInfo(
Position instructionPosition, Position[] operandPosition) {
if (operandPosition == null) {
- return new FullStmtPositionInfo(convertPosition(instructionPosition), null);
+ return new SimpleStmtPositionInfo(convertPosition(instructionPosition));
}
FullPosition[] operandPos =
Arrays.stream(operandPosition)
From 453bb7bd0d774056ce873cb49b6c5b31a7e24b40 Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Fri, 11 Aug 2023 17:53:16 +0200
Subject: [PATCH 05/36] used FieldSignature instead of FieldRef in MethodHandle
---
.../core/jimple/common/constant/MethodHandle.java | 14 ++++++++------
.../java/bytecode/frontend/AsmMethodSource.java | 9 ++++++++-
.../java/sootup/java/core/language/JavaJimple.java | 4 ++--
3 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java b/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java
index d7e0bf53303..58cfd51cd75 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java
@@ -23,8 +23,8 @@
*/
import javax.annotation.Nonnull;
-import sootup.core.jimple.common.ref.JFieldRef;
import sootup.core.jimple.visitor.ConstantVisitor;
+import sootup.core.signatures.FieldSignature;
import sootup.core.signatures.MethodSignature;
import sootup.core.types.Type;
@@ -80,19 +80,19 @@ public static Kind getKind(String kind) {
}
private final MethodSignature methodSignature;
- private final JFieldRef fieldRef;
+ private final FieldSignature fieldSignature;
public int tag;
public MethodHandle(MethodSignature methodSignature, int tag, Type type) {
this.methodSignature = methodSignature;
this.tag = tag;
- this.fieldRef = null;
+ this.fieldSignature = null;
this.type = type;
}
- public MethodHandle(JFieldRef ref, int tag, Type type) {
- this.fieldRef = ref;
+ public MethodHandle(FieldSignature ref, int tag, Type type) {
+ this.fieldSignature = ref;
this.tag = tag;
this.methodSignature = null;
this.type = type;
@@ -110,7 +110,9 @@ public static boolean isMethodRef(int kind) {
// FIXME: [ms] serialize in a way it can be restored with the same parameters; adapt Jimple.g4 and
// JimpleConverter.java
public String toString() {
- return "handle: " + methodSignature;
+ return "handle: "
+ + (methodSignature == null ? "" : methodSignature)
+ + (fieldSignature == null ? "" : fieldSignature);
}
@Nonnull
diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
index 536a6619dfb..db76ca5dd91 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
@@ -1148,7 +1148,7 @@ private Immediate toSootValue(@Nonnull Object val) throws UnsupportedOperationEx
} else {
v =
JavaJimple.getInstance()
- .newMethodHandle(toSootFieldRef((Handle) val), ((Handle) val).getTag());
+ .newMethodHandle(toSootFieldSignature((Handle) val), ((Handle) val).getTag());
}
} else {
throw new UnsupportedOperationException("Unknown constant type: " + val.getClass());
@@ -1172,6 +1172,13 @@ private JFieldRef toSootFieldRef(Handle methodHandle) {
}
}
+ private FieldSignature toSootFieldSignature(Handle methodHandle) {
+ String bsmClsName = AsmUtil.toQualifiedName(methodHandle.getOwner());
+ JavaClassType bsmCls = identifierFactory.getClassType(bsmClsName);
+ Type t = AsmUtil.toJimpleSignatureDesc(methodHandle.getDesc()).get(0);
+ return identifierFactory.getFieldSignature(methodHandle.getName(), bsmCls, t);
+ }
+
private MethodSignature toMethodSignature(Handle methodHandle) {
String bsmClsName = AsmUtil.toQualifiedName(methodHandle.getOwner());
JavaClassType bsmCls = identifierFactory.getClassType(bsmClsName);
diff --git a/sootup.java.core/src/main/java/sootup/java/core/language/JavaJimple.java b/sootup.java.core/src/main/java/sootup/java/core/language/JavaJimple.java
index 23bc6b44319..3ec7d04c4ca 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/language/JavaJimple.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/language/JavaJimple.java
@@ -32,7 +32,7 @@
import sootup.core.jimple.common.constant.MethodType;
import sootup.core.jimple.common.constant.StringConstant;
import sootup.core.jimple.common.ref.JCaughtExceptionRef;
-import sootup.core.jimple.common.ref.JFieldRef;
+import sootup.core.signatures.FieldSignature;
import sootup.core.signatures.MethodSignature;
import sootup.core.types.NullType;
import sootup.core.types.PrimitiveType;
@@ -86,7 +86,7 @@ public StringConstant newStringConstant(String value) {
return new StringConstant(value, getIdentifierFactory().getType("java.lang.String"));
}
- public MethodHandle newMethodHandle(JFieldRef ref, int tag) {
+ public MethodHandle newMethodHandle(FieldSignature ref, int tag) {
return new MethodHandle(
ref, tag, getIdentifierFactory().getType("java.lang.invoke.MethodHandle"));
}
From 5e8fc4a2bd01d3d2b6d52d8b01ebda00939a093a Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Fri, 11 Aug 2023 17:53:34 +0200
Subject: [PATCH 06/36] added Test for Records in Java14
---
.../java14/binary/RecordTest.class | Bin 0 -> 1216 bytes
.../java14/source/RecordTest.java | 6 +++
.../minimaltestsuite/java14/RecordTest.java | 51 ++++++++++++++++++
3 files changed, 57 insertions(+)
create mode 100644 shared-test-resources/miniTestSuite/java14/binary/RecordTest.class
create mode 100644 shared-test-resources/miniTestSuite/java14/source/RecordTest.java
create mode 100644 sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/RecordTest.java
diff --git a/shared-test-resources/miniTestSuite/java14/binary/RecordTest.class b/shared-test-resources/miniTestSuite/java14/binary/RecordTest.class
new file mode 100644
index 0000000000000000000000000000000000000000..f10d31483f04146a0c7febafc173050014f7935c
GIT binary patch
literal 1216
zcmaJ=U2hUW6g?Lx3%C@DZM9-ss;$DdminzheXzzzf*-M@5BfB~q-+bjxVtp*Klxx2
z8xtP<0sbiC9d?mLNFR3Y?A>$ExpVf;?>~cI0G{J%3K2v##B|IdPRJgMQ&H{+>!|!u
zHf^Uxh(9we(|bXP7E6aoB#_jQ(s2noA?1VW()9==_^B$yyp9aA{MI1kYGcX+&oQl|
zN{*#-Ixb_8knn6jODGg;W4cOdcHOd$E4a#aZQ-`}?Up2DChMw-{+fhR?qf9=Uv(rr3s&$FFy$$m$;Za5Kee4Zu=t4~Zp;8y~BY^SI+G6apEG(oRgmUM<1
z($(;gur)T}fv|!m|}YPEEfWVm0O*;~>61tNdk+-|nj`#W7?2
z1R42rXvWSt(r29Fzr$+|F%oo{I~dNk*8L>-bsV+p)oL#kbCpIBLd#^Z3qN
zpGV26{Q_T!8yx=!F9F|Xfb+N+fD7D&I#I&d9$;k_nz*A8^(t2>!8zjxv}s}<+(tKYcfE4|9YfTa!Q;cX5wB1yZd30FUqlD}MpmfC1G2
literal 0
HcmV?d00001
diff --git a/shared-test-resources/miniTestSuite/java14/source/RecordTest.java b/shared-test-resources/miniTestSuite/java14/source/RecordTest.java
new file mode 100644
index 00000000000..cc11333dcf5
--- /dev/null
+++ b/shared-test-resources/miniTestSuite/java14/source/RecordTest.java
@@ -0,0 +1,6 @@
+record RecordTest(int a, String b) {
+ public RecordTest(int a, String b) {
+ this.a = a;
+ this.b = b;
+ }
+}
\ No newline at end of file
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/RecordTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/RecordTest.java
new file mode 100644
index 00000000000..154bd616084
--- /dev/null
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/RecordTest.java
@@ -0,0 +1,51 @@
+package sootup.java.bytecode.minimaltestsuite.java14;
+
+import categories.Java9Test;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import sootup.core.model.SootMethod;
+import sootup.core.signatures.MethodSignature;
+import sootup.java.bytecode.minimaltestsuite.MinimalBytecodeTestSuiteBase;
+import sootup.java.core.JavaIdentifierFactory;
+import sootup.java.core.types.JavaClassType;
+
+/** @author Jonas Klauke */
+@Category(Java9Test.class)
+public class RecordTest extends MinimalBytecodeTestSuiteBase {
+
+ @Override
+ public JavaClassType getDeclaredClassSignature() {
+ return JavaIdentifierFactory.getInstance().getClassType("RecordTest");
+ }
+
+ @Override
+ public MethodSignature getMethodSignature() {
+ System.out.println(getDeclaredClassSignature());
+ return identifierFactory.getMethodSignature(
+ getDeclaredClassSignature(),
+ "equals",
+ "boolean",
+ Collections.singletonList("java.lang.Object"));
+ }
+
+ @Override
+ public List expectedBodyStmts() {
+ return Stream.of(
+ "l0 := @this: RecordTest",
+ "l1 := @parameter0: java.lang.Object",
+ "$stack2 = dynamicinvoke \"equals\" (l0, l1) (class \"LRecordTest;\", \"a;b\", handle: , handle: )",
+ "return $stack2")
+ .collect(Collectors.toCollection(ArrayList::new));
+ }
+
+ @Test
+ public void test() {
+ SootMethod method = loadMethod(getMethodSignature());
+ assertJimpleStmts(method, expectedBodyStmts());
+ }
+}
From e544a578b8f6befa5b6b37d98fe1f71e4a99521a Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Mon, 14 Aug 2023 18:16:24 +0200
Subject: [PATCH 07/36] added the tag to the methodhandle serialization.
Adapted the jimple parser to the new changes
---
.../InstantiateClassValueVisitorTest.java | 12 +-
.../jimple/common/constant/MethodHandle.java | 109 ++++++++++++------
.../minimaltestsuite/java14/RecordTest.java | 44 ++++++-
.../sootup/java/core/language/JavaJimple.java | 12 +-
.../src/main/antlr4/sootup/jimple/Jimple.g4 | 5 +-
.../sootup/jimple/parser/JimpleConverter.java | 22 ++--
.../jimple/MethodAcceptingLamExpr.jimple | 2 +-
.../resources/jimple/MethodReference.jimple | 2 +-
.../java8/MethodAcceptingLamExprTest.java | 2 +-
9 files changed, 149 insertions(+), 61 deletions(-)
diff --git a/sootup.callgraph/src/test/java/sootup/callgraph/InstantiateClassValueVisitorTest.java b/sootup.callgraph/src/test/java/sootup/callgraph/InstantiateClassValueVisitorTest.java
index 7186e18082e..2313bfaea48 100644
--- a/sootup.callgraph/src/test/java/sootup/callgraph/InstantiateClassValueVisitorTest.java
+++ b/sootup.callgraph/src/test/java/sootup/callgraph/InstantiateClassValueVisitorTest.java
@@ -14,13 +14,10 @@
import sootup.core.jimple.basic.Local;
import sootup.core.jimple.basic.Value;
import sootup.core.jimple.common.constant.BooleanConstant;
-import sootup.core.jimple.common.constant.ClassConstant;
import sootup.core.jimple.common.constant.DoubleConstant;
-import sootup.core.jimple.common.constant.EnumConstant;
import sootup.core.jimple.common.constant.FloatConstant;
import sootup.core.jimple.common.constant.IntConstant;
import sootup.core.jimple.common.constant.LongConstant;
-import sootup.core.jimple.common.constant.MethodHandle;
import sootup.core.jimple.common.constant.MethodType;
import sootup.core.jimple.common.constant.StringConstant;
import sootup.core.jimple.common.expr.JAddExpr;
@@ -70,6 +67,7 @@
import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation;
import sootup.java.core.JavaProject;
import sootup.java.core.JavaSootClass;
+import sootup.java.core.language.JavaJimple;
import sootup.java.core.language.JavaLanguage;
@Category(Java8Test.class)
@@ -153,10 +151,10 @@ private void fillList(List listWithAllValues, View view) {
listWithAllValues.add(FloatConstant.getInstance(2.5f));
listWithAllValues.add(IntConstant.getInstance(3));
listWithAllValues.add(LongConstant.getInstance(3L));
- listWithAllValues.add(new StringConstant("String", StringClass));
- listWithAllValues.add(new EnumConstant("3", StringClass));
- listWithAllValues.add(new ClassConstant("java/lang/String", StringClass));
- listWithAllValues.add(new MethodHandle(toStringMethod, 3, StringClass));
+ listWithAllValues.add(stringConstant);
+ listWithAllValues.add(JavaJimple.getInstance().newEnumConstant("3", "EnumTest"));
+ listWithAllValues.add(JavaJimple.getInstance().newClassConstant("java/lang/String"));
+ listWithAllValues.add(JavaJimple.getInstance().newMethodHandle(toStringMethod, 5));
listWithAllValues.add(new MethodType(toStringMethod.getSubSignature(), StringClass));
listWithAllValues.add(new JAddExpr(stringConstant, stringConstant));
listWithAllValues.add(new JAndExpr(stringConstant, stringConstant));
diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java b/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java
index 58cfd51cd75..fd1792c29e4 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java
@@ -4,7 +4,7 @@
* #%L
* Soot - a J*va Optimization Framework
* %%
- * Copyright (C) 2005-2020 Jennifer Lhotak, Andreas Dann, Linghui Luo and others
+ * Copyright (C) 2005-2023 Jennifer Lhotak, Andreas Dann, Linghui, Luo Jonas Klauke and others
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
@@ -26,11 +26,13 @@
import sootup.core.jimple.visitor.ConstantVisitor;
import sootup.core.signatures.FieldSignature;
import sootup.core.signatures.MethodSignature;
+import sootup.core.signatures.SootClassMemberSignature;
+import sootup.core.signatures.SootClassMemberSubSignature;
import sootup.core.types.Type;
public class MethodHandle implements Constant {
- private final Type type;
+ @Nonnull private final Type type;
public enum Kind {
REF_GET_FIELD(1, "REF_GET_FIELD"),
@@ -60,6 +62,10 @@ public int getValue() {
return val;
}
+ public String getValueName() {
+ return valStr;
+ }
+
public static Kind getKind(int kind) {
for (Kind k : Kind.values()) {
if (k.getValue() == kind) {
@@ -69,50 +75,83 @@ public static Kind getKind(int kind) {
throw new RuntimeException("Error: No method handle kind for value '" + kind + "'.");
}
- public static Kind getKind(String kind) {
+ public static Kind getKind(String kindName) {
for (Kind k : Kind.values()) {
- if (k.toString().equals(kind)) {
+ if (k.getValueName().equals(kindName)) {
return k;
}
}
- throw new RuntimeException("Error: No method handle kind for value '" + kind + "'.");
+ throw new RuntimeException("Error: No method handle kind for value name '" + kindName + "'.");
}
}
- private final MethodSignature methodSignature;
- private final FieldSignature fieldSignature;
+ @Nonnull
+ private final SootClassMemberSignature extends SootClassMemberSubSignature> referenceSignature;
- public int tag;
+ @Nonnull private final Kind kind;
- public MethodHandle(MethodSignature methodSignature, int tag, Type type) {
- this.methodSignature = methodSignature;
- this.tag = tag;
- this.fieldSignature = null;
+ public MethodHandle(
+ @Nonnull SootClassMemberSignature extends SootClassMemberSubSignature> referenceSignature,
+ int tag,
+ @Nonnull Type type) {
+ this.kind = Kind.getKind(tag);
this.type = type;
+ this.referenceSignature = referenceSignature;
+ if ((this.isMethodRef() && !(referenceSignature instanceof MethodSignature))
+ || (this.isFieldRef() && !(referenceSignature instanceof FieldSignature))) {
+ throw new IllegalArgumentException(
+ "Tag:"
+ + tag
+ + " "
+ + kind.valStr
+ + " does not match with the given signature:"
+ + referenceSignature.getClass());
+ }
}
- public MethodHandle(FieldSignature ref, int tag, Type type) {
- this.fieldSignature = ref;
- this.tag = tag;
- this.methodSignature = null;
+ public MethodHandle(
+ @Nonnull SootClassMemberSignature extends SootClassMemberSubSignature> referenceSignature,
+ @Nonnull MethodHandle.Kind kind,
+ @Nonnull Type type) {
+ this.kind = kind;
this.type = type;
+ this.referenceSignature = referenceSignature;
+ if ((this.isMethodRef() && !(referenceSignature instanceof MethodSignature))
+ || (this.isFieldRef() && !(referenceSignature instanceof FieldSignature))) {
+ throw new IllegalArgumentException(
+ "Kind:"
+ + kind.valStr
+ + " does not match with the given signature:"
+ + referenceSignature.getClass());
+ }
}
- public static boolean isMethodRef(int kind) {
- return kind == Kind.REF_INVOKE_VIRTUAL.getValue()
- || kind == Kind.REF_INVOKE_STATIC.getValue()
- || kind == Kind.REF_INVOKE_SPECIAL.getValue()
- || kind == Kind.REF_INVOKE_CONSTRUCTOR.getValue()
- || kind == Kind.REF_INVOKE_INTERFACE.getValue();
+ public static boolean isMethodRef(int tag) {
+ return tag == Kind.REF_INVOKE_VIRTUAL.getValue()
+ || tag == Kind.REF_INVOKE_STATIC.getValue()
+ || tag == Kind.REF_INVOKE_SPECIAL.getValue()
+ || tag == Kind.REF_INVOKE_CONSTRUCTOR.getValue()
+ || tag == Kind.REF_INVOKE_INTERFACE.getValue();
+ }
+
+ public static boolean isFieldRef(int tag) {
+ return tag == Kind.REF_GET_FIELD.getValue()
+ || tag == Kind.REF_PUT_FIELD.getValue()
+ || tag == Kind.REF_PUT_FIELD_STATIC.getValue()
+ || tag == Kind.REF_GET_FIELD_STATIC.getValue();
+ }
+
+ public boolean isMethodRef() {
+ return MethodHandle.isMethodRef(this.kind.getValue());
+ }
+
+ public boolean isFieldRef() {
+ return MethodHandle.isFieldRef(this.kind.getValue());
}
@Override
- // FIXME: [ms] serialize in a way it can be restored with the same parameters; adapt Jimple.g4 and
- // JimpleConverter.java
public String toString() {
- return "handle: "
- + (methodSignature == null ? "" : methodSignature)
- + (fieldSignature == null ? "" : fieldSignature);
+ return "methodhandle: \"" + kind.valStr + "\" " + referenceSignature;
}
@Nonnull
@@ -121,8 +160,8 @@ public Type getType() {
return type;
}
- public MethodSignature getMethodSignature() {
- return methodSignature;
+ public SootClassMemberSignature extends SootClassMemberSubSignature> getReferenceSignature() {
+ return referenceSignature;
}
@Override
@@ -132,9 +171,9 @@ public void accept(@Nonnull ConstantVisitor v) {
@Override
public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((methodSignature == null) ? 0 : methodSignature.hashCode());
+ int result = type.hashCode();
+ result = 31 * result + referenceSignature.hashCode();
+ result = 31 * result + kind.hashCode();
return result;
}
@@ -150,10 +189,6 @@ public boolean equals(Object obj) {
return false;
}
MethodHandle other = (MethodHandle) obj;
- if (methodSignature == null) {
- return other.methodSignature == null;
- } else {
- return methodSignature.equals(other.methodSignature);
- }
+ return referenceSignature.equals(other.referenceSignature);
}
}
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/RecordTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/RecordTest.java
index 154bd616084..c56e28548c9 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/RecordTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/RecordTest.java
@@ -1,5 +1,8 @@
package sootup.java.bytecode.minimaltestsuite.java14;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import categories.Java9Test;
import java.util.ArrayList;
import java.util.Collections;
@@ -8,10 +11,17 @@
import java.util.stream.Stream;
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import sootup.core.jimple.basic.Immediate;
+import sootup.core.jimple.common.expr.JDynamicInvokeExpr;
+import sootup.core.jimple.common.stmt.Stmt;
import sootup.core.model.SootMethod;
+import sootup.core.signatures.FieldSignature;
import sootup.core.signatures.MethodSignature;
+import sootup.core.signatures.PackageName;
+import sootup.core.types.PrimitiveType;
import sootup.java.bytecode.minimaltestsuite.MinimalBytecodeTestSuiteBase;
import sootup.java.core.JavaIdentifierFactory;
+import sootup.java.core.language.JavaJimple;
import sootup.java.core.types.JavaClassType;
/** @author Jonas Klauke */
@@ -38,7 +48,7 @@ public List expectedBodyStmts() {
return Stream.of(
"l0 := @this: RecordTest",
"l1 := @parameter0: java.lang.Object",
- "$stack2 = dynamicinvoke \"equals\" (l0, l1) (class \"LRecordTest;\", \"a;b\", handle: , handle: )",
+ "$stack2 = dynamicinvoke \"equals\" (l0, l1) (class \"LRecordTest;\", \"a;b\", methodhandle: \"REF_GET_FIELD\" , methodhandle: \"REF_GET_FIELD\" )",
"return $stack2")
.collect(Collectors.toCollection(ArrayList::new));
}
@@ -47,5 +57,37 @@ public List expectedBodyStmts() {
public void test() {
SootMethod method = loadMethod(getMethodSignature());
assertJimpleStmts(method, expectedBodyStmts());
+ List dynamicInvokes =
+ method.getBody().getStmts().stream()
+ .filter(Stmt::containsInvokeExpr)
+ .map(Stmt::getInvokeExpr)
+ .filter(abstractInvokeExpr -> abstractInvokeExpr instanceof JDynamicInvokeExpr)
+ .map(abstractInvokeExpr -> (JDynamicInvokeExpr) abstractInvokeExpr)
+ .collect(Collectors.toList());
+ assertEquals(1, dynamicInvokes.size());
+ JDynamicInvokeExpr invoke = dynamicInvokes.get(0);
+
+ // test bootstrap args
+ List bootTrapArgs = invoke.getBootstrapArgs();
+ assertTrue(bootTrapArgs.contains(JavaJimple.getInstance().newClassConstant("LRecordTest;")));
+ assertTrue(bootTrapArgs.contains(JavaJimple.getInstance().newStringConstant("a;b")));
+ assertTrue(
+ bootTrapArgs.contains(
+ JavaJimple.getInstance()
+ .newMethodHandle(
+ new FieldSignature(
+ new JavaClassType("RecordTest", new PackageName("")),
+ "a",
+ PrimitiveType.getInt()),
+ 1)));
+ assertTrue(
+ bootTrapArgs.contains(
+ JavaJimple.getInstance()
+ .newMethodHandle(
+ new FieldSignature(
+ new JavaClassType("RecordTest", new PackageName("")),
+ "b",
+ new JavaClassType("String", new PackageName("java.lang"))),
+ 1)));
}
}
diff --git a/sootup.java.core/src/main/java/sootup/java/core/language/JavaJimple.java b/sootup.java.core/src/main/java/sootup/java/core/language/JavaJimple.java
index 3ec7d04c4ca..5d238bf85b8 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/language/JavaJimple.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/language/JavaJimple.java
@@ -32,8 +32,8 @@
import sootup.core.jimple.common.constant.MethodType;
import sootup.core.jimple.common.constant.StringConstant;
import sootup.core.jimple.common.ref.JCaughtExceptionRef;
-import sootup.core.signatures.FieldSignature;
-import sootup.core.signatures.MethodSignature;
+import sootup.core.signatures.SootClassMemberSignature;
+import sootup.core.signatures.SootClassMemberSubSignature;
import sootup.core.types.NullType;
import sootup.core.types.PrimitiveType;
import sootup.core.types.Type;
@@ -86,14 +86,16 @@ public StringConstant newStringConstant(String value) {
return new StringConstant(value, getIdentifierFactory().getType("java.lang.String"));
}
- public MethodHandle newMethodHandle(FieldSignature ref, int tag) {
+ public MethodHandle newMethodHandle(
+ SootClassMemberSignature extends SootClassMemberSubSignature> ref, int tag) {
return new MethodHandle(
ref, tag, getIdentifierFactory().getType("java.lang.invoke.MethodHandle"));
}
- public MethodHandle newMethodHandle(MethodSignature ref, int tag) {
+ public MethodHandle newMethodHandle(
+ SootClassMemberSignature extends SootClassMemberSubSignature> ref, MethodHandle.Kind kind) {
return new MethodHandle(
- ref, tag, getIdentifierFactory().getType("java.lang.invoke.MethodHandle"));
+ ref, kind, getIdentifierFactory().getType("java.lang.invoke.MethodHandle"));
}
public MethodType newMethodType(List parameterTypes, Type returnType) {
diff --git a/sootup.jimple.parser/src/main/antlr4/sootup/jimple/Jimple.g4 b/sootup.jimple.parser/src/main/antlr4/sootup/jimple/Jimple.g4
index 31082f1cd23..ecfbf9debcb 100644
--- a/sootup.jimple.parser/src/main/antlr4/sootup/jimple/Jimple.g4
+++ b/sootup.jimple.parser/src/main/antlr4/sootup/jimple/Jimple.g4
@@ -280,6 +280,9 @@ grammar Jimple;
/*local*/ local=identifier |
/*constant*/ constant;
+ methodhandle:
+ 'methodhandle: ' STRING_CONSTANT (method_signature|field_signature);
+
constant :
/*boolean*/ BOOL_CONSTANT |
/*integer*/ integer_constant |
@@ -287,7 +290,7 @@ grammar Jimple;
/*string*/ STRING_CONSTANT |
/*clazz*/ CLASS STRING_CONSTANT |
/*null*/ NULL |
- methodhandle='handle:' method_signature |
+ methodhandle |
methodtype='methodtype:' method_subsignature ;
binop :
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverter.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverter.java
index 6dda6e812b3..66334b3caf0 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverter.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverter.java
@@ -23,6 +23,8 @@
import sootup.core.model.*;
import sootup.core.signatures.FieldSignature;
import sootup.core.signatures.MethodSignature;
+import sootup.core.signatures.SootClassMemberSignature;
+import sootup.core.signatures.SootClassMemberSubSignature;
import sootup.core.transform.BodyInterceptor;
import sootup.core.types.*;
import sootup.java.core.JavaIdentifierFactory;
@@ -696,13 +698,19 @@ public Constant visitConstant(JimpleParser.ConstantContext ctx) {
return BooleanConstant.getInstance(firstChar == 't' || firstChar == 'T');
} else if (ctx.NULL() != null) {
return NullConstant.getInstance();
- } else if (ctx.methodhandle != null && ctx.method_signature() != null) {
- final MethodSignature methodSignature =
- util.getMethodSignature(ctx.method_signature(), ctx);
- // TODO: [ms] support handles with JFieldRef too
- // FIXME: [ms] update/specify tag when its printed
- // return JavaJimple.getInstance().newMethodHandle( , 0);
- return JavaJimple.getInstance().newMethodHandle(methodSignature, 0);
+ } else if (ctx.methodhandle() != null) {
+ JimpleParser.MethodhandleContext methodhandleContext = ctx.methodhandle();
+ final String kindName = methodhandleContext.STRING_CONSTANT().getText();
+ final SootClassMemberSignature extends SootClassMemberSubSignature>
+ referenceSignature =
+ (methodhandleContext.method_signature() != null)
+ ? util.getMethodSignature(
+ methodhandleContext.method_signature(), methodhandleContext)
+ : util.getFieldSignature(methodhandleContext.field_signature());
+ return JavaJimple.getInstance()
+ .newMethodHandle(
+ referenceSignature,
+ MethodHandle.Kind.getKind(kindName.substring(1, kindName.length() - 1)));
} else if (ctx.methodtype != null && ctx.method_subsignature() != null) {
final JimpleParser.Type_listContext typelist = ctx.method_subsignature().type_list();
final List typeList = util.getTypeList(typelist);
diff --git a/sootup.jimple.parser/src/test/java/resources/jimple/MethodAcceptingLamExpr.jimple b/sootup.jimple.parser/src/test/java/resources/jimple/MethodAcceptingLamExpr.jimple
index edace00f545..e2c37e9db00 100644
--- a/sootup.jimple.parser/src/test/java/resources/jimple/MethodAcceptingLamExpr.jimple
+++ b/sootup.jimple.parser/src/test/java/resources/jimple/MethodAcceptingLamExpr.jimple
@@ -19,7 +19,7 @@ public super class MethodAcceptingLamExpr extends java.lang.Object
l0 := @this: MethodAcceptingLamExpr;
- $stack2 = dynamicinvoke "calcPercentage" () (methodtype: double __METHODTYPE__(double), handle: , methodtype: double __METHODTYPE__(double));
+ $stack2 = dynamicinvoke "calcPercentage" () (methodtype: double __METHODTYPE__(double), methodhandle: "REF_INVOKE_STATIC" , methodtype: double __METHODTYPE__(double));
l1 = $stack2;
diff --git a/sootup.jimple.parser/src/test/java/resources/jimple/MethodReference.jimple b/sootup.jimple.parser/src/test/java/resources/jimple/MethodReference.jimple
index e433a96e522..33aeb4fc0ff 100644
--- a/sootup.jimple.parser/src/test/java/resources/jimple/MethodReference.jimple
+++ b/sootup.jimple.parser/src/test/java/resources/jimple/MethodReference.jimple
@@ -41,7 +41,7 @@ public super class MethodReference extends java.lang.Object
$stack4 = staticinvoke (l1);
- $stack5 = dynamicinvoke "display" (l1) (methodtype: void __METHODTYPE__(), handle: , methodtype: void __METHODTYPE__());
+ $stack5 = dynamicinvoke "display" (l1) (methodtype: void __METHODTYPE__(), methodhandle: "REF_INVOKE_VIRTUAL" , methodtype: void __METHODTYPE__());
l2 = $stack5;
diff --git a/sootup.jimple.parser/src/test/java/sootup/jimple/parser/javatestsuite/java8/MethodAcceptingLamExprTest.java b/sootup.jimple.parser/src/test/java/sootup/jimple/parser/javatestsuite/java8/MethodAcceptingLamExprTest.java
index 3710d168925..fd4e0f5269d 100644
--- a/sootup.jimple.parser/src/test/java/sootup/jimple/parser/javatestsuite/java8/MethodAcceptingLamExprTest.java
+++ b/sootup.jimple.parser/src/test/java/sootup/jimple/parser/javatestsuite/java8/MethodAcceptingLamExprTest.java
@@ -30,7 +30,7 @@ public void test() {
public List expectedBodyStmts() {
return Stream.of(
"l0 := @this: MethodAcceptingLamExpr",
- "$stack2 = dynamicinvoke \"calcPercentage\" () (methodtype: double __METHODTYPE__(double), handle: , methodtype: double __METHODTYPE__(double))",
+ "$stack2 = dynamicinvoke \"calcPercentage\" () (methodtype: double __METHODTYPE__(double), methodhandle: \"REF_INVOKE_STATIC\" , methodtype: double __METHODTYPE__(double))",
"l1 = $stack2",
"$stack4 = ",
"$stack3 = new java.lang.StringBuilder",
From 859304efe89dd3541453fb0f17646605cff50cd2 Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Mon, 14 Aug 2023 18:29:39 +0200
Subject: [PATCH 08/36] Adapted bytecode testcases to new methodhandle
serialization
---
.../minimaltestsuite/java11/TypeInferenceLambdaTest.java | 2 +-
.../minimaltestsuite/java8/MethodAcceptingLamExprTest.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java11/TypeInferenceLambdaTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java11/TypeInferenceLambdaTest.java
index f640bfc4714..454822e66e8 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java11/TypeInferenceLambdaTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java11/TypeInferenceLambdaTest.java
@@ -33,7 +33,7 @@ public MethodSignature getMethodSignature() {
public List expectedBodyStmts() {
return Stream.of(
"l0 := @this: TypeInferenceLambda",
- "l1 = dynamicinvoke \"apply\" () (methodtype: java.lang.Object __METHODTYPE__(java.lang.Object,java.lang.Object), handle: , methodtype: java.lang.Integer __METHODTYPE__(java.lang.Integer,java.lang.Integer))",
+ "l1 = dynamicinvoke \"apply\" () (methodtype: java.lang.Object __METHODTYPE__(java.lang.Object,java.lang.Object), methodhandle: \"REF_INVOKE_STATIC\" , methodtype: java.lang.Integer __METHODTYPE__(java.lang.Integer,java.lang.Integer))",
"$stack4 = staticinvoke (2)",
"$stack3 = staticinvoke (3)",
"$stack5 = interfaceinvoke l1.($stack4, $stack3)",
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java8/MethodAcceptingLamExprTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java8/MethodAcceptingLamExprTest.java
index 9042cd14b7d..7901fb7612d 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java8/MethodAcceptingLamExprTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java8/MethodAcceptingLamExprTest.java
@@ -43,7 +43,7 @@ public void test() {
public List expectedBodyStmts() {
return Stream.of(
"l0 := @this: MethodAcceptingLamExpr",
- "l1 = dynamicinvoke \"calcPercentage\" () (methodtype: double __METHODTYPE__(double), handle: , methodtype: double __METHODTYPE__(double))",
+ "l1 = dynamicinvoke \"calcPercentage\" () (methodtype: double __METHODTYPE__(double), methodhandle: \"REF_INVOKE_STATIC\" , methodtype: double __METHODTYPE__(double))",
"$stack3 = ",
"$stack2 = new java.lang.StringBuilder",
"specialinvoke $stack2.()>()",
From d13cc919a98e9f5be31b31546f3ede075cabfadf Mon Sep 17 00:00:00 2001
From: Markus Schmidt
Date: Mon, 14 Aug 2023 22:42:50 +0200
Subject: [PATCH 09/36] fix annotations
---
.../src/test/java/sootup/java/bytecode/Soot1577.java | 7 ++++++-
.../src/test/java/sootup/java/bytecode/Soot1580.java | 3 +++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/Soot1577.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/Soot1577.java
index 5e76875a2fa..56bb29a92d2 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/Soot1577.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/Soot1577.java
@@ -1,7 +1,10 @@
package sootup.java.bytecode;
+import categories.Java8Test;
import org.junit.Assert;
+import org.junit.Ignore;
import org.junit.Test;
+import org.junit.experimental.categories.Category;
import sootup.core.inputlocation.AnalysisInputLocation;
import sootup.core.model.SootMethod;
import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation;
@@ -10,16 +13,18 @@
import sootup.java.core.language.JavaLanguage;
import sootup.java.core.views.JavaView;
+@Category(Java8Test.class)
public class Soot1577 {
final String directory = "../shared-test-resources/soot-1577/";
@Test
+ @Ignore("conversion fails - could be a dex2jar conversion problem")
public void test() {
AnalysisInputLocation inputLocation =
new JavaClassPathAnalysisInputLocation(directory);
JavaProject project =
- JavaProject.builder(new JavaLanguage(7)).addInputLocation(inputLocation).build();
+ JavaProject.builder(new JavaLanguage(8)).addInputLocation(inputLocation).build();
JavaView view = project.createView();
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/Soot1580.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/Soot1580.java
index 9cecd0aa910..0d5555d72ec 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/Soot1580.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/Soot1580.java
@@ -1,9 +1,11 @@
package sootup.java.bytecode;
+import categories.Java8Test;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.Assert;
import org.junit.Test;
+import org.junit.experimental.categories.Category;
import sootup.core.inputlocation.AnalysisInputLocation;
import sootup.core.model.SootMethod;
import sootup.core.types.ClassType;
@@ -15,6 +17,7 @@
import sootup.java.core.language.JavaLanguage;
import sootup.java.core.views.JavaView;
+@Category(Java8Test.class)
public class Soot1580 {
final Path jar = Paths.get("../shared-test-resources/soot-1580/jpush-android_v3.0.5.jar");
From 03b20238b96fafa5b7f4c09a2ec6583239165e4f Mon Sep 17 00:00:00 2001
From: Markus Schmidt
Date: Mon, 14 Aug 2023 22:44:20 +0200
Subject: [PATCH 10/36] add proposed indy testcase - rhs is null
---
shared-test-resources/bugfixes/Indy.java | 15 ++++++++++
.../core/jimple/common/stmt/JAssignStmt.java | 4 ++-
.../java/sootup/java/bytecode/IndyTests.java | 30 +++++++++++++++++++
3 files changed, 48 insertions(+), 1 deletion(-)
create mode 100644 shared-test-resources/bugfixes/Indy.java
create mode 100644 sootup.java.bytecode/src/test/java/sootup/java/bytecode/IndyTests.java
diff --git a/shared-test-resources/bugfixes/Indy.java b/shared-test-resources/bugfixes/Indy.java
new file mode 100644
index 00000000000..800203ab873
--- /dev/null
+++ b/shared-test-resources/bugfixes/Indy.java
@@ -0,0 +1,15 @@
+import java.time.LocalDate;
+import java.time.Period;
+import java.util.stream.LongStream;
+import java.util.stream.Stream;
+class Indy{
+ public Stream test(LocalDate endExclusive, Period step) {
+ long months = step.toTotalMonths();
+ long days = step.getDays();
+ int sign = months > 0 || days > 0 ? 1 : -1;
+ long steps = 200000 / (months + days);
+ return LongStream.rangeClosed(0, steps).mapToObj(
+ n -> endExclusive.plusDays(days * n));
+ }
+
+}
\ No newline at end of file
diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java
index 389f13edb12..01e871d4abe 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java
@@ -53,7 +53,9 @@ public JAssignStmt(
}
if (!validateValue(rValue)) {
throw new RuntimeException(
- "Illegal Assignment statement. Make sure that right hand side has a valid operand.");
+ "Illegal Assignment statement. Make sure that right hand side ("
+ + rValue
+ + ") has a valid operand.");
}
}
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/IndyTests.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/IndyTests.java
new file mode 100644
index 00000000000..f1ced45cb93
--- /dev/null
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/IndyTests.java
@@ -0,0 +1,30 @@
+package sootup.java.bytecode;
+
+import org.junit.Assert;
+import org.junit.Test;
+import sootup.core.inputlocation.AnalysisInputLocation;
+import sootup.core.model.SootMethod;
+import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation;
+import sootup.java.core.JavaProject;
+import sootup.java.core.JavaSootClass;
+import sootup.java.core.language.JavaLanguage;
+import sootup.java.core.views.JavaView;
+
+/** InvokeDynamics and the Operand stack.. */
+public class IndyTests {
+ final String directory = "../shared-test-resources/misc/";
+
+ @Test
+ public void test() {
+ AnalysisInputLocation inputLocation =
+ new JavaClassPathAnalysisInputLocation(directory);
+
+ JavaProject project =
+ JavaProject.builder(new JavaLanguage(8)).addInputLocation(inputLocation).build();
+
+ JavaView view = project.createView();
+ Assert.assertEquals(1, view.getClasses().size());
+
+ view.getClasses().stream().findFirst().get().getMethods().forEach(SootMethod::getBody);
+ }
+}
From 6bf2fb7ae0dc0d936c6075c03164347b8cd058d2 Mon Sep 17 00:00:00 2001
From: Markus Schmidt
Date: Mon, 14 Aug 2023 22:54:44 +0200
Subject: [PATCH 11/36] fix errmsg and directory
---
.../main/java/sootup/core/jimple/common/stmt/JAssignStmt.java | 2 +-
.../src/test/java/sootup/java/bytecode/IndyTests.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java
index 01e871d4abe..865223653cb 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java
@@ -55,7 +55,7 @@ public JAssignStmt(
throw new RuntimeException(
"Illegal Assignment statement. Make sure that right hand side ("
+ rValue
- + ") has a valid operand.");
+ + ") is a valid operand.");
}
}
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/IndyTests.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/IndyTests.java
index f1ced45cb93..45fb8cd0e82 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/IndyTests.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/IndyTests.java
@@ -12,7 +12,7 @@
/** InvokeDynamics and the Operand stack.. */
public class IndyTests {
- final String directory = "../shared-test-resources/misc/";
+ final String directory = "../shared-test-resources/bugfixes/";
@Test
public void test() {
From 1472cb74ea15fdd5e7b00888a6a52c9863486fdb Mon Sep 17 00:00:00 2001
From: Markus Schmidt
Date: Tue, 15 Aug 2023 09:24:10 +0200
Subject: [PATCH 12/36] add missing annotation
---
.../src/test/java/sootup/java/bytecode/IndyTests.java | 3 +++
.../minimaltestsuite/java14/SwitchExprWithYieldTest.java | 1 -
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/IndyTests.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/IndyTests.java
index 45fb8cd0e82..c0cc8ba5e63 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/IndyTests.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/IndyTests.java
@@ -1,7 +1,9 @@
package sootup.java.bytecode;
+import categories.Java9Test;
import org.junit.Assert;
import org.junit.Test;
+import org.junit.experimental.categories.Category;
import sootup.core.inputlocation.AnalysisInputLocation;
import sootup.core.model.SootMethod;
import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation;
@@ -11,6 +13,7 @@
import sootup.java.core.views.JavaView;
/** InvokeDynamics and the Operand stack.. */
+@Category(Java9Test.class)
public class IndyTests {
final String directory = "../shared-test-resources/bugfixes/";
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/SwitchExprWithYieldTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/SwitchExprWithYieldTest.java
index a0c7f2a48fe..f03a07a699a 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/SwitchExprWithYieldTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/SwitchExprWithYieldTest.java
@@ -25,7 +25,6 @@ public JavaClassType getDeclaredClassSignature() {
@Override
public MethodSignature getMethodSignature() {
- System.out.println(getDeclaredClassSignature());
return identifierFactory.getMethodSignature(
getDeclaredClassSignature(), "switchSomething", "void", Collections.emptyList());
}
From c4297293b00bd642a8f4fa627c19456c83937ce0 Mon Sep 17 00:00:00 2001
From: Markus Schmidt
Date: Tue, 15 Aug 2023 10:27:28 +0200
Subject: [PATCH 13/36] simplified test input; add missing .class
---
shared-test-resources/bugfixes/Indy.class | Bin 0 -> 1064 bytes
shared-test-resources/bugfixes/Indy.java | 18 +++++++++---------
2 files changed, 9 insertions(+), 9 deletions(-)
create mode 100644 shared-test-resources/bugfixes/Indy.class
diff --git a/shared-test-resources/bugfixes/Indy.class b/shared-test-resources/bugfixes/Indy.class
new file mode 100644
index 0000000000000000000000000000000000000000..1b83ecee8411bf2eeb26e8c39f3437f23313f6e7
GIT binary patch
literal 1064
zcmbVL%Wl&^6g?A%m^cmzg#rzvKuKvHPy@>bkRTEwQc96hy6B2YGA(YLv1N}d<7hFp;%!0Xc^95kKaR$K|23
zGdL1M#gKdIN>@E+FzSuH0xlwN!m?3-%}`0)W952Iq(Z?bPFJdaA~9HQ^p=O*^MscK
z?=KPMB^xD_$;gAio4$z1pJAik=$#=Q#B!)yUuvv(l84isK!jZRVOz5=*|>tM1UTUV
zL#O^vfob?Z6K$Kg#*ppG(Ud+NekQVv}M0T$BD*uL+vT>S9+~k6CkYhZr;TzyX5}EfW~7lT@WI)0*a2urDMq
z+@M>VXZH#!Bx~0#0?-i4trM6GA7QjkQ3OtKIfKt+$Rwe9Wuf00MF
rRdPruE9K_(*BJjTi|FGdj}
literal 0
HcmV?d00001
diff --git a/shared-test-resources/bugfixes/Indy.java b/shared-test-resources/bugfixes/Indy.java
index 800203ab873..2143e237efe 100644
--- a/shared-test-resources/bugfixes/Indy.java
+++ b/shared-test-resources/bugfixes/Indy.java
@@ -1,15 +1,15 @@
import java.time.LocalDate;
import java.time.Period;
-import java.util.stream.LongStream;
import java.util.stream.Stream;
+import java.util.stream.IntStream;
+
+/** conversion failed when there is a merge (here: after the if) and an invokedynamic followed */
class Indy{
- public Stream test(LocalDate endExclusive, Period step) {
- long months = step.toTotalMonths();
- long days = step.getDays();
- int sign = months > 0 || days > 0 ? 1 : -1;
- long steps = 200000 / (months + days);
- return LongStream.rangeClosed(0, steps).mapToObj(
- n -> endExclusive.plusDays(days * n));
+ public IntStream test(IntStream s) {
+ int sign;
+ if (s.isParallel()) {
+ sign = 1;
+ }
+ return s.map(n -> n+42);
}
-
}
\ No newline at end of file
From bc74bf541c3797656d5e75dc77b6dd5248357ece Mon Sep 17 00:00:00 2001
From: Markus Schmidt
Date: Tue, 15 Aug 2023 10:36:20 +0200
Subject: [PATCH 14/36] that input was too simple..
---
shared-test-resources/bugfixes/Indy.class | Bin 1064 -> 1083 bytes
shared-test-resources/bugfixes/Indy.java | 2 ++
2 files changed, 2 insertions(+)
diff --git a/shared-test-resources/bugfixes/Indy.class b/shared-test-resources/bugfixes/Indy.class
index 1b83ecee8411bf2eeb26e8c39f3437f23313f6e7..4e5ccd49f98348a241eed9f6fb7e62fc4b6d4c33 100644
GIT binary patch
delta 110
zcmWN`y%B;?5Jlm$`*7X^Mow1inHy84KK`uXk57IIPBbE$7b4T?dda8Dz5Ws5
B4hjGO
delta 75
zcmdnZv4Uem2eSej10#bZgA|YyXJBBkVqgM71_n{>oeb=Z3^N&+C$DD~72yI4axic*
Ya5G2)rI{HRIVV41)?(zI%+I0&0CvC$JOBUy
diff --git a/shared-test-resources/bugfixes/Indy.java b/shared-test-resources/bugfixes/Indy.java
index 2143e237efe..98441621cd4 100644
--- a/shared-test-resources/bugfixes/Indy.java
+++ b/shared-test-resources/bugfixes/Indy.java
@@ -9,6 +9,8 @@ public IntStream test(IntStream s) {
int sign;
if (s.isParallel()) {
sign = 1;
+ }else{
+ sign = -1;
}
return s.map(n -> n+42);
}
From a12a41dfcd231e4425899433e564b1932620ec59 Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Fri, 18 Aug 2023 12:16:37 +0200
Subject: [PATCH 15/36] fixed extension checking in the analysis location
---
.../java-miniapps/MiniApp.jar | Bin 4316 -> 4475 bytes
.../java-miniapps/src/junkclass | 1 +
.../requires_exports/jar/modb.jar | Bin 1074 -> 1243 bytes
.../requires_exports/src/modb/pkgb/junkclass | 1 +
.../sootup/core/inputlocation/FileType.java | 5 +++
.../main/java/sootup/core/util/PathUtils.java | 2 +-
.../JrtFileSystemAnalysisInputLocation.java | 32 ++++++++----------
.../PathBasedAnalysisInputLocation.java | 12 ++++---
.../AnalysisInputLocationTest.java | 9 ++---
.../PathBasedAnalysisInputLocationTest.java | 8 ++---
10 files changed, 35 insertions(+), 35 deletions(-)
create mode 100644 shared-test-resources/java-miniapps/src/junkclass
create mode 100644 shared-test-resources/jigsaw-examples/requires_exports/src/modb/pkgb/junkclass
diff --git a/shared-test-resources/java-miniapps/MiniApp.jar b/shared-test-resources/java-miniapps/MiniApp.jar
index bb7ebf378d97a9b8379ef5939d265c49e513ea0c..a8f33af1e9217117ca71af9ddf811ca2028775e7 100644
GIT binary patch
delta 189
zcmcbk_*-d1FkcEYiwFY;2M0q=xKKC)65s@~vr6-_lXDV_i+K+@ay1wTFdta|B>VKN
zTL~Kziavd{@>$kXuUKNRr6cD{O8kX}ruMz(qxJcxTwMKzKfs%vLv8yuaYLXfW(=GC
s`6`*b8JR>F5OyJC85lrzAwVD>lFb3$tZX1DZXjI4#K5o|eGoO%W*
diff --git a/shared-test-resources/java-miniapps/src/junkclass b/shared-test-resources/java-miniapps/src/junkclass
new file mode 100644
index 00000000000..e3bc908497b
--- /dev/null
+++ b/shared-test-resources/java-miniapps/src/junkclass
@@ -0,0 +1 @@
+this is a test file to check if it recognized as class
\ No newline at end of file
diff --git a/shared-test-resources/jigsaw-examples/requires_exports/jar/modb.jar b/shared-test-resources/jigsaw-examples/requires_exports/jar/modb.jar
index 3079df5844ceca92eea3e410699dae387217ecba..154aa390259fc423b67199306763c83d9b9c5536 100644
GIT binary patch
delta 322
zcmdnQahr3(Q7$e91`Y;>mPn!S&8rx_8S9x@L>M?YI2dxmg~Az-03VQDke!~SpH-Td
zot%?cT+DmOk*mQ#fce1sC)uZG-AdS)Q1t1mmCv%Cdc_ihEgd;uQsOT(G_~(NAFaKl$`~lwV9BSLQi5miqG6UiOZ03m)*9{>OV
delta 145
zcmcc3xrt-K(TOZ#ljk!X=3!>xVqoB4VAva3;=l2{H{;|a=6ZDz1`!4h4i1KEDW(42
ztv-Tt7#J8X1F;|wBf!DQ3z$R%0=yZSxEK(IOn%EO#WaU;GAE0n+I~g`hJx($Bz-5n
Yb%7
diff --git a/shared-test-resources/jigsaw-examples/requires_exports/src/modb/pkgb/junkclass b/shared-test-resources/jigsaw-examples/requires_exports/src/modb/pkgb/junkclass
new file mode 100644
index 00000000000..e3bc908497b
--- /dev/null
+++ b/shared-test-resources/jigsaw-examples/requires_exports/src/modb/pkgb/junkclass
@@ -0,0 +1 @@
+this is a test file to check if it recognized as class
\ No newline at end of file
diff --git a/sootup.core/src/main/java/sootup/core/inputlocation/FileType.java b/sootup.core/src/main/java/sootup/core/inputlocation/FileType.java
index 06e5f3c9852..67fb9267614 100644
--- a/sootup.core/src/main/java/sootup/core/inputlocation/FileType.java
+++ b/sootup.core/src/main/java/sootup/core/inputlocation/FileType.java
@@ -47,6 +47,11 @@ public enum FileType {
this.extension = fileExtension;
}
+ @Nonnull
+ public String getExtensionWithDot() {
+ return "." + extension;
+ }
+
@Nonnull
public String getExtension() {
return extension;
diff --git a/sootup.core/src/main/java/sootup/core/util/PathUtils.java b/sootup.core/src/main/java/sootup/core/util/PathUtils.java
index 2253e4d7c39..613f2e3088a 100644
--- a/sootup.core/src/main/java/sootup/core/util/PathUtils.java
+++ b/sootup.core/src/main/java/sootup/core/util/PathUtils.java
@@ -60,7 +60,7 @@ public static boolean hasExtension(@Nonnull Path path, @Nonnull Collection> getClassSource(
Path filepath =
theFileSystem.getPath(
klassType.getFullyQualifiedName().replace('.', '/')
- + "."
- + classProvider.getHandledFileType().getExtension());
+ + classProvider.getHandledFileType().getExtensionWithDot());
// parse as module
if (klassType.getPackageName() instanceof ModulePackageName) {
@@ -136,8 +134,7 @@ protected Stream> getClassSourcesInternal(
String moduleInfoFilename =
JavaModuleIdentifierFactory.MODULE_INFO_FILE
- + "."
- + classProvider.getHandledFileType().getExtension();
+ + classProvider.getHandledFileType().getExtensionWithDot();
final Path archiveRoot = theFileSystem.getPath("modules", moduleSignature.getModuleName());
try {
@@ -148,20 +145,19 @@ protected Stream> getClassSourcesInternal(
!Files.isDirectory(filePath)
&& filePath
.toString()
- .endsWith(classProvider.getHandledFileType().getExtension())
+ .endsWith(classProvider.getHandledFileType().getExtensionWithDot())
&& !filePath.toString().endsWith(moduleInfoFilename))
.flatMap(
- p -> {
- return StreamUtils.optionalToStream(
- Optional.of(
- classProvider.createClassSource(
- this,
- p,
- this.fromPath(
- p.subpath(2, p.getNameCount()),
- p.subpath(1, 2),
- identifierFactory))));
- });
+ p ->
+ StreamUtils.optionalToStream(
+ Optional.of(
+ classProvider.createClassSource(
+ this,
+ p,
+ this.fromPath(
+ p.subpath(2, p.getNameCount()),
+ p.subpath(1, 2),
+ identifierFactory)))));
} catch (IOException e) {
throw new ResolveException("Error loading module " + moduleSignature, archiveRoot, e);
}
@@ -246,7 +242,7 @@ public Set getModules(View> view) {
return Collections.unmodifiableSet(moduleInfoMap.keySet());
}
- @Nullable
+ @Nonnull
@Override
public SourceType getSourceType() {
return sourceType;
diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java
index 8c7b8ace543..262fe3cbbbc 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java
@@ -177,8 +177,7 @@ protected Optional extends AbstractClassSource> getClassSourceI
path.getFileSystem()
.getPath(
signature.getFullyQualifiedName().replace('.', '/')
- + "."
- + classProvider.getHandledFileType().getExtension()));
+ + classProvider.getHandledFileType().getExtensionWithDot()));
if (!Files.exists(pathToClass)) {
return Optional.empty();
@@ -653,7 +652,8 @@ protected void extractWarFile(Path warFilePath, final Path destDirectory) {
dest.deleteOnExit();
}
- ZipInputStream zis = new ZipInputStream(new FileInputStream(warFilePath.toString()));
+ ZipInputStream zis =
+ new ZipInputStream(Files.newInputStream(Paths.get(warFilePath.toString())));
ZipEntry zipEntry;
while ((zipEntry = zis.getNextEntry()) != null) {
Path filepath = destDirectory.resolve(zipEntry.getName());
@@ -668,7 +668,8 @@ protected void extractWarFile(Path warFilePath, final Path destDirectory) {
if (file.exists()) {
// compare contents -> does it contain the extracted war already?
int readBytesExistingFile;
- final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
+ final BufferedInputStream bis =
+ new BufferedInputStream(Files.newInputStream(file.toPath()));
byte[] bisBuf = new byte[4096];
while ((readBytesZip = zis.read(incomingValues)) != -1) {
if (extractedSize > maxAllowedBytesToExtract) {
@@ -693,7 +694,8 @@ protected void extractWarFile(Path warFilePath, final Path destDirectory) {
}
} else {
- BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
+ BufferedOutputStream bos =
+ new BufferedOutputStream(Files.newOutputStream(file.toPath()));
while ((readBytesZip = zis.read(incomingValues)) != -1) {
if (extractedSize > maxAllowedBytesToExtract) {
throw new RuntimeException(
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java
index e29df69cd36..dab4fe1236c 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java
@@ -8,10 +8,8 @@
import java.util.Optional;
import sootup.core.IdentifierFactory;
import sootup.core.frontend.AbstractClassSource;
-import sootup.core.frontend.ClassProvider;
import sootup.core.inputlocation.AnalysisInputLocation;
import sootup.core.types.ClassType;
-import sootup.java.bytecode.frontend.AsmJavaClassProvider;
import sootup.java.core.JavaIdentifierFactory;
import sootup.java.core.JavaProject;
import sootup.java.core.JavaSootClass;
@@ -52,19 +50,16 @@ public abstract class AnalysisInputLocationTest {
final Path mmrj = Paths.get("../shared-test-resources/multi-release-jar-modular/mrjar.jar");
final Path apk = Paths.get("../shared-test-resources/apk/SimpleApk.apk");
- private ClassProvider classProvider;
-
protected IdentifierFactory getIdentifierFactory() {
return JavaIdentifierFactory.getInstance();
}
protected void testClassReceival(
- AnalysisInputLocation ns, ClassType sig, int minClassesFound) {
+ AnalysisInputLocation ns, ClassType sig, int classesFound) {
final JavaProject project =
JavaProject.builder(new JavaLanguage(8)).addInputLocation(ns).build();
final JavaView view = project.createView();
- classProvider = new AsmJavaClassProvider(view);
final Optional extends AbstractClassSource> clazzOpt =
ns.getClassSource(sig, view);
@@ -73,6 +68,6 @@ protected void testClassReceival(
final Collection extends AbstractClassSource>> classSources = ns.getClassSources(view);
- assertTrue(classSources.size() >= minClassesFound);
+ assertEquals(classSources.size(), classesFound);
}
}
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java
index 6830c69b2a1..273bd2be66e 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java
@@ -273,7 +273,7 @@ public void testApk() {
PathBasedAnalysisInputLocation.create(apk, null);
final ClassType mainClass =
getIdentifierFactory().getClassType("de.upb.futuresoot.fields.MainActivity");
- testClassReceival(pathBasedNamespace, mainClass, 1);
+ testClassReceival(pathBasedNamespace, mainClass, 1392);
}
@Test
@@ -283,8 +283,8 @@ public void testJar() {
final ClassType class1 = getIdentifierFactory().getClassType("Employee", "ds");
final ClassType mainClass = getIdentifierFactory().getClassType("MiniApp");
- testClassReceival(pathBasedNamespace, class1, 4);
- testClassReceival(pathBasedNamespace, mainClass, 4);
+ testClassReceival(pathBasedNamespace, class1, 6);
+ testClassReceival(pathBasedNamespace, mainClass, 6);
}
@Test
@@ -292,7 +292,7 @@ public void testWar() {
PathBasedAnalysisInputLocation pathBasedNamespace =
PathBasedAnalysisInputLocation.create(war, null);
final ClassType warClass1 = getIdentifierFactory().getClassType("SimpleWarRead");
- testClassReceival(pathBasedNamespace, warClass1, 2);
+ testClassReceival(pathBasedNamespace, warClass1, 19);
}
@Test
From 6b59bbf052505b67e8f9969d945e0f44ada6790c Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Fri, 18 Aug 2023 14:17:57 +0200
Subject: [PATCH 16/36] fixed extension checking in the analysis location and
added handling of source resolve errors
---
.../java-miniapps/MiniApp.jar | Bin 4475 -> 4612 bytes
.../java-miniapps/src/NoClass.class | 1 +
.../wala-tests/FakeJava.java | 1 +
.../sootup/core/frontend/ClassProvider.java | 6 ++--
.../frontend/AsmJavaClassProvider.java | 33 +++++++++++-------
.../JrtFileSystemAnalysisInputLocation.java | 19 +++++-----
.../PathBasedAnalysisInputLocation.java | 5 ++-
.../AnalysisInputLocationTest.java | 14 ++++----
.../PathBasedAnalysisInputLocationTest.java | 13 +++----
.../frontend/WalaJavaClassProvider.java | 4 +--
.../JavaSourcePathAnalysisInputLocation.java | 2 +-
.../frontend/WalaJavaClassProviderTest.java | 14 +++++++-
.../parser/JimpleAnalysisInputLocation.java | 5 ++-
.../jimple/parser/JimpleClassProvider.java | 24 ++++++++++---
.../java/resources/jimple/FakeJimple.jimple | 1 +
.../JimpleAnalysisInputLocationTest.java | 25 +++++++++++++
16 files changed, 115 insertions(+), 52 deletions(-)
create mode 100644 shared-test-resources/java-miniapps/src/NoClass.class
create mode 100644 shared-test-resources/wala-tests/FakeJava.java
create mode 100644 sootup.jimple.parser/src/test/java/resources/jimple/FakeJimple.jimple
diff --git a/shared-test-resources/java-miniapps/MiniApp.jar b/shared-test-resources/java-miniapps/MiniApp.jar
index a8f33af1e9217117ca71af9ddf811ca2028775e7..64f7fb6d76194ce5a8391ea934a2d2577262902d 100644
GIT binary patch
delta 166
zcmeyZ)S|LsH=idniwFY;2M2>|u247w65s{0{qmi25{rxVl0hW*$rCzZ42$;s5o&d5
zeKP0Bqa=m^Z*~s#S@pYxfog>}Z{yp@3v#@_~2&l=%i?
diff --git a/shared-test-resources/java-miniapps/src/NoClass.class b/shared-test-resources/java-miniapps/src/NoClass.class
new file mode 100644
index 00000000000..b8e300dcb2c
--- /dev/null
+++ b/shared-test-resources/java-miniapps/src/NoClass.class
@@ -0,0 +1 @@
+This is not a class
\ No newline at end of file
diff --git a/shared-test-resources/wala-tests/FakeJava.java b/shared-test-resources/wala-tests/FakeJava.java
new file mode 100644
index 00000000000..69d3f89baec
--- /dev/null
+++ b/shared-test-resources/wala-tests/FakeJava.java
@@ -0,0 +1 @@
+This is a fake java file
\ No newline at end of file
diff --git a/sootup.core/src/main/java/sootup/core/frontend/ClassProvider.java b/sootup.core/src/main/java/sootup/core/frontend/ClassProvider.java
index 60f352d9be2..99a67c278f0 100644
--- a/sootup.core/src/main/java/sootup/core/frontend/ClassProvider.java
+++ b/sootup.core/src/main/java/sootup/core/frontend/ClassProvider.java
@@ -22,9 +22,9 @@
*/
import java.nio.file.Path;
+import java.util.Optional;
import sootup.core.inputlocation.AnalysisInputLocation;
import sootup.core.inputlocation.FileType;
-import sootup.core.model.AbstractClass;
import sootup.core.model.SootClass;
import sootup.core.types.ClassType;
@@ -34,9 +34,9 @@
*
* @author Manuel Benz
*/
-public interface ClassProvider>> {
+public interface ClassProvider>> {
- AbstractClassSource createClassSource(
+ Optional> createClassSource(
AnalysisInputLocation extends SootClass>> inputLocation,
Path sourcePath,
ClassType classSignature);
diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java
index b026a595382..e6bb38027a2 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java
@@ -22,15 +22,16 @@
*/
import java.io.IOException;
import java.nio.file.Path;
+import java.util.Optional;
import javax.annotation.Nonnull;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.tree.ClassNode;
-import sootup.core.frontend.AbstractClassSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import sootup.core.frontend.ClassProvider;
-import sootup.core.frontend.ResolveException;
+import sootup.core.frontend.SootClassSource;
import sootup.core.inputlocation.AnalysisInputLocation;
import sootup.core.inputlocation.FileType;
-import sootup.core.jimple.basic.NoPositionInformation;
import sootup.core.model.SootClass;
import sootup.core.types.ClassType;
import sootup.core.views.View;
@@ -44,13 +45,14 @@
public class AsmJavaClassProvider implements ClassProvider {
@Nonnull private final View> view;
+ private static final @Nonnull Logger logger = LoggerFactory.getLogger(AsmJavaClassProvider.class);
public AsmJavaClassProvider(@Nonnull View> view) {
this.view = view;
}
@Override
- public AbstractClassSource createClassSource(
+ public Optional> createClassSource(
AnalysisInputLocation extends SootClass>> analysisInputLocation,
Path sourcePath,
ClassType classType) {
@@ -58,23 +60,30 @@ public AbstractClassSource createClassSource(
try {
AsmUtil.initAsmClassSource(sourcePath, classNode);
- } catch (IOException exception) {
- throw new ResolveException(
- exception.getMessage(), sourcePath, NoPositionInformation.getInstance(), exception);
+ } catch (IOException | IllegalArgumentException exception) {
+ logger.warn(
+ "ASM could not resolve class source of "
+ + classType
+ + " in "
+ + sourcePath
+ + " causing "
+ + exception.getMessage());
+ return Optional.empty();
}
JavaClassType klassType = (JavaClassType) classType;
if (klassType instanceof ModuleJavaClassType
&& klassType.getClassName().equals(JavaModuleIdentifierFactory.MODULE_INFO_FILE)) {
- throw new ResolveException(
- "Can not create ClassSource from a module info descriptor!", sourcePath);
+ logger.warn("Can not create ClassSource from a module info descriptor! path:" + sourcePath);
+ return Optional.empty();
} else {
if (klassType instanceof AnnotationType) {
- return new AsmAnnotationClassSource(
- analysisInputLocation, sourcePath, klassType, classNode);
+ return Optional.of(
+ new AsmAnnotationClassSource(analysisInputLocation, sourcePath, klassType, classNode));
}
- return new AsmClassSource(analysisInputLocation, sourcePath, klassType, classNode);
+ return Optional.of(
+ new AsmClassSource(analysisInputLocation, sourcePath, klassType, classNode));
}
}
diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java
index 80df4e0d727..d3803134f6f 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java
@@ -90,7 +90,7 @@ public Optional extends AbstractClassSource> getClassSource(
"modules", modulePackageSignature.getModuleSignature().getModuleName());
Path foundClass = module.resolve(filepath);
if (Files.isRegularFile(foundClass)) {
- return Optional.of(classProvider.createClassSource(this, foundClass, klassType));
+ return classProvider.createClassSource(this, foundClass, klassType);
} else {
return Optional.empty();
}
@@ -104,7 +104,7 @@ public Optional extends AbstractClassSource> getClassSource(
// check each module folder for the class
Path foundfile = entry.resolve(filepath);
if (Files.isRegularFile(foundfile)) {
- return Optional.of(classProvider.createClassSource(this, foundfile, klassType));
+ return classProvider.createClassSource(this, foundfile, klassType);
}
}
}
@@ -150,14 +150,13 @@ protected Stream> getClassSourcesInternal(
.flatMap(
p ->
StreamUtils.optionalToStream(
- Optional.of(
- classProvider.createClassSource(
- this,
- p,
- this.fromPath(
- p.subpath(2, p.getNameCount()),
- p.subpath(1, 2),
- identifierFactory)))));
+ classProvider.createClassSource(
+ this,
+ p,
+ this.fromPath(
+ p.subpath(2, p.getNameCount()),
+ p.subpath(1, 2),
+ identifierFactory))));
} catch (IOException e) {
throw new ResolveException("Error loading module " + moduleSignature, archiveRoot, e);
}
diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java
index 262fe3cbbbc..9ba65dda6f7 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java
@@ -157,8 +157,7 @@ Collection extends AbstractClassSource> walkDirectory(
.flatMap(
p ->
StreamUtils.optionalToStream(
- Optional.of(
- classProvider.createClassSource(this, p, factory.fromPath(dirPath, p)))))
+ classProvider.createClassSource(this, p, factory.fromPath(dirPath, p))))
.collect(Collectors.toList());
} catch (IOException e) {
@@ -183,7 +182,7 @@ protected Optional extends AbstractClassSource> getClassSourceI
return Optional.empty();
}
- return Optional.of(classProvider.createClassSource(this, pathToClass, signature));
+ return classProvider.createClassSource(this, pathToClass, signature);
}
private static class DirectoryBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation {
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java
index dab4fe1236c..bc1f9b0ae1e 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java
@@ -5,6 +5,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
+import java.util.List;
import java.util.Optional;
import sootup.core.IdentifierFactory;
import sootup.core.frontend.AbstractClassSource;
@@ -55,17 +56,18 @@ protected IdentifierFactory getIdentifierFactory() {
}
protected void testClassReceival(
- AnalysisInputLocation ns, ClassType sig, int classesFound) {
+ AnalysisInputLocation ns, List sigs, int classesFound) {
final JavaProject project =
JavaProject.builder(new JavaLanguage(8)).addInputLocation(ns).build();
final JavaView view = project.createView();
- final Optional extends AbstractClassSource> clazzOpt =
- ns.getClassSource(sig, view);
- assertTrue(clazzOpt.isPresent());
- assertEquals(sig, clazzOpt.get().getClassType());
-
+ for (ClassType classType:sigs) {
+ final Optional extends AbstractClassSource> clazzOpt =
+ ns.getClassSource(classType, view);
+ assertTrue(clazzOpt.isPresent());
+ assertEquals(classType, clazzOpt.get().getClassType());
+ }
final Collection extends AbstractClassSource>> classSources = ns.getClassSources(view);
assertEquals(classSources.size(), classesFound);
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java
index 273bd2be66e..33f4c877747 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java
@@ -29,6 +29,7 @@
import categories.Java8Test;
import java.io.File;
import java.nio.file.Paths;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
@@ -273,7 +274,7 @@ public void testApk() {
PathBasedAnalysisInputLocation.create(apk, null);
final ClassType mainClass =
getIdentifierFactory().getClassType("de.upb.futuresoot.fields.MainActivity");
- testClassReceival(pathBasedNamespace, mainClass, 1392);
+ testClassReceival(pathBasedNamespace, Collections.singletonList(mainClass), 1392);
}
@Test
@@ -281,10 +282,10 @@ public void testJar() {
PathBasedAnalysisInputLocation pathBasedNamespace =
PathBasedAnalysisInputLocation.create(jar, null);
- final ClassType class1 = getIdentifierFactory().getClassType("Employee", "ds");
- final ClassType mainClass = getIdentifierFactory().getClassType("MiniApp");
- testClassReceival(pathBasedNamespace, class1, 6);
- testClassReceival(pathBasedNamespace, mainClass, 6);
+ ArrayList sigs=new ArrayList<>();
+ sigs.add(getIdentifierFactory().getClassType("Employee", "ds"));
+ sigs.add(getIdentifierFactory().getClassType("MiniApp"));
+ testClassReceival(pathBasedNamespace, sigs, 6);
}
@Test
@@ -292,7 +293,7 @@ public void testWar() {
PathBasedAnalysisInputLocation pathBasedNamespace =
PathBasedAnalysisInputLocation.create(war, null);
final ClassType warClass1 = getIdentifierFactory().getClassType("SimpleWarRead");
- testClassReceival(pathBasedNamespace, warClass1, 19);
+ testClassReceival(pathBasedNamespace, Collections.singletonList(warClass1), 19);
}
@Test
diff --git a/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaJavaClassProvider.java b/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaJavaClassProvider.java
index 7f43e7a72a9..e241bb39334 100644
--- a/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaJavaClassProvider.java
+++ b/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaJavaClassProvider.java
@@ -347,9 +347,9 @@ private void setExclusions(@Nullable String exclusionFilePath) {
}
@Override
- public SootClassSource createClassSource(
+ public Optional> createClassSource(
AnalysisInputLocation extends SootClass>> srcNamespace, Path sourcePath, ClassType type) {
- return getClassSource(type).orElse(null);
+ return getClassSource(type);
}
@Override
diff --git a/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/inputlocation/JavaSourcePathAnalysisInputLocation.java b/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/inputlocation/JavaSourcePathAnalysisInputLocation.java
index 4876bed564c..7fd91ca9cfd 100644
--- a/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/inputlocation/JavaSourcePathAnalysisInputLocation.java
+++ b/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/inputlocation/JavaSourcePathAnalysisInputLocation.java
@@ -159,7 +159,7 @@ public Optional extends AbstractClassSource> getClassSource(
@Nonnull ClassType type, @Nonnull View> view) {
for (String path : sourcePaths) {
try {
- return Optional.ofNullable(classProvider.createClassSource(this, Paths.get(path), type));
+ return classProvider.createClassSource(this, Paths.get(path), type);
} catch (ResolveException e) {
log.debug(type + " not found in sourcePath " + path, e);
}
diff --git a/sootup.java.sourcecode/src/test/java/sootup/java/sourcecode/frontend/WalaJavaClassProviderTest.java b/sootup.java.sourcecode/src/test/java/sootup/java/sourcecode/frontend/WalaJavaClassProviderTest.java
index ae1887fb03f..ca29d2cc1b8 100644
--- a/sootup.java.sourcecode/src/test/java/sootup/java/sourcecode/frontend/WalaJavaClassProviderTest.java
+++ b/sootup.java.sourcecode/src/test/java/sootup/java/sourcecode/frontend/WalaJavaClassProviderTest.java
@@ -1,15 +1,19 @@
package sootup.java.sourcecode.frontend;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import categories.Java8Test;
import java.nio.file.Paths;
+import java.util.Optional;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import sootup.core.frontend.SootClassSource;
import sootup.core.signatures.PackageName;
import sootup.core.util.ImmutableUtils;
+import sootup.java.core.JavaSootClass;
import sootup.java.core.types.JavaClassType;
import sootup.java.sourcecode.inputlocation.JavaSourcePathAnalysisInputLocation;
@@ -26,10 +30,18 @@ public void testCreateClassSource() {
new JavaSourcePathAnalysisInputLocation(
ImmutableUtils.immutableSet(srcDir), exclusionFilePath);
JavaClassType type = new JavaClassType("Array1", PackageName.DEFAULT_PACKAGE);
+ JavaClassType faketype = new JavaClassType("FakeJava", PackageName.DEFAULT_PACKAGE);
WalaJavaClassProvider provider = new WalaJavaClassProvider(srcDir, exclusionFilePath);
- SootClassSource classSource =
+
+ Optional> opFakeClass =
+ provider.createClassSource(inputLocation, Paths.get(srcDir), faketype);
+ assertFalse(opFakeClass.isPresent());
+
+ Optional> opClass =
provider.createClassSource(inputLocation, Paths.get(srcDir), type);
+ assertTrue(opClass.isPresent());
+ SootClassSource classSource = opClass.get();
assertEquals(type, classSource.getClassType());
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java
index cc961cb0ea4..6b4c77f9e5b 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java
@@ -85,8 +85,7 @@ List>> walkDirectory(
.flatMap(
p ->
StreamUtils.optionalToStream(
- Optional.of(
- classProvider.createClassSource(this, p, factory.fromPath(dirPath, p)))))
+ classProvider.createClassSource(this, p, factory.fromPath(dirPath, p))))
.collect(Collectors.toList());
} catch (IOException e) {
@@ -126,7 +125,7 @@ public Optional extends SootClassSource> getClassSource(
}
}
- return Optional.of(classProvider.createClassSource(this, pathToClass, type));
+ return classProvider.createClassSource(this, pathToClass, type);
}
@Override
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleClassProvider.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleClassProvider.java
index 1f50f58fc94..ea0ffa2c960 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleClassProvider.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleClassProvider.java
@@ -3,9 +3,13 @@
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
+import java.util.Optional;
import javax.annotation.Nonnull;
import org.antlr.v4.runtime.CharStreams;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import sootup.core.frontend.ClassProvider;
+import sootup.core.frontend.ResolveException;
import sootup.core.frontend.SootClassSource;
import sootup.core.inputlocation.AnalysisInputLocation;
import sootup.core.inputlocation.FileType;
@@ -19,22 +23,32 @@ public class JimpleClassProvider bodyInterceptors;
+ private static final @Nonnull Logger logger = LoggerFactory.getLogger(JimpleClassProvider.class);
+
public JimpleClassProvider(List bodyInterceptors) {
this.bodyInterceptors = bodyInterceptors;
}
@Override
- public SootClassSource createClassSource(
+ public Optional> createClassSource(
AnalysisInputLocation extends SootClass>> inputlocation,
Path sourcePath,
ClassType classSignature) {
try {
final JimpleConverter jimpleConverter = new JimpleConverter();
- return jimpleConverter.run(
- CharStreams.fromPath(sourcePath), inputlocation, sourcePath, bodyInterceptors);
- } catch (IOException e) {
- throw new RuntimeException(e);
+ return Optional.of(
+ jimpleConverter.run(
+ CharStreams.fromPath(sourcePath), inputlocation, sourcePath, bodyInterceptors));
+ } catch (IOException | ResolveException e) {
+ logger.warn(
+ "The jimple file of "
+ + classSignature
+ + " in path: "
+ + sourcePath
+ + " could not be converted because of: "
+ + e.getMessage());
+ return Optional.empty();
}
}
diff --git a/sootup.jimple.parser/src/test/java/resources/jimple/FakeJimple.jimple b/sootup.jimple.parser/src/test/java/resources/jimple/FakeJimple.jimple
new file mode 100644
index 00000000000..e320f3f2c48
--- /dev/null
+++ b/sootup.jimple.parser/src/test/java/resources/jimple/FakeJimple.jimple
@@ -0,0 +1 @@
+This is not a correct jimple file
\ No newline at end of file
diff --git a/sootup.jimple.parser/src/test/java/sootup/jimple/parser/JimpleAnalysisInputLocationTest.java b/sootup.jimple.parser/src/test/java/sootup/jimple/parser/JimpleAnalysisInputLocationTest.java
index a05bc8bd7ad..ce86f569cb0 100644
--- a/sootup.jimple.parser/src/test/java/sootup/jimple/parser/JimpleAnalysisInputLocationTest.java
+++ b/sootup.jimple.parser/src/test/java/sootup/jimple/parser/JimpleAnalysisInputLocationTest.java
@@ -69,6 +69,29 @@ public PackageName getPackageName() {
}
};
+ final ClassType classTypeFake =
+ new ClassType() {
+ @Override
+ public boolean isBuiltInClass() {
+ return false;
+ }
+
+ @Override
+ public String getFullyQualifiedName() {
+ return "jimple.FakeJimple";
+ }
+
+ @Override
+ public String getClassName() {
+ return "FakeJimple";
+ }
+
+ @Override
+ public PackageName getPackageName() {
+ return new PackageName("jimple");
+ }
+ };
+
final String resourceDir = "src/test/java/resources/";
// files direct in dir
@@ -79,6 +102,8 @@ public PackageName getPackageName() {
assertTrue(classSource1.isPresent());
final Optional> classSource2 = jv1.getClass(classType);
assertFalse(classSource2.isPresent());
+ final Optional> classSourceNon = jv1.getClass(classTypeFake);
+ assertFalse(classSourceNon.isPresent());
// files in subdir structure
final JimpleAnalysisInputLocation inputLocation2 =
From aab87242fa1cee1b2a8776d6c0a79e246a5c602a Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Fri, 18 Aug 2023 14:18:30 +0200
Subject: [PATCH 17/36] fmt
---
.../java/bytecode/inputlocation/AnalysisInputLocationTest.java | 2 +-
.../inputlocation/PathBasedAnalysisInputLocationTest.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java
index bc1f9b0ae1e..c740571158b 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java
@@ -62,7 +62,7 @@ protected void testClassReceival(
JavaProject.builder(new JavaLanguage(8)).addInputLocation(ns).build();
final JavaView view = project.createView();
- for (ClassType classType:sigs) {
+ for (ClassType classType : sigs) {
final Optional extends AbstractClassSource> clazzOpt =
ns.getClassSource(classType, view);
assertTrue(clazzOpt.isPresent());
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java
index 33f4c877747..b60892e6002 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java
@@ -282,7 +282,7 @@ public void testJar() {
PathBasedAnalysisInputLocation pathBasedNamespace =
PathBasedAnalysisInputLocation.create(jar, null);
- ArrayList sigs=new ArrayList<>();
+ ArrayList sigs = new ArrayList<>();
sigs.add(getIdentifierFactory().getClassType("Employee", "ds"));
sigs.add(getIdentifierFactory().getClassType("MiniApp"));
testClassReceival(pathBasedNamespace, sigs, 6);
From 95496b3cb45ebb58dd31b6157d45093243667fd8 Mon Sep 17 00:00:00 2001
From: stschott
Date: Fri, 1 Sep 2023 12:24:06 +0200
Subject: [PATCH 18/36] update doc
---
docs/getting-started.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/docs/getting-started.md b/docs/getting-started.md
index 4e5d609bb81..d2b41ac9e60 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -53,6 +53,10 @@ You can use bytecode analysis typically when you do not have access to the sourc
If you have access to the source code, it is also possible to create a project for analyzing source code. Following example shows how to create project for analyzing Java source code.
+!!! info "Experimental"
+
+ The source code frontend is experimental and should only be used for testing purposes. You should compile the code for analysis first and use the bytecode frontend instead.
+
!!! example "Create a project to analyze Java source code"
~~~java
From 51afb96c50832d874e575296b0d51a62924c3bb4 Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Fri, 8 Sep 2023 10:45:13 +0200
Subject: [PATCH 19/36] remove incomplete multi release handling in the class
type generation via a given path
---
.../java/core/JavaIdentifierFactory.java | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)
diff --git a/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java b/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java
index c9742affc49..963179dfd0d 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java
@@ -33,7 +33,6 @@
import javax.annotation.Nonnull;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.ClassUtils;
-import org.apache.commons.lang3.StringUtils;
import sootup.core.IdentifierFactory;
import sootup.core.model.SootClass;
import sootup.core.signatures.FieldSignature;
@@ -234,24 +233,15 @@ public AnnotationType getAnnotationType(final String fullyQualifiedClassName) {
@Override
@Nonnull
public JavaClassType fromPath(@Nonnull final Path rootDirectory, @Nonnull final Path file) {
- String path = file.toString();
- String separator = file.getFileSystem().getSeparator();
-
- // for multi release jars, remove beginning of path
- // /META-INF/versions/15/de/upb...
- // we only want /de/upb...
- if (path.startsWith("/META-INF/")) {
- // start at 4th separator
- int index = StringUtils.ordinalIndexOf(path, separator, 4);
- path = path.substring(index);
- }
final int nameCountBaseDir =
rootDirectory.toString().isEmpty() ? 0 : rootDirectory.getNameCount();
String fullyQualifiedName =
FilenameUtils.removeExtension(
- file.subpath(nameCountBaseDir, file.getNameCount()).toString().replace(separator, "."));
+ file.subpath(nameCountBaseDir, file.getNameCount())
+ .toString()
+ .replace(file.getFileSystem().getSeparator(), "."));
return getClassType(fullyQualifiedName);
}
@@ -524,7 +514,7 @@ public MethodSubSignature parseMethodSubSignature(@Nonnull String subSignature)
return true;
})
- .map(typeName -> getType(typeName))
+ .map(this::getType)
.collect(Collectors.toList());
return getMethodSubSignature(methodName, getType(returnName), argsList);
From 1ec5b1256639b21b4f6249de2918694386723f03 Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Fri, 8 Sep 2023 10:57:35 +0200
Subject: [PATCH 20/36] adapted incompleteSuperclassesOf to the new thrown
exception in the class resolving method
---
.../src/main/java/sootup/core/typehierarchy/TypeHierarchy.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sootup.core/src/main/java/sootup/core/typehierarchy/TypeHierarchy.java b/sootup.core/src/main/java/sootup/core/typehierarchy/TypeHierarchy.java
index 6e70a97ae20..5efed1cff0c 100644
--- a/sootup.core/src/main/java/sootup/core/typehierarchy/TypeHierarchy.java
+++ b/sootup.core/src/main/java/sootup/core/typehierarchy/TypeHierarchy.java
@@ -28,7 +28,6 @@
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import sootup.core.frontend.ResolveException;
import sootup.core.types.*;
import sootup.core.views.View;
@@ -198,7 +197,7 @@ default List incompleteSuperClassesOf(@Nonnull ClassType classType) {
superClasses.add(currentSuperClass);
currentSuperClass = superClassOf(currentSuperClass);
}
- } catch (ResolveException ex) {
+ } catch (IllegalArgumentException ex) {
logger.warn(
"Could not find "
+ (currentSuperClass != null ? currentSuperClass : classType)
From 32f856e4189f79471d1f6b7daa449b0a0f423d3a Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Fri, 8 Sep 2023 11:39:38 +0200
Subject: [PATCH 21/36] added test case for incomplete Superclasses
---
.../IncompleteSuperclassTest.java | 31 +++++++++++++++++++
.../IncompleteSuperclass/SubClassA.java | 3 ++
.../IncompleteSuperclass/SubClassB.java | 3 ++
3 files changed, 37 insertions(+)
create mode 100644 sootup.tests/src/test/java/sootup/tests/typehierarchy/viewtypehierarchytestcase/IncompleteSuperclassTest.java
create mode 100644 sootup.tests/src/test/resources/javatypehierarchy/IncompleteSuperclass/SubClassA.java
create mode 100644 sootup.tests/src/test/resources/javatypehierarchy/IncompleteSuperclass/SubClassB.java
diff --git a/sootup.tests/src/test/java/sootup/tests/typehierarchy/viewtypehierarchytestcase/IncompleteSuperclassTest.java b/sootup.tests/src/test/java/sootup/tests/typehierarchy/viewtypehierarchytestcase/IncompleteSuperclassTest.java
new file mode 100644
index 00000000000..c51a52b0a8f
--- /dev/null
+++ b/sootup.tests/src/test/java/sootup/tests/typehierarchy/viewtypehierarchytestcase/IncompleteSuperclassTest.java
@@ -0,0 +1,31 @@
+package sootup.tests.typehierarchy.viewtypehierarchytestcase;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static sootup.core.util.ImmutableUtils.immutableList;
+
+import categories.Java8Test;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import sootup.core.typehierarchy.ViewTypeHierarchy;
+import sootup.core.types.ClassType;
+import sootup.tests.typehierarchy.JavaTypeHierarchyTestBase;
+
+/** @author Jonas Klauke * */
+@Category(Java8Test.class)
+public class IncompleteSuperclassTest extends JavaTypeHierarchyTestBase {
+ @Test
+ public void method() {
+ ViewTypeHierarchy typeHierarchy =
+ (ViewTypeHierarchy) customTestWatcher.getView().getTypeHierarchy();
+ List superclasses =
+ typeHierarchy.incompleteSuperClassesOf(getClassType("SubClassB"));
+ ClassType object = getClassType("java.lang.Object");
+ ImmutableList expectedSuperClasses =
+ immutableList(getClassType("SubClassA"), object);
+ assertEquals(expectedSuperClasses, superclasses);
+ assertFalse(customTestWatcher.getView().getClass(object).isPresent());
+ }
+}
diff --git a/sootup.tests/src/test/resources/javatypehierarchy/IncompleteSuperclass/SubClassA.java b/sootup.tests/src/test/resources/javatypehierarchy/IncompleteSuperclass/SubClassA.java
new file mode 100644
index 00000000000..b3301dd276e
--- /dev/null
+++ b/sootup.tests/src/test/resources/javatypehierarchy/IncompleteSuperclass/SubClassA.java
@@ -0,0 +1,3 @@
+public class SubClassA {
+
+}
\ No newline at end of file
diff --git a/sootup.tests/src/test/resources/javatypehierarchy/IncompleteSuperclass/SubClassB.java b/sootup.tests/src/test/resources/javatypehierarchy/IncompleteSuperclass/SubClassB.java
new file mode 100644
index 00000000000..d278f9127fc
--- /dev/null
+++ b/sootup.tests/src/test/resources/javatypehierarchy/IncompleteSuperclass/SubClassB.java
@@ -0,0 +1,3 @@
+public class SubClassB extends SubClassA {
+
+}
\ No newline at end of file
From f2e01b2091d5a00dbbc0a4d6c9b20accce6e6b5d Mon Sep 17 00:00:00 2001
From: Stefan Schott <64211065+stschott@users.noreply.github.com>
Date: Thu, 14 Sep 2023 14:28:07 +0200
Subject: [PATCH 22/36] add javadoc link to readme
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 9ba2e4492ff..051d37be1da 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
-# SootUp library ![Java CI with Maven](https://github.com/soot-oss/SootUp/workflows/Java%20CI%20with%20Maven/badge.svg?branch=develop) [![codecov](https://codecov.io/gh/soot-oss/SootUp/branch/develop/graph/badge.svg?token=ELA7U7IAWD)](https://codecov.io/gh/soot-oss/SootUp)
+# SootUp library ![Java CI with Maven](https://github.com/soot-oss/SootUp/workflows/Java%20CI%20with%20Maven/badge.svg?branch=develop) [![codecov](https://codecov.io/gh/soot-oss/SootUp/branch/develop/graph/badge.svg?token=ELA7U7IAWD)](https://codecov.io/gh/soot-oss/SootUp) [![javadoc](https://javadoc.io/badge2/org.soot-oss/sootup.core/javadoc.svg)](https://javadoc.io/doc/org.soot-oss/sootup.core)
This is the home of the **SootUp** project.
A complete overhaul of the good, old static analysis framework [Soot](https://github.com/soot-oss/soot).
From 7047cdfa09c0031d379ecf3a55ceccd5dca065a6 Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Fri, 15 Sep 2023 18:45:36 +0200
Subject: [PATCH 23/36] fixed that nrArgs can be -1 if the while condition is
false but the -- instruction is still performed
---
.../java/sootup/java/bytecode/frontend/AsmMethodSource.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
index 5b43a1771a1..a7ba0680728 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
@@ -1394,7 +1394,8 @@ private void convertInvokeDynamicInsn(@Nonnull InvokeDynamicInsnNode insn) {
oprs = new Operand[nrArgs + 1];
}
if (oprs != null) {
- while (nrArgs-- > 0) {
+ while (nrArgs > 0) {
+ nrArgs--;
oprs[nrArgs] = operandStack.pop(types.get(nrArgs));
}
if (!isStaticInvokeExpr) {
From 725710f19c09bf1cf3373207dd349be2bcdc5039 Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Tue, 19 Sep 2023 13:01:47 +0200
Subject: [PATCH 24/36] improved the getting started documentation
---
docs/getting-started.md | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/docs/getting-started.md b/docs/getting-started.md
index d2b41ac9e60..ece9f35b4d7 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -40,10 +40,8 @@ You can use bytecode analysis typically when you do not have access to the sourc
!!! example "Create a project to analyze Java bytecode"
~~~java
- Path pathToBinary = Paths.get("src/test/resources/BasicSetup/binary");
-
AnalysisInputLocation inputLocation =
- PathBasedAnalysisInputLocation.createForClassContainer(pathToBinary);
+ new JavaClassPathAnalysisInputLocation("path2Binary");
JavaLanguage language = new JavaLanguage(8);
@@ -60,10 +58,8 @@ If you have access to the source code, it is also possible to create a project f
!!! example "Create a project to analyze Java source code"
~~~java
- Path pathToSource = Paths.get("src/test/resources/BasicSetup/source");
-
AnalysisInputLocation inputLocation =
- new JavaSourcePathAnalysisInputLocation(pathToSource.toString());
+ new JavaSourcePathAnalysisInputLocation("path2Source");
JavaLanguage language = new JavaLanguage(8);
@@ -76,7 +72,7 @@ If you have a [Jimple](../jimple) file, you can create a project for analyzing j
!!! example "Create a project to analyze jimple code"
~~~java
- Path pathToJimple = Paths.get("src/test/resources/BasicSetup/jimple");
+ Path pathToJimple = Paths.get("path2Jimple");
AnalysisInputLocation inputLocation =
new JimpleAnalysisInputLocation(pathToJimple);
@@ -124,10 +120,13 @@ Let's say the following is the target program that we want to analyze:
}
- public static void main(String[] var0) {
-
- System.out.println("Hello World!");
-
+ public static void main(String[] args) {
+ HelloWorld hw = new HelloWorld;
+ hw.hello();
+ }
+
+ public void hello() {
+
}
}
@@ -213,9 +212,8 @@ Below we show a comparison of the code so far with the same functionality in soo
=== "SootUp"
``` java
- Path pathToBinary = Paths.get("src/test/resources/BasicSetup/binary");
AnalysisInputLocation inputLocation =
- PathBasedAnalysisInputLocation.createForClassContainer(pathToBinary);
+ new JavaClassPathAnalysisInputLocation("path2Binary");
JavaLanguage language = new JavaLanguage(8);
From 9343413bb5121d57f4ea03cda209e3ad0e20b81a Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Tue, 19 Sep 2023 13:05:20 +0200
Subject: [PATCH 25/36] fixed example
---
docs/getting-started.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/getting-started.md b/docs/getting-started.md
index ece9f35b4d7..d913d88bd55 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -121,7 +121,7 @@ Let's say the following is the target program that we want to analyze:
}
public static void main(String[] args) {
- HelloWorld hw = new HelloWorld;
+ HelloWorld hw = new HelloWorld();
hw.hello();
}
From e5086703a4f8b6244cf001e8885f1cc435f3a500 Mon Sep 17 00:00:00 2001
From: liyiwei <979621500@qq.com>
Date: Mon, 9 Oct 2023 21:36:02 +0800
Subject: [PATCH 26/36] format
---
.../core/typehierarchy/MethodDispatchResolver.java | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java b/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
index 16c604ceb09..80cd7734ac9 100644
--- a/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
+++ b/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
@@ -22,12 +22,6 @@
*/
import com.google.common.collect.Sets;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
import sootup.core.frontend.ResolveException;
import sootup.core.jimple.common.expr.JSpecialInvokeExpr;
import sootup.core.model.Method;
@@ -37,6 +31,13 @@
import sootup.core.types.ClassType;
import sootup.core.views.View;
+import javax.annotation.Nonnull;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
public final class MethodDispatchResolver {
private MethodDispatchResolver() {}
From e4e5d762e62d5b67e0bb3a22e66638c81a4960da Mon Sep 17 00:00:00 2001
From: liyiwei <979621500@qq.com>
Date: Mon, 9 Oct 2023 21:41:13 +0800
Subject: [PATCH 27/36] inline findConcreteMethodInSootClass with
sootClass.getMethod
---
.../typehierarchy/MethodDispatchResolver.java | 31 +++----------------
1 file changed, 4 insertions(+), 27 deletions(-)
diff --git a/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java b/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
index 80cd7734ac9..2b168fcef17 100644
--- a/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
+++ b/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
@@ -86,7 +86,7 @@ public static Set resolveAbstractDispatch(
() ->
new ResolveException(
"Could not resolve " + subtype + ", but found it in hierarchy.")))
- .map(sootClass -> findConcreteMethodInSootClass(sootClass, m))
+ .map(sootClass -> sootClass.getMethod(m.getSubSignature()))
.filter(Optional::isPresent)
.map(Optional::get)
.filter(method -> !method.isAbstract())
@@ -112,7 +112,7 @@ public static Set resolveAllDispatchesInClasses(
new ResolveException(
"Could not resolve " + subtype + ", but found it in hierarchy.")))
.filter(c -> classes.contains(c.getType()))
- .map(sootClass -> findConcreteMethodInSootClass(sootClass, m))
+ .map(sootClass -> sootClass.getMethod(m.getSubSignature()))
.filter(Optional::isPresent)
.map(Optional::get)
.filter(method -> !method.isAbstract())
@@ -198,7 +198,7 @@ public static Optional resolveConcreteDispatch(
classesInHierachyOrder.add(superClass);
- SootMethod concreteMethod = findConcreteMethodInSootClass(superClass, m).orElse(null);
+ SootMethod concreteMethod = superClass.getMethod(m.getSubSignature()).orElse(null);
if (concreteMethod != null && !concreteMethod.isAbstract()) {
// found method is not abstract
return Optional.of(concreteMethod.getSignature());
@@ -234,7 +234,7 @@ public static Optional resolveConcreteDispatch(
// add found default method to possibleDefaultMethods
Optional extends SootMethod> concreteMethod =
- findConcreteMethodInSootClass(currentInterface, m);
+ currentInterface.getMethod(m.getSubSignature());
concreteMethod.ifPresent(possibleDefaultMethods::add);
// if no default message is found search the default message in super interfaces
@@ -283,29 +283,6 @@ private static List> getSootClassesOfInterfaces(
.collect(Collectors.toList());
}
- /**
- * finds the concrete method in a SootClass
- *
- * this method returns the concrete method of given method signature in a SootClass. Due to
- * covariant, the given method signature can differ from the concrete method at the return type
- * The method goes through all methods of the given SootClass and searches for a method which can
- * dispatch.
- *
- * @param sootClass The method is searched in this SootClass
- * @param methodSignature the signature of the searched method
- * @return an Optional Object that can contain the found concrete method in the given SootClass
- */
- private static Optional extends SootMethod> findConcreteMethodInSootClass(
- SootClass> sootClass, MethodSignature methodSignature) {
- return sootClass.getMethods().stream()
- .filter(
- potentialTarget ->
- methodSignature
- .getSubSignature()
- .equals(potentialTarget.getSignature().getSubSignature()))
- .findAny();
- }
-
/**
* Resolves the actual method called by the specialInvokeExpr
that is contained by
* container
.
From 7ba783f2bb928d32801f37f43c56f6507b0b44cc Mon Sep 17 00:00:00 2001
From: liyiwei <979621500@qq.com>
Date: Mon, 9 Oct 2023 21:41:52 +0800
Subject: [PATCH 28/36] typo cleanup
---
.../sootup/core/typehierarchy/MethodDispatchResolver.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java b/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
index 2b168fcef17..e6bf587f51f 100644
--- a/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
+++ b/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
@@ -184,7 +184,7 @@ public static Optional resolveConcreteDispatch(
TypeHierarchy hierarchy = view.getTypeHierarchy();
ClassType superClassType = m.getDeclClassType();
SootClass> startClass = view.getClass(superClassType).orElse(null);
- ArrayList> classesInHierachyOrder = new ArrayList<>();
+ ArrayList> classesInHierarchyOrder = new ArrayList<>();
// search concrete method in the class itself and its super classes
do {
@@ -196,7 +196,7 @@ public static Optional resolveConcreteDispatch(
new ResolveException(
"Did not find class " + finalSuperClassType + " in View"));
- classesInHierachyOrder.add(superClass);
+ classesInHierarchyOrder.add(superClass);
SootMethod concreteMethod = superClass.getMethod(m.getSubSignature()).orElse(null);
if (concreteMethod != null && !concreteMethod.isAbstract()) {
@@ -209,7 +209,7 @@ public static Optional resolveConcreteDispatch(
// A not implemented method of an abstract class results into an abstract method
return Optional.empty();
}
- // found method is abstract and the startclass is not abstract
+ // found method is abstract and the start class is not abstract
throw new ResolveException(
"Could not find concrete method for " + m + " because the method is abstract");
}
@@ -220,7 +220,7 @@ public static Optional resolveConcreteDispatch(
// No super class contains the implemented method, search the concrete method in interfaces
// first collect all interfaces and super interfaces
List> worklist =
- classesInHierachyOrder.stream()
+ classesInHierarchyOrder.stream()
.flatMap(sootClass -> getSootClassesOfInterfaces(view, sootClass).stream())
.collect(Collectors.toList());
ArrayList> processedInterface = new ArrayList<>();
From fc3bd0df7a175b5bb9e684c1892aabb82f96c571 Mon Sep 17 00:00:00 2001
From: liyiwei <979621500@qq.com>
Date: Mon, 9 Oct 2023 22:37:48 +0800
Subject: [PATCH 29/36] refactor resolveConcreteDispatch
---
.../typehierarchy/MethodDispatchResolver.java | 40 ++++++++++---------
1 file changed, 21 insertions(+), 19 deletions(-)
diff --git a/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java b/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
index e6bf587f51f..56f17a25832 100644
--- a/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
+++ b/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
@@ -37,6 +37,7 @@
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
public final class MethodDispatchResolver {
private MethodDispatchResolver() {}
@@ -173,6 +174,19 @@ public static boolean canDispatch(
|| hierarchy.isSubtype(called.getType(), potentialTarget.getType())); // covariant
}
+ /**
+ * Returns all superclasses of classType
(inclusive) up to java.lang.Object
, which
+ * will be the last entry in the list, or till one of the superclasses is not contained in view.
+ */
+ private static List> findSuperClassesInclusive(
+ View extends SootClass>> view, ClassType classType) {
+ return Stream.concat(
+ Stream.of(classType),
+ view.getTypeHierarchy().incompleteSuperClassesOf(classType).stream()
+ ).flatMap(t -> view.getClass(t).map(Stream::of).orElseGet(Stream::empty))
+ .collect(Collectors.toList());
+ }
+
/**
* Searches for the signature of the method that is the concrete implementation of m
.
* This is done by checking each superclass and the class itself for whether it contains the
@@ -182,23 +196,12 @@ public static boolean canDispatch(
public static Optional resolveConcreteDispatch(
View extends SootClass>> view, MethodSignature m) {
TypeHierarchy hierarchy = view.getTypeHierarchy();
- ClassType superClassType = m.getDeclClassType();
- SootClass> startClass = view.getClass(superClassType).orElse(null);
- ArrayList> classesInHierarchyOrder = new ArrayList<>();
-
- // search concrete method in the class itself and its super classes
- do {
- ClassType finalSuperClassType = superClassType;
- SootClass> superClass =
- view.getClass(superClassType)
- .orElseThrow(
- () ->
- new ResolveException(
- "Did not find class " + finalSuperClassType + " in View"));
+ ClassType current = m.getDeclClassType();
+ SootClass> startClass = view.getClass(current).orElse(null);
+ List> classesInHierarchyOrder = findSuperClassesInclusive(view, current);
- classesInHierarchyOrder.add(superClass);
-
- SootMethod concreteMethod = superClass.getMethod(m.getSubSignature()).orElse(null);
+ for (SootClass> currentClass : classesInHierarchyOrder) {
+ SootMethod concreteMethod = currentClass.getMethod(m.getSubSignature()).orElse(null);
if (concreteMethod != null && !concreteMethod.isAbstract()) {
// found method is not abstract
return Optional.of(concreteMethod.getSignature());
@@ -209,13 +212,12 @@ public static Optional resolveConcreteDispatch(
// A not implemented method of an abstract class results into an abstract method
return Optional.empty();
}
- // found method is abstract and the start class is not abstract
+ // found method is abstract and the startClass is not abstract
throw new ResolveException(
"Could not find concrete method for " + m + " because the method is abstract");
}
+ }
- superClassType = hierarchy.superClassOf(superClassType);
- } while (superClassType != null);
// No super class contains the implemented method, search the concrete method in interfaces
// first collect all interfaces and super interfaces
From 4705075c2a312e4c9262c16714bd3c5bd249b841 Mon Sep 17 00:00:00 2001
From: liyiwei <979621500@qq.com>
Date: Mon, 9 Oct 2023 23:33:03 +0800
Subject: [PATCH 30/36] format
---
.../typehierarchy/MethodDispatchResolver.java | 39 +++++++++----------
1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java b/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
index 56f17a25832..11f83a7e73e 100644
--- a/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
+++ b/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
@@ -22,6 +22,13 @@
*/
import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.annotation.Nonnull;
import sootup.core.frontend.ResolveException;
import sootup.core.jimple.common.expr.JSpecialInvokeExpr;
import sootup.core.model.Method;
@@ -31,14 +38,6 @@
import sootup.core.types.ClassType;
import sootup.core.views.View;
-import javax.annotation.Nonnull;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
public final class MethodDispatchResolver {
private MethodDispatchResolver() {}
@@ -87,7 +86,7 @@ public static Set resolveAbstractDispatch(
() ->
new ResolveException(
"Could not resolve " + subtype + ", but found it in hierarchy.")))
- .map(sootClass -> sootClass.getMethod(m.getSubSignature()))
+ .map(sootClass -> sootClass.getMethod(m.getSubSignature()))
.filter(Optional::isPresent)
.map(Optional::get)
.filter(method -> !method.isAbstract())
@@ -113,7 +112,7 @@ public static Set resolveAllDispatchesInClasses(
new ResolveException(
"Could not resolve " + subtype + ", but found it in hierarchy.")))
.filter(c -> classes.contains(c.getType()))
- .map(sootClass -> sootClass.getMethod(m.getSubSignature()))
+ .map(sootClass -> sootClass.getMethod(m.getSubSignature()))
.filter(Optional::isPresent)
.map(Optional::get)
.filter(method -> !method.isAbstract())
@@ -175,16 +174,17 @@ public static boolean canDispatch(
}
/**
- * Returns all superclasses of classType
(inclusive) up to java.lang.Object
, which
- * will be the last entry in the list, or till one of the superclasses is not contained in view.
+ * Returns all superclasses of classType
(inclusive) up to java.lang.Object
+ *
, which will be the last entry in the list, or till one of the superclasses is not
+ * contained in view.
*/
private static List> findSuperClassesInclusive(
- View extends SootClass>> view, ClassType classType) {
+ View extends SootClass>> view, ClassType classType) {
return Stream.concat(
- Stream.of(classType),
- view.getTypeHierarchy().incompleteSuperClassesOf(classType).stream()
- ).flatMap(t -> view.getClass(t).map(Stream::of).orElseGet(Stream::empty))
- .collect(Collectors.toList());
+ Stream.of(classType),
+ view.getTypeHierarchy().incompleteSuperClassesOf(classType).stream())
+ .flatMap(t -> view.getClass(t).map(Stream::of).orElseGet(Stream::empty))
+ .collect(Collectors.toList());
}
/**
@@ -218,11 +218,10 @@ public static Optional resolveConcreteDispatch(
}
}
-
// No super class contains the implemented method, search the concrete method in interfaces
// first collect all interfaces and super interfaces
List> worklist =
- classesInHierarchyOrder.stream()
+ classesInHierarchyOrder.stream()
.flatMap(sootClass -> getSootClassesOfInterfaces(view, sootClass).stream())
.collect(Collectors.toList());
ArrayList> processedInterface = new ArrayList<>();
@@ -236,7 +235,7 @@ public static Optional resolveConcreteDispatch(
// add found default method to possibleDefaultMethods
Optional extends SootMethod> concreteMethod =
- currentInterface.getMethod(m.getSubSignature());
+ currentInterface.getMethod(m.getSubSignature());
concreteMethod.ifPresent(possibleDefaultMethods::add);
// if no default message is found search the default message in super interfaces
From 312465ce31605328f3cadc5271107ac40f256742 Mon Sep 17 00:00:00 2001
From: liyiwei <979621500@qq.com>
Date: Tue, 10 Oct 2023 22:47:38 +0800
Subject: [PATCH 31/36] unify conditions
---
.../typehierarchy/MethodDispatchResolver.java | 27 ++++++++++---------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java b/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
index 11f83a7e73e..ff6f94fb36d 100644
--- a/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
+++ b/sootup.core/src/main/java/sootup/core/typehierarchy/MethodDispatchResolver.java
@@ -201,20 +201,21 @@ public static Optional resolveConcreteDispatch(
List> classesInHierarchyOrder = findSuperClassesInclusive(view, current);
for (SootClass> currentClass : classesInHierarchyOrder) {
- SootMethod concreteMethod = currentClass.getMethod(m.getSubSignature()).orElse(null);
- if (concreteMethod != null && !concreteMethod.isAbstract()) {
- // found method is not abstract
- return Optional.of(concreteMethod.getSignature());
- }
- if (concreteMethod != null && concreteMethod.isAbstract()) {
- if (startClass.isAbstract()
- && !startClass.getType().equals(concreteMethod.getDeclaringClassType())) {
- // A not implemented method of an abstract class results into an abstract method
- return Optional.empty();
+ SootMethod method = currentClass.getMethod(m.getSubSignature()).orElse(null);
+ if (method != null) {
+ if (!method.isAbstract()) {
+ // found method is not abstract
+ return Optional.of(method.getSignature());
+ } else {
+ if (startClass.isAbstract()
+ && !startClass.getType().equals(method.getDeclaringClassType())) {
+ // A not implemented method of an abstract class results into an abstract method
+ return Optional.empty();
+ }
+ // found method is abstract and the startClass is not abstract
+ throw new ResolveException(
+ "Could not find concrete method for " + m + " because the method is abstract");
}
- // found method is abstract and the startClass is not abstract
- throw new ResolveException(
- "Could not find concrete method for " + m + " because the method is abstract");
}
}
From ee41bafa92304eb345dc52bb17ae410cd4d40dd4 Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Mon, 16 Oct 2023 18:31:07 +0200
Subject: [PATCH 32/36] removed static invoke handling caused by wrongly
adaption of soot code for SootUp. SootUp does not model lambda expressions as
static method calls.
---
.../java/bytecode/frontend/AsmMethodSource.java | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
index a7ba0680728..857b4d21349 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
@@ -73,7 +73,6 @@
import sootup.core.jimple.common.expr.JInstanceOfExpr;
import sootup.core.jimple.common.expr.JNewArrayExpr;
import sootup.core.jimple.common.expr.JNewMultiArrayExpr;
-import sootup.core.jimple.common.expr.JStaticInvokeExpr;
import sootup.core.jimple.common.ref.*;
import sootup.core.jimple.common.stmt.*;
import sootup.core.jimple.javabytecode.stmt.JSwitchStmt;
@@ -1387,20 +1386,12 @@ private void convertInvokeDynamicInsn(@Nonnull InvokeDynamicInsnNode insn) {
List types = expr.getMethodSignature().getParameterTypes();
Operand[] oprs;
int nrArgs = types.size();
- final boolean isStaticInvokeExpr = expr instanceof JStaticInvokeExpr;
- if (isStaticInvokeExpr) {
- oprs = (nrArgs == 0) ? null : new Operand[nrArgs];
- } else {
- oprs = new Operand[nrArgs + 1];
- }
+ oprs = (nrArgs == 0) ? null : new Operand[nrArgs];
if (oprs != null) {
while (nrArgs > 0) {
nrArgs--;
oprs[nrArgs] = operandStack.pop(types.get(nrArgs));
}
- if (!isStaticInvokeExpr) {
- oprs[oprs.length - 1] = operandStack.pop();
- }
frame.mergeIn(currentLineNumber, oprs);
}
returnType = expr.getType();
From 74da0deb0dc141068fe0bd838d025b66d97bd43c Mon Sep 17 00:00:00 2001
From: liyiwei <979621500@qq.com>
Date: Tue, 17 Oct 2023 00:34:56 +0800
Subject: [PATCH 33/36] clean up assertions
---
.../java/sootup/callgraph/AbstractCallGraphAlgorithm.java | 8 +++++---
.../java/sootup/core/typehierarchy/TypeHierarchy.java | 2 +-
.../src/main/java/sootup/java/core/views/JavaView.java | 6 +-----
3 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/sootup.callgraph/src/main/java/sootup/callgraph/AbstractCallGraphAlgorithm.java b/sootup.callgraph/src/main/java/sootup/callgraph/AbstractCallGraphAlgorithm.java
index eb899f1e0af..0cb5d0c7275 100644
--- a/sootup.callgraph/src/main/java/sootup/callgraph/AbstractCallGraphAlgorithm.java
+++ b/sootup.callgraph/src/main/java/sootup/callgraph/AbstractCallGraphAlgorithm.java
@@ -291,7 +291,7 @@ protected final T findMethodInHierarchy(
if (optSc.isPresent()) {
SootClass> sc = optSc.get();
- List superClasses = view.getTypeHierarchy().superClassesOf(sc.getType());
+ List superClasses = view.getTypeHierarchy().incompleteSuperClassesOf(sc.getType());
Set interfaces = view.getTypeHierarchy().implementedInterfacesOf(sc.getType());
superClasses.addAll(interfaces);
@@ -364,7 +364,7 @@ public CallGraph addClass(@Nonnull CallGraph oldCallGraph, @Nonnull JavaClassTyp
processWorkList(view, workList, processed, updated);
// Step 2: Add edges from old methods to methods overridden in the new class
- List superClasses = view.getTypeHierarchy().superClassesOf(classType);
+ List superClasses = view.getTypeHierarchy().incompleteSuperClassesOf(classType);
Set implementedInterfaces =
view.getTypeHierarchy().implementedInterfacesOf(classType);
Stream superTypes =
@@ -376,7 +376,9 @@ public CallGraph addClass(@Nonnull CallGraph oldCallGraph, @Nonnull JavaClassTyp
.collect(Collectors.toSet());
superTypes
- .map(view::getClassOrThrow)
+ .map(view::getClass)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
.flatMap(superType -> superType.getMethods().stream())
.map(Method::getSignature)
.filter(
diff --git a/sootup.core/src/main/java/sootup/core/typehierarchy/TypeHierarchy.java b/sootup.core/src/main/java/sootup/core/typehierarchy/TypeHierarchy.java
index 5efed1cff0c..5a5b0e1ab59 100644
--- a/sootup.core/src/main/java/sootup/core/typehierarchy/TypeHierarchy.java
+++ b/sootup.core/src/main/java/sootup/core/typehierarchy/TypeHierarchy.java
@@ -154,7 +154,7 @@ default boolean isSubtype(@Nonnull Type supertype, @Nonnull Type potentialSubtyp
return (supertypeName.equals("java.lang.Object")
&& !potentialSubtypeName.equals("java.lang.Object"))
|| supertype.equals(superClassOf((ClassType) potentialSubtype))
- || superClassesOf((ClassType) potentialSubtype).contains(supertype)
+ || incompleteSuperClassesOf((ClassType) potentialSubtype).contains(supertype)
|| implementedInterfacesOf((ClassType) potentialSubtype).contains(supertype);
} else if (potentialSubtype instanceof ArrayType) {
// Arrays are subtypes of java.lang.Object, java.io.Serializable and java.lang.Cloneable
diff --git a/sootup.java.core/src/main/java/sootup/java/core/views/JavaView.java b/sootup.java.core/src/main/java/sootup/java/core/views/JavaView.java
index 682edb9333a..f891055ad5f 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/views/JavaView.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/views/JavaView.java
@@ -130,11 +130,7 @@ public synchronized Optional getClass(@Nonnull ClassType type) {
Optional extends AbstractClassSource extends JavaSootClass>> abstractClass =
getAbstractClass(type);
- if (!abstractClass.isPresent()) {
- return Optional.empty();
- }
-
- return buildClassFrom(abstractClass.get());
+ return abstractClass.flatMap(this::buildClassFrom);
}
/** Returns the amount of classes that are currently stored in the cache. */
From 884c62820ba90381069176975b5dfba68333c975 Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Tue, 17 Oct 2023 17:48:24 +0200
Subject: [PATCH 34/36] removed unnecessary constructor in MethodHandle
---
.../core/jimple/common/constant/MethodHandle.java | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java b/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java
index fd1792c29e4..f26729b0a8c 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java
@@ -94,19 +94,7 @@ public MethodHandle(
@Nonnull SootClassMemberSignature extends SootClassMemberSubSignature> referenceSignature,
int tag,
@Nonnull Type type) {
- this.kind = Kind.getKind(tag);
- this.type = type;
- this.referenceSignature = referenceSignature;
- if ((this.isMethodRef() && !(referenceSignature instanceof MethodSignature))
- || (this.isFieldRef() && !(referenceSignature instanceof FieldSignature))) {
- throw new IllegalArgumentException(
- "Tag:"
- + tag
- + " "
- + kind.valStr
- + " does not match with the given signature:"
- + referenceSignature.getClass());
- }
+ this(referenceSignature, Kind.getKind(tag), type);
}
public MethodHandle(
From 1ed3ab1a3266190027c42bbd59b6495b0a3fda9f Mon Sep 17 00:00:00 2001
From: Jonas Klauke
Date: Tue, 17 Oct 2023 17:48:40 +0200
Subject: [PATCH 35/36] added tests for MethodHandle
---
.../jimple/common/constant/MethodHandle.java | 4 +
.../common/constant/MethodHandleTest.java | 114 ++++++++++++++++++
2 files changed, 118 insertions(+)
create mode 100644 sootup.core/src/test/java/sootup/core/jimple/common/constant/MethodHandleTest.java
diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java b/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java
index f26729b0a8c..8c02e3246f8 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodHandle.java
@@ -148,6 +148,10 @@ public Type getType() {
return type;
}
+ public Kind getKind() {
+ return kind;
+ }
+
public SootClassMemberSignature extends SootClassMemberSubSignature> getReferenceSignature() {
return referenceSignature;
}
diff --git a/sootup.core/src/test/java/sootup/core/jimple/common/constant/MethodHandleTest.java b/sootup.core/src/test/java/sootup/core/jimple/common/constant/MethodHandleTest.java
new file mode 100644
index 00000000000..e6db3b602dd
--- /dev/null
+++ b/sootup.core/src/test/java/sootup/core/jimple/common/constant/MethodHandleTest.java
@@ -0,0 +1,114 @@
+package sootup.core.jimple.common.constant;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThrows;
+
+import categories.Java8Test;
+import java.util.Collections;
+import junit.framework.TestCase;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import sootup.core.jimple.common.constant.MethodHandle.Kind;
+import sootup.core.signatures.FieldSignature;
+import sootup.core.signatures.MethodSignature;
+import sootup.core.signatures.PackageName;
+import sootup.core.types.ClassType;
+import sootup.core.types.PrimitiveType.IntType;
+import sootup.core.types.VoidType;
+
+@Category(Java8Test.class)
+public class MethodHandleTest extends TestCase {
+
+ @Test
+ public void testMethodHandle() {
+ assertEquals(Kind.REF_GET_FIELD.toString(), "REF_GET_FIELD");
+ assertEquals(Kind.REF_GET_FIELD.getValueName(), "REF_GET_FIELD");
+ assertEquals(Kind.REF_GET_FIELD.getValue(), 1);
+
+ for (Kind currentKind : Kind.values()) {
+ assertEquals(currentKind, Kind.getKind(currentKind.getValueName()));
+ assertEquals(currentKind, Kind.getKind(currentKind.getValue()));
+ }
+ // not valid kinds
+ assertThrows(RuntimeException.class, () -> Kind.getKind(0));
+ assertThrows(RuntimeException.class, () -> Kind.getKind("invalid"));
+
+ assertTrue(MethodHandle.isMethodRef(Kind.REF_INVOKE_VIRTUAL.getValue()));
+ assertTrue(MethodHandle.isMethodRef(Kind.REF_INVOKE_STATIC.getValue()));
+ assertTrue(MethodHandle.isMethodRef(Kind.REF_INVOKE_SPECIAL.getValue()));
+ assertTrue(MethodHandle.isMethodRef(Kind.REF_INVOKE_CONSTRUCTOR.getValue()));
+ assertTrue(MethodHandle.isMethodRef(Kind.REF_INVOKE_INTERFACE.getValue()));
+ assertFalse(MethodHandle.isMethodRef(Kind.REF_GET_FIELD.getValue()));
+ assertFalse(MethodHandle.isMethodRef(Kind.REF_PUT_FIELD.getValue()));
+ assertFalse(MethodHandle.isMethodRef(Kind.REF_PUT_FIELD_STATIC.getValue()));
+ assertFalse(MethodHandle.isMethodRef(Kind.REF_GET_FIELD_STATIC.getValue()));
+
+ assertFalse(MethodHandle.isFieldRef(Kind.REF_INVOKE_VIRTUAL.getValue()));
+ assertFalse(MethodHandle.isFieldRef(Kind.REF_INVOKE_STATIC.getValue()));
+ assertFalse(MethodHandle.isFieldRef(Kind.REF_INVOKE_SPECIAL.getValue()));
+ assertFalse(MethodHandle.isFieldRef(Kind.REF_INVOKE_CONSTRUCTOR.getValue()));
+ assertFalse(MethodHandle.isFieldRef(Kind.REF_INVOKE_INTERFACE.getValue()));
+ assertTrue(MethodHandle.isFieldRef(Kind.REF_GET_FIELD.getValue()));
+ assertTrue(MethodHandle.isFieldRef(Kind.REF_PUT_FIELD.getValue()));
+ assertTrue(MethodHandle.isFieldRef(Kind.REF_PUT_FIELD_STATIC.getValue()));
+ assertTrue(MethodHandle.isFieldRef(Kind.REF_GET_FIELD_STATIC.getValue()));
+
+ ClassType classType =
+ new ClassType() {
+ @Override
+ public boolean isBuiltInClass() {
+ return false;
+ }
+
+ @Override
+ public String getFullyQualifiedName() {
+ return "test.A";
+ }
+
+ @Override
+ public String getClassName() {
+ return "A";
+ }
+
+ @Override
+ public PackageName getPackageName() {
+ return new PackageName("test");
+ }
+ };
+ MethodSignature ms =
+ new MethodSignature(classType, "m1", Collections.emptyList(), VoidType.getInstance());
+ FieldSignature fs = new FieldSignature(classType, "f", IntType.getInstance());
+
+ MethodHandle mhms = new MethodHandle(ms, Kind.REF_INVOKE_VIRTUAL.getValue(), classType);
+ MethodHandle mhfs = new MethodHandle(fs, Kind.REF_GET_FIELD, classType);
+
+ // not valid Method handles
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> new MethodHandle(fs, Kind.REF_INVOKE_CONSTRUCTOR, classType));
+ assertThrows(
+ IllegalArgumentException.class, () -> new MethodHandle(ms, Kind.REF_GET_FIELD, classType));
+
+ assertTrue(mhms.isMethodRef());
+ assertFalse(mhms.isFieldRef());
+
+ assertFalse(mhfs.isMethodRef());
+ assertTrue(mhfs.isFieldRef());
+
+ assertEquals(mhfs.getType(), classType);
+ assertEquals(
+ mhfs.toString(),
+ "methodhandle: \"" + mhfs.getKind() + "\" " + mhfs.getReferenceSignature());
+
+ MethodHandle mhms2 = new MethodHandle(ms, Kind.REF_INVOKE_VIRTUAL.getValue(), classType);
+ assertTrue(mhfs.equals(mhfs));
+ assertFalse(mhfs.equals(mhms));
+ assertFalse(mhfs.equals(null));
+ assertFalse(mhfs.equals(classType));
+ assertFalse(mhfs.equals(mhms2));
+
+ assertEquals(mhfs.hashCode(), mhfs.hashCode());
+ assertEquals(mhms.hashCode(), mhms2.hashCode());
+ assertNotEquals(mhfs.hashCode(), mhms.hashCode());
+ }
+}
From 1f2614b037961a110f14121a982cdeae8012130f Mon Sep 17 00:00:00 2001
From: Indrale Dnyaneshwar <118615488+Dnyanu76@users.noreply.github.com>
Date: Wed, 18 Oct 2023 18:52:54 +0530
Subject: [PATCH 36/36] Remove typo
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 051d37be1da..5d2b9119d87 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ Do you have questions? Feel free to start a [Discussion](https://github.com/soot
#### (compared to its predecessor [Soot](https://github.com/soot-oss/soot).)
- [x] New Improved API (without Globals/Singletons)
- [x] Fully-Parallelizable Architecture
-- [x] Enables lazyloading of classes (no interleaved loading of used/dependend classes anymore)
+- [x] Enables lazyloading of classes (no interleaved loading of used/dependent classes anymore)
- [x] Fail early strategy - input validation while constructing/building objects
- [x] Up-to-Date (i.e. Java8!) Sourcecode Frontend
- [x] Full Java 21 Support for Bytecode