github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/astutils/staticmethodcollector.go (about)

     1  package astutils
     2  
     3  import (
     4  	"github.com/sirupsen/logrus"
     5  	"go/ast"
     6  	"go/parser"
     7  	"go/token"
     8  )
     9  
    10  // StaticMethodCollector collect methods by parsing source code
    11  type StaticMethodCollector struct {
    12  	Methods    []MethodMeta
    13  	Package    PackageMeta
    14  	exprString func(ast.Expr) string
    15  }
    16  
    17  // Visit traverse each node from source code
    18  func (sc *StaticMethodCollector) Visit(n ast.Node) ast.Visitor {
    19  	return sc.Collect(n)
    20  }
    21  
    22  // Collect collects all static methods from source code
    23  func (sc *StaticMethodCollector) Collect(n ast.Node) ast.Visitor {
    24  	switch spec := n.(type) {
    25  	case *ast.Package:
    26  		return sc
    27  	case *ast.File: // actually it is package name
    28  		sc.Package = PackageMeta{
    29  			Name: spec.Name.Name,
    30  		}
    31  		return sc
    32  	case *ast.FuncDecl:
    33  		if spec.Recv == nil {
    34  			sc.Methods = append(sc.Methods, GetMethodMeta(spec))
    35  		}
    36  	case *ast.GenDecl:
    37  	}
    38  	return nil
    39  }
    40  
    41  type StaticMethodCollectorOption func(collector *StaticMethodCollector)
    42  
    43  // NewStaticMethodCollector initializes an StaticMethodCollector
    44  func NewStaticMethodCollector(exprString func(ast.Expr) string, opts ...StaticMethodCollectorOption) *StaticMethodCollector {
    45  	sc := &StaticMethodCollector{
    46  		Methods:    make([]MethodMeta, 0),
    47  		Package:    PackageMeta{},
    48  		exprString: exprString,
    49  	}
    50  	for _, opt := range opts {
    51  		opt(sc)
    52  	}
    53  	return sc
    54  }
    55  
    56  // BuildStaticMethodCollector initializes an StaticMethodCollector and collects static methods
    57  func BuildStaticMethodCollector(file string, exprString func(ast.Expr) string) StaticMethodCollector {
    58  	sc := NewStaticMethodCollector(exprString)
    59  	fset := token.NewFileSet()
    60  	root, err := parser.ParseFile(fset, file, nil, parser.ParseComments)
    61  	if err != nil {
    62  		logrus.Panicln(err)
    63  	}
    64  	ast.Walk(sc, root)
    65  	return *sc
    66  }