Project

Profile

Help

Feature #4961

open

use-when in SEF compilation phase

Added by Martynas Jusevicius over 3 years ago. Updated over 2 years ago.

Status:
New
Priority:
High
Assignee:
-
Category:
-
Sprint/Milestone:
Start date:
2021-04-02
Due date:
% Done:

0%

Estimated time:
Applies to JS Branch:
2
Fix Committed on JS Branch:
Fixed in JS Release:
SEF Generated with:
Platforms:
Company:
-
Contact person:
-
Additional contact persons:
-

Description

ac:uuid is my custom extension function which is obviously not available client-side. But using use-when as follows allowed me to differentiate between function calls on the server and in the browser:

<xsl:value-of use-when="system-property('xsl:product-name') eq 'Saxon-JS'" select="resolve-uri(concat('/', ixsl:call(ixsl:window(), 'generateUUID', [])), $ac:uri)"/>
<xsl:value-of use-when="system-property('xsl:product-name') = 'SAXON'" select="resolve-uri(concat('/', ac:uuid()), $ac:uri)"/>

That worked fine when compiling SEF with Saxon-JS. Now I'm trying Saxon-EE for that, and a different use-when kicks in and I get an error about the missing ac:uuid function:

Error near {...ve-uri(concat('/', ac:uuid(...} at char 24 in xsl:value-of/@select on line 460 column 175 of default.xsl:
  XPST0017  Cannot find a 0-argument function named Q{https://w3id.org/atomgraph/client#}uuid()
Error near {...ac:forClass, $ldt:base) els...} at char 24 in xsl:param/@select on line 230 column 161 of resource.xsl:
  XPST0017  Cannot find a 3-argument function named
  Q{https://w3id.org/atomgraph/client#}construct-doc()

Is there a workaround here? Can some property be used to differentiate between compilation and execution phases in use-when?

Actions #1

Updated by Martynas Jusevicius over 3 years ago

To clarify: ac:uuid is registered as an extension function in Java, that is why Saxon-EE cannot find it.

Actions #2

Updated by Martynas Jusevicius over 3 years ago

Worked around this by adding function stubs as suggested by Michael on xml.com Slack:

    <xsl:function name="ac:construct-doc" as="document-node()*" override-extension-function="no">
        <xsl:message use-when="system-property('xsl:product-name') = 'SAXON'" terminate="yes">
            Not implemented -- com.atomgraph.client.writer.function.ConstructDocument needs to be registered as an extension function
        </xsl:message>
    </xsl:function>

Now the stylesheet SEF compiles with both Saxon-JS 2.1 and Saxon-EE 10.3

Actions #3

Updated by Martynas Jusevicius over 3 years ago

Now I have a problem with execution on Saxon-HE however. Since I've removed use-when, IXSL functions ixsl:call/ixsl:eval/ixsl:window are not recognized:

Error near {...'limit', [ $limit ]), 'offs...} at char 20 in xsl:sequence/@select on line 180 column 355 of default.xsl:
  XPST0017  Cannot find a 3-argument function named Q{http://saxonica.com/ns/interactiveXSLT}call()
Error near {...'limit', [ $limit ]), 'offs...} at char 10 in xsl:sequence/@select on line 183 column 123 of default.xsl:
  XPST0017  Cannot find a 3-argument function named Q{http://saxonica.com/ns/interactiveXSLT}call()
Error near {...ing($js-statement/@statemen...} at char 0 in xsl:sequence/@select on line 225 column 77 of default.xsl:
  XPST0017  Cannot find a 1-argument function named Q{http://saxonica.com/ns/interactiveXSLT}eval()
Error near {...ing($js-statement/@statemen...} at char 0 in xsl:sequence/@select on line 244 column 77 of default.xsl:
  XPST0017  Cannot find a 1-argument function named Q{http://saxonica.com/ns/interactiveXSLT}eval()
Error near {...ing($js-statement/@statemen...} at char 0 in xsl:sequence/@select on line 276 column 85 of default.xsl:
  XPST0017  Cannot find a 1-argument function named Q{http://saxonica.com/ns/interactiveXSLT}eval()
Error near {...ing($js-statement/@statemen...} at char 0 in xsl:sequence/@select on line 282 column 85 of default.xsl:
  XPST0017  Cannot find a 1-argument function named Q{http://saxonica.com/ns/interactiveXSLT}eval()
Error near {...ing($js-statement/@statemen...} at char 0 in xsl:sequence/@select on line 288 column 85 of default.xsl:
  XPST0017  Cannot find a 1-argument function named Q{http://saxonica.com/ns/interactiveXSLT}eval()
Error in {ixsl:call(ixsl:window(), 'aler...} at char 10 in xsl:value-of/@select on line 195 column 89 of sparql.xsl:
  XPST0017  Cannot find a 0-argument function named Q{http://saxonica.com/ns/interactiveXSLT}window()
15:05:08,546 [http-nio-8080-exec-1] ERROR Application:618 - System XSLT stylesheet error
net.sf.saxon.s9api.SaxonApiException: Errors were reported during stylesheet compilation

Now I'm lost again.

Actions #4

Updated by Martynas Jusevicius over 3 years ago

I think a property like saxon:phase which would return Compilation/Execution would address my use-when use case.

Actions #5

Updated by Michael Kay over 3 years ago

It's a bit more tricky than that. We have to evaluate xsl:use-when at compile time, and there's a question of how much we know at that stage about the target environment for execution. We can certainly add a system property such as saxon:target which tells you what the compilation target environment is. But we don't know (and don't want to know) the version of the target environment, and we don't know what extension functions are available in that environment -- we only know what stubs are available in the compile time environment. So this all requires some rather careful thought.

But apart from xsl:use-when (and other static expressions) there's also the question of calls to system-property(), function-available(), etc appearing in dynamic expressions. Currently I suspect the compiler will evaluate these eagerly, assuming that the answer is the same for the execution environment as for the compiler environment. If that's the case, it doesn't seem the right thing to do.

Actions #7

Updated by Michael Kay over 3 years ago

Perhaps we want rules something like the following:

(a) system-property() and XX-available() (whether called statically or dynamically) are intended to return properties of the target (run-time) environment.

(b) the target (run-time) environment is presumed to be the same as the compile-time environment unless otherwise specified.

(c) one way it can be "specified otherwise" is by use of -target on the command line. (But does this give us enough information, e.g. do we need to know whether it's JS-in-the-browser vs JS-on-node? And what do we do about xsl:product-version?)

(d) perhaps we want other ways of "specifying otherwise" e.g. a declaration in the stylesheet itself?

In static expressions we have to evaluate the function at compile time, and therefore with incomplete knowledge of the run-time environment.

In dynamic expressions we should behave as if we evaluated the function dynamically; we should only do eager/early evaluation if we are sure we know the answer (e.g. if not generating a SEF).

Actions #8

Updated by Martynas Jusevicius over 3 years ago

(c) also relates to https://saxonica.plan.io/issues/4962, I think

Actions #9

Updated by Martynas Jusevicius about 3 years ago

For the next release, it would be nice to have this prioritized. I've bought a Saxon-EE license partially because I was planning to compile SEF with it, but because of this issue I'm not able to. I have to use the Saxon-JS compiler.

Actions #10

Updated by Michael Kay about 3 years ago

We do need to do something about system-property().

But as regards function-available(), I think something along the lines of comment #2 (override-extension-function) is going to remain necessary, at least in the case of user-defined functions. A use-when expression (or other static expression) needs to be evaluated at compile time, by definition, and there's no way the processor can have compile-time knowledge of every detail of the run-time environment unless that information is statically supplied by the stylesheet author; and in the case of external functions, supplying it through a declaration that provides the signature without the implementation seems the cleanest approach.

Actions #12

Updated by Norm Tovey-Walsh over 2 years ago

  • Category deleted (Command line)
  • Priority changed from Normal to High
  • Sprint/Milestone set to SaxonJS 3.0

Please register to edit this issue

Also available in: Atom PDF Tracking page