Bug #6165
closedSpurious template rule ambiguity reported
100%
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.
Updated by Michael Kay over 1 year ago
Reproduced as test apply-templates/conflict-resolution-1901
Updated by Michael Kay over 1 year 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.
Updated by Michael Kay over 1 year 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.
Updated by Michael Kay over 1 year 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).
Updated by Michael Kay over 1 year 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.
Updated by Michael Kay over 1 year 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"
.
Updated by Michael Kay over 1 year 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
Updated by Michael Kay over 1 year 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.
Updated by Michael Kay over 1 year 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.
Updated by Michael Kay over 1 year 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
Updated by O'Neil Delpratt about 1 year 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