|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectkorat.instrumentation.AbstractInstrumenter
korat.instrumentation.FieldInstrumenter
class FieldInstrumenter
This class does all the instrumentation related to non-array fields. For all declared fields, this instrumenter does the following:
handleFieldDeclaration(CtClass, CtField)
,
handleFieldDeclaration(CtClass, CtField)
.
Setter classes serve for improving performance when building
test case from the candidate vector because this technique does not
use (slow) java reflection mechanism. For more info see
handleFieldDeclaration(CtClass, CtField)
createNestedSetterClass(CtClass, CtField)
AbstractInstrumenter
,
ArrayFieldInstrumenter
,
SpecialConstructorInstrumenter
Field Summary |
---|
Fields inherited from class korat.instrumentation.AbstractInstrumenter |
---|
cp |
Constructor Summary | |
---|---|
FieldInstrumenter()
|
Method Summary | |
---|---|
protected void |
addGetSetterMethod(CtClass clz,
CtField f)
Adds getter method for the setter of the given field. |
protected void |
addGetterMethod(CtClass clz,
CtField f)
Adds special getter method which before returning the value of the field notifies the instance of the ITestCradle about the field access. |
protected void |
addIdField(CtClass clz,
CtField f)
Just adds one extra int field. |
protected void |
createNestedSetterClass(CtClass clz,
CtField f)
Nested setter classes are implemented in the following way: static nested classes have constructor that takes one parameter of the type same as type of clz parameter. |
protected String |
getGetSetterSrc(CtClass clz,
String fieldName,
String idFieldName,
String setterClassName)
Returns source code for the "get setter" method. |
protected String |
getGetterSrc(CtClass clz,
String fieldName,
String idFieldName)
Returns the source for the "korat getter method". |
private String |
getSetterSrc(CtField f)
Source for the setter's set method. |
protected void |
handleFieldDeclaration(CtClass clz,
CtField f)
For the given field: adds "id field" of type int adds special getter method creates nested setter class adds get setter method For each field, "id filed" is added to store its index in the candidate vector. |
protected void |
instrument(CtClass clz)
|
protected void |
instrumentFieldDeclarations(CtClass clz)
For each field in the given class adds additional stuff needed for instrumentation (by calling handleFieldDeclaration . |
protected void |
replaceFieldAccesses(CtClass clz)
Searches for all read field accesses (GETFIELD instructions) and replaces them with appropriate getter method call (those getter methods that were generated in the addGetterMethod operation). |
Methods inherited from class korat.instrumentation.AbstractInstrumenter |
---|
getBytecode, shouldProcessField, shouldProcessMethod |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructor Detail |
---|
FieldInstrumenter()
Method Detail |
---|
protected void instrument(CtClass clz) throws CannotCompileException, NotFoundException, IOException
instrument
in class AbstractInstrumenter
CannotCompileException
NotFoundException
IOException
protected void instrumentFieldDeclarations(CtClass clz) throws NotFoundException, CannotCompileException
For each field in the given class adds additional stuff needed for
instrumentation (by calling handleFieldDeclaration
.
Fields of type array are not handled by this class.
clz
-
CannotCompileException
NotFoundException
protected void handleFieldDeclaration(CtClass clz, CtField f) throws NotFoundException, CannotCompileException
For each field, "id filed" is added to store its index in the candidate vector. These indices remain the same during the state space exploration so it is a good idea to calculate them only once at the beginning of the exploration and to keep them for the rest of execution. It is most efficient to do that this way, with one extra "id field" per field.
Special getter method has to inform the instance of the
ITestCradle
that the field has been accessed before
returning the value of the requested field. In order to do that, it first
checks if the corresponding "id field" is equal to -1. If it is, it
retrieves index in the candidate vector for the requested field (time
consuming operation) and stores it in the "id field". After that,
notifies ITestCradle
that the element with index "id
field" has been accessed.
Nested setter classes are used to improve performances. They extend
ISetter
abstract class and override one appropriate method
that the ICandidateBuilder
will call in order to build
object (test case) from the IStateSpace
. This
is efficient way to build test case because it avoids using java reflection.
Static nested classes can access and set fields directly. It would be
more convenient to use inner nested classes, but Javassist doesn't
provide support for them.
Get setter method just returns previously created ISetter
class for the given field.
clz
- f
-
CannotCompileException
NotFoundException
protected void addIdField(CtClass clz, CtField f) throws CannotCompileException
int
field. It's important to set its
initial value to -1 denoting that id is not yet initialized.
clz
- f
-
CannotCompileException
protected void addGetterMethod(CtClass clz, CtField f) throws NotFoundException, CannotCompileException
ITestCradle
about the field access.
clz
- f
-
NotFoundException
CannotCompileException
protected String getGetterSrc(CtClass clz, String fieldName, String idFieldName)
public int __korat_get_foo() { if (__myTester != null) __myTester.notifyFieldAccess(__id_foo); return foo; }
clz
- fieldName
- idFieldName
-
protected void replaceFieldAccesses(CtClass clz) throws CannotCompileException
Searches for all read field accesses (GETFIELD instructions) and replaces
them with appropriate getter method call (those getter methods that were
generated in the addGetterMethod
operation).
clz
-
CannotCompileException
protected void createNestedSetterClass(CtClass clz, CtField f) throws NotFoundException, CannotCompileException
Nested setter classes are implemented in the following way:
clz
parameter. That because static nested class don't
have "second this" and they need explicit reference to the object of
enclosing class. They need that object since their job is to set field
values for that object. set
method. It is enough to
override only one method, based on the type of the field which setter
class should set.
clz
- f
-
NotFoundException
CannotCompileException
private String getSetterSrc(CtField f) throws NotFoundException
public void set(Object val) { ___this.foo = (Foo)val; }
f
- field that should be set
NotFoundException
protected void addGetSetterMethod(CtClass clz, CtField f) throws NotFoundException, CannotCompileException
clz
- f
-
NotFoundException
CannotCompileException
protected String getGetSetterSrc(CtClass clz, String fieldName, String idFieldName, String setterClassName)
public ISetter __korat_get_foo_setter(int fieldId) { this.__id_foo = fieldId; return new Korat_foo_setter(this); }
clz
- fieldName
- idFieldName
- setterClassName
-
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |