Use semantic parent to refactor scoping expression construction

This commit is contained in:
luoliwoshang
2024-08-27 11:40:29 +08:00
parent 38eb981d2c
commit a897683272

View File

@@ -15,11 +15,10 @@ import (
) )
type Converter struct { type Converter struct {
Files map[string]*ast.File Files map[string]*ast.File
curLoc ast.Location curLoc ast.Location
index *clang.Index index *clang.Index
unit *clang.TranslationUnit unit *clang.TranslationUnit
scopeContext []ast.Expr //namespace & class
} }
type Config struct { type Config struct {
@@ -92,33 +91,6 @@ func (ct *Converter) Dispose() {
ct.unit.Dispose() ct.unit.Dispose()
} }
func (ct *Converter) PushScope(cursor clang.Cursor) {
name := cursor.String()
defer name.Dispose()
ident := &ast.Ident{Name: c.GoString(name.CStr())}
if len(ct.scopeContext) == 0 {
ct.scopeContext = append(ct.scopeContext, ident)
} else {
parent := ct.scopeContext[len(ct.scopeContext)-1]
newContext := &ast.ScopingExpr{Parent: parent, X: ident}
ct.scopeContext = append(ct.scopeContext, newContext)
}
}
func (ct *Converter) PopScope() {
if len(ct.scopeContext) > 0 {
ct.scopeContext = ct.scopeContext[:len(ct.scopeContext)-1]
}
}
func (ct *Converter) GetCurScope() ast.Expr {
if len(ct.scopeContext) == 0 {
return nil
}
return ct.scopeContext[len(ct.scopeContext)-1]
}
func (ct *Converter) UpdateLoc(cursor clang.Cursor) { func (ct *Converter) UpdateLoc(cursor clang.Cursor) {
loc := cursor.Location() loc := cursor.Location()
var file clang.File var file clang.File
@@ -165,7 +137,7 @@ func (ct *Converter) CreateDeclBase(cursor clang.Cursor) ast.DeclBase {
loc := ct.curLoc loc := ct.curLoc
return ast.DeclBase{ return ast.DeclBase{
Loc: &loc, Loc: &loc,
Parent: ct.GetCurScope(), Parent: buildScopingExpr(cursor.SemanticParent()),
Doc: commentGroup, Doc: commentGroup,
} }
} }
@@ -215,9 +187,7 @@ func visitTop(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.Chil
case clang.CursorTypedefDecl: case clang.CursorTypedefDecl:
curFile.Decls = append(curFile.Decls, ct.ProcessTypeDefDecl(cursor)) curFile.Decls = append(curFile.Decls, ct.ProcessTypeDefDecl(cursor))
case clang.CursorNamespace: case clang.CursorNamespace:
ct.PushScope(cursor)
clang.VisitChildren(cursor, visitTop, c.Pointer(ct)) clang.VisitChildren(cursor, visitTop, c.Pointer(ct))
ct.PopScope()
} }
return clang.ChildVisit_Continue return clang.ChildVisit_Continue
} }
@@ -306,7 +276,7 @@ func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl {
if isMethod(cursor) { if isMethod(cursor) {
if parent := cursor.SemanticParent(); parent.Equal(cursor.LexicalParent()) != 1 { if parent := cursor.SemanticParent(); parent.Equal(cursor.LexicalParent()) != 1 {
fn.DeclBase.Parent = qualifiedExpr(buildQualifiedName(cursor)) fn.DeclBase.Parent = buildScopingExpr(cursor.SemanticParent())
} }
if cursor.Kind == clang.CursorDestructor { if cursor.Kind == clang.CursorDestructor {
@@ -522,9 +492,7 @@ func (ct *Converter) ProcessClassDecl(cursor clang.Cursor) *ast.TypeDecl {
// Pushing class scope before processing its type and popping after // Pushing class scope before processing its type and popping after
base := ct.CreateDeclBase(cursor) base := ct.CreateDeclBase(cursor)
ct.PushScope(cursor)
typ := ct.ProcessRecordType(cursor, ast.Class) typ := ct.ProcessRecordType(cursor, ast.Class)
ct.PopScope()
return &ast.TypeDecl{ return &ast.TypeDecl{
DeclBase: base, DeclBase: base,
@@ -561,12 +529,12 @@ func (ct *Converter) ProcessElaboratedType(t clang.Type) ast.Expr {
if tagValue, ok := tagMap[parts[0]]; ok { if tagValue, ok := tagMap[parts[0]]; ok {
return &ast.TagExpr{ return &ast.TagExpr{
Tag: tagValue, Tag: tagValue,
Name: qualifiedExpr(parts[1]), Name: buildScopingExpr(t.TypeDeclaration()),
} }
} }
} }
return qualifiedExpr(typeName) return buildScopingExpr(t.TypeDeclaration())
} }
func (ct *Converter) ProcessBuiltinType(t clang.Type) *ast.BuiltinType { func (ct *Converter) ProcessBuiltinType(t clang.Type) *ast.BuiltinType {
@@ -665,9 +633,9 @@ func isMethod(cursor clang.Cursor) bool {
return cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorConstructor || cursor.Kind == clang.CursorDestructor return cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorConstructor || cursor.Kind == clang.CursorDestructor
} }
func buildQualifiedName(cursor clang.Cursor) string { // Constructs a complete scoping expression by traversing the semantic parents, starting from the given clang.Cursor
func buildScopingExpr(cursor clang.Cursor) ast.Expr {
var parts []string var parts []string
cursor = cursor.SemanticParent()
// Traverse up the semantic parents // Traverse up the semantic parents
for cursor.IsNull() != 1 && cursor.Kind != clang.CursorTranslationUnit { for cursor.IsNull() != 1 && cursor.Kind != clang.CursorTranslationUnit {
@@ -678,11 +646,14 @@ func buildQualifiedName(cursor clang.Cursor) string {
name.Dispose() name.Dispose()
} }
return strings.Join(parts, "::") return buildScopingFromParts(parts)
} }
func qualifiedExpr(name string) ast.Expr { func buildScopingFromParts(parts []string) ast.Expr {
parts := strings.Split(name, "::") if len(parts) == 0 {
return nil
}
var expr ast.Expr = &ast.Ident{Name: parts[0]} var expr ast.Expr = &ast.Ident{Name: parts[0]}
for _, part := range parts[1:] { for _, part := range parts[1:] {
expr = &ast.ScopingExpr{ expr = &ast.ScopingExpr{