<
aspect xmlns:src="
http://www.sdml.info/srcML/src"
xmlns:xsl="
http://www.w3.org/1999/XSL/Transform"
xmlns:cpp="
http://www.sdml.info/srcML/cpp"
xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xmlns="
http://control.ee.ethz.ch/XWeaver/AspectX"
xsi:schemaLocation="
http://control.ee.ethz.ch/XWeaver/AspectX ../../../../src/xsd/aspectX.xsd"
name="
TraceClassEntry">
<
description>
Sample aspect program to insert tracing instructions when a selected class is
entered. This aspect program shows an example of how the implementation of a class in a certain
code base can be modified to output a tracing message every time one of its methods is entered.
In this example, the tracing message is output using a <
code>
printf</
code>
instruction that
writes a message to the output device stating the name of the method and the name of the class
to which it belongs. In this example, the identification of the target class for which tracing
is to be performed (and which therefore must be modified by the aspect) is done "by name". The
aspect only covers the case of a single target class but it could be easily modified to cover
several target classes. <
p />
This aspect defines four advices that describe four separate but
related changes. The first advice inserts the tracing code in the methods of the target class.
The second advice inserts the tracing code in the constructors of the target class.
The third advice inserts a new <
code>
include</
code>
statement to include the <
code>
stdio</
code>
library that is required by the <
code>
printf</
code>
method. The fourth advice modifies the
comment of the target class to include a statement that the class code has been automatically
modified by an aspect program. <
p />
This sample aspect program targets a class called
<
code>
Derived</
code>
. <
author>
A. Pasetti, O. Rohlik</
author>
<
see>
TraceMethodEntry</
see>
<
see>
TraceConstructorEntry</
see>
<
see>
TraceMethodEntryUsingTracer</
see>
</
description>
<
pointcut name="
targetMethodImplementation"
type="
src:function"
constraint="
src:name/src:name[1]='Derived'">
<
description>
Points to the implementations of the methods in the target class. The
identification of the methods in the target class is done as follows. A pointcut is defined
that captures all method implementations. This pointcut is then restricted to include only
methods that belong to the target class. The implementation of the restriction relies on the
fact that in srcML the element <
code>
name</
code>
contains two other <
code>
name</
code>
subelements
where the first of them contains the class name and the second contains name of the method.
Therefore to access the name of the class the following expression is used:
<
code>
src:name/src:name[1]</
code>
.
<
p />
If it were
desired to capture more than one target class, this could be done by modifying the XPath
expression in the constraint to include names whose class part matches several class names.
<
p />
Note that this pointcut only points to the method <
i>
implementation</
i>
. There is no need
to capture the method declarations since this aspect program does not make any modifications
to the method declarations or to their comments.</
description>
</
pointcut>
<
pointcut name="
targetConstructorImplementation"
type="
src:constructor"
constraint="
substring-before(src:name,'::')='Derived'">
<
description>
Points to the constructors of the target class. The
identification of the constructors in the target class is done as follows. A pointcut is defined
that captures all constructor implementations. This pointcut is then restricted to include only
methods that belong to the target class. The implementation of the restriction relies on the
fact that in srcML the element <
code>
name</
code>
contains the fully qualified name of the
constructors and methods. This has the form "CCC::CCC" where "CCC" is the class name.
<
p />
This pointcut only points to the class <
i>
constructors</
i>
. This excludes the class
destructors because srcML treats them
separately. Another dedicated pointcut would be required if it were
desired to insert the tracing message in the destructor.
<
p />
If it were
desired to capture more than one target class, this could be done by modifying the XPath
expression in the constraint to include names whose class part matches several class names.
</
description>
</
pointcut>
<
pointcut name="
targetClass"
type="
src:class"
constraint="
src:name='Derived'">
<
description>
Points to the target class to be modified by this aspect program. This is a very
simple pointcut that captures all classes and then adds the restriction that the name of the
class must be equal to "Derived". Note that this pointcut points to the class
<
i>
declaration</
i>
only, not the class implementation. The class implementation is captured by
the <
code>
targetMethodImplementation</
code>
pointcut that points to the implementation of the
methods in the target class.</
description>
</
pointcut>
<
pointcut name="
targetClassComment"
type="
src:comment">
<
description>
Points to the comment of the target class. This pointcut is necessary because this
aspect program contains an advice that modifies the comment of the target class. The target
comment is identified as the comment that is followed by the target class. </
description>
<
restriction type="
followedBy">
<
pointcutRef type="
src:class"
ref="
targetClass" />
</
restriction>
</
pointcut>
<
pointcut name="
targetImplementationUnit"
type="
src:unit">
<
description>
Points to the unit that contains the implementations of the target class. In srcML,
a <
i>
unit</
i>
is a source file (a definition file, a declaration file, or an inline file).
This pointcut therefore identifies all the source files that contain an implementation of the
target method or constructor. </
description>
<
or>
<
restriction type="
contain">
<
pointcutRef type="
src:function"
ref="
targetMethodImplementation" />
</
restriction>
<
restriction type="
contain">
<
pointcutRef type="
src:constructor"
ref="
targetConstructorImplementation" />
</
restriction>
</
or>
</
pointcut>
<
advice type="
begin"
name="
insertMethodTrace">
<
description>
Insert the tracing instruction in the target methods. This advice inserts a printf
instruction at the beginning of the target methods. The printf instruction prints a message
stating the name of the target method and of the target class. The names of the target method
and target class are accessed using "dollar variables".</
description>
<
pointcutRef ref="
targetMethodImplementation"
type="
src:function" />
<
codeModifier type="
codeFragment">
<
text>
printf("Execution starts for method ${functionName} in class ${className}\n"); // code WOVEN by ASPECT</
text>
</
codeModifier>
</
advice>
<
advice type="
begin"
name="
insertConstructorTrace">
<
description>
Insert the tracing instruction in the target construtors. This advice inserts a printf
instruction at the beginning of the target construtors. The printf instruction prints a message
stating the name of the target class. The name of the target class is accessed using
XSL instruction <
code>
value-of</
code>
with XPath expression that extracts the class name
from scrML. See also the pointcut <
code>
targetConstructorImplementation</
code>
.</
description>
<
pointcutRef ref="
targetConstructorImplementation"
type="
src:constructor" />
<
codeModifier type="
codeFragment">
<
xsl>
printf("Execution starts for constructor of class <
xsl:
value-of select="
substring-before(src:name,'::')" />
\n"); // code WOVEN by ASPECT</
xsl>
</
codeModifier>
</
advice>
<
advice type="
add"
name="
addInclude">
<
description>
Add the <
code>
#include</
code>
statement for the <
code>
stdio</
code>
library.
Inclusion of this library is necessary because the code that is woven into the target class
calls the stdio function <
code>
printf</
code>
. Note that the code to be added by this advice is
specified using the CDATA section because otherwise the braces around "stdio" would be
interpreted as XML braces by the XWeaver program.</
description>
<
pointcutRef ref="
targetImplementationUnit"
type="
src:unit" />
<
codeModifier type="
include">
<
text>
#include <stdio.h> // code WOVEN by ASPECT</
text>
</
codeModifier>
</
advice>
<
advice name="
insertClassComment"
type="
end">
<
description>
Add a comment at the end of the comment of the target class. The comment thus
inserted in the target class states that the class has been automatically modified by an
aspect program and describes the nature of the modification. Note that this aspect program
defines no modifications to the comments of the methods in the target class.</
description>
<
pointcutRef ref="
targetClassComment"
type="
src:comment" />
<
codeModifier type="
comment">
<
text>
The implementation of this class has been modified by an aspect
program. The aspect program adds code to each constructor and method defined by this class. The added code
consists of a single printf statement inserted as the first statement in each constructor or method. The
printf statement sends a message to the standard output that states the name of the class
and of the method (if applicable). These messages can be used to trace execution of class code.</
text>
</
codeModifier>
</
advice>
</
aspect>
v