[enhancement] function type checks#3389
Conversation
exist-core/src/main/java/org/exist/xquery/functions/fn/FunHigherOrderFun.java
Outdated
Show resolved
Hide resolved
a475f6d to
ef097a5
Compare
ef097a5 to
021dee1
Compare
d43dff6 to
1403b00
Compare
|
Nine additional XQTS cases pass:
failing XQTS tests are due to
|
|
SonarCloud Quality Gate failed.
|
|
As discussed in the Community Call, this PR helps with XQuery conformance, achieves 9 more passing XQTS tests that previously failed, provides better static checking, and lays the groundwork for additional type checking of function parameters and return values. |
adamretter
left a comment
There was a problem hiding this comment.
I think this is a great start, and I am excited to see it. I do think it requires some work yet to complete it and polish it.
Apart from my specific code comments I am a bit confused by this statement in the PR description:
NOTE:
An implementation decision was, to still allow developers to writefilter(1, function ($a) { exists($a) })instead of having to write
filter(1, function ($a) as xs:boolean { exists($a) })
Unless I am mistaken, that isn't a decision for an Implementation... It is actually required by the XQuery 3.1 specification, see: https://www.w3.org/TR/xquery-31/#prod-xquery31-InlineFunctionExpr
I am also not sure I understand this statement:
This later check is currently done in the function implementation itself (see fn:filter).
I understand that every function that accepts a function (as a parameter) will need its function signature modified to declare the additional parameter/return types, but
does that also mean that each of those also needs to be modified to perform the actual type checks of the function parameter's parameters? If so, it would seem that this checking should be moved out into something like the DynamicCardinalityCheck class.
exist-core/src/main/java/org/exist/xquery/value/FunctionParameterFunctionSequenceType.java
Outdated
Show resolved
Hide resolved
exist-core/src/main/java/org/exist/xquery/value/FunctionParameterFunctionSequenceType.java
Outdated
Show resolved
Hide resolved
exist-core/src/main/java/org/exist/xquery/value/FunctionParameterFunctionSequenceType.java
Outdated
Show resolved
Hide resolved
exist-core/src/main/java/org/exist/xquery/value/FunctionParameterFunctionSequenceType.java
Outdated
Show resolved
Hide resolved
exist-core/src/main/java/org/exist/xquery/value/FunctionParameterFunctionSequenceType.java
Show resolved
Hide resolved
| * @param primaryType The <strong>Type</strong> of the parameter. | ||
| * @param parameterTypes The <strong>parameters</strong> the function(s) must accept. | ||
| * @param returnType The <strong>Type</strong> the function(s) needs to return. | ||
| * @param cardinality The <strong>Cardinality</strong> of the parameter. |
There was a problem hiding this comment.
The cardinality parameter should follow the primaryType parameter, as they are part of the same sequence type. This is how it currently works in FunctionParameterSequenceType and that should be preserved here, as it makes the code for defining a FunctionSignature more logical to both write and read.
- Static errors in Function.createFunction now throw an XPathException with error code `EXXQST0001`. - remove redundant null initialization - replace call to PathExpr.getExpression with getSubExpression
- incorporate learnings from eXist-db#5018 - refactor both implementations of checkType for readability - remove unused constructor - remove unnecessary method arityUnspecified
- fix formatting - mark getters as nullable that might return null - remove redundant initializations - remove dead code # Conflicts: # exist-core/src/main/java/org/exist/xquery/FunctionSignature.java
# Conflicts: # exist-core/src/main/java/org/exist/xquery/FunctionSignature.java
Adding some lines to make the intent a little more obvious to the reader. Also, module.isInternalModule() will not change and should therefore only be called once.
Testcases are much more concise and assert more properties.
- added two new XQSuite tests to ensure this functionality
- Add new Function funParam to FunctionDSL to integrate new FunctionParameterFunctionSequenceType parameters - FunctionParameterFunctionSequenceType now uses FunctionParameterSequenceType instead of SequenceType for better integration with FunctionDSL - Use FunctionDSL in MapFunction - use new switch statement in MapFunction.eval - add enum for MapFunction similar to ArrayFunction - adapt FunHigherOrderFun and ArrayFunction
- Refactor ArrayModule and ArrayFunction to use FunctionDSL and export each function as a named static export. ArrayFunction.eval also now just dispatches to private methods which greatly reduces complexity. - Make better use of FunctionDSL in MapModule: - drop functionSignatures in favour of named exports denoting the arity rather than the position in an array - rename function exports for brevity - make use of functionDefs
fixes eXist-db#6125 - simplify MapType.get by directly providing the default value - refactor MapFunction for readability and maintainability by extracting methods for different merge scenarios and introducing a method to select the duplicate handling strategy - add xqsuite test
- Clarified text - removed author
- use enum for function list - switch to FunctionDSL for all functions - eval is just one switch dispatching calls to extracted private methods - add methods for all function implementations
- return early - extract method getRealName - toString method outputs function item types in their most generic but correct form
Used in stacktraces for example FunctionParameterFunctionSequenceType will now show up with all their information.
Declare variable realNode only when needed.
Improve FunctionDSL - drop redundant parameters from funParam - add optFunParam, optManyFunParam Reorganize constructors or FunctionParameterFunctionSequenceType for ease of use. Adapt calls to funParam
aed2487 to
66db85e
Compare
2195ec7 to
66db85e
Compare
- expand all imports to single class imports - move function enum to the end of the class - reorder function signature definitions - fix formatting
- reorder the functions, enums and function defitions by the order of appearance in the XQuery Functions and Operators specification - add and improve topmost documentation blocks
690ed3b to
b4947b5
Compare










Description:
BREAKING CHANGE
Internal module functions can now enforce function parameters to adhere to a given signature.
This is added to all HoFs
fn:filter,fn:for-each,fn:fold-left,fn:fold-rightas wellas their Array and Map function variants.
It is written such that other function values can also be checked
array(xs:string)or complex ones likemap(xs:integer, function(array(*)) as xs:boolean))NOTE:
An implementation decision was, to still allow developers to write
instead of having to write
For function parameters that return
item()*, defer the return type check. Throw an error when the first non-matching result is returned.This later check is currently done in the function implementation itself (see
fn:filter).A better alternative would be:
item()*Examples:
fn:filter->function (item()) as xs:booleanarray:for-each-pair->function (item()*, item()*) as item()*map:for-each->function (xs:anyAtomicValue, item()*) as item()*Basex seems to follow the same optimistic approach
Reference:
Result of discussion with @adamretter in #3364
Is related to #1917
supersedes #3361 (the expathrepo related commit will be added here)
fixes #3382
fixes #4596
fixes #6125
related #3370
Type of tests:
All tests pass, two where adapted to match correct behaviour.