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

View File

@ -305,21 +305,23 @@
template; this inlines it as if it were copied and pasted directly
into the XML, much like a C macro -->
<xsl:variable name="apply-result">
<xsl:apply-templates
select="$tpl[ 1 ]/*"
mode="preproc:apply-template">
<preproc:tpl-barrier>
<xsl:apply-templates
select="$tpl[ 1 ]/*"
mode="preproc:apply-template">
<xsl:with-param name="apply" select="$context"
tunnel="yes" />
<xsl:with-param name="apply-tpl-name" select="$name"
tunnel="yes" />
<xsl:with-param name="params" select="$params"
tunnel="yes" />
<xsl:with-param name="apply" select="$context"
tunnel="yes" />
<xsl:with-param name="apply-tpl-name" select="$name"
tunnel="yes" />
<xsl:with-param name="params" select="$params"
tunnel="yes" />
<xsl:with-param name="first-child" select="true()" />
<xsl:with-param name="src-root" select="$src-root"
tunnel="yes" />
</xsl:apply-templates>
<xsl:with-param name="first-child" select="true()" />
<xsl:with-param name="src-root" select="$src-root"
tunnel="yes" />
</xsl:apply-templates>
</preproc:tpl-barrier>
</xsl:variable>
<xsl:apply-templates mode="preproc:mark-tpl-expansion"
@ -336,6 +338,30 @@
</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.
@ -568,6 +594,13 @@
</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:param name="apply" as="node()"
tunnel="yes" />
@ -579,7 +612,11 @@
</xsl:call-template>
</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>
@ -985,6 +1022,8 @@
<!-- find the metadata -->
<xsl:variable name="values"
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" />
<!-- take the last one (precedence) -->