<!--
  Weaving rule for
    srcML element:     unit
    advice type:       add
    codeModifier type: include
-->
<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:ax="http://control.ee.ethz.ch/XWeaver/AspectX" version="2.0">
                
  
                   <xd:doc type="stylesheet">
    
<xd:short>Weaving Rule that adds an include statement to a unit. </xd:short>
    
<xd:detail>
      
<ul> 
        
<li>srcML element:     <code>src:unit</code></li>
        
<li>advice type:       <code>add</code></li>
        
<li>codeModifier type: <code>cpp:include</code></li>
      
</ul>
      Adds includes to the first possible location of the following choices: 
      
<ol>
        
<li>Directly before other inlcudes</li>
        
<li>Before first class definition (or before the comment or this class if it has one)</li>
        
<li>Before first function definition</li>
      
</ol>
      
<h2>Example</h2>
      
<div class="source">
<pre>#include &lt;stdio.h&gt;
void Foo:foo() {
  printf("foo");
}
</pre>
      
</div>
      
<h3>Code Modifier</h3>
      
<xd:xml>
<codeModifier type="include">
  
<text>#include "MyClass.h"</text>
</codeModifier>
      
</xd:xml>
      
<h3>Modified Code</h3>
      
<div class="source">
<pre>#include &lt;stdio.h&gt;
<span class="highlightedCode">#include "MyClass.h"</span>
void Foo:foo() {
  printf("foo");
}
</pre>
      
</div>
     
<xd:weaverRuleLinks pointcutType="src:unit" adviceType="add" codeModifierType="include" />
    
</xd:detail>
    
<xd:cvsId>$Id$</xd:cvsId>
    
<xd:author>ibirrer</xd:author>
    
<xd:copyright>2004, P&amp;P Software GmbH</xd:copyright>
  
</xd:doc>

  
  
<!-- Preserve Whitespaces -->
  
<xsl:preserve-space elements="*" />
  
  
                   <xd:doc>
    Adds includes to the first possible location of the following choices: 
    
<ul>
      
<li>Directly before other inlcudes</li>
      
<li>Before first class definition (or before the comment or this class if it has one)</li>
      
<li>Before first function definition</li>
    
</ul>
  
</xd:doc>

  
<xsl:template match="src:unit[ax:advice[@type='add' and position() = 1]/ax:codeModifier[@type='include']]" mode="weaving">
    
<xsl:copy>
      
<xsl:copy-of select="@*" />
      
<!-- The current advice has to be deleted. Others must be preserved.  -->
      
<xsl:copy-of select="ax:advice[position() != 1]" />
      
      
<xsl:choose>
        
<xsl:when test=".//cpp:include">
          
<!-- 
            There are other includes. Add new includes directly before them 
          
-->
          
<xsl:apply-templates select="child::node()[not(self::ax:advice)]" mode="weaving_unit_add_include_include">
            
<xsl:with-param name="advice" select="ax:advice[1]" />
          
</xsl:apply-templates>
        
</xsl:when>
        
<xsl:when test=".//src:class[.//src:block]">
          
<!-- 
            No existing includes in source file, but a class definition found. Add includes before first
            class definition
          
-->
          
<xsl:apply-templates select="child::node()[not(self::ax:advice)]" mode="weaving_unit_add_include_class">
            
<xsl:with-param name="advice" select="ax:advice[1]" />
          
</xsl:apply-templates>
        
</xsl:when>
        
<xsl:when test=".//src:function">
          
<!-- 
            No existing includes in source file and no class definition, but 
            a function definition found. Add includes before first function definition.
          
-->
          
<xsl:apply-templates select="child::node()[not(self::ax:advice)]" mode="weaving_unit_add_include_function">
            
<xsl:with-param name="advice" select="ax:advice[1]" />
          
</xsl:apply-templates>
        
</xsl:when>
        
<xsl:otherwise>
          
<xsl:message terminate="yes">ERROR: In unit_add_include.xsl.</xsl:message>
        
</xsl:otherwise>
      
</xsl:choose>
    
</xsl:copy>
  
</xsl:template>
  
  
  
                   <xd:doc>
    Adds includes before the first class containing a block that 
    occurs in the source file.
    
<xd:param name="advice" type="node-set">The advice element which will be used for weaving the unit.</xd:param>
  
</xd:doc>

  
<xsl:template match="src:class[1]" mode="weaving_unit_add_include_class">
    
<xsl:param name="advice" />
    
<!-- If the class has a comment, the include was already added before the comment -->
    
<xsl:if test="preceding-sibling::*[position() = 1 and not(self::src:comment)]">  
      
<!-- Add new includes -->
      
<xsl:value-of select="xw:getCodeModifierContent($advice/ax:codeModifier)" />
      
<xsl:text>
</xsl:text>
      
