Suppose I want to print all locations with a hard coded value, in a context were d is an M3 Declaration:
top-down visit(d) {
case \number(str numberValue) :
println("hardcode value <numberValue> encountered at <d@\src>");
}
The problem is that the location <d@\src> is too generic, it yields the entire declaration (like the whole procedure). The expression <numberValue@\src> seems more appropriate, but it is not allowed, probably because we are too low in the parse tree.
So, the question is how to get a parent E (the closest parent, like the expression itself) of <numberValue> such that <E@\src> is defined?
One option is to add an extra level in the top-down traversal:
top-down visit(d) {
case \expressionStatement(Expression stmt): {
case \number(str numberValue) :
println("hardcode value <numberValue> encountered at <stmt@\src>");
}
}
This works, but has some drawbacks:
- It is ugly, in order to cover all cases we have to add many more variants;
- It is very inefficient.
So, what is the proper way to get the location of a numberValue (and similar low-level constructs like stringValue's, etc)?