package org.scribble.ast; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; import org.antlr.runtime.tree.CommonTree; import org.scribble.main.ScribbleException; import org.scribble.sesstype.kind.ProtocolKind; import org.scribble.visit.AstVisitor; public abstract class InteractionSeq<K extends ProtocolKind> extends ScribNodeBase implements ProtocolKindNode<K> { private final List<? extends InteractionNode<K>> inters; /*@SuppressWarnings("unchecked") private final Function<ScribNode, InteractionNode<K>> cast = (n) -> (InteractionNode<K>) n;*/ protected InteractionSeq(CommonTree source, List<? extends InteractionNode<K>> inters) { super(source); this.inters = inters; } public abstract InteractionSeq<K> reconstruct(List<? extends InteractionNode<K>> ins); @SuppressWarnings("unchecked") private final Function<ScribNode, ProtocolKindNode<K>> KIND_CAST = (n) -> (ProtocolKindNode<K>) n; @Override public ScribNode visitChildren(AstVisitor nv) throws ScribbleException { //List<? extends InteractionNode<K>> actions = visitChildListWithStrictClassCheck(this, this.actions, nv); //List<InteractionNode<K>> actions = visitChildListWithCastCheck(this, this.inters, nv, InteractionNode.class, getKind(), this.cast); // Maybe too strict (e.g. rec unfolding maybe shouldn't return the rec) List<InteractionNode<K>> actions = new LinkedList<>(); for (InteractionNode<K> in : this.inters) { //ScribNode visited = visitChild(in, nv); ProtocolKindNode<K> visited = visitProtocolKindChildWithCastCheck(this, in, nv, ProtocolKindNode.class, in.getKind(), KIND_CAST); if (visited instanceof InteractionSeq<?>) { InteractionSeq<K> tmp = (InteractionSeq<K>) visited; actions.addAll(tmp.inters); } else { InteractionNode<K> tmp = (InteractionNode<K>) visited; actions.add(tmp); } } return reconstruct(actions); } public List<? extends InteractionNode<K>> getInteractions() { return Collections.unmodifiableList(this.inters); } public boolean isEmpty() { return this.inters.isEmpty(); } @Override public String toString() { return this.inters.stream().map((i) -> i.toString()).collect(Collectors.joining("\n")); } }