Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] XQuery, GH-1424: Fixes Closure copying. #1425

Merged
merged 1 commit into from Feb 25, 2017
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 16 additions & 6 deletions basex-core/src/main/java/org/basex/query/func/Closure.java
Expand Up @@ -227,18 +227,28 @@ public Expr inline(final Var var, final Expr ex, final CompileContext cc) throws

@Override
public Expr copy(final CompileContext cc, final IntObjMap<Var> vm) {
cc.pushScope(new VarScope(vs.sc));
final VarScope innerScope = new VarScope(vs.sc);

final HashMap<Var, Expr> outer = new HashMap<>();
for(final Entry<Var, Expr> e : global.entrySet()) {
outer.put(e.getKey(), e.getValue().copy(cc, vm));
}

cc.pushScope(innerScope);
try {
vs.copy(cc, vm);
final IntObjMap<Var> innerVars = new IntObjMap<>();
vs.copy(cc, innerVars);

final HashMap<Var, Expr> nl = new HashMap<>();
for(final Entry<Var, Expr> e : global.entrySet()) {
nl.put(vm.get(e.getKey().id), e.getValue().copy(cc, vm));
for(final Entry<Var, Expr> e : outer.entrySet()) {
nl.put(innerVars.get(e.getKey().id), e.getValue());
}

final Var[] vars = args.clone();
final int vl = vars.length;
for(int v = 0; v < vl; v++) vars[v] = vm.get(vars[v].id);
for(int v = 0; v < vl; v++) vars[v] = innerVars.get(vars[v].id);

final Expr e = expr.copy(cc, vm);
final Expr e = expr.copy(cc, innerVars);
e.markTailCalls(null);
return copyType(new Closure(info, name, type, vars, e, anns, nl, cc.vs()));
} finally {
Expand Down
15 changes: 15 additions & 0 deletions basex-core/src/test/java/org/basex/query/ast/InlineTest.java
Expand Up @@ -143,4 +143,19 @@ public final class InlineTest extends QueryPlanTest {
"count(//Window) eq 1",
"//Let << //Window");
}

/** Checks that inlining a nested closure works properly. */
@Test public void gh1424() {
check("declare function local:f() {"
+ " let $func := function($key) { map { $key: 'ok' }($key) }"
+ " let $input := <ok/>"
+ " let $call := $func(name($input))"
+ " return function() { $call }"
+ "};"
+ "local:f()()",
"ok",
"exists(/*/DynFuncCall)",
"empty(//StaticFunc)",
"exists(/*/DynFuncCall/GFLWOR/Closure)");
}
}