llcppsigfetch:Scope Context
This commit is contained in:
@@ -17,7 +17,7 @@ type Converter struct {
|
||||
curFile *ast.File
|
||||
index *clang.Index
|
||||
unit *clang.TranslationUnit
|
||||
// todo(zzy):current namespace expr
|
||||
scopeStack []ast.Expr //namespace & class
|
||||
}
|
||||
|
||||
func NewConverter(file string, temp bool) (*Converter, error) {
|
||||
@@ -68,41 +68,31 @@ func (ct *Converter) Dispose() {
|
||||
ct.unit.Dispose()
|
||||
}
|
||||
|
||||
// visit top decls (struct,class,function,enum & marco,include)
|
||||
func visit(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult {
|
||||
ct := (*Converter)(clientData)
|
||||
ct.UpdateCurFile(cursor)
|
||||
func (ct *Converter) PushScope(cursor clang.Cursor) {
|
||||
name := cursor.String()
|
||||
defer name.Dispose()
|
||||
ident := &ast.Ident{Name: c.GoString(name.CStr())}
|
||||
|
||||
switch cursor.Kind {
|
||||
case clang.CursorInclusionDirective:
|
||||
// todo(zzy)
|
||||
return clang.ChildVisit_Continue
|
||||
case clang.CursorMacroDefinition:
|
||||
// todo(zzy)
|
||||
return clang.ChildVisit_Continue
|
||||
case clang.CursorEnumDecl:
|
||||
// todo(zzy)
|
||||
return clang.ChildVisit_Continue
|
||||
case clang.CursorClassDecl:
|
||||
ct.ProcessClass(cursor)
|
||||
return clang.ChildVisit_Continue
|
||||
case clang.CursorStructDecl:
|
||||
// todo(zzy)
|
||||
return clang.ChildVisit_Continue
|
||||
case clang.CursorFunctionDecl:
|
||||
ct.ProcessFunc(cursor)
|
||||
return clang.ChildVisit_Continue
|
||||
default:
|
||||
// non-top-level decl, continue recursion
|
||||
return clang.ChildVisit_Recurse
|
||||
if len(ct.scopeStack) == 0 {
|
||||
ct.scopeStack = append(ct.scopeStack, ident)
|
||||
} else {
|
||||
parent := ct.scopeStack[len(ct.scopeStack)-1]
|
||||
newContext := &ast.ScopingExpr{Parent: parent, X: ident}
|
||||
ct.scopeStack = append(ct.scopeStack, newContext)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
func (ct *Converter) PopScope() {
|
||||
if len(ct.scopeStack) > 0 {
|
||||
ct.scopeStack = ct.scopeStack[:len(ct.scopeStack)-1]
|
||||
}
|
||||
}
|
||||
|
||||
func (ct *Converter) GetCurScope() ast.Expr {
|
||||
if len(ct.scopeStack) == 0 {
|
||||
return nil
|
||||
}
|
||||
return ct.scopeStack[len(ct.scopeStack)-1]
|
||||
}
|
||||
|
||||
func (ct *Converter) UpdateCurFile(cursor clang.Cursor) {
|
||||
@@ -118,6 +108,8 @@ func (ct *Converter) UpdateCurFile(cursor clang.Cursor) {
|
||||
}
|
||||
|
||||
filePath := c.GoString(filename.CStr())
|
||||
ct.curLoc = ast.Location{File: filePath}
|
||||
|
||||
if ct.curFile == nil || ct.curFile.Path != filePath {
|
||||
if f, ok := ct.files[filePath]; ok {
|
||||
ct.curFile = f
|
||||
@@ -128,9 +120,51 @@ func (ct *Converter) UpdateCurFile(cursor clang.Cursor) {
|
||||
Includes: make([]*ast.Include, 0),
|
||||
Macros: make([]*ast.Macro, 0),
|
||||
}
|
||||
}
|
||||
ct.files[filePath] = ct.curFile
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ct *Converter) CreateDeclBase(cursor clang.Cursor) ast.DeclBase {
|
||||
return ast.DeclBase{
|
||||
Loc: &ct.curLoc,
|
||||
Parent: ct.GetCurScope(),
|
||||
}
|
||||
}
|
||||
|
||||
// visit top decls (struct,class,function,enum & marco,include)
|
||||
func visit(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult {
|
||||
ct := (*Converter)(clientData)
|
||||
ct.UpdateCurFile(cursor)
|
||||
|
||||
switch cursor.Kind {
|
||||
case clang.CursorInclusionDirective:
|
||||
// todo(zzy)
|
||||
case clang.CursorMacroDefinition:
|
||||
// todo(zzy)
|
||||
case clang.CursorEnumDecl:
|
||||
// todo(zzy)
|
||||
case clang.CursorClassDecl:
|
||||
ct.PushScope(cursor)
|
||||
ct.ProcessClass(cursor)
|
||||
ct.PopScope()
|
||||
case clang.CursorStructDecl:
|
||||
// todo(zzy)
|
||||
case clang.CursorFunctionDecl:
|
||||
ct.ProcessFunc(cursor)
|
||||
case clang.CursorNamespace:
|
||||
ct.PushScope(cursor)
|
||||
clang.VisitChildren(cursor, visit, c.Pointer(ct))
|
||||
ct.PopScope()
|
||||
}
|
||||
return clang.ChildVisit_Continue
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (ct *Converter) ProcessType(t clang.Type) ast.Expr {
|
||||
@@ -179,12 +213,11 @@ func (ct *Converter) ProcessFunc(cursor clang.Cursor) {
|
||||
params := ct.ProcessFuncParams(cursor)
|
||||
funcType.Params = params
|
||||
fn := &ast.FuncDecl{
|
||||
DeclBase: ct.CreateDeclBase(cursor),
|
||||
Name: &ast.Ident{Name: c.GoString(name.CStr())},
|
||||
Type: funcType,
|
||||
// todo(zzy):DeclBase use the converter's current namespace expr
|
||||
}
|
||||
ct.curFile.Decls = append(ct.curFile.Decls, fn)
|
||||
// ct.declMap[cursor] = fn
|
||||
}
|
||||
|
||||
type visitParamContext struct {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
func main() {
|
||||
TestFuncDecl()
|
||||
TestScope()
|
||||
}
|
||||
|
||||
func TestFuncDecl() {
|
||||
@@ -35,7 +36,38 @@ func TestFuncDecl() {
|
||||
}
|
||||
|
||||
json := converter.GetFilesJSON()
|
||||
c.Printf(c.Str("Test Case %d:\n%s\n\n"), c.Int(i+1), json.Print())
|
||||
c.Printf(c.Str("TestFuncDecl Case %d:\n%s\n\n"), c.Int(i+1), json.Print())
|
||||
|
||||
converter.Dispose()
|
||||
}
|
||||
}
|
||||
|
||||
func TestScope() {
|
||||
testCases := []string{
|
||||
`void foo();`,
|
||||
`namespace a {
|
||||
void foo();
|
||||
}`,
|
||||
`namespace a {
|
||||
namespace b {
|
||||
void foo();
|
||||
}
|
||||
}`,
|
||||
}
|
||||
|
||||
for i, content := range testCases {
|
||||
converter, err := parse.NewConverter(content, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = converter.Convert()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
json := converter.GetFilesJSON()
|
||||
c.Printf(c.Str("TestScope Case %d:\n%s\n\n"), c.Int(i+1), json.Print())
|
||||
|
||||
converter.Dispose()
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#stdout
|
||||
Test Case 1:
|
||||
TestFuncDecl Case 1:
|
||||
{
|
||||
"temp.h": {
|
||||
"path": "temp.h",
|
||||
"decls": [{
|
||||
"Loc": null,
|
||||
"Loc": {
|
||||
"File": "temp.h"
|
||||
},
|
||||
"Doc": null,
|
||||
"Parent": null,
|
||||
"Name": {
|
||||
@@ -25,12 +27,14 @@ Test Case 1:
|
||||
}
|
||||
}
|
||||
|
||||
Test Case 2:
|
||||
TestFuncDecl Case 2:
|
||||
{
|
||||
"temp.h": {
|
||||
"path": "temp.h",
|
||||
"decls": [{
|
||||
"Loc": null,
|
||||
"Loc": {
|
||||
"File": "temp.h"
|
||||
},
|
||||
"Doc": null,
|
||||
"Parent": null,
|
||||
"Name": {
|
||||
@@ -61,12 +65,14 @@ Test Case 2:
|
||||
}
|
||||
}
|
||||
|
||||
Test Case 3:
|
||||
TestFuncDecl Case 3:
|
||||
{
|
||||
"temp.h": {
|
||||
"path": "temp.h",
|
||||
"decls": [{
|
||||
"Loc": null,
|
||||
"Loc": {
|
||||
"File": "temp.h"
|
||||
},
|
||||
"Doc": null,
|
||||
"Parent": null,
|
||||
"Name": {
|
||||
@@ -107,12 +113,14 @@ Test Case 3:
|
||||
}
|
||||
}
|
||||
|
||||
Test Case 4:
|
||||
TestFuncDecl Case 4:
|
||||
{
|
||||
"temp.h": {
|
||||
"path": "temp.h",
|
||||
"decls": [{
|
||||
"Loc": null,
|
||||
"Loc": {
|
||||
"File": "temp.h"
|
||||
},
|
||||
"Doc": null,
|
||||
"Parent": null,
|
||||
"Name": {
|
||||
@@ -155,12 +163,14 @@ Test Case 4:
|
||||
}
|
||||
}
|
||||
|
||||
Test Case 5:
|
||||
TestFuncDecl Case 5:
|
||||
{
|
||||
"temp.h": {
|
||||
"path": "temp.h",
|
||||
"decls": [{
|
||||
"Loc": null,
|
||||
"Loc": {
|
||||
"File": "temp.h"
|
||||
},
|
||||
"Doc": null,
|
||||
"Parent": null,
|
||||
"Name": {
|
||||
@@ -205,12 +215,14 @@ Test Case 5:
|
||||
}
|
||||
}
|
||||
|
||||
Test Case 6:
|
||||
TestFuncDecl Case 6:
|
||||
{
|
||||
"temp.h": {
|
||||
"path": "temp.h",
|
||||
"decls": [{
|
||||
"Loc": null,
|
||||
"Loc": {
|
||||
"File": "temp.h"
|
||||
},
|
||||
"Doc": null,
|
||||
"Parent": null,
|
||||
"Name": {
|
||||
@@ -259,12 +271,14 @@ Test Case 6:
|
||||
}
|
||||
}
|
||||
|
||||
Test Case 7:
|
||||
TestFuncDecl Case 7:
|
||||
{
|
||||
"temp.h": {
|
||||
"path": "temp.h",
|
||||
"decls": [{
|
||||
"Loc": null,
|
||||
"Loc": {
|
||||
"File": "temp.h"
|
||||
},
|
||||
"Doc": null,
|
||||
"Parent": null,
|
||||
"Name": {
|
||||
@@ -310,12 +324,14 @@ Test Case 7:
|
||||
}
|
||||
}
|
||||
|
||||
Test Case 8:
|
||||
TestFuncDecl Case 8:
|
||||
{
|
||||
"temp.h": {
|
||||
"path": "temp.h",
|
||||
"decls": [{
|
||||
"Loc": null,
|
||||
"Loc": {
|
||||
"File": "temp.h"
|
||||
},
|
||||
"Doc": null,
|
||||
"Parent": null,
|
||||
"Name": {
|
||||
@@ -360,6 +376,99 @@ Test Case 8:
|
||||
}
|
||||
}
|
||||
|
||||
TestScope Case 1:
|
||||
{
|
||||
"temp.h": {
|
||||
"path": "temp.h",
|
||||
"decls": [{
|
||||
"Loc": {
|
||||
"File": "temp.h"
|
||||
},
|
||||
"Doc": null,
|
||||
"Parent": null,
|
||||
"Name": {
|
||||
"Name": "foo"
|
||||
},
|
||||
"Type": {
|
||||
"Params": {
|
||||
"List": []
|
||||
},
|
||||
"Ret": {
|
||||
"Kind": 0,
|
||||
"Flags": 0
|
||||
}
|
||||
}
|
||||
}],
|
||||
"includes": [],
|
||||
"macros": []
|
||||
}
|
||||
}
|
||||
|
||||
TestScope Case 2:
|
||||
{
|
||||
"temp.h": {
|
||||
"path": "temp.h",
|
||||
"decls": [{
|
||||
"Loc": {
|
||||
"File": "temp.h"
|
||||
},
|
||||
"Doc": null,
|
||||
"Parent": {
|
||||
"Name": "a"
|
||||
},
|
||||
"Name": {
|
||||
"Name": "foo"
|
||||
},
|
||||
"Type": {
|
||||
"Params": {
|
||||
"List": []
|
||||
},
|
||||
"Ret": {
|
||||
"Kind": 0,
|
||||
"Flags": 0
|
||||
}
|
||||
}
|
||||
}],
|
||||
"includes": [],
|
||||
"macros": []
|
||||
}
|
||||
}
|
||||
|
||||
TestScope Case 3:
|
||||
{
|
||||
"temp.h": {
|
||||
"path": "temp.h",
|
||||
"decls": [{
|
||||
"Loc": {
|
||||
"File": "temp.h"
|
||||
},
|
||||
"Doc": null,
|
||||
"Parent": {
|
||||
"X": {
|
||||
"Name": "b"
|
||||
},
|
||||
"Parent": {
|
||||
"Name": "a"
|
||||
}
|
||||
},
|
||||
"Name": {
|
||||
"Name": "foo"
|
||||
},
|
||||
"Type": {
|
||||
"Params": {
|
||||
"List": []
|
||||
},
|
||||
"Ret": {
|
||||
"Kind": 0,
|
||||
"Flags": 0
|
||||
}
|
||||
}
|
||||
}],
|
||||
"includes": [],
|
||||
"macros": []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#stderr
|
||||
|
||||
|
||||
@@ -109,6 +109,9 @@ func (ct *Converter) TypeJSON(t ast.Expr) *cjson.JSON {
|
||||
list.AddItem(ct.TypeJSON(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))
|
||||
default:
|
||||
return cjson.Null()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user