package nl.utwente.viskell.ui.components; import java.util.ArrayList; import java.util.Optional; import nl.utwente.viskell.haskell.expr.Binder; import nl.utwente.viskell.haskell.type.Type; /** Variant of the OutputAnchor that maintains a separate type for each connections. * This is used e.g. for the anchor from a lambda block to allow each use site having a different specialized type. */ public class PolyOutputAnchor extends OutputAnchor { /** List of type corresponding to each connection */ private final ArrayList<Type> connectionTypes; public PolyOutputAnchor(Block block, Binder binder) { super(block, binder); this.connectionTypes = new ArrayList<>(); } @Override public Type getType(Optional<Connection> targetConnection) { if (targetConnection.isPresent()) { int index = this.connections.indexOf(targetConnection.get()); return this.connectionTypes.get(index); } return this.binder.getBoundType(); } @Override protected void addConnection(Connection connection) { super.addConnection(connection); this.connectionTypes.add(this.binder.getBoundType().getFresh()); } @Override protected void dropConnection(Connection connection) { int index = this.connections.indexOf(connection); super.dropConnection(connection); if (index >= 0) { this.connectionTypes.remove(index); } } @Override public void removeConnections() { super.removeConnections(); this.connectionTypes.clear(); } public void setExactRequiredType(Type type) { super.setExactRequiredType(type); for (int i = 0; i < this.connectionTypes.size(); i++) { this.connectionTypes.set(i, this.binder.getBoundType().getFresh()); } } }