Search code examples
treerascal

Rascal MPL how to get all direct node descendants of a node itself


I have a list[Declaration] asts and traverse it as follows:

visit(asts) {
    case node n: {
        println(getChildren(n));
    }
}

I realize that visit will by default traverse the nodes using a top-down strategy. At any point during this traversal, I would like to get the direct node descendants of this node in order to compare them. Now, getChildren(node T) returns list[value], see getChildren. How do I get all direct children as a list[node] instead? As a node is a part of a tree, I would expect a node to have node children of itself.

Additionally, how does one know that lang::java::m3::AST contains nodes? There is no mention of this in either of node, visit, m3::AST. I often find myself spending hours looking for use cases and feature examples like these.


Solution

  • The type system works as follows

    • value is the top
    • node is a sub-type of value representing all tree-shaped abstractions
    • All data types are all sub-types of node (like data Expression = ...)

    So in lang::java::m3::AST everything defined with data declarations are also node's. Some fields in their definitions are str or int. Those values are not of type node.

    If you use getChildren as a generic function for any data type, then they could be anything, from integer to lists and sets and maps, etc. So its return type is list[value].

    If you want to filter the nodes from the list:

    [n | node n <- getChildren(myNode)]
    

    Or you could filter the nodes with location information:

    [n | node n <- getChildren(myNode), n.src?]
    

    Side note: most of the time, however, it is better to focus on specific Statement or Expression nodes rather then writing generic code. Source code analysis is typically specific to the source code. Generic algorithms are scarce and often inaccurate.