github.com/blueinnovationsgroup/can-go@v0.0.0-20230518195432-d0567cda0028/pkg/dbc/analysis/passes/nodereferences/analyzer.go (about)

     1  package nodereferences
     2  
     3  import (
     4  	"github.com/blueinnovationsgroup/can-go/pkg/dbc"
     5  	"github.com/blueinnovationsgroup/can-go/pkg/dbc/analysis"
     6  )
     7  
     8  func Analyzer() *analysis.Analyzer {
     9  	return &analysis.Analyzer{
    10  		Name: "nodereferences",
    11  		Doc:  "check that all node references refer to declared nodes",
    12  		Run:  run,
    13  	}
    14  }
    15  
    16  func run(pass *analysis.Pass) error {
    17  	declaredNodes := map[dbc.Identifier]struct{}{
    18  		dbc.NodePlaceholder: {}, // placeholder is implicitly declared
    19  	}
    20  	// collect declared nodes
    21  	for _, def := range pass.File.Defs {
    22  		if def, ok := def.(*dbc.NodesDef); ok {
    23  			for _, nodeName := range def.NodeNames {
    24  				declaredNodes[nodeName] = struct{}{}
    25  			}
    26  		}
    27  	}
    28  	// verify node references
    29  	for _, def := range pass.File.Defs {
    30  		switch def := def.(type) {
    31  		case *dbc.MessageDef:
    32  			if _, ok := declaredNodes[def.Transmitter]; !ok {
    33  				pass.Reportf(def.Pos, "undeclared transmitter node: %v", def.Transmitter)
    34  			}
    35  			for i := range def.Signals {
    36  				signal := &def.Signals[i]
    37  				for _, receiver := range signal.Receivers {
    38  					if _, ok := declaredNodes[receiver]; !ok {
    39  						pass.Reportf(signal.Pos, "undeclared receiver node: %v", receiver)
    40  					}
    41  				}
    42  			}
    43  		case *dbc.EnvironmentVariableDef:
    44  			for _, accessNode := range def.AccessNodes {
    45  				if _, ok := declaredNodes[accessNode]; !ok {
    46  					pass.Reportf(def.Pos, "undeclared access node: %v", accessNode)
    47  				}
    48  			}
    49  		case *dbc.MessageTransmittersDef:
    50  			for _, transmitter := range def.Transmitters {
    51  				if _, ok := declaredNodes[transmitter]; !ok {
    52  					pass.Reportf(def.Pos, "undeclared transmitter node: %v", transmitter)
    53  				}
    54  			}
    55  		}
    56  	}
    57  	return nil
    58  }