Project

Profile

Help

Bug #6165

closed

Spurious template rule ambiguity reported

Added by Michael Kay 9 months ago. Updated 5 months ago.

Status:
Closed
Priority:
Low
Assignee:
Category:
XSLT conformance
Sprint/Milestone:
-
Start date:
2023-08-10
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
12, trunk
Fix Committed on Branch:
12, trunk
Fixed in Maintenance Release:
Platforms:
.NET, Java

Description

This is happening when running the Java-to-C# transpiler.

There is an element <name nodeType="NameExpr">, and there are two template rules with match patterns:

match="name | *[@nodeType='Name']
match="*[@nodeType='NameExpr']

An ambiguous match is reported in Saxon 12; none was reported in Saxon 11. I don't think this is ambiguous. The union pattern should be treated as two separate template rules with different (defaulted) priority and the second one should win unambiguously.

Actions #1

Updated by Michael Kay 9 months ago

Reproduced as test apply-templates/conflict-resolution-1901

Actions #2

Updated by Michael Kay 9 months ago

We're successfully splitting the pattern into two and registering two rules with different patterns and different priorities. But then XSLTemplateRule.compileTemplateRule() kicks in and line 772 calls setMatchPattern setting the pattern for both rules back to the union pattern.

The logic in 11.x seems to be very similar.

I think the key is probably in the fact that the RuleEE and the TemplateRuleEE objects both have a pattern (or matchPattern) attribute, which are in many ways interchangeable; but the call on setMatchPattern at line 772 affects one and not the other.

Actions #3

Updated by Michael Kay 9 months ago

In Saxon 11, TemplateRule.setMatchPattern() reads:

    public void setMatchPattern(Pattern pattern) {
//        if (matchPattern != pattern) {
//            for (Rule r : rules) {
//                r.setPattern(pattern);
//            }
//        }
        matchPattern = pattern;
    }

In Saxon 12, the commented-out code is live, so when the matchPattern of the TemplateRule is updated, the pattern of the Rule is changed too.

The reinstatement of the commented-out code on the 12.x branch happened recently - 7 July 2023, in response to performance bug #6090.

This was concerned with improvements to the performance of a GeneralNodePattern. I suspect that the rationale was that when we optimized a pattern, we needed to write the revised pattern to both the TemplateRule and the Rule objects.

Actions #4

Updated by Michael Kay 9 months ago

I think we need to rethink the way template rules with union patterns are handled.

Instead of breaking the pattern up within RuleManager.registerRule(), we should break it up earlier, at the level of the XSLTemplate. An XSLTemplate already creates one TemplateRule for each mode, it should also create one for each decomposed pattern.

I've made this change and the test case is now working; but a lot more regression testing is needed (e.g. the change affects how mode="#all" works, and the functioning of xsl:next-match on the branches of a union pattern).

Actions #5

Updated by Michael Kay 9 months ago

We have two regression test failures: match-245 and match-261. Both are concerned with mode="#all".

Perhaps the time is ripe for a rethink as to how we handle mode="#all". Currently we construct a pseudo-mode, the OmniMode, and place templates in this mode, to be copied into every real mode later. I think we could discover the complete list of modes in an earlier operation, which would eliminate the need for the OmniMode.

Actions #6

Updated by Michael Kay 9 months ago

  • Category set to XSLT conformance
  • Status changed from New to Resolved
  • Fix Committed on Branch 12, trunk added

Note that this bug was never present in an issued product, it was a regression caused by a patch that is not yet issued.

I have taken the opportunity for a design clean-up of the way multiple template rules are compiled from a single xsl:template element in the face of (a) multiple modes, (b) mode="#all", and (c) union patterns. A fair bit of code has been simplified, especially code relating to mode="#all".

Actions #7

Updated by Michael Kay 9 months ago

  • Status changed from Resolved to In Progress

Reopening because we are getting some failures in SaxonCS:

-s:mode.enclosing -t:enclosing-001
Unable to cast object of type 'Saxon.Hej.style.XSLMode' to type 'Saxon.Hej.style.XSLTemplate'.
System.InvalidCastException: Unable to cast object of type 'Saxon.Hej.style.XSLMode' to type 'Saxon.Hej.style.XSLTemplate'.
   at Saxon.Eej.ee.trans.TemplateRuleInitializer..ctor(Compilation comp, ComponentDeclaration decl, TemplateRuleEE templateRule) in /Users/mike/GitHub/saxon2020/build/cs/Saxon/Eej/ee/trans/TemplateRuleInitializer.cs:line 17
   at Saxon.Eej.ee.trans.TemplateRuleEE.prepareInitializer(Compilation compilation, ComponentDeclaration decl) in /Users/mike/GitHub/saxon2020/build/cs/Saxon/Eej/ee/trans/TemplateRuleEE.cs:line 24
   at Saxon.Hej.style.XSLTemplate.createSkeletonTemplate(Compilation compilation, ComponentDeclaration decl) in /Users/mike/GitHub/saxon2020/build/cs/Saxon/Hej/style/XSLTemplate.cs:line 595
   at Saxon.Hej.style.XSLTemplate.compileDeclaration(Compilation compilation, ComponentDeclaration decl) in /Users/mike/GitHub/saxon2020/build/cs/Saxon/Hej/style/XSLTemplate.cs:line 478
   at Saxon.Hej.style.XSLMode.compileDeclaration(Compilation compilation, ComponentDeclaration decl) in /Users/mike/GitHub/saxon2020/build/cs/Saxon/Hej/style/XSLMode.cs:line 268
   at Saxon.Hej.style.PrincipalStylesheetModule.compile(Compilation compilation) in /Users/mike/GitHub/saxon2020/build/cs/Saxon/Hej/style/PrincipalStylesheetModule.cs:line 703
   at Saxon.Hej.style.Compilation.compilePackage(Source source) in /Users/mike/GitHub/saxon2020/build/cs/Saxon/Hej/style/Compilation.cs:line 203
   at Saxon.Hej.style.StylesheetModule.loadStylesheet(Source styleSource, Compilation compilation) in /Users/mike/GitHub/saxon2020/build/cs/Saxon/Hej/style/StylesheetModule.cs:line 123

Actions #8

Updated by Michael Kay 9 months ago

  • Status changed from In Progress to Resolved

The latest failure is an unrelated problem: it occurs both in SaxonJ and SaxonCS when the tests in test set mode.enclosing (using the 4.0 feature of enclosing modes) are run with -jit:on.

Actions #9

Updated by Michael Kay 9 months ago

  • Status changed from Resolved to In Progress

Another problem that does appear to be a related regression: in test case match-245, mode="#all" is failing when used in conjunction with JIT template rule compilation. The reason is that with JIT enabled, we're skipping the early processing of xsl:apply-template instructions to build up the complete list of all modes that are declared explicitly or implicitly.

This is fairly challenging, because the new design depends on us knowing all the modes at a fairly early stage of processing, and they can appear either in at least four ways: xsl:apply-templates/@mode, */@[xsl:]default-mode, xsl:mode/@name, xsl:template/@mode. I'm going to try processing these during the xsl:use-when filtering pass and collecting the list of mode names in the Compilation object.

Actions #10

Updated by Michael Kay 9 months ago

  • Status changed from In Progress to Resolved

I wrote a new test match-285 that uses xsl:default-mode="zzz" in conjunction with mode="#all", and this is failing in SaxonJ 11. So I'm going to treat this as a new issue.

Note: we don't appear to be systematically running tests with -jit:on

Actions #11

Updated by O'Neil Delpratt 5 months ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 12.4 added

Bug fix applied in the Saxon 12.4 maintenance release

Please register to edit this issue

Also available in: Atom PDF