178 lines
4.2 KiB
Go
178 lines
4.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"go/ast"
|
|
"go/parser"
|
|
"go/token"
|
|
"os"
|
|
"strings"
|
|
"text/template"
|
|
)
|
|
|
|
// The package path you want to scan for functions
|
|
const (
|
|
packagePath = "api/" // Update this to your package path
|
|
packageName = "eiaapi"
|
|
mapperFile = "api/eiaapi_funcmap.gen.go"
|
|
)
|
|
|
|
const tmplParseFuncs = `package ` + packageName + `
|
|
|
|
// Generated map of Parse functions to support
|
|
// dynamic reflection upon parser functions
|
|
var ParseFunctionsMap = map[string]interface{}{
|
|
{{- range .}}
|
|
"{{ . }}": {{ . }},
|
|
{{- end}}
|
|
}
|
|
`
|
|
|
|
type FunctionParamInfo struct {
|
|
FunctionName string
|
|
Params []FunctionParam
|
|
}
|
|
|
|
type FunctionParam struct {
|
|
Name string
|
|
Type string
|
|
}
|
|
|
|
const tmplFuncParams = `
|
|
// List of functions in eiaapi package
|
|
// with slice of arg types as strings
|
|
|
|
type FunctionParam struct {
|
|
Name string
|
|
Type string
|
|
}
|
|
|
|
var FunctionParams = map[string][]FunctionParam{
|
|
{{- range .}}
|
|
"{{ .FunctionName }}": {
|
|
{{- range .Params }}
|
|
{
|
|
Name: {{ .Name | printf "\"%s\"" }},
|
|
Type: {{ .Type | printf "\"%s\"" }},
|
|
},
|
|
{{- end }}
|
|
},
|
|
{{- end}}
|
|
}
|
|
|
|
func GetFuncParamType(funcName string, idx int) *FunctionParam {
|
|
var param FunctionParam
|
|
|
|
funcParams, exists := FunctionParams[funcName]
|
|
if !exists {
|
|
return nil
|
|
}
|
|
|
|
if idx < len(funcParams) {
|
|
param = funcParams[idx]
|
|
}
|
|
|
|
return ¶m
|
|
}
|
|
`
|
|
|
|
func main() {
|
|
// Parse the package
|
|
fset := token.NewFileSet()
|
|
node, err := parser.ParseDir(fset, packagePath, nil, parser.ParseComments)
|
|
if err != nil {
|
|
fmt.Println("Error parsing package:", err)
|
|
return
|
|
}
|
|
|
|
parseFunctions := make([]string, 0)
|
|
functionParams := make([]FunctionParamInfo, 0)
|
|
|
|
for _, pkg := range node {
|
|
for _, file := range pkg.Files {
|
|
for _, decl := range file.Decls {
|
|
if funcDecl, ok := decl.(*ast.FuncDecl); ok {
|
|
// Load up Parse functions
|
|
if strings.HasPrefix(funcDecl.Name.Name, "Parse") {
|
|
// Add function name to the list
|
|
parseFunctions = append(parseFunctions, funcDecl.Name.Name)
|
|
}
|
|
|
|
if strings.HasPrefix(funcDecl.Name.Name, "Status") {
|
|
continue
|
|
}
|
|
|
|
// Load up params for all functions
|
|
if funcDecl.Name.IsExported() {
|
|
paramTypes := make([]FunctionParam, 0)
|
|
if funcDecl.Type.Params != nil {
|
|
for _, param := range funcDecl.Type.Params.List {
|
|
// Convert the type expression to a string representation
|
|
typeExpr := param.Type
|
|
typeStr := exprToString(typeExpr)
|
|
if typeStr == "" {
|
|
continue
|
|
}
|
|
// Append the type once for each name in the parameter
|
|
for _, name := range param.Names {
|
|
paramTypes = append(paramTypes, FunctionParam{
|
|
Name: name.Name,
|
|
Type: typeStr,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
functionParams = append(functionParams, FunctionParamInfo{
|
|
FunctionName: funcDecl.Name.String(),
|
|
Params: paramTypes,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Generate Go code for the map
|
|
mapFile, err := os.Create(mapperFile)
|
|
if err != nil {
|
|
fmt.Println("Error creating file:", err)
|
|
return
|
|
}
|
|
defer mapFile.Close()
|
|
|
|
// Execute the template for parse funcs and write to the file
|
|
parseFuncsTpl := template.Must(template.New("mapTemplate").Parse(tmplParseFuncs))
|
|
if err := parseFuncsTpl.Execute(mapFile, parseFunctions); err != nil {
|
|
fmt.Println("Error generating Go code:", err)
|
|
return
|
|
}
|
|
|
|
// Execute the template for func params and write to the file
|
|
funcParamsTpl := template.Must(template.New("paramsTemplate").Parse(tmplFuncParams))
|
|
if err := funcParamsTpl.Execute(mapFile, functionParams); err != nil {
|
|
fmt.Println("Error generating FunctionParams:", err)
|
|
return
|
|
}
|
|
|
|
fmt.Printf("%s has been generated successfully!\n", mapperFile)
|
|
}
|
|
|
|
func exprToString(expr ast.Expr) string {
|
|
switch t := expr.(type) {
|
|
case *ast.Ident:
|
|
return t.Name // Simple type like "int" or "string"
|
|
case *ast.ArrayType:
|
|
return "[]" + exprToString(t.Elt) // Array type
|
|
case *ast.StarExpr:
|
|
return "*" + exprToString(t.X) // Pointer type
|
|
case *ast.SelectorExpr:
|
|
return fmt.Sprintf("%s.%s", exprToString(t.X), t.Sel.Name) // Qualified type like "pkg.Type"
|
|
case *ast.FuncType:
|
|
return "func" // Handle function types minimally
|
|
case *ast.Ellipsis:
|
|
return ""
|
|
default:
|
|
return fmt.Sprintf("%T", expr) // Fallback to the type's Go type
|
|
}
|
|
}
|