github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/compiler/desugarer/del.go (about)

     1  package desugarer
     2  
     3  import (
     4  	src "github.com/nevalang/neva/internal/compiler/sourcecode"
     5  	"github.com/nevalang/neva/internal/compiler/sourcecode/core"
     6  )
     7  
     8  type voidResult struct {
     9  	voidNodeName       string
    10  	voidNode           src.Node
    11  	virtualConnections []src.Connection
    12  }
    13  
    14  func (Desugarer) handleUnusedOutports(unusedOutports nodePortsMap) voidResult {
    15  	destructorNodeName := "__del__"
    16  
    17  	result := voidResult{
    18  		voidNodeName: destructorNodeName,
    19  		voidNode: src.Node{
    20  			EntityRef: core.EntityRef{
    21  				Pkg:  "builtin",
    22  				Name: "Del",
    23  			},
    24  		},
    25  		virtualConnections: make([]src.Connection, 0, len(unusedOutports.m)),
    26  	}
    27  
    28  	receiverSides := []src.ConnectionReceiver{
    29  		{
    30  			PortAddr: src.PortAddr{
    31  				Node: destructorNodeName,
    32  				Port: "msg",
    33  			},
    34  		},
    35  	}
    36  
    37  	voidConns := make([]src.Connection, 0, len(unusedOutports.m))
    38  	for nodeName, ports := range unusedOutports.m {
    39  		for portName := range ports {
    40  			voidConns = append(voidConns, src.Connection{
    41  				Normal: &src.NormalConnection{
    42  					SenderSide: src.ConnectionSenderSide{
    43  						PortAddr: &src.PortAddr{
    44  							Node: nodeName,
    45  							Port: portName,
    46  						},
    47  					},
    48  					ReceiverSide: src.ConnectionReceiverSide{
    49  						Receivers: receiverSides,
    50  					},
    51  				},
    52  				Meta: core.Meta{},
    53  			})
    54  		}
    55  	}
    56  
    57  	result.virtualConnections = voidConns
    58  
    59  	return result
    60  }
    61  
    62  func (Desugarer) findUnusedOutports(
    63  	component src.Component,
    64  	scope src.Scope,
    65  	usedNodePorts nodePortsMap,
    66  ) nodePortsMap {
    67  	unusedOutports := newNodePortsMap()
    68  
    69  	for nodeName, node := range component.Nodes {
    70  		entity, _, err := scope.Entity(node.EntityRef)
    71  		if err != nil {
    72  			continue
    73  		}
    74  		if entity.Kind != src.InterfaceEntity && entity.Kind != src.ComponentEntity {
    75  			continue
    76  		}
    77  
    78  		var io src.IO
    79  		if entity.Kind == src.InterfaceEntity {
    80  			io = entity.Interface.IO
    81  		} else {
    82  			io = entity.Component.Interface.IO
    83  		}
    84  
    85  		for outportName := range io.Out {
    86  			ok := usedNodePorts.get(nodeName, outportName)
    87  			if !ok {
    88  				unusedOutports.set(nodeName, outportName)
    89  			}
    90  		}
    91  	}
    92  
    93  	if unusedOutports.len() == 0 {
    94  		return nodePortsMap{}
    95  	}
    96  
    97  	return unusedOutports
    98  }
    99  
   100  type nodePortsMap struct {
   101  	m map[string]map[string]struct{}
   102  }
   103  
   104  func (n nodePortsMap) set(node string, outport string) {
   105  	if n.m[node] == nil {
   106  		n.m[node] = map[string]struct{}{}
   107  	}
   108  	n.m[node][outport] = struct{}{}
   109  }
   110  
   111  func (n nodePortsMap) get(node, port string) bool {
   112  	ports, ok := n.m[node]
   113  	if !ok {
   114  		return false
   115  	}
   116  	_, ok = ports[port]
   117  	return ok
   118  }
   119  
   120  func (n nodePortsMap) merge(m nodePortsMap) {
   121  	for node, ports := range m.m {
   122  		for outport := range ports {
   123  			n.set(node, outport)
   124  		}
   125  	}
   126  }
   127  
   128  func (n nodePortsMap) len() int {
   129  	return len(n.m)
   130  }
   131  
   132  func newNodePortsMap() nodePortsMap {
   133  	return nodePortsMap{
   134  		m: map[string]map[string]struct{}{},
   135  	}
   136  }