<
aspect xmlns:cpp="
http://www.sdml.info/srcML/cpp"
xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsl="
http://www.w3.org/1999/XSL/Transform"
xmlns="
http://control.ee.ethz.ch/XWeaver/AspectX"
xmlns:src="
http://www.sdml.info/srcML/src"
xsi:schemaLocation="
http://control.ee.ethz.ch/XWeaver/AspectX ../../../../src/xsd/aspectX.xsd"
name="
CarPostCondition">
<
description>
Some methods in the base code return a pointer to an object. The pointer
should be non-NULL but there is no check that this is indeed the case. We
want to modify the base code in the following manner:
<
ol>
<
li>
If a method returns a pointer, then there should be a check that the
pointer is non-NULL</
li>
<
li>
If a pointer return value is found to be <
code>
NULL</
code>
, then a recovery action
should be executed.</
li>
</
ol>
A "recovery action" in our context is an instance of a class derived
from class <
CODE>
RecoveryAction</
CODE>
. The recovery action should be a plug-in component
for the class where the parameter valildity check is performed.
<
author>
I. Birrer, O. Rohlik</
author>
<
see>
CarBeginEnd</
see>
<
see>
CarPreCondition</
see>
<
see>
CarSynchronizeWindows</
see>
</
description>
<
pointcut name="
pointerReturningFunctions"
type="
src:function"
constraint="
contains(src:type,'*')">
<
description>
Points to all functions that return a pointer type.</
description>
</
pointcut>
<
pointcut name="
pointerReturningFunctionDeclarations"
type="
src:function_decl"
constraint="
contains(src:type,'*')">
<
description>
Points to all function declarations that return a pointer type.</
description>
</
pointcut>
<
pointcut name="
classesWithPointerReturningFunctions"
type="
src:class">
<
description>
Points to all classes that contain at least one function declaration which returns a pointer type.</
description>
<
restriction type="
contain">
<
pointcutRef ref="
pointerReturningFunctionDeclarations"
type="
src:function_decl" />
</
restriction>
</
pointcut>
<
pointcut name="
unitsWithPointerReturningFunctions"
type="
src:unit">
<
description>
Points to all units that contain at least one function which returns a pointer type.</
description>
<
restriction type="
contain">
<
pointcutRef ref="
pointerReturningFunctions"
type="
src:function" />
</
restriction>
</
pointcut>
<
pointcut name="
returnStatements"
type="
src:return">
<
description>
Points to all return statements inside the function located by pointerReturningFunctions pointcut.
This points to all return statements in all functions that return pointers.
</
description>
<
restriction type="
within">
<
pointcutRef ref="
pointerReturningFunctions"
type="
src:function" />
</
restriction>
</
pointcut>
<
advice name="
commentsForCheckedFunctions"
type="
end">
<
description>
Adds a comment in front of the function declarartion located by pointcut <
code>
pointerReturningFunctionDeclarations</
code>
.</
description>
<
pointcut type="
src:comment">
<
restriction type="
followedBy">
<
pointcutRef ref="
pointerReturningFunctionDeclarations"
type="
src:function_decl" />
</
restriction>
</
pointcut>
<
codeModifier type="
comment">
<
text />
<
text>
XWeaver: The return value is tested for NULL value.
If a NULL value is detected, a recovery action is called.</
text>
<
text />
</
codeModifier>
</
advice>
<
advice name="
commentsForClassesWithCheckedFunctions"
type="
end">
<
description>
Adds a comment in front of the class that contain classes with functions that returns pointers.</
description>
<
pointcut type="
src:comment">
<
restriction type="
followedBy">
<
pointcutRef type="
src:class"
ref="
classesWithPointerReturningFunctions" />
</
restriction>
</
pointcut>
<
codeModifier type="
comment">
<
text />
<
text>
This class has been changed by an aspect program</
text>
<
text />
</
codeModifier>
</
advice>
<
advice name="
checkBeforeReturn"
type="
before">
<
description>
Adds a check of expresion value that is to be returned. Recover if return expression evaluates to NULL.</
description>
<
pointcutRef ref="
returnStatements"
type="
src:return" />
<
codeModifier type="
codeFragment">
<
xsl>
if( <
xsl:
value-of select="
src:expr" />
== 0 ) {</
xsl>
<
text>
recoveryAction.recover();</
text>
<
text>
}</
text>
</
codeModifier>
</
advice>
<
advice name="
addRecoverySupportMethodDeclaration"
type="
add">
<
description>
Adds a method <
code>
setRecoveryAction()</
code>
to the classes that support recovery.</
description>
<
pointcutRef ref="
classesWithPointerReturningFunctions"
type="
src:class" />
<
codeModifier type="
declaration">
<
accessModifier type="
public" />
<
text />
<
text>
/**
* Sets the recovery action to be taken, if a method returns a NULL pointer
* @param RecoveryAction The recoveryAction to be taken, if a method returns a NULL pointer
*/
void setRecoveryAction( RecoveryAction aRecoveryAction );</
text>
</
codeModifier>
</
advice>
<
advice name="
addRecoverySupportFieldDeclaration"
type="
add">
<
description>
Adds a field variable declaration <
code>
RecoveryAction</
code>
to classes that support recovery action.</
description>
<
pointcutRef ref="
classesWithPointerReturningFunctions"
type="
src:class" />
<
codeModifier type="
declaration">
<
accessModifier type="
private" />
<
text>
/** The recovery action to be taken, if a method returns a NULL pointer */</
text>
<
text>
RecoveryAction recoveryAction;</
text>
</
codeModifier>
</
advice>
<
advice name="
addRecoverySupportDefinition"
type="
add">
<
description>
Adds the definition of <
code>
setRecoveryAction()</
code>
method to appropriate unit.</
description>
<
pointcutRef ref="
unitsWithPointerReturningFunctions"
type="
src:unit" />
<
codeModifier type="
definition">
<
text>
void ${className}::setRecoveryAction( RecoveryAction aRecoveryAction ) {</
text>
<
text>
recoveryAction = aRecoveryAction;</
text>
<
text>
}</
text>
</
codeModifier>
</
advice>
<
advice type="
add"
name="
addIncludeDecl">
<
description>
Adds <
CODE>
#include "RecoveryAction.h"</
CODE>
to all units where classes with functions returning pointers are defined.</
description>
<
pointcut type="
src:unit">
<
or>
<
restriction type="
contain">
<
pointcutRef ref="
classesWithPointerReturningFunctions"
type="
src:class" />
</
restriction>
<
restriction type="
contain">
<
pointcut type="
src:class"
constraint="
src:name='Battery'" />
</
restriction>
</
or>
</
pointcut>
<
codeModifier type="
include">
<
text>
#include "RecoveryAction.h"</
text>
</
codeModifier>
</
advice>
<
advice type="
add"
name="
addIncludeDef">
<
description>
Adds <
CODE>
#include "RecoveryAction.h"</
CODE>
to all units where
functions returning pointer are defined.</
description>
<
pointcutRef ref="
unitsWithPointerReturningFunctions"
type="
src:unit" />
<
codeModifier type="
include">
<
text>
#include "RecoveryAction.h"</
text>
</
codeModifier>
</
advice>
</
aspect>
v