<
xsl:
stylesheet xmlns:src="
http://www.sdml.info/srcML/src"
xmlns:cpp="
http://www.sdml.info/srcML/cpp"
xmlns:xsl="
http://www.w3.org/1999/XSL/Transform"
xmlns:xw="
http://www.pnp-software.com/XWeaver"
xmlns:xd="
http://www.pnp-software.com/XSLTdoc"
xmlns:util="
http://www.pnp-software.com/util"
xmlns:ax="
http://control.ee.ethz.ch/XWeaver/AspectX"
version="
2.0">
<
xd:
doc type="
stylesheet">
<
xd:
short>
Weaving Rule that adds a declaration to a class</
xd:
short>
<
xd:
detail>
<
ul>
<
li>
srcML element: <
code>
src:class</
code></
li>
<
li>
advice type: <
code>
add</
code></
li>
<
li>
codeModifier type: <
code>
declaration</
code></
li>
</
ul>
Adds a declaration to the first possible location of the following choices:
<
ul>
<
li>
Check if appropriate access modifiers exist, if not add an advice to the class so they are added the next time.</
li>
<
li>
If all access modifiers have been added, the add advices of the class are moved to the access modifier elements.</
li>
</
ul>
<
h2>
Example 1</
h2>
<
h3>
Base Code</
h3>
<
div class="
source">
<
pre>
class Foo {
public:
}</
pre>
</
div>
<
h3>
Code Modifier</
h3>
<
xd:
xml>
<
codeModifier type="
declaration">
<
accessModifier type="
public" />
<
text>
int foo();</
text>
</
codeModifier>
</
xd:
xml>
<
h3>
Modified Code</
h3>
<
div class="
source">
<
pre>
class Foo {
public:
<
span class="
highlightedCode">
int foo();</
span>
}</
pre>
</
div>
<
h2>
Example 2</
h2>
<
p>
Access modifier blocks are added by the weaver if needed.</
p>
<
h3>
Base Code</
h3>
<
div class="
source">
<
pre>
class Foo {
public:
int foo1();
}</
pre>
</
div>
<
h3>
Code Modifier</
h3>
<
xd:
xml>
<
codeModifier type="
declaration">
<
accessModifier type="
private" />
<
text>
int foo2();</
text>
</
codeModifier>
</
xd:
xml>
<
h3>
Modified Code</
h3>
<
div class="
source">
<
pre>
class Foo {
public:
int foo1();
private:
<
span class="
highlightedCode">
int foo2();</
span>
}</
pre>
</
div>
<
xd:
weaverRuleLinks pointcutType="
src:class"
adviceType="
add"
codeModifierType="
declaration" />
</
xd:
detail>
<
xd:
cvsId>
$Id$</
xd:
cvsId>
<
xd:
author>
ibirrer</
xd:
author>
<
xd:
copyright>
2004, P&P Software GmbH</
xd:
copyright>
</
xd:
doc>
<!---->
<
xsl:
preserve-space elements="
*" />
<
xd:
doc>
<
xd:
detail>
This template does the following:
<
ul>
<
li>
Check if appropriate access modifiers exist, if not add an advice to the class so they are added the next time.</
li>
<
li>
If all access modifiers have been added, the add advices of the class are moved to the access modifier elements.</
li>
</
ul>
</
xd:
detail>
</
xd:
doc>
<
xsl:
template match="
src:class[ax:advice[@type='add' and position() = 1]/ax:codeModifier[@type='declaration']]"
mode="
weaving">
<
xsl:
variable name="
advice"
select="
ax:advice[1]" />
<
xsl:
variable name="
class"
select="
." />
<!---->
<
xsl:
choose>
<
xsl:
when test="
not(.//src:block)">
<!---->
<
xsl:
message terminate="
yes">
ERROR: Cannot weave classes, which do not have a body (block element). Use .//block in the constraint of a
class join point to exclude forward declarations from being annotated.</
xsl:
message>
</
xsl:
when>
<
xsl:
when test="
exists(ax:advice/ax:codeModifier[not(ax:accessModifier)])">
<
xsl:
message terminate="
yes">
ERROR: A declaration codeModifier must contain an accessModifier child elmement of type 'public', 'private', 'protected' or 'default'.</
xsl:
message>
</
xsl:
when>
</
xsl:
choose>
<!---->
<
xsl:
variable name="
additionalAccessModifiersAdvice">
<
ax:
advice type="
add">
<
ax:
codeModifier type="
accessModifierBlock">
<
xsl:
for-each-group select="
ax:advice/ax:codeModifier/ax:accessModifier"
group-by="
@type">
<
xsl:
choose>
<
xsl:
when test="
current()/@type = 'public' and count($class//src:public) = 0">
<
ax:
accessModifierBlock type="
public" />
</
xsl:
when>
<
xsl:
when test="
current()/@type = 'protected' and count($class//src:protected) = 0">
<
ax:
accessModifierBlock type="
protected" />
</
xsl:
when>
<
xsl:
when test="
current()/@type = 'private' and count($class//src:private[not(@type) or @type != 'default']) = 0">
<
ax:
accessModifierBlock type="
private" />
</
xsl:
when>
</
xsl:
choose>
</
xsl:
for-each-group>
</
ax:
codeModifier>
</
ax:
advice>
</
xsl:
variable>
<
xsl:
variable name="
modifiedClass">
<
xsl:
choose>
<!---->
<
xsl:
when test="
count($additionalAccessModifiersAdvice/ax:advice/ax:codeModifier/ax:accessModifierBlock) > 0">
<
xsl:
copy>
<
xsl:
copy-of select="
@*" />
<!---->
<
xsl:
copy-of select="
$additionalAccessModifiersAdvice" />
<!---->
<
xsl:
copy-of select="
child::node()" />
</
xsl:
copy>
</
xsl:
when>
<
xsl:
otherwise>
<!---->
<
xsl:
copy>
<
xsl:
copy-of select="
@*" />
<!---->
<
xsl:
copy-of select="
ax:advice[not(@type='add' and ax:codeModifier/@type='declaration')]" />
<!---->
<
xsl:
apply-templates select="
child::node()[not(self::ax:advice)]"
mode="
class_add_declaration_move_declarations">
<
xsl:
with-param name="
advices"
select="
ax:advice[@type='add' and ax:codeModifier/@type='declaration']" />
</
xsl:
apply-templates>
</
xsl:
copy>
</
xsl:
otherwise>
</
xsl:
choose>
</
xsl:
variable>
<
xsl:
apply-templates select="
$modifiedClass"
mode="
weaving" />
</
xsl:
template>
<
xd:
doc>
Move advices to the appropriate access modifier element.
</
xd:
doc>
<
xsl:
template match="
src:public | src:private | src:protected"
mode="
class_add_declaration_move_declarations">
<
xsl:
param name="
advices" />
<
xsl:
variable name="
accessModifierString">
<
xsl:
choose>
<
xsl:
when test="
@type='default'">
<
xsl:
text>
default</
xsl:
text>
</
xsl:
when>
<
xsl:
otherwise>
<
xsl:
value-of select="
local-name()" />
</
xsl:
otherwise>
</
xsl:
choose>
</
xsl:
variable>
<
xsl:
copy>
<
xsl:
copy-of select="
@*" />
<
xsl:
for-each select="
$advices[ax:codeModifier/ax:accessModifier/@type = $accessModifierString]">
<
xsl:
copy>
<
xsl:
copy-of select="
@*" />
<
xsl:
for-each select="
ax:codeModifier">
<
xsl:
if test="
ax:accessModifier/@type = $accessModifierString">
<
xsl:
copy-of select="
." />
</
xsl:
if>
</
xsl:
for-each>
</
xsl:
copy>
</
xsl:
for-each>
<
xsl:
copy-of select="
child::node()" />
</
xsl:
copy>
</
xsl:
template>
<
xd:
doc>
Default copy template for class_add_declaration_move_declarations.
</
xd:
doc>
<
xsl:
template match="
*"
mode="
class_add_declaration_move_declarations">
<
xsl:
param name="
advices" />
<
xsl:
copy>
<
xsl:
copy-of select="
@*" />
<
xsl:
apply-templates mode="
class_add_declaration_move_declarations">
<
xsl:
with-param name="
advices"
select="
$advices" />
</
xsl:
apply-templates>
</
xsl:
copy>
</
xsl:
template>
</
xsl:
stylesheet>
v