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