I'm trying to develop a application using javassist, which should count the number of writes and reads to a field in an object. However when a field is written to inside the constructor it shouldn't be counted, only reads. My problem is that if I have a constructor that receives an object of the same type as a parameter and a field of that object is affected I want to count that write. However I don't know how to know to which object instance in javassist that field belongs to. For example taking this constructor as example:
Person(Person p) {
this.firstname = p.firstname;
p.surname = "";
this.surname = p.surname;
}
I want to count the first and third lines as reads, since a read is valid in a constructor. But the only write I want to count is in the second line since it is a write to a field of a different instance of the object.
At the moment I have search the documentation on javassist and can't find a way to find in runtime to which instance a field belongs to. What I have so far is:
for (CtConstructor ctConstructor : ctClass.getDeclaredConstructors()) {
ctConstructor.instrument(new ExprEditor() {
public void edit(FieldAccess fa) throws CannotCompileException {
replaceFieldAccess(fa, fieldAccess -> fieldAccess.isStatic() || (fieldAccess.getClassName().equals(className) && fieldAccess.isWriter()));
}
});
}
And my problem is in the second condition of the predicate in the lambda function.
The output I'm looking for is Total reads: 2 Total writes: 1, but I either get no writes, or 3 writes and both options are wrong in my problem.
You only know to which object instance a field belongs during the runtime. You need to inject code that verifies it. One possible solution is to inject this code
if (this != $0) writeCounter++;
Remember that it is only possible because the field you want to count is an instance and not a static field.