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 }