This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 29763 - [XSLT30] overriding xsl:param with xsl:variable or vice versa should be disallowed
Summary: [XSLT30] overriding xsl:param with xsl:variable or vice versa should be disal...
Status: RESOLVED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Candidate Recommendation
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Michael Kay
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-07-31 14:09 UTC by Abel Braaksma
Modified: 2017-01-30 15:52 UTC (History)
1 user (show)

See Also:


Attachments

Description Abel Braaksma 2016-07-31 14:09:47 UTC
We say in xsl:override that you can override when two components are homonymous. That term is defined with reference to *symbolic identifier*, which reads:

[Definition: The symbolic identifier of a component is a composite name used to identify the component uniquely within a package. The symbolic identifier comprises the kind of component (stylesheet function, named template, accumulator, attribute set, global variable, key, or mode), the expanded QName of the component (namespace URI plus local name), and in the case of stylesheet functions, the arity.]

We mention here "global variable", which refers to both xsl:variable and xsl:param. But we also say "the same kind of component", and I think that the component declared with xsl:param is different (not homonymous) from one defined with xsl:variable.

Max Toro reported this in Bug 29574, comment 18, claiming you can *convert* a variable into a parameter this way (or vv). I don't think this was an intended behavior and if the WG agrees, I would like this behavior to be an error scenario: an xsl:param cannot be overridden by an xsl:variable, or the other way around.

Note also that an xsl:param is implicitly public and has no @visibility. An xsl:variable has a visibility. I don't think we need the complexity of the interactions of these rather confusing/conflicting declarations if you try to override them.
Comment 1 Michael Kay 2016-07-31 21:18:04 UTC
Overriding a param with a variable is a very important use case because it's the only way an overriding stylesheet can "fix" the value for the parameter.

Overriding a variable with a param is also useful. If an overriding stylesheet can change the value of the variable, why shouldn't it be allowed to say "I want the user to be able to set the value of this variable".
Comment 2 Abel Braaksma 2016-08-01 09:09:25 UTC
The use case seems viable, indeed. But there was a reason that xsl:param was made implicitly public (to enforce it is always settable externally). Now by overriding it with xsl:variable it can be hidden. I'm unsure whether we have properly understood the consequences of this. Maybe there's no problem and it should / could stay the way it is. I'll chew a bit more on this.
Comment 3 Abel Braaksma 2016-08-24 09:30:19 UTC
> I'll chew a bit more on this.
I did the chewing :). 

We agreed that an xsl:variable can be overridden by an xsl:param and vv, provided the correct visibility and homonimity are present.

This seems to be supported by the specification by absence of a rule that the overriding declaration of xsl:param or xsl:variable must have a matching overriding declaration (instead, we speak of "global variables" in the general sense). This could be made explicit, but I don't think there's an error here.

Max Toro's comment in Bug 29574 refers to an (apparent) ambiguity in the spec: under 3.5.3.2. we explain that if you use a package with xsl:use-package, and there is *no* matching declaration inside xsl:override or xsl:accept, the default visibility of a public component becomes *private*.

In the case of xsl:param this is not possible, as it is implicitly public and it has no visibility attribute. To fix this, I propose to add a row in the table under 3.5.3.2 that there's an exception for xsl:param: the default visibility does *not* change from public to private, instead, it remains public.

This makes sense, because a global parameter is never private.

Under 3.5.3.3 we added this exception already ("except in the case of xsl:param, which is implicitly public.").

Instead of adding a Note as suggested by Max Toro, I think a normative entry in the table (under 3.5.3.2) for the xsl:param exception makes more sense.
Comment 4 Michael Kay 2016-08-25 09:26:46 UTC
I agree with comment #3
Comment 5 Michael Kay 2016-09-01 15:14:59 UTC
The WG discussed this and resolved it with the action:

ACTION-2016-08-25-001: MKay to implement comment#3 of bug 29763 into the spec on fixing default visibility of xsl:param for used packages
Comment 6 Michael Kay 2017-01-30 15:05:49 UTC
It seems that this change was never applied to the spec.

I am doing so now.
Comment 7 Michael Kay 2017-01-30 15:52:25 UTC
The rules turned out to be a bit more complex than envisaged. The main change is to specify that xsl:accept and xsl:expose never match an xsl:param declaration, which means that (a) if an explicit name is used and the declaration is an xsl:param, then it's a static error, (b) if a wildcard is used, it doesn't apply to xsl:param declarations.