Working mapgen
This commit is contained in:
+129
-2
@@ -1,15 +1,45 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
"go/types"
|
||||||
|
"os"
|
||||||
|
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type TypeSymbol string
|
||||||
|
|
||||||
|
type VarSymbol struct {
|
||||||
|
Export bool `json:"export"`
|
||||||
|
VarType TypeSymbol `json:"var_type"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FunctionSymbol struct {
|
||||||
|
Export bool `json:"export"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Params map[string]VarSymbol `json:"params"`
|
||||||
|
ReturnTypes []TypeSymbol `json:"return_types"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructSymbol struct {
|
||||||
|
Export bool `json:"export"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Fields map[string]VarSymbol `json:"fields"`
|
||||||
|
Methods map[string]FunctionSymbol `json:"methods"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TopLevelSymbolScope struct {
|
||||||
|
Structs map[string]StructSymbol `json:"structs"`
|
||||||
|
Functions map[string]FunctionSymbol `json:"functions"`
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cfg := &packages.Config{
|
cfg := &packages.Config{
|
||||||
Mode: packages.NeedTypes,
|
Mode: packages.NeedTypes | packages.NeedTypesInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
pkgs, err := packages.Load(cfg, "fmt")
|
pkgs, err := packages.Load(cfg, "fmt")
|
||||||
@@ -17,6 +47,15 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if packages.PrintErrors(pkgs) > 0 {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := TopLevelSymbolScope{
|
||||||
|
Structs: make(map[string]StructSymbol),
|
||||||
|
Functions: make(map[string]FunctionSymbol),
|
||||||
|
}
|
||||||
|
|
||||||
for _, pkg := range pkgs {
|
for _, pkg := range pkgs {
|
||||||
scope := pkg.Types.Scope()
|
scope := pkg.Types.Scope()
|
||||||
|
|
||||||
@@ -26,7 +65,95 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
obj := scope.Lookup(name)
|
obj := scope.Lookup(name)
|
||||||
fmt.Println(name, obj.Type())
|
|
||||||
|
switch obj := obj.(type) {
|
||||||
|
|
||||||
|
case *types.Func:
|
||||||
|
fn := buildFunction(obj)
|
||||||
|
result.Functions[name] = fn
|
||||||
|
|
||||||
|
case *types.TypeName:
|
||||||
|
if strct, ok := buildStruct(obj); ok {
|
||||||
|
result.Structs[name] = strct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := json.MarshalIndent(result, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(string(out))
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildFunction(fn *types.Func) FunctionSymbol {
|
||||||
|
sig := fn.Type().(*types.Signature)
|
||||||
|
|
||||||
|
params := make(map[string]VarSymbol)
|
||||||
|
for i := 0; i < sig.Params().Len(); i++ {
|
||||||
|
p := sig.Params().At(i)
|
||||||
|
|
||||||
|
name := p.Name()
|
||||||
|
if name == "" {
|
||||||
|
name = fmt.Sprintf("param%d", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
params[name] = VarSymbol{
|
||||||
|
Export: true,
|
||||||
|
Name: name,
|
||||||
|
VarType: TypeSymbol(p.Type().String()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var returnTypes []TypeSymbol
|
||||||
|
for i := 0; i < sig.Results().Len(); i++ {
|
||||||
|
r := sig.Results().At(i)
|
||||||
|
returnTypes = append(returnTypes, TypeSymbol(r.Type().String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return FunctionSymbol{
|
||||||
|
Export: token.IsExported(fn.Name()),
|
||||||
|
Name: fn.Name(),
|
||||||
|
Params: params,
|
||||||
|
ReturnTypes: returnTypes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildStruct(tn *types.TypeName) (StructSymbol, bool) {
|
||||||
|
underlying := tn.Type().Underlying()
|
||||||
|
|
||||||
|
strct, ok := underlying.(*types.Struct)
|
||||||
|
if !ok {
|
||||||
|
return StructSymbol{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := make(map[string]VarSymbol)
|
||||||
|
|
||||||
|
for i := 0; i < strct.NumFields(); i++ {
|
||||||
|
f := strct.Field(i)
|
||||||
|
|
||||||
|
fields[f.Name()] = VarSymbol{
|
||||||
|
Export: token.IsExported(f.Name()),
|
||||||
|
Name: f.Name(),
|
||||||
|
VarType: TypeSymbol(f.Type().String()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
methods := make(map[string]FunctionSymbol)
|
||||||
|
methodSet := types.NewMethodSet(tn.Type())
|
||||||
|
|
||||||
|
for i := 0; i < methodSet.Len(); i++ {
|
||||||
|
m := methodSet.At(i).Obj().(*types.Func)
|
||||||
|
|
||||||
|
methods[m.Name()] = buildFunction(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
return StructSymbol{
|
||||||
|
Export: token.IsExported(tn.Name()),
|
||||||
|
Name: tn.Name(),
|
||||||
|
Fields: fields,
|
||||||
|
Methods: methods,
|
||||||
|
}, true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user