}
private IValue traverseNodeOnce(IValue subject, CaseBlockList casesOrRules,
DIRECTION direction, PROGRESS progress, FIXEDPOINT fixedpoint, TraverseResult tr) {
IValue result;
INode node = (INode)subject;
if (node.arity() == 0 && !(node.mayHaveKeywordParameters() && node.asWithKeywordParameters().hasParameters()) ){
result = subject;
}
else {
IValue args[] = new IValue[node.arity()];
Map<String, IValue> kwParams = null;
if (node.mayHaveKeywordParameters() && node.asWithKeywordParameters().hasParameters()) {
kwParams = new HashMap<>();
}
boolean hasChanged = false;
boolean hasMatched = false;
for (int i = 0; i < node.arity(); i++){
IValue child = node.get(i);
tr.changed = false;
tr.matched = false;
args[i] = traverseOnce(child, casesOrRules, direction, progress, fixedpoint, tr);
hasChanged |= tr.changed;
hasMatched |= tr.matched;
}
if (kwParams != null) {
IWithKeywordParameters<? extends INode> nodeKw = node.asWithKeywordParameters();
for (String kwName : nodeKw.getParameterNames()) {
IValue val = nodeKw.getParameter(kwName);
tr.changed = false;
tr.matched = false;
IValue newVal = traverseOnce(val, casesOrRules, direction, progress, fixedpoint, tr);
kwParams.put(kwName, newVal);
hasChanged |= tr.changed;
hasMatched |= tr.matched;
}
}
tr.changed = hasChanged;
tr.matched = hasMatched;
INode n = null;
if (kwParams != null) {
n = eval.getValueFactory().node(node.getName(), args, kwParams);
}
else {
n = eval.getValueFactory().node(node.getName(), args);
if (!node.mayHaveKeywordParameters() && node.asAnnotatable().hasAnnotations()) {
n = n.asAnnotatable().setAnnotations(node.asAnnotatable().getAnnotations());
}
}
result = n;
}