<
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="
AddComplexGetterMethod">
<
description>
Sample aspect program to add a method to a class. The added method return a more
complex function of the inner state of the object than the simple getter method
defined in aspect <
code>
AddGetterMethod</
code>
.
<
p />
This aspect is implemented through three advices. The first advice modifies the
comment of the target class to include a statement that the class has been modified by an aspect
weaver. The second advice adds the method declaration (inclusive of its comment). The third
advice adds the method implementation. <
p />
The name of target class is
<
code>
Derived</
code>
and the name of the getter method is <
code>
getInternalState()</
code>
.
This method does not return a value of some single member variable but it combines values of several
member variables together thus it returns the aggregated value representing the part of the state
of the object in which we are intrested.
<
author>
A. Pasetti, O. Rohlik</
author>
</
description>
<
pointcut name="
targetClass"
type="
src:class"
constraint="
src:name='Derived'">
<
description>
Points to the target class to which the getter method should be added.</
description>
</
pointcut>
<
pointcut name="
methodImplementation"
type="
src:function"
constraint="
src:name/src:name[1]='Derived'">
<
description>
Points to all the implementations of the methods of 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.</
description>
</
pointcut>
<
pointcut name="
targetUnit"
type="
src:unit">
<
description>
Points to the unit where the target class is defined. In srcML, the file that
contains the definition part of a class is a "unit". This pointcut identifies the desired unit
as the unit that contains a <
code>
methodImplementation</
code>
pointcut, namely as the unit
that contains the implementation of the method of the target class.</
description>
<
restriction type="
contain">
<
pointcutRef type="
src:function"
ref="
methodImplementation" />
</
restriction>
</
pointcut>
<
pointcut name="
targetClassComment"
type="
src:comment">
<
description>
Points to the comment of the target class where the getter method should be added.
that must be modified. The comment that must be modified is the comment that is followed by
the <
code>
targetClass</
code>
pointcut. </
description>
<
restriction type="
followedBy">
<
pointcutRef type="
src:class"
ref="
targetClass" />
</
restriction>
</
pointcut>
<
advice name="
addClassComment"
type="
end">
<
description>
Add a comment at the end of the comment of the target class. The comment thus
inserted states that the class was modified by an aspect program and describes the nature of
the modification. The HTML tags in the comment are expressed using escape sequences.</
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 a method that return the complex function of
the inner state of the object. It combines two memeber variables
<code>_integer1</code> and <code>_integer2</code>
using weight <code>_float1</code>.</
text>
</
codeModifier>
</
advice>
<
advice type="
add"
name="
addMethodDeclaration">
<
description>
Add the declaration for the <
code>
getInternalState()</
code>
method. Note that the code
modifier must include
an <
code>
accessModifier</
code>
subelement to specify the access protection level of the new
method. Note also that the declaration statements are written without indentation. The
indentation is automatically inserted by the weaver to be compatible with the indentation of
other parts of the declaration file.</
description>
<
pointcutRef ref="
targetClass"
type="
src:class" />
<
codeModifier type="
declaration">
<
accessModifier type="
public" />
<
text>
/** </
text>
<
text>
* Getter method for the object internal state. The declaration and definition of </
text>
<
text>
* this getter method was automatically generated by an aspect program. </
text>
<
text />
<
text>
The method returns the inner state of the object. </
text>
<
text>
It returns the weighted sum of two memeber variables </
text>
<
text>
<code>_integer1</code> and <code>_integer2</code></
text>
<
text>
using <code>_float1</code> as a weight.</
text>
<
text>
*/ </
text>
<
text>
void float getInternalState(); </
text>
</
codeModifier>
</
advice>
<
advice type="
add"
name="
addMethodDefinition">
<
description>
Add the definition for the complex getter method.</
description>
<
pointcutRef ref="
targetUnit"
type="
src:unit" />
<
codeModifier type="
definition">
<
text>
float Derived::getInternalState() {</
text>
<
text>
return ( (1-_float1)*_integer1 + _float1 *_integer2; ) / 2.0;</
text>
<
text>
}</
text>
</
codeModifier>
</
advice>
</
aspect>
v