<xsl:text>
</xsl:text>
    
</xsl:if>
    
<!-- copy the class -->
    
<xsl:copy>
      
<xsl:copy-of select="@*" />
      
<!-- Copy all advices of this class -->
      
<xsl:copy-of select="ax:advice" />
      
<xsl:apply-templates mode="weaving" />
    
</xsl:copy>
  
</xsl:template>
  
  
                   <xd:doc>
    If a class has a comment attached the include is added before the comment
    
<xd:param name="advice" type="node-set">The advice element which will be used for weaving the unit.</xd:param>
  
</xd:doc>

  
<xsl:template match="src:comment[following-sibling::src:class[1]][last()]" mode="weaving_unit_add_include_class">
    
<xsl:param name="advice" />
    
<!-- If the class has a comment, the include is woven here -->
    
<!-- Add new includes -->
    
<xsl:value-of select="xw:getCodeModifierContent($advice/ax:codeModifier)" />
    
<xsl:text>
</xsl:text>
    
<xsl:text>
</xsl:text>
    
<xsl:copy>
      
<xsl:copy-of select="@*" />
      
<!-- Copy all advices of this class -->
      
<xsl:copy-of select="ax:advice" />
      
<xsl:apply-templates mode="weaving" />
    
</xsl:copy>
  
</xsl:template>
  
  
                   <xd:doc>
    Default copy template for adding an include before a class definition.
    
<xd:param name="advice" type="node-set">The advice element which will be used for weaving the unit.</xd:param>
  
</xd:doc>

  
<xsl:template match="*" mode="weaving_unit_add_include_class">
    
<xsl:param name="advice" />
    
<xsl:copy>
      
<xsl:copy-of select="@*" />
      
<xsl:apply-templates mode="weaving_unit_add_include_class">
        
<xsl:with-param name="advice" select="$advice" />
      
</xsl:apply-templates>
    
</xsl:copy>
  
</xsl:template>
  
  
                   <xd:doc>
     This template adds the includes before the first function that occurs in the source file.
    
<xd:param name="advice" type="node-set">The advice element which will be used for weaving the unit.</xd:param>
  
</xd:doc>

  
<xsl:template match="src:function[1]" mode="weaving_unit_add_include_function">
    
<xsl:param name="advice" />
    
<!-- Add new includes -->
    
<xsl:value-of select="xw:getCodeModifierContent($advice/ax:codeModifier)" />
    
<xsl:text>
</xsl:text>
    
<xsl:copy>
      
<xsl:copy-of select="@*" />
      
<!-- Copy all advices of this function -->
      
<xsl:copy-of select="ax:advice" />
      
<xsl:apply-templates mode="weaving" />
    
</xsl:copy>
  
</xsl:template>
  
  
                   <xd:doc>
     Default copy template for adding includes before a function definiton
    
<xd:param name="advice" type="node-set">The advice element which will be used for weaving the unit.</xd:param>
  
</xd:doc>

  
<xsl:template match="*" mode="weaving_unit_add_include_function">
    
<xsl:param name="advice" />
    
<xsl:copy>
      
<xsl:copy-of select="@*" />
      
<xsl:apply-templates mode="weaving_unit_add_include_function">
        
<xsl:with-param name="advice" select="$advice" />
      
</xsl:apply-templates>
    
</xsl:copy>
  
</xsl:template>
  
  
                   <xd:doc>
     This template adds the includes before the first include
    
<xd:param name="advice" type="node-set">The advice element which will be used for weaving the unit.</xd:param>
  
</xd:doc>

  
<xsl:template match="cpp:include[1]" mode="weaving_unit_add_include_include">
    
<xsl:param name="advice" />
    
<!-- Add new includes -->
    
<xsl:value-of select="xw:getCodeModifierContent($advice/ax:codeModifier)" />
    
<xsl:text>
</xsl:text>
    
<xsl:copy>
      
<xsl:copy-of select="@*" />
      
<!-- Copy all advices of this class -->
      
<xsl:copy-of select="ax:advice" />
      
<xsl:apply-templates mode="weaving" />
    
</xsl:copy>
  
</xsl:template>
  
  
                   <xd:doc>
     Default copy template for adding includes before an existing include.
    
<xd:param name="advice" type="node-set">The advice element which will be used for weaving the unit.</xd:param>
  
</xd:doc>

  
<xsl:template match="*" mode="weaving_unit_add_include_include">
    
<xsl:param name="advice" />
    
<xsl:copy>
      
<xsl:copy-of select="@*" />
      
<xsl:apply-templates mode="weaving_unit_add_include_include">
        
<xsl:with-param name="advice" select="$advice" />
      
</xsl:apply-templates>
    
</xsl:copy>
  
</xsl:template>
</xsl:stylesheet>






































v