I have some triples representing the AST of a super simple mock program:
mutation {
set {
_:a <name> "a" .
_:b <name> "b" .
_:c <name> "c" .
_:d <name> "d" .
_:e <name> "e" .
_:a <child> _:b .
_:b <child> _:c .
_:c <child> _:d .
_:d <child> _:e .
_:a <type> "astnode" .
_:b <type> "astnode" .
_:c <type> "astnode" .
_:d <type> "astnode" .
_:e <type> "astnode" .
_:a <kind> "file" .
_:b <kind> "class" .
_:c <kind> "func" .
_:d <kind> "if" .
_:e <kind> "var" .
}
}
The actual data is a more complex tree, and obviously files can contain multiple classes etc.
I would like to create queries that start at a given point in the tree, and traverse children recursively to find elements of various kinds with various properties.
For instance, can I find all descendants of file
of type func
?
I tried:
{
file as f(func: eq(type, "astnode")) {
@filter(eq(kind, "file"))
name
}
recurse(func: eq(type, "astnode")) {
@filter(uid(file))
name
filechildren as child
}
vars(func: uid(filechildren)) {
@filter(eq(kind: "func"))
kind
name
}
}
But the filechildren
variable is only ever set to the uid of the class node. And if I set the filechildren variable like this instead:
filechildren as recurse(func: eq(type, "astnode")) {
@filter(uid(file))
name
child
}
Then the filechildren
variable will only take the value of the uid
of the file node.
In either case, the second block returns the full set of children, but on sets the first child to the filechildren variable. So it seems that variables are only assigned in the first application of the recursive block.