package org.scribble.ast.local;
import java.util.Set;
import org.antlr.runtime.tree.CommonTree;
import org.scribble.ast.AstFactoryImpl;
import org.scribble.ast.ProtocolBlock;
import org.scribble.ast.Recursion;
import org.scribble.ast.name.simple.RecVarNode;
import org.scribble.del.ScribDel;
import org.scribble.main.ScribbleException;
import org.scribble.sesstype.Message;
import org.scribble.sesstype.kind.Local;
import org.scribble.sesstype.name.Role;
import org.scribble.visit.context.ProjectedChoiceSubjectFixer;
public class LRecursion extends Recursion<Local> implements LCompoundInteractionNode
{
public LRecursion(CommonTree source, RecVarNode recvar, LProtocolBlock block)
{
super(source, recvar, block);
}
@Override
protected LRecursion copy()
{
return new LRecursion(this.source, this.recvar, getBlock());
}
@Override
public LRecursion reconstruct(RecVarNode recvar, ProtocolBlock<Local> block)
{
ScribDel del = del();
LRecursion lr = new LRecursion(this.source, recvar, (LProtocolBlock) block);
lr = (LRecursion) lr.del(del);
return lr;
}
@Override
public LRecursion clone()
{
RecVarNode recvar = this.recvar.clone();
LProtocolBlock block = getBlock().clone();
return AstFactoryImpl.FACTORY.LRecursion(this.source, recvar, block);
}
@Override
public LProtocolBlock getBlock()
{
return (LProtocolBlock) this.block;
}
@Override
public Role inferLocalChoiceSubject(ProjectedChoiceSubjectFixer fixer)
{
//fixer.pushRec(this.recvar.toName());
return getBlock().getInteractionSeq().getInteractions().get(0).inferLocalChoiceSubject(fixer);
}
// FIXME: shouldn't be needed, but here due to Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=436350
@Override
public Local getKind()
{
return LCompoundInteractionNode.super.getKind();
}
@Override
public LInteractionNode merge(LInteractionNode ln) throws ScribbleException
{
if (!(ln instanceof LRecursion) || !this.canMerge(ln))
{
throw new ScribbleException("Cannot merge " + this.getClass() + " and " + ln.getClass() + ": " + this + ", " + ln);
}
LRecursion them = ((LRecursion) ln);
if (!this.recvar.equals(them.recvar))
{
throw new ScribbleException("Cannot merge recursions for " + this.recvar + " and " + them.recvar + ": " + this + ", " + ln);
}
return AstFactoryImpl.FACTORY.LRecursion(this.source, this.recvar.clone(), getBlock().merge(them.getBlock())); // Not reconstruct: leave context building to post-projection passes
// HACK: this source
}
@Override
public boolean canMerge(LInteractionNode ln)
{
return ln instanceof LRecursion;
}
@Override
public Set<Message> getEnabling()
{
return getBlock().getEnabling();
}
}