1+ package org .basex .query .func .fn ;
2+
3+ import static org .basex .query .value .type .SeqType .*;
4+
5+ import java .util .*;
6+
7+ import org .basex .query .*;
8+ import org .basex .query .expr .*;
9+ import org .basex .query .func .*;
10+ import org .basex .query .util .list .*;
11+ import org .basex .query .value .*;
12+ import org .basex .query .value .item .*;
13+ import org .basex .query .value .map .*;
14+ import org .basex .query .value .seq .*;
15+ import org .basex .query .value .type .*;
16+ import org .basex .query .var .*;
17+
18+ /**
19+ * Function implementation.
20+ *
21+ * @author BaseX Team, BSD License
22+ * @author Gunther Rademacher
23+ */
24+ public class FnPartialApply extends StandardFunc {
25+ /** The type of parameter "arguments". */
26+ private static final SeqType ARGS_TYPE = MapType .get (AtomType .POSITIVE_INTEGER ,
27+ ITEM_ZM ).seqType ();
28+ /** The name of parameter "arguments". */
29+ private static final QNm ARGS_NAME = new QNm ("arguments" );
30+
31+ @ Override
32+ public Value value (final QueryContext qc ) throws QueryException {
33+ final FItem function = toFunction (arg (0 ), qc );
34+ final XQMap arguments = toMap (ARGS_TYPE .coerce (arg (1 ).value (qc ), ARGS_NAME , qc , null , info ),
35+ qc );
36+ final int arity = function .arity ();
37+ if (arity == 0 || arguments == XQMap .empty ()) return function ;
38+
39+ final FuncType ft = function .funcType ();
40+ final Expr [] funcArgs = new Expr [arity ];
41+ Arrays .fill (funcArgs , Empty .UNDEFINED );
42+ int placeholders = arity ;
43+ for (final Item key : arguments .keys ()) {
44+ final long index = toLong (key );
45+ if (index <= arity ) {
46+ final int i = (int ) index - 1 ;
47+ funcArgs [i ] = ft .argTypes [i ].coerce (arguments .get (key ), function .paramName (i ), qc , null ,
48+ info );
49+ --placeholders ;
50+ }
51+ }
52+ if (placeholders == arity ) return function ;
53+
54+ final DynFuncCall funcCall ;
55+ final Var [] params = new Var [placeholders ];
56+ final SeqType [] argTypes = new SeqType [placeholders ];
57+ if (placeholders == 0 ) {
58+ funcCall = new DynFuncCall (info , function , funcArgs );
59+ } else {
60+ final VarScope vs = new VarScope ();
61+ final Expr [] args = new Expr [placeholders ];
62+ int p = 0 ;
63+ for (int i = 0 ; i < arity ; ++i ) {
64+ if (funcArgs [i ] == Empty .UNDEFINED ) {
65+ final Var var = vs .addNew (function .paramName (i ), ft .argTypes [i ], qc , info );
66+ params [p ] = var ;
67+ args [p ++] = new VarRef (info , var );
68+ }
69+ }
70+ funcCall = new DynFuncCall (info ,
71+ new PartFunc (info , ExprList .concat (funcArgs , function ), placeholders , null ), args );
72+ }
73+ return new FuncItem (info , funcCall , params , AnnList .EMPTY , FuncType .get (ft .declType , argTypes ),
74+ params .length , null );
75+ }
76+
77+ @ Override
78+ public int hofIndex () {
79+ return 0 ;
80+ }
81+ }
0 commit comments