diff --git a/chore/_xtool/llcppsigfetch/llcppsigfetch.go b/chore/_xtool/llcppsigfetch/llcppsigfetch.go index 19746b09..9c3cd6b3 100644 --- a/chore/_xtool/llcppsigfetch/llcppsigfetch.go +++ b/chore/_xtool/llcppsigfetch/llcppsigfetch.go @@ -22,7 +22,9 @@ import ( "os" "path/filepath" "strings" + "unsafe" + "github.com/goplus/llgo/c" "github.com/goplus/llgo/chore/_xtool/llcppsigfetch/parse" "github.com/goplus/llgo/chore/_xtool/llcppsymg/config" ) @@ -76,5 +78,7 @@ func getHeaderFiles(cflags string, files []string) []string { } func outputInfo(context *parse.Context) { - // TODO(zzy): + output := context.Output().Print() + defer c.Free(unsafe.Pointer(output)) + c.Printf(output) } diff --git a/chore/_xtool/llcppsigfetch/parse/cvt.go b/chore/_xtool/llcppsigfetch/parse/cvt.go index be52e641..a87a7aed 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt.go @@ -8,12 +8,13 @@ import ( "unsafe" "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/cjson" "github.com/goplus/llgo/c/clang" "github.com/goplus/llgo/chore/llcppg/ast" ) type Converter struct { - files map[string]*ast.File + Files map[string]*ast.File curLoc ast.Location curFile *ast.File index *clang.Index @@ -58,7 +59,7 @@ func NewConverter(file string, temp bool) (*Converter, error) { } return &Converter{ - files: make(map[string]*ast.File), + Files: make(map[string]*ast.File), index: index, unit: unit, }, nil @@ -112,7 +113,7 @@ func (ct *Converter) UpdateCurFile(cursor clang.Cursor) { ct.curLoc = ast.Location{File: filePath} if ct.curFile == nil || ct.curFile.Path != filePath { - if f, ok := ct.files[filePath]; ok { + if f, ok := ct.Files[filePath]; ok { ct.curFile = f } else { ct.curFile = &ast.File{ @@ -121,7 +122,7 @@ func (ct *Converter) UpdateCurFile(cursor clang.Cursor) { Includes: make([]*ast.Include, 0), Macros: make([]*ast.Macro, 0), } - ct.files[filePath] = ct.curFile + ct.Files[filePath] = ct.curFile } } } @@ -135,8 +136,9 @@ func (ct *Converter) CreateDeclBase(cursor clang.Cursor) ast.DeclBase { commentGroup = ct.ParseComment(c.GoString(rawComment.CStr())) } + loc := ct.curLoc return ast.DeclBase{ - Loc: &ct.curLoc, + Loc: &loc, Parent: ct.GetCurScope(), Doc: commentGroup, } @@ -183,7 +185,7 @@ func (ct *Converter) Convert() (map[string]*ast.File, error) { cursor := ct.unit.Cursor() // visit top decls (struct,class,function & marco,include) clang.VisitChildren(cursor, visit, c.Pointer(ct)) - return ct.files, nil + return ct.Files, nil } func (ct *Converter) ProcessType(t clang.Type) ast.Expr { @@ -395,6 +397,11 @@ func (ct *Converter) ProcessBuiltinType(t clang.Type) *ast.BuiltinType { Flags: flags, } } + +func (ct *Converter) MarshalASTFiles() *cjson.JSON { + return MarshalASTFiles(ct.Files) +} + func IsExplicitSigned(t clang.Type) bool { return t.Kind == clang.TypeCharS || t.Kind == clang.TypeSChar } diff --git a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/decl.go b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/decl.go index 908fcc3e..bba657f6 100644 --- a/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/decl.go +++ b/chore/_xtool/llcppsigfetch/parse/cvt_test/decl_test/decl.go @@ -38,7 +38,7 @@ func TestFuncDecl() { panic(err) } - json := converter.GetFilesJSON() + json := converter.MarshalASTFiles() c.Printf(c.Str("TestFuncDecl Case %d:\n%s\n\n"), c.Int(i+1), json.Print()) converter.Dispose() @@ -77,7 +77,7 @@ func TestScope() { panic(err) } - json := converter.GetFilesJSON() + json := converter.MarshalASTFiles() c.Printf(c.Str("TestScope Case %d:\n%s\n\n"), c.Int(i+1), json.Print()) converter.Dispose() @@ -123,7 +123,7 @@ void foo();`, panic(err) } - json := converter.GetFilesJSON() + json := converter.MarshalASTFiles() c.Printf(c.Str("TestComment Case %d:\n%s\n\n"), c.Int(i+1), json.Print()) converter.Dispose() @@ -157,7 +157,7 @@ func TestStructDecl() { panic(err) } - json := converter.GetFilesJSON() + json := converter.MarshalASTFiles() c.Printf(c.Str("TestStructDecl Case %d:\n%s\n\n"), c.Int(i+1), json.Print()) converter.Dispose() @@ -188,7 +188,7 @@ func TestClassDecl() { panic(err) } - json := converter.GetFilesJSON() + json := converter.MarshalASTFiles() c.Printf(c.Str("TestClassDecl Case %d:\n%s\n\n"), c.Int(i+1), json.Print()) converter.Dispose() diff --git a/chore/_xtool/llcppsigfetch/parse/dump.go b/chore/_xtool/llcppsigfetch/parse/dump.go index e36f2617..c8c20c90 100644 --- a/chore/_xtool/llcppsigfetch/parse/dump.go +++ b/chore/_xtool/llcppsigfetch/parse/dump.go @@ -6,66 +6,73 @@ import ( "github.com/goplus/llgo/chore/llcppg/ast" ) -func (ct *Converter) GetFilesJSON() *cjson.JSON { +func MarshalASTFiles(files map[string]*ast.File) *cjson.JSON { root := cjson.Object() - for _, file := range ct.files { - root.SetItem(c.AllocaCStr(file.Path), ct.FileJSON(file)) + for _, file := range files { + root.SetItem(c.AllocaCStr(file.Path), MarshalASTFile(file)) } return root } -func (ct *Converter) FileJSON(file *ast.File) *cjson.JSON { +func MarshalASTFile(file *ast.File) *cjson.JSON { root := cjson.Object() decls := cjson.Array() - includes := cjson.Array() - macros := cjson.Array() for _, decl := range file.Decls { - decls.AddItem(ct.DeclJSON(decl)) + decls.AddItem(MarshalASTDecl(decl)) } root.SetItem(c.Str("path"), cjson.String(c.AllocaCStr(file.Path))) root.SetItem(c.Str("decls"), decls) - root.SetItem(c.Str("includes"), includes) - root.SetItem(c.Str("macros"), macros) + + // json:includes,omitempty + if file.Includes != nil { + includes := cjson.Array() + root.SetItem(c.Str("includes"), includes) + } + + // json:macros,omitempty + if file.Macros != nil { + macros := cjson.Array() + root.SetItem(c.Str("macros"), macros) + } + return root } -func (ct *Converter) DeclJSON(decl ast.Decl) *cjson.JSON { +func MarshalASTDecl(decl ast.Decl) *cjson.JSON { if decl == nil { return cjson.Null() } root := cjson.Object() switch d := decl.(type) { case *ast.FuncDecl: - ct.DeclBaseJSON(d.DeclBase, root) - root.SetItem(c.Str("Name"), ct.TypeJSON(d.Name)) - root.SetItem(c.Str("Type"), ct.TypeJSON(d.Type)) + MarshalASTDeclBase(d.DeclBase, root) + root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name)) + root.SetItem(c.Str("Type"), MarshalASTExpr(d.Type)) case *ast.TypeDecl: - ct.DeclBaseJSON(d.DeclBase, root) + MarshalASTDeclBase(d.DeclBase, root) root.SetItem(c.Str("Tag"), cjson.Number(float64(d.Tag))) - root.SetItem(c.Str("Fields"), ct.TypeJSON(d.Fields)) + root.SetItem(c.Str("Fields"), MarshalASTExpr(d.Fields)) methods := cjson.Array() for _, m := range d.Methods { - methods.AddItem(ct.DeclJSON(m)) + methods.AddItem(MarshalASTDecl(m)) } root.SetItem(c.Str("Methods"), methods) } return root } -func (ct *Converter) DeclBaseJSON(decl ast.DeclBase, root *cjson.JSON) { - if decl.Loc == nil { - root.SetItem(c.Str("Loc"), cjson.Null()) - } else { - loc := cjson.Object() - loc.SetItem(c.Str("File"), cjson.String(c.AllocaCStr(decl.Loc.File))) - root.SetItem(c.Str("Loc"), loc) - } - root.SetItem(c.Str("Doc"), ct.TypeJSON(decl.Doc)) - root.SetItem(c.Str("Parent"), ct.TypeJSON(decl.Parent)) + +func MarshalASTDeclBase(decl ast.DeclBase, root *cjson.JSON) { + loc := cjson.Object() + loc.SetItem(c.Str("File"), cjson.String(c.AllocaCStr(decl.Loc.File))) + root.SetItem(c.Str("Loc"), loc) + + root.SetItem(c.Str("Doc"), MarshalASTExpr(decl.Doc)) + root.SetItem(c.Str("Parent"), MarshalASTExpr(decl.Parent)) } -func (ct *Converter) TypeJSON(t ast.Expr) *cjson.JSON { +func MarshalASTExpr(t ast.Expr) *cjson.JSON { if t == nil { return cjson.Null() } @@ -74,24 +81,24 @@ func (ct *Converter) TypeJSON(t ast.Expr) *cjson.JSON { switch d := t.(type) { case *ast.FuncType: - root.SetItem(c.Str("Params"), ct.TypeJSON(d.Params)) - root.SetItem(c.Str("Ret"), ct.TypeJSON(d.Ret)) + root.SetItem(c.Str("Params"), MarshalASTExpr(d.Params)) + root.SetItem(c.Str("Ret"), MarshalASTExpr(d.Ret)) case *ast.FieldList: if d == nil { return cjson.Null() } list := cjson.Array() for _, f := range d.List { - list.AddItem(ct.TypeJSON(f)) + list.AddItem(MarshalASTExpr(f)) } root.SetItem(c.Str("List"), list) case *ast.Field: - root.SetItem(c.Str("Type"), ct.TypeJSON(d.Type)) - root.SetItem(c.Str("Doc"), ct.TypeJSON(d.Doc)) - root.SetItem(c.Str("Comment"), ct.TypeJSON(d.Comment)) + root.SetItem(c.Str("Type"), MarshalASTExpr(d.Type)) + root.SetItem(c.Str("Doc"), MarshalASTExpr(d.Doc)) + root.SetItem(c.Str("Comment"), MarshalASTExpr(d.Comment)) names := cjson.Array() for _, n := range d.Names { - names.AddItem(ct.TypeJSON(n)) + names.AddItem(MarshalASTExpr(n)) } root.SetItem(c.Str("Names"), names) case *ast.Ident: @@ -100,10 +107,10 @@ func (ct *Converter) TypeJSON(t ast.Expr) *cjson.JSON { root.SetItem(c.Str("Kind"), cjson.Number(float64(d.Kind))) root.SetItem(c.Str("Value"), cjson.String(c.AllocaCStr(d.Value))) case *ast.PointerType: - root.SetItem(c.Str("X"), ct.TypeJSON(d.X)) + root.SetItem(c.Str("X"), MarshalASTExpr(d.X)) case *ast.ArrayType: - root.SetItem(c.Str("Elt"), ct.TypeJSON(d.Elt)) - root.SetItem(c.Str("Len"), ct.TypeJSON(d.Len)) + root.SetItem(c.Str("Elt"), MarshalASTExpr(d.Elt)) + root.SetItem(c.Str("Len"), MarshalASTExpr(d.Len)) case *ast.BuiltinType: root.SetItem(c.Str("Kind"), cjson.Number(float64(d.Kind))) root.SetItem(c.Str("Flags"), cjson.Number(float64(d.Flags))) @@ -115,12 +122,12 @@ func (ct *Converter) TypeJSON(t ast.Expr) *cjson.JSON { } list := cjson.Array() for _, c := range d.List { - list.AddItem(ct.TypeJSON(c)) + list.AddItem(MarshalASTExpr(c)) } root.SetItem(c.Str("List"), list) case *ast.ScopingExpr: - root.SetItem(c.Str("X"), ct.TypeJSON(d.X)) - root.SetItem(c.Str("Parent"), ct.TypeJSON(d.Parent)) + root.SetItem(c.Str("X"), MarshalASTExpr(d.X)) + root.SetItem(c.Str("Parent"), MarshalASTExpr(d.Parent)) default: return cjson.Null() } diff --git a/chore/_xtool/llcppsigfetch/parse/parse.go b/chore/_xtool/llcppsigfetch/parse/parse.go index ce36a352..e7b3bee4 100644 --- a/chore/_xtool/llcppsigfetch/parse/parse.go +++ b/chore/_xtool/llcppsigfetch/parse/parse.go @@ -3,6 +3,8 @@ package parse import ( "errors" + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/cjson" "github.com/goplus/llgo/chore/llcppg/ast" ) @@ -16,6 +18,18 @@ func NewContext() *Context { } } +func (p *Context) Output() *cjson.JSON { + root := cjson.Array() + for path, file := range p.Files { + f := cjson.Object() + path := cjson.String(c.AllocaCStr(path)) + f.SetItem(c.Str("path"), path) + f.SetItem(c.Str("doc"), MarshalASTFile(file)) + root.AddItem(f) + } + return root +} + // ProcessFiles processes the given files and adds them to the context func (p *Context) ProcessFiles(files []string) error { for _, file := range files {