Add template barriers for metadata

This (hopefully) prevents metadata from leaking outside of template
expansions where they are not wanted.

* src/current/include/preproc/macros.xsl (preproc:macropass): Strip
    cruft (new barrier nodes) on final pass.
* src/current/include/preproc/template.xsl (preproc:expand-template):
    Enclose template expansion in preproc:tpl-barrier (which is stripped on
    the final pass).
  (preproc:apply-template)[lv:param-meta]: Document template.  "Hoist"
    node (set attribute) if not contained within lv:param-copy.
  (preproc:gen-param-value)[lv:param-inherit]: Consider hoisted nodes behind
    barrier.
master
Mike Gerwitz 2017-12-08 14:44:26 -05:00
parent 75aa0fab7e
commit f38e6c896b
2 changed files with 57 additions and 17 deletions

View File

@ -2,7 +2,7 @@
<!-- <!--
Handles macro preprocessing Handles macro preprocessing
Copyright (C) 2016 LoVullo Associates, Inc. Copyright (C) 2016, 2017 LoVullo Associates, Inc.
This file is part of TAME. This file is part of TAME.
@ -79,9 +79,10 @@
</xsl:apply-templates> </xsl:apply-templates>
</xsl:when> </xsl:when>
<!-- no more passes needed; macro expansion complete --> <!-- no more passes needed; strip any cruft and we're done -->
<xsl:otherwise> <xsl:otherwise>
<xsl:sequence select="$nodeset" /> <xsl:apply-templates mode="preproc:strip-tpl-cruft"
select="$nodeset" />
</xsl:otherwise> </xsl:otherwise>
</xsl:choose> </xsl:choose>
</xsl:template> </xsl:template>

View File

@ -305,21 +305,23 @@
template; this inlines it as if it were copied and pasted directly template; this inlines it as if it were copied and pasted directly
into the XML, much like a C macro --> into the XML, much like a C macro -->
<xsl:variable name="apply-result"> <xsl:variable name="apply-result">
<xsl:apply-templates <preproc:tpl-barrier>
select="$tpl[ 1 ]/*" <xsl:apply-templates
mode="preproc:apply-template"> select="$tpl[ 1 ]/*"
mode="preproc:apply-template">
<xsl:with-param name="apply" select="$context" <xsl:with-param name="apply" select="$context"
tunnel="yes" /> tunnel="yes" />
<xsl:with-param name="apply-tpl-name" select="$name" <xsl:with-param name="apply-tpl-name" select="$name"
tunnel="yes" /> tunnel="yes" />
<xsl:with-param name="params" select="$params" <xsl:with-param name="params" select="$params"
tunnel="yes" /> tunnel="yes" />
<xsl:with-param name="first-child" select="true()" /> <xsl:with-param name="first-child" select="true()" />
<xsl:with-param name="src-root" select="$src-root" <xsl:with-param name="src-root" select="$src-root"
tunnel="yes" /> tunnel="yes" />
</xsl:apply-templates> </xsl:apply-templates>
</preproc:tpl-barrier>
</xsl:variable> </xsl:variable>
<xsl:apply-templates mode="preproc:mark-tpl-expansion" <xsl:apply-templates mode="preproc:mark-tpl-expansion"
@ -336,6 +338,30 @@
</xsl:function> </xsl:function>
<!--
Strip tpl barriers, which serve to scope metadata.
-->
<xsl:template mode="preproc:strip-tpl-cruft" priority="5"
match="preproc:tpl-barrier">
<xsl:apply-templates mode="preproc:strip-tpl-cruft"
select="node()" />
</xsl:template>
<!--
Everything else stays.
-->
<xsl:template mode="preproc:strip-tpl-cruft" priority="3"
match="node()">
<xsl:copy>
<xsl:sequence select="@*" />
<xsl:apply-templates mode="preproc:strip-tpl-cruft"
select="node()" />
</xsl:copy>
</xsl:template>
<!-- <!--
Add nodes describing where the parent node came from. Add nodes describing where the parent node came from.
@ -568,6 +594,13 @@
</xsl:template> </xsl:template>
<!--
Generate template metadata from lv:param-meta nodes.
Metadata contained within an lv:param-copy has its scope limited to
children only. Standalone lv:param-meta nodes are "hoisted" and are
available to siblings.
-->
<xsl:template match="lv:param-meta" mode="preproc:apply-template" priority="5"> <xsl:template match="lv:param-meta" mode="preproc:apply-template" priority="5">
<xsl:param name="apply" as="node()" <xsl:param name="apply" as="node()"
tunnel="yes" /> tunnel="yes" />
@ -579,7 +612,11 @@
</xsl:call-template> </xsl:call-template>
</xsl:variable> </xsl:variable>
<preproc:tpl-meta name="{@name}" value="{$value}" /> <preproc:tpl-meta name="{@name}" value="{$value}">
<xsl:if test="not( parent::lv:param-copy )">
<xsl:attribute name="hoist" select="'true'" />
</xsl:if>
</preproc:tpl-meta>
</xsl:template> </xsl:template>
@ -985,6 +1022,8 @@
<!-- find the metadata --> <!-- find the metadata -->
<xsl:variable name="values" <xsl:variable name="values"
select="$apply/ancestor::*/preceding-sibling::preproc:tpl-meta[ @name=$name ]/@value select="$apply/ancestor::*/preceding-sibling::preproc:tpl-meta[ @name=$name ]/@value
, $apply/ancestor::*/preproc:tpl-barrier
/preproc:tpl-meta[ @hoist = 'true' and @name=$name ]/@value
, $apply/preceding-sibling::preproc:tpl-meta[ @name=$name ]/@value" /> , $apply/preceding-sibling::preproc:tpl-meta[ @name=$name ]/@value" />
<!-- take the last one (precedence) --> <!-- take the last one (precedence) -->