github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/transform/staticlark/analyze.go (about)

     1  package staticlark
     2  
     3  import (
     4  	golog "github.com/ipfs/go-log"
     5  	"go.starlark.net/starlark"
     6  	"go.starlark.net/syntax"
     7  )
     8  
     9  var log = golog.Logger("staticlark")
    10  
    11  // AnalyzeFile performs static analysis and returns diagnostic results
    12  func AnalyzeFile(filename string) ([]Diagnostic, error) {
    13  	// Parse the script to abstract syntax
    14  	f, err := syntax.Parse(filename, nil, 0)
    15  	if err != nil {
    16  		return nil, err
    17  	}
    18  	// Collect function definitions and top level function calls
    19  	funcs, topLevel, err := collectFuncDefsTopLevelCalls(f.Stmts)
    20  	if err != nil {
    21  		return nil, err
    22  	}
    23  	// Constuct pre-defined global symbols
    24  	globals := newSymtable(starlark.Universe)
    25  	// Build a graph of all calls, using top level calls and pre-defined globals
    26  	callGraph := buildCallGraph(funcs, topLevel, globals)
    27  
    28  	// Trace sensitive data using dataflow analysis
    29  	dataflowDiags, err := analyzeSensitiveDataflow(callGraph, nil)
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  
    34  	// Return any unused functions
    35  	// TODO(dustmop): As more analysis steps are introduced, refactor this
    36  	// into a generic interface that creates Diagnostics
    37  	unusedDiags := callGraph.findUnusedFuncs()
    38  	return append(dataflowDiags, unusedDiags...), nil
    39  }
    40  
    41  // Diagnostic represents a diagnostic message describing an issue with the code
    42  type Diagnostic struct {
    43  	Pos      syntax.Position
    44  	Category string
    45  	Message  string
    46  }
    47  
    48  func newSymtable(symbols starlark.StringDict) map[string]*funcNode {
    49  	table := make(map[string]*funcNode)
    50  	for name := range symbols {
    51  		table[name] = &funcNode{name: name}
    52  	}
    53  	return table
    54  }