Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions basex-core/src/main/java/org/basex/query/func/Closure.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,8 @@ public Expr optimize(final CompileContext cc) {
cc.removeScope(this);
}

final SeqType st = expr.seqType();
final SeqType dt = declType == null || st.instanceOf(declType) ? st : declType;
exprType.assign(FuncType.get(anns, dt, params));
// declared type for instance-of/coercion (item()* if none), body type as refined return type
exprType.assign(FuncType.get(anns, declType, params).withRefinedType(expr.seqType()));

// only evaluate if:
// - the closure is empty, so we don't lose variables
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public Expr optimize(final CompileContext cc) throws QueryException {
if(!updating && ft.anns.contains(Annotation.UPDATING)) {
throw FUNCUP_X.get(info, func);
}
exprType.assign(ft.declType);
exprType.assign(ft.refinedType);
}

if(func instanceof XQStruct) {
Expand Down
4 changes: 2 additions & 2 deletions basex-core/src/main/java/org/basex/query/func/PartFunc.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public Expr optimize(final CompileContext cc) throws QueryException {
args[placeholderPerm == null ? a : placeholderPerm[a]] = ft.argTypes[e];
++a;
}
exprType.assign(FuncType.get(ft.declType, args).seqType());
exprType.assign(FuncType.get(ft.declType, args).withRefinedType(ft.refinedType).seqType());
}
}
return this;
Expand Down Expand Up @@ -114,7 +114,7 @@ private FuncItem funcItem(final FItem func, final QueryContext qc) throws QueryE
final boolean updating = anns.contains(Annotation.UPDATING);
final DynFuncCall expr = new DynFuncCall(info, updating, false, func, args);

final FuncType type = FuncType.get(anns, ft.declType, params);
final FuncType type = FuncType.get(anns, ft.declType, params).withRefinedType(ft.refinedType);
return new FuncItem(info, expr, params, anns, type, vs.stackSize(), null, qc.focus.copy());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ public QNm paramName(final int pos) {

@Override
public FuncType funcType() {
return FuncType.get(anns, declType, params);
// refined return type: the body type (via seqType), consistent with call-result typing
return FuncType.get(anns, declType, params).withRefinedType(seqType());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ protected Expr opt(final CompileContext cc) throws QueryException {

arg(1, arg -> refineFunc(arg, cc, st.with(Occ.EXACTLY_ONE), Types.INTEGER_O));
final FuncType ft = arg(1).funcType();
if(ft != null) exprType.assign(ArrayType.get(ft.declType));
if(ft != null) exprType.assign(ArrayType.get(ft.refinedType));
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ protected Expr opt(final CompileContext cc) throws QueryException {

// assign type after coercion (expression might have changed)
final FuncType ft = arg(1).funcType();
if(ft != null) exprType.assign(ArrayType.get(ft.declType));
if(ft != null) exprType.assign(ArrayType.get(ft.refinedType));

return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ protected Expr opt(final CompileContext cc) throws QueryException {

// assign type after coercion (expression might have changed)
final FuncType ft = arg(2).funcType();
if(ft != null) exprType.assign(ArrayType.get(ft.declType));
if(ft != null) exprType.assign(ArrayType.get(ft.refinedType));

return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ protected Expr opt(final CompileContext cc) throws QueryException {
}

ft = arg(0).funcType();
if(ft != null) exprType.assign(ft.declType);
if(ft != null) exprType.assign(ft.refinedType);
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,12 @@ protected final Expr optType(final CompileContext cc, final boolean array, final
final SeqType[] types = { left ? st : i1t, left ? i1t : st, Types.INTEGER_O };
arg(2, arg -> refineFunc(action, cc, types));
ost = st;
st = st.union(arg(2).funcType().declType);
st = st.union(arg(2).funcType().refinedType);
} while(!st.eq(ost));
exprType.assign(st);
} else {
final FuncType ft = action.funcType();
if(ft != null) exprType.assign(ist.oneOrMore() ? ft.declType : zst.union(ft.declType));
if(ft != null) exprType.assign(ist.oneOrMore() ? ft.refinedType : zst.union(ft.refinedType));
}
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public final Iter iter(final QueryContext qc) throws QueryException {
final FItem action = toFunction(arg(2), 3, this instanceof UpdateForEachPair, qc);

return new Iter() {
final long size = action.funcType().declType.one() ?
final long size = action.funcType().refinedType.one() ?
Math.min(input1.size(), input2.size()) : -1;
final HofArgs args = new HofArgs(3, action);
Iter iter = Empty.ITER;
Expand Down Expand Up @@ -64,7 +64,7 @@ protected final Expr opt(final CompileContext cc) throws QueryException {
// assign type after refinement
final FuncType ft = arg(2).funcType();
if(ft != null) {
final SeqType declType = ft.declType;
final SeqType declType = ft.refinedType;
final boolean oneOrMore = st1.oneOrMore() && st2.oneOrMore() && declType.oneOrMore();
final long size = declType.zero() ? 0 : declType.one() ?
Math.min(input1.size(), input2.size()) : -1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ protected Expr opt(final CompileContext cc) throws QueryException {
final SeqType[] types = { st, Types.INTEGER_O };
arg(1, arg -> refineFunc(step, cc, types));
ost = st;
st = st.union(arg(1).funcType().declType);
st = st.union(arg(1).funcType().refinedType);
} while(!st.eq(ost));
exprType.assign(st.with(Occ.ONE_OR_MORE));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public Value value(final QueryContext qc) throws QueryException {
funcCall = new DynFuncCall(info,
new PartFunc(info, ExprList.concat(funcArgs, function), placeholders, null), args);
}
return new FuncItem(info, funcCall, params, AnnList.EMPTY, FuncType.get(ft.declType, argTypes),
params.length, null);
return new FuncItem(info, funcCall, params, AnnList.EMPTY,
FuncType.get(ft.declType, argTypes).withRefinedType(ft.refinedType), params.length, null);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ protected final Expr opt(final CompileContext cc) throws QueryException {
final SeqType[] types = { st, Types.INTEGER_O };
arg(a, arg -> refineFunc(action, cc, types));
ost = st;
st = st.union(arg(a).funcType().declType);
st = st.union(arg(a).funcType().refinedType);
} while(!st.eq(ost));

final SeqType[] types = { st, Types.INTEGER_O };
Expand All @@ -48,7 +48,7 @@ protected final Expr opt(final CompileContext cc) throws QueryException {
exprType.assign(st);
} else {
final FuncType ft = action.funcType();
if(ft != null) exprType.assign(st.union(ft.declType));
if(ft != null) exprType.assign(st.union(ft.refinedType));
}
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ protected Expr opt(final CompileContext cc) {
if(input.seqType().zero()) return input;

final FuncType ft = action.funcType();
if(ft != null) exprType.assign(ft.declType);
if(ft != null) exprType.assign(ft.refinedType);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ protected Expr opt(final CompileContext cc) throws QueryException {

SeqType st = zero.seqType();
final FuncType ft = action.funcType();
if(ft != null) st = st.union(ft.declType);
if(ft != null) st = st.union(ft.refinedType);
exprType.assign(st.with(Occ.ZERO_OR_MORE));
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ protected Expr opt(final CompileContext cc) throws QueryException {
Type kt = fiKey || keys.size() == 0 ? s1t.type : BasicType.ITEM;
if(fiKey) {
arg(1, arg -> refineFunc(arg, cc, s1t));
kt = arg(1).funcType().declType.type;
kt = arg(1).funcType().refinedType.type;
}
kt = kt.atomic();

final boolean fiValue = value instanceof FuncItem || value instanceof Closure;
SeqType vt = fiValue || value.size() == 0 ? s1t : Types.ITEM_ZM;
if(fiValue) {
arg(2, arg -> refineFunc(arg, cc, s1t));
vt = arg(2).funcType().declType;
vt = arg(2).funcType().refinedType;
}
assignType(kt, vt);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public Iter iter(final QueryContext qc) throws QueryException {
final FItem action = toFunction(arg(1), 3, this instanceof UpdateMapForEach, qc);

return new Iter() {
final long size = action.funcType().declType.one() ? map.structSize() : -1;
final long size = action.funcType().refinedType.one() ? map.structSize() : -1;
final BasicIter<Item> keys = map.keys().iter();
final HofArgs args = new HofArgs(3, action);
Iter iter = Empty.ITER;
Expand Down Expand Up @@ -65,7 +65,7 @@ protected final Expr opt(final CompileContext cc) throws QueryException {

final FuncType ft = arg(1).funcType();
if(ft != null) {
final SeqType st = ft.declType;
final SeqType st = ft.refinedType;
exprType.assign(st.type.seqType(Occ.ZERO_OR_MORE), st.one() ? map.structSize() : -1);
}
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ Value get(final Item key, final Value old, final Value value, final QueryContext

@Override
SeqType type(final SeqType st) {
return st.union(function.funcType().declType);
return st.union(function.funcType().refinedType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ protected Expr opt(final CompileContext cc) throws QueryException {
if(arg(2) == Empty.UNDEFINED) {
final FuncType ft = action.funcType();
if(ft != null) {
final SeqType dt = ft.declType;
final SeqType dt = ft.refinedType;
exprType.assign(dt.with(dt.occ.multiply(input.seqType().occ)));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ protected Expr opt(final CompileContext cc) throws QueryException {
return new DynFuncCall(info, coerceFunc(0, cc)).optimize(cc);
}
final FuncType ft = functions.funcType();
if(ft != null) exprType.assign(ft.declType);
if(ft != null) exprType.assign(ft.refinedType);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ protected Expr opt(final CompileContext cc) throws QueryException {
if(results == Boolean.TRUE) {
final FuncType ft = functions.funcType();
if(ft != null) {
final SeqType dt = ft.declType;
final SeqType dt = ft.refinedType;
exprType.assign(dt.with(dt.occ.multiply(st.occ)));
}
} else if(results == Boolean.FALSE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ protected Expr opt(final CompileContext cc) {
// result type: union of the seed type and the declared action/combine types
SeqType st = init.seqType();
final FuncType at = arg(2).funcType(), ct = arg(3).funcType();
if(at != null) st = st.union(at.declType);
if(ct != null) st = st.union(ct.declType);
if(at != null) st = st.union(at.refinedType);
if(ct != null) st = st.union(ct.refinedType);
exprType.assign(st);
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,13 @@ public FItem coerceTo(final FuncType ft, final QueryContext qc, final CompileCon

// add type check if return types differ
final SeqType dt = ft.declType;
FuncType tp = funcType();
if(!body.seqType().instanceOf(dt)) {
body = new TypeCheck(info, body, dt);
if(cc != null) body = body.optimize(cc);
}

// adopt type of optimized body if it is more specific than passed on type
final SeqType bt = body.seqType();
tp = cc != null && !bt.eq(dt) && bt.instanceOf(dt) ? FuncType.get(bt, argTypes) : ft;
// advertise the target type; keep the body type as refined return type for result typing
final FuncType tp = cc != null ? ft.withRefinedType(body.seqType()) : ft;
body.markTailCalls(null);
return new FuncItem(info, body, vars, annotations(), tp, vs.stackSize(), funcName());
} finally {
Expand Down
Loading
Loading