Skip to content

Commit

Permalink
Merge pull request #1132 from michaelhkay/122-item-type-choice
Browse files Browse the repository at this point in the history
122 Choice item types (generalizing local union types)
  • Loading branch information
ndw authored Apr 9, 2024
2 parents 1bd0b67 + 2e8204f commit f7b2043
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 344 deletions.
36 changes: 21 additions & 15 deletions specifications/grammar-40/xpath-grammar.xml
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,14 @@ apply.
<g:ref name="MapTest" lookahead="2" if="xpath40 xquery40 xslt40-patterns"/>
<g:ref name="ArrayTest" lookahead="2" if="xpath40 xquery40 xslt40-patterns"/>
<g:ref name="RecordTest" lookahead="2" if="xpath40 xquery40 xslt40-patterns"/>
<g:ref name="LocalUnionType" lookahead="2" if="xpath40 xquery40 xslt40-patterns"/>
<g:ref name="EnumerationType" lookahead="2" if="xpath40 xquery40 xslt40-patterns"/>
<!--<g:ref name="NamedItemType" lookahead="2" if="xpath40 xquery40"/>-->
</g:choice>
<g:ref name="PredicateList"/>
</g:production>

<g:production name="WrappedItemTest" if="xslt40-patterns">
<g:string>type</g:string>
<g:string>(</g:string>
<g:ref name="ItemType"/>
<g:string>)</g:string>
<g:ref name="ChoiceItemType"/>
</g:production>

<g:production name="NodePattern" if="xslt40-patterns">
Expand Down Expand Up @@ -1602,7 +1598,10 @@ ErrorVal ::= "$" VarName
<g:sequence name="CastableExprOps">
<g:string>castable</g:string>
<g:string>as</g:string>
<g:ref name="SingleType"/>
<g:ref name="CastTarget"/>
<g:optional>
<g:string>?</g:string>
</g:optional>
</g:sequence>
</g:postfix>
</g:level>
Expand All @@ -1611,7 +1610,10 @@ ErrorVal ::= "$" VarName
<g:sequence name="CastExprOps">
<g:string>cast</g:string>
<g:string>as</g:string>
<g:ref name="SingleType"/>
<g:ref name="CastTarget"/>
<g:optional>
<g:string>?</g:string>
</g:optional>
</g:sequence>
</g:postfix>
</g:level>
Expand Down Expand Up @@ -2657,13 +2659,13 @@ ErrorVal ::= "$" VarName

<!-- [ start Types + Tests -->

<g:production name="SingleType" >
<!--<g:production name="SingleType" >
<g:ref name="CastTarget"/>
<g:optional name="OptionalOccurrenceIndicator">
<g:string process-value="yes">?</g:string>
</g:optional>
</g:production>

-->
<g:production name="TypeDeclaration" if=" xpath40 xquery40 xslt40-patterns">
<g:string>as</g:string>
<g:ref name="SequenceType"/>
Expand Down Expand Up @@ -2702,9 +2704,9 @@ ErrorVal ::= "$" VarName
<g:ref name="MapTest" lookahead="2" if="xpath40 xquery40 xslt40-patterns"/>
<g:ref name="ArrayTest" lookahead="2" if="xpath40 xquery40 xslt40-patterns"/>
<g:ref name="RecordTest" lookahead="2" if="xpath40 xquery40 xslt40-patterns"/>
<g:ref name="LocalUnionType" lookahead="2" if="xpath40 xquery40 xslt40-patterns"/>
<!--<g:ref name="LocalUnionType" lookahead="2" if="xpath40 xquery40 xslt40-patterns"/>-->
<g:ref name="EnumerationType" lookahead="2" if="xpath40 xquery40 xslt40-patterns"/>
<g:ref name="ParenthesizedItemType" if="xpath40 xquery40 xslt40-patterns"/>
<g:ref name="ChoiceItemType" if="xpath40 xquery40 xslt40-patterns"/>
</g:choice>
</g:production>

Expand Down Expand Up @@ -2841,7 +2843,7 @@ ErrorVal ::= "$" VarName
<g:ref name="TypeName" not-if="xpath40 xquery40"/>
<g:choice if="xpath40 xquery40">
<g:ref name="TypeName"/>
<g:ref name="LocalUnionType"/>
<g:ref name="ChoiceItemType"/>
<g:ref name="EnumerationType"/>
</g:choice>
</g:production>
Expand Down Expand Up @@ -2963,7 +2965,7 @@ ErrorVal ::= "$" VarName
<g:string>*</g:string>
</g:production>

<g:production name="LocalUnionType" if="xpath40 xquery40 xslt40-patterns">
<!--<g:production name="LocalUnionType" if="xpath40 xquery40 xslt40-patterns">
<g:string>union</g:string>
<g:string>(</g:string>
<g:ref name="ItemType"/>
Expand All @@ -2972,7 +2974,7 @@ ErrorVal ::= "$" VarName
<g:ref name="ItemType"/>
</g:zeroOrMore>
<g:string>)</g:string>
</g:production>
</g:production>-->

<g:production name="EnumerationType" if="xpath40 xquery40 xslt40-patterns">
<g:string>enum</g:string>
Expand Down Expand Up @@ -3013,9 +3015,13 @@ ErrorVal ::= "$" VarName
<g:string>)</g:string>
</g:production>-->

<g:production name="ParenthesizedItemType" if="xpath40 xquery40 xslt40-patterns">
<g:production name="ChoiceItemType" if="xpath40 xquery40 xslt40-patterns">
<g:string>(</g:string>
<g:ref name="ItemType"/>
<g:zeroOrMore>
<g:string>|</g:string>
<g:ref name="ItemType"/>
</g:zeroOrMore>
<g:string>)</g:string>
</g:production>

Expand Down
44 changes: 22 additions & 22 deletions specifications/xpath-functions-40/src/function-catalog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
<fos:type id="parse-html-options">
<fos:record extensible="true">
<fos:field name="method" type="xs:string" required="false"/>
<fos:field name="html-version" type="union(enum('LS'), xs:decimal)" required="false"/>
<fos:field name="html-version" type="(enum('LS') | xs:decimal)" required="false"/>
<fos:field name="encoding" type="xs:string?" required="false"/>
<fos:field name="include-template-content" type="xs:boolean?" required="false"/>
</fos:record>
Expand Down Expand Up @@ -89,7 +89,7 @@
<fos:field name="columns" type="xs:string*" required="true"/>
<fos:field name="column-index" type="map(xs:string, xs:positiveInteger)" required="true"/>
<fos:field name="rows" type="array(xs:string)*" required="true"/>
<fos:field name="get" required="true" type="function(xs:positiveInteger, union(xs:positiveInteger, xs:string)) as xs:string?"/>
<fos:field name="get" required="true" type="function(xs:positiveInteger, (xs:positiveInteger | xs:string)) as xs:string?"/>
</fos:record>
</fos:type>

Expand Down Expand Up @@ -2207,7 +2207,7 @@ compare($N * $arg2, 0) eq compare($arg1, 0).</eg>
<fos:proto name="format-number" return-type="xs:string">
<fos:arg name="value" type="xs:numeric?"/>
<fos:arg name="picture" type="xs:string"/>
<fos:arg name="format-name" type="union(xs:string, xs:QName)?" default="()"/>
<fos:arg name="format-name" type="(xs:string | xs:QName)?" default="()"/>
<fos:arg name="format" type="map(*)?" default="()"/>
</fos:proto>
</fos:signatures>
Expand Down Expand Up @@ -2308,7 +2308,7 @@ compare($N * $arg2, 0) eq compare($arg1, 0).</eg>
representing higher powers of ten) always precede digits with lower significance, even when
the rendered text flow is from right to left.</p>
<p diff="add" at="issue780">The type of the third argument changes in version 4.0 from
<code>xs:string</code> to <code>union(xs:string, xs:QName)</code>. This introduces a
<code>xs:string</code> to <code>(xs:string | xs:QName)</code>. This introduces a
minor incompatibility: for example, it is no longer possible to supply a value
of type <code>xs:anyURI</code>.</p>

Expand Down Expand Up @@ -4833,7 +4833,7 @@ return normalize-unicode(concat($v1, $v2))</eg>
<fos:function name="hash" prefix="fn" at="2024-01-10" diff="add">
<fos:signatures>
<fos:proto name="hash" return-type="xs:hexBinary?">
<fos:arg name="value" type="union(xs:string, xs:hexBinary, xs:base64Binary)?"/>
<fos:arg name="value" type="(xs:string | xs:hexBinary | xs:base64Binary)?"/>
<fos:arg name="options" type="map(*)?" default="{}"/>
<!--<fos:arg name="algorithm" type="xs:string?" default="'MD5'"/>-->
</fos:proto>
Expand Down Expand Up @@ -11205,7 +11205,7 @@ else QName("", $value)</eg>
<fos:function name="namespace-uri-for-prefix" prefix="fn">
<fos:signatures>
<fos:proto name="namespace-uri-for-prefix" return-type="xs:anyURI?">
<fos:arg name="value" type="union(xs:NCName, enum(''))?"/>
<fos:arg name="value" type="(xs:NCName | enum(''))?"/>
<fos:arg name="element" type="element()" usage="inspection"/>
</fos:proto>
</fos:signatures>
Expand Down Expand Up @@ -11255,7 +11255,7 @@ else QName("", $value)</eg>
<fos:function name="in-scope-namespaces" prefix="fn" diff="add" at="A">
<fos:signatures>
<fos:proto name="in-scope-namespaces"
return-type="map(union(xs:NCName, enum('')), xs:anyURI)">
return-type="map((xs:NCName | enum('')), xs:anyURI)">
<fos:arg name="element" type="element()" usage="inspection"/>
</fos:proto>
</fos:signatures>
Expand Down Expand Up @@ -11336,8 +11336,8 @@ else QName("", $value)</eg>
<fos:function name="binary-equal" prefix="op">
<fos:signatures>
<fos:proto name="binary-equal" return-type="xs:boolean">
<fos:arg name="value1" type="union(xs:hexBinary, xs:base64Binary)"/>
<fos:arg name="value2" type="union(xs:hexBinary, xs:base64Binary)"/>
<fos:arg name="value1" type="(xs:hexBinary | xs:base64Binary)"/>
<fos:arg name="value2" type="(xs:hexBinary | xs:base64Binary)"/>
</fos:proto>
</fos:signatures>
<fos:opermap operator="eq" types="xs:binary" other-operators="ne"
Expand All @@ -11357,8 +11357,8 @@ else QName("", $value)</eg>
<fos:function name="binary-less-than" prefix="op">
<fos:signatures>
<fos:proto name="binary-less-than" return-type="xs:boolean">
<fos:arg name="arg1" type="union(xs:hexBinary, xs:base64Binary)"/>
<fos:arg name="arg2" type="union(xs:hexBinary, xs:base64Binary)"/>
<fos:arg name="arg1" type="(xs:hexBinary | xs:base64Binary)"/>
<fos:arg name="arg2" type="(xs:hexBinary | xs:base64Binary)"/>
</fos:proto>
</fos:signatures>
<fos:opermap operator="lt" types="xs:hexBinary" other-operators="ge"
Expand Down Expand Up @@ -17336,7 +17336,7 @@ return tokenize(normalize-space($s), ' ')[. castable as xs:IDREF]</eg>
<fos:signatures>
<fos:proto name="serialize" return-type="xs:string">
<fos:arg name="input" type="item()*" usage="absorption"/>
<fos:arg name="options" type="item()?" usage="absorption" default="()" example="{}"/>
<fos:arg name="options" type="(element(output:serialization-parameters) | map(*))" usage="absorption" default="()" example="{}"/>
</fos:proto>
</fos:signatures>
<fos:properties>
Expand Down Expand Up @@ -17587,7 +17587,7 @@ return tokenize(normalize-space($s), ' ')[. castable as xs:IDREF]</eg>
<code>json-node-output-method</code>
</td>
<td>
<code>union(xs:string, xs:QName)?</code>
<code>(xs:string | xs:QName)?</code>
</td>
<td>See Notes 1, 2</td>
<td>
Expand All @@ -17609,7 +17609,7 @@ return tokenize(normalize-space($s), ' ')[. castable as xs:IDREF]</eg>
<code>method</code>
</td>
<td>
<code>union(xs:string, xs:QName)?</code>
<code>(xs:string | xs:QName)?</code>
</td>
<td>See Notes 1, 2</td>
<td>
Expand Down Expand Up @@ -17707,7 +17707,7 @@ return tokenize(normalize-space($s), ' ')[. castable as xs:IDREF]</eg>

<olist>
<item>
<p>The notation <code>union(A, B)</code> is used to represent a union type whose member types are <code>A</code>
<p>The notation <code>(A | B)</code> represents a union type whose member types are <code>A</code>
and <code>B</code>.</p>
</item>
<item>
Expand Down Expand Up @@ -17835,7 +17835,7 @@ serialize(
<fos:function name="parse-html" prefix="fn">
<fos:signatures>
<fos:proto name="parse-html" return-type="document-node(element(*:html))?">
<fos:arg name="html" type="union(xs:string, xs:hexBinary, xs:base64Binary)?"/>
<fos:arg name="html" type="(xs:string | xs:hexBinary | xs:base64Binary)?"/>
<fos:arg name="options" type-ref="parse-html-options"
default="{
&quot;method&quot;: &quot;html&quot;,
Expand Down Expand Up @@ -19771,8 +19771,8 @@ else let $rel = op:simple-compare(head($a), head($b), $C)
then op:lexicographic-compare(tail($a), tail($b), $C)
else $rel</eg></item>
<item><p>Here <code>op:simple-compare($k1, $k2)</code> is defined as follows:</p>
<eg>if ($k1 instance of union(xs:string, xs:anyURI, xs:untypedAtomic)
and $k2 instance of union(xs:string, xs:anyURI, xs:untypedAtomic))
<eg>if ($k1 instance of (xs:string | xs:anyURI | xs:untypedAtomic)
and $k2 instance of (xs:string | xs:anyURI | xs:untypedAtomic))
then compare($k1, $k2, $C)
else if ($k1 instance of xs:numeric and $k2 instance of xs:numeric)
then compare($k1, $k2)
Expand Down Expand Up @@ -22518,7 +22518,7 @@ return $M(collation-key("a", $C))</eg></fos:expression>
converting to <code>xs:double</code> using the XPath casting rules.
Supplying the value <code>xs:decimal#1</code> will instead convert to <code>xs:decimal</code>
(which potentially retains more precision, but disallows exponential notation), while
supplying a function that casts to <code>union(xs:decimal, xs:double)</code> will treat
supplying a function that casts to <code>(xs:decimal | xs:double)</code> will treat
the value as <code>xs:decimal</code> if there is no exponent, or as <code>xs:double</code>
otherwise. Supplying the value <code>fn:identity#1</code> causes the value to be retained
unchanged as an <code>xs:untypedAtomic</code>. Before calling the supplied <code>number-parser</code>,
Expand Down Expand Up @@ -23267,7 +23267,7 @@ return json-to-xml($json, $options)]]></eg>
<p>parameter names: (<var>$row</var>, <var>$col</var>)</p>
</item>
<item>
<p>signature: <code>(xs:positiveInteger, union(xs:xs:positiveInteger, xs:string)) => xs:string?</code></p>
<p>signature: <code>(xs:positiveInteger, (xs:positiveInteger | xs:string)) => xs:string?</code></p>
</item>
<item>
<p>non-local variable bindings: none</p>
Expand Down Expand Up @@ -24388,7 +24388,7 @@ return <csv xmlns="http://www.w3.org/2005/xpath-functions"> {
converting to <code>xs:double</code> using the XPath casting rules.
Supplying the value <code>xs:decimal#1</code> will instead convert to <code>xs:decimal</code>
(which potentially retains more precision, but disallows exponential notation), while
supplying a function that casts to <code>union(xs:decimal, xs:double)</code> will treat
supplying a function that casts to <code>(xs:decimal | xs:double)</code> will treat
the value as <code>xs:decimal</code> if there is no exponent, or as <code>xs:double</code>
otherwise. Supplying the value <code>fn:identity#1</code> causes the value to be retained
unchanged as an <code>xs:untypedAtomic</code>.
Expand Down Expand Up @@ -28071,7 +28071,7 @@ return every($dl/*, fn($elem, $pos) {
<fos:function name="char" prefix="fn">
<fos:signatures>
<fos:proto name="char" return-type="xs:string">
<fos:arg name="value" type="union(xs:string, xs:positiveInteger)"/>
<fos:arg name="value" type="(xs:string | xs:positiveInteger)"/>
</fos:proto>
</fos:signatures>
<fos:properties>
Expand Down
4 changes: 2 additions & 2 deletions specifications/xquery-40/src/errors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1091,11 +1091,11 @@ It is a static error if the name of a feature in
operator.)</p>
</error>

<error spec="XP" code="0147" class="ST" type="static">
<!--<error spec="XP" code="0147" class="ST" type="static">
<p>It is a <termref def="dt-static-error">static error</termref> if a type used as a member
type in a <nt def="LocalUnionType">LocalUnionType</nt> is not a
<termref def="dt-generalized-atomic-type"/>.</p>
</error>
</error>-->

<error spec="XQ" role="xquery" code="0148" class="ST" type="static">
<p>It is a <termref def="dt-static-error">static error</termref> if an optional parameter
Expand Down
Loading

0 comments on commit f7b2043

Please sign in to comment.