diff options
Diffstat (limited to 'src/current/include/preproc/eligclass.xsl')
-rw-r--r-- | src/current/include/preproc/eligclass.xsl | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/src/current/include/preproc/eligclass.xsl b/src/current/include/preproc/eligclass.xsl new file mode 100644 index 0000000..8e78c09 --- /dev/null +++ b/src/current/include/preproc/eligclass.xsl @@ -0,0 +1,261 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!-- + Package eligibility class generation + + Here, the term "eligibility" means whether the package is eligible to be used + in a result set basead on the values of its params within their respective + domains and other factors such as the results of terminating classifications + and the eligibility of imported packages. + + The goal of the eligibility classification is to create a cascading failure in + the event of bad data. +--> + +<xsl:stylesheet version="2.0" + xmlns="http://www.w3.org/1999/xhtml" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:preproc="http://www.lovullo.com/rater/preproc" + xmlns:lv="http://www.lovullo.com/rater" + xmlns:c="http://www.lovullo.com/calc"> + + + +<!-- + Trigger eligibility class generation +--> +<xsl:template match="lv:package[ not( @preproc:elig-class-yields ) ]" + as="element( lv:package )" + priority="5" + mode="preproc:expand-elig-class"> + <xsl:param name="orig-root" as="element( lv:package )" /> + + <xsl:variable name="elig-class" as="element( lv:classify )"> + <xsl:apply-templates select="." mode="preproc:gen-elig-class"> + <xsl:with-param name="orig-root" select="$orig-root" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:copy> + <xsl:sequence select="@*" /> + + <xsl:attribute name="preproc:elig-class" + select="$elig-class/@as" /> + + <xsl:attribute name="preproc:elig-class-yields" + select="$elig-class/@yields" /> + + <xsl:sequence select="$elig-class" /> + <xsl:apply-templates mode="preproc:macros" /> + </xsl:copy> +</xsl:template> + + +<xsl:template match="lv:package" as="element( lv:package )" + priority="1" + mode="preproc:expand-elig-class"> + + <!-- already processed --> + <xsl:sequence select="." /> +</xsl:template> + + + +<!-- + Generate eligibility classification asserting all data integrity aspects of a + package + + The eligibility classification will yield a scalar. +--> +<xsl:template match="lv:package" as="element( lv:classify )" + mode="preproc:gen-elig-class"> + <xsl:param name="orig-root" as="element( lv:package )" /> + + <xsl:message>[preproc/eligclass] generating eligibility class</xsl:message> + + + <!-- class-ify name --> + <xsl:variable name="as" as="xs:string" + select="preproc:gen-elig-class-name( @name )" /> + <xsl:variable name="yields" as="xs:string" + select="preproc:gen-elig-class-yields( @name )" /> + + + <lv:classify as="{$as}" yields="{$yields}" + desc="{@name} package is eligible"> + + <!-- TODO: this should really be a compile-time value --> + <xsl:if test="@keep-elig-class = 'true'"> + <xsl:attribute name="keep" select="'true'" /> + </xsl:if> + + <!-- each of our imported packages' elig classes must be truthful --> + <xsl:apply-templates mode="preproc:gen-elig-class-matches" + select="lv:import"> + + <xsl:with-param name="orig-root" select="$orig-root" /> + </xsl:apply-templates> + + <!-- param values must be within their domain --> + <!-- XXX: does not work when param is undefined due to no mapping + <xsl:apply-templates mode="preproc:gen-elig-param-class" + select="lv:param" /> + --> + + <!-- terminating classifications must not have matched --> + <xsl:apply-templates mode="preproc:gen-elig-term-class" + select="preproc:symtable/preproc:sym[ @type='class' ]" /> + </lv:classify> +</xsl:template> + + +<!-- + Generate eligibility classification name for package +--> +<xsl:function name="preproc:gen-elig-class-name" + as="xs:string"> + <xsl:param name="name" /> + + <xsl:sequence select=" + concat( '--elig-', + translate( + translate( $name, '.', '' ), + '/', '-' + ) + ) + " /> +</xsl:function> + + +<!-- + Generate eligibility result scalar name for package +--> +<xsl:function name="preproc:gen-elig-class-yields" + as="xs:string"> + <xsl:param name="name" /> + + <xsl:sequence select=" + concat( + 'isElig', + translate( + translate( $name, '.', '' ), + '/-', '' ) )" /> +</xsl:function> + + +<!-- + Generate matches on eligibility of imported packages + + For each imported package, its eligibility classification must be true. +--> +<xsl:template match="lv:import[ @package ]" + as="element( lv:match )?" + priority="5" + mode="preproc:gen-elig-class-matches"> + <xsl:param name="orig-root" as="element( lv:package )" /> + + <!-- FIXME: path may not yet be resolved due to preprocessing order --> + <xsl:variable name="pkg-path" as="xs:string"> + <xsl:call-template name="__apply-relroot"> + <xsl:with-param name="path" select="@package" /> + </xsl:call-template> + </xsl:variable> + + <xsl:variable name="pkg" as="element( lv:package )" + select="document( concat( $pkg-path, '.xmlo' ), + $__entry-root ) + /lv:package" /> + + <xsl:if test="not( $pkg )"> + <xsl:message terminate="yes"> + <xsl:text>[preproc/eligclass] error: could not load `</xsl:text> + <xsl:value-of select="$pkg-path" /> + <xsl:text>' object file</xsl:text> + </xsl:message> + </xsl:if> + + <xsl:variable name="chk" as="xs:string?" + select="$pkg/@preproc:elig-class-yields" /> + + <xsl:choose> + <xsl:when test="not( $chk ) or ( $chk = '' )"> + <!-- TODO: make this an error once we make maps part of the + conventional build process --> + <xsl:message> + <xsl:text>[preproc/eligclass] internal: empty eligibility </xsl:text> + <xsl:text>class for `</xsl:text> + <xsl:value-of select="$pkg/@name" /> + <xsl:text>'; skipping</xsl:text> + </xsl:message> + </xsl:when> + + <xsl:otherwise> + <!-- use eligibility class as stated by the package --> + <lv:match on="{$chk}" value="TRUE" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + + +<xsl:template match="lv:import" priority="1" + mode="preproc:gen-elig-class-matches"> + + <!-- do nothing --> +</xsl:template> + + +<!-- + Param values must be within their domain + + This is a trivial operation. +--> +<xsl:template match="lv:param" + as="element( lv:any )" + mode="preproc:gen-elig-param-class" priority="5"> + + <lv:any> + <lv:match on="{@name}" anyOf="{@type}" /> + + <!-- TODO: defaults should always be within the domain! --> + <xsl:if test="@default"> + <lv:match on="{@name}" anyOf="empty" /> + </xsl:if> + </lv:any> +</xsl:template> + + + +<!-- + Terminating classification dependencies + + All terminiating classifications defined in the package must yield false + for the package to be eligible. + + N.B. This checks to ensure @extclass is not set; this prevents errors when + the eligibility classification attempts to pull in a terminating + classification marked as external to the classifier. There may or may not + be something we want to do about this in the future. +--> +<xsl:template match="preproc:sym[ + not( @src ) + and not( @pollute='true' ) + and @type='class' + and @terminate='true' + and not( @extclass='true' ) + ]" + as="element( lv:match )" + priority="5" + mode="preproc:gen-elig-term-class"> + + <lv:match on="{@yields}" value="FALSE" /> +</xsl:template> + + +<xsl:template match="preproc:sym" priority="1" + mode="preproc:gen-elig-term-class"> + + <!-- do nothing --> +</xsl:template> + +</xsl:stylesheet> + |