I'm now looking at the SEF file output to ensure backwards compatibility in SaxonJS.
For this function (in test as-0152):
<xsl:function name="f:promote" as="xs:double">
<xsl:param name="p"/>
<xsl:sequence select="$p"/>
</xsl:function>
we are now generating:
<function name='Q{f}promote' line='10' module='file:/Users/mike/GitHub/xslt30-test/tests/attr/as/as-0152.xsl' flags='pU' as='1AO' slots='1'>
<arg name='Q{}p' as='*'/>
<check role='body' baseUri='file:/Users/mike/GitHub/xslt30-test/tests/attr/as/as-0152.xsl' ns='f=f xs=~ xsl=~' line='12' card='1' diag='5|0|XTTE0780|f:promote#1'>
<convert from='A' to='AO' flags='p' diag='5|0|XTTE0780|f:promote#1'>
<data diag='5|0|XTTE0780|f:promote#1'>
<varRef name='Q{}p' slot='0'/>
</data>
</convert>
</check>
</function>
Specifcally, the varRef
is wrapped in data
(to do atomisation) then convert
which now does both numeric type promotion and conversion from untyped atomic, and then check
for a cardinality check.
Saxon 11 generated:
<function name='Q{f}promote' line='10' module='file:/Users/mike/GitHub/xslt30-test/tests/attr/as/as-0152.xsl' eval='16' flags='pU' as='1AO' slots='1'>
<arg name='Q{}p' as='*'/>
<check role='body' baseUri='file:/Users/mike/GitHub/xslt30-test/tests/attr/as/as-0152.xsl' ns='f=f xs=~ xsl=~' line='12' card='1' diag='5|0|XTTE0780|f:promote#1'>
<convert from='A' to='AO' flags='p' diag='5|0|XTTE0780|f:promote#1'>
<cvUntyped to='AO' diag='5|0|XTTE0780|f:promote#1'>
<data diag='5|0|XTTE0780|f:promote#1'>
<varRef name='Q{}p' slot='0'/>
</data>
</cvUntyped>
</convert>
</check>
</function>
So the conversion was done in two steps: cvUntyped
to convert untypedAtomic to double, and then convert
to do promotion from decimal/float to double.
Attempting to run the SEF file from Saxon 12.x using SaxonJS 2.6 results in "Incompatible operands: xs:untypedAtomic (01.123) and xs:double". So we're going to need to adapt the SEF output from 12.x when target=JS.