package org.scribble.del.local;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.scribble.ast.AstFactoryImpl;
import org.scribble.ast.RoleDecl;
import org.scribble.ast.RoleDeclList;
import org.scribble.ast.ScribNode;
import org.scribble.ast.local.LProtocolDecl;
import org.scribble.ast.local.LProtocolHeader;
import org.scribble.main.ScribbleException;
import org.scribble.sesstype.name.GProtocolName;
import org.scribble.sesstype.name.Role;
import org.scribble.visit.context.ProjectedRoleDeclFixer;
public class LProjectionDeclDel extends LProtocolDeclDel
{
// Maybe better to store in context, but more convenient to pass to here via factory (than infer in context building) -- could alternatively store in projected module
private final GProtocolName fullname;
private final Role self;
public LProjectionDeclDel(GProtocolName fullname, Role self)
{
this.fullname = fullname;
this.self = self;
}
@Override
protected LProtocolDeclDel copy()
{
return new LProjectionDeclDel(this.fullname, this.self);
}
@Override
public ScribNode leaveProjectedRoleDeclFixing(ScribNode parent, ScribNode child, ProjectedRoleDeclFixer fixer, ScribNode visited) throws ScribbleException
{
LProtocolDecl lpd = (LProtocolDecl) visited;
// FIXME: ensure all role params are used, to avoid empty roledecllist
Set<Role> occs = ((LProtocolDeclDel) lpd.del()).getProtocolDeclContext().getRoleOccurrences();
List<RoleDecl> rds = lpd.header.roledecls.getDecls().stream().filter((rd) ->
occs.contains(rd.getDeclName())).collect(Collectors.toList());
RoleDeclList rdl = AstFactoryImpl.FACTORY.RoleDeclList(lpd.header.roledecls.getSource(), rds);
LProtocolHeader header = lpd.getHeader().reconstruct(lpd.getHeader().getNameNode(), rdl, lpd.header.paramdecls);
LProtocolDecl fixed = lpd.reconstruct(header, lpd.def);
fixer.job.debugPrintln("\n[DEBUG] Projected " + getSourceProtocol() + " for " + getSelfRole() + ":\n" + fixed);
return super.leaveProjectedRoleDeclFixing(parent, child, fixer, fixed);
}
public GProtocolName getSourceProtocol()
{
return this.fullname;
}
// Redundant with SelfRoleDecl in header
public Role getSelfRole()
{
return this.self;
}
}