llcppsigfetch:distinguish collect doc&comment
This commit is contained in:
@@ -212,23 +212,42 @@ func (ct *Converter) GetTypeDecl(cursor clang.Cursor) (ast.Decl, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ct *Converter) CreateDeclBase(cursor clang.Cursor) ast.DeclBase {
|
func (ct *Converter) CreateDeclBase(cursor clang.Cursor) ast.DeclBase {
|
||||||
rawComment := cursor.RawCommentText()
|
base := ast.DeclBase{
|
||||||
defer rawComment.Dispose()
|
|
||||||
|
|
||||||
res := ast.DeclBase{
|
|
||||||
Loc: &ct.curLoc,
|
Loc: &ct.curLoc,
|
||||||
Parent: ct.BuildScopingExpr(cursor.SemanticParent()),
|
Parent: ct.BuildScopingExpr(cursor.SemanticParent()),
|
||||||
}
|
}
|
||||||
|
commentGroup, isDoc := ct.ParseCommentGroup(cursor)
|
||||||
|
if isDoc {
|
||||||
|
base.Doc = commentGroup
|
||||||
|
}
|
||||||
|
return base
|
||||||
|
}
|
||||||
|
|
||||||
|
// extracts and parses comments associated with a given Clang cursor,
|
||||||
|
// distinguishing between documentation comments and line comments.
|
||||||
|
// It uses libclang to parse only Doxygen-style comments.
|
||||||
|
|
||||||
|
// Reference for Doxygen documentation blocks: https://www.doxygen.nl/manual/docblocks.html
|
||||||
|
|
||||||
|
// The function determines whether a comment is a documentation comment or a line comment by
|
||||||
|
// comparing the range of the comment node with the range of the declaration node in the AST.
|
||||||
|
|
||||||
|
// Note: In cases where both documentation comments and line comments conceptually exist,
|
||||||
|
// only the line comment will be preserved.
|
||||||
|
func (ct *Converter) ParseCommentGroup(cursor clang.Cursor) (comentGroup *ast.CommentGroup, isDoc bool) {
|
||||||
|
rawComment := cursor.RawCommentText()
|
||||||
|
defer rawComment.Dispose()
|
||||||
commentGroup := &ast.CommentGroup{}
|
commentGroup := &ast.CommentGroup{}
|
||||||
if rawComment.CStr() != nil {
|
if rawComment.CStr() != nil {
|
||||||
|
commentRange := cursor.CommentRange()
|
||||||
|
cursorRange := cursor.Extent()
|
||||||
|
isDoc := getOffset(commentRange.RangeStart()) < getOffset(cursorRange.RangeStart())
|
||||||
commentGroup = ct.ParseComment(c.GoString(rawComment.CStr()))
|
commentGroup = ct.ParseComment(c.GoString(rawComment.CStr()))
|
||||||
if len(commentGroup.List) > 0 {
|
if len(commentGroup.List) > 0 {
|
||||||
res.Doc = commentGroup
|
return commentGroup, isDoc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil, false
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ct *Converter) ParseComment(rawComment string) *ast.CommentGroup {
|
func (ct *Converter) ParseComment(rawComment string) *ast.CommentGroup {
|
||||||
@@ -560,13 +579,31 @@ type visitFieldContext struct {
|
|||||||
converter *Converter
|
converter *Converter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *visitFieldContext) createBaseField(cursor clang.Cursor) *ast.Field {
|
||||||
|
field := &ast.Field{
|
||||||
|
Type: p.converter.ProcessType(cursor.Type()),
|
||||||
|
}
|
||||||
|
fieldName := cursor.String()
|
||||||
|
defer fieldName.Dispose()
|
||||||
|
|
||||||
|
commentGroup, isDoc := p.converter.ParseCommentGroup(cursor)
|
||||||
|
if commentGroup != nil {
|
||||||
|
if isDoc {
|
||||||
|
field.Doc = commentGroup
|
||||||
|
} else {
|
||||||
|
field.Comment = commentGroup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if name := fieldName.CStr(); name != nil {
|
||||||
|
field.Names = []*ast.Ident{{Name: c.GoString(name)}}
|
||||||
|
}
|
||||||
|
return field
|
||||||
|
}
|
||||||
func visitFieldList(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult {
|
func visitFieldList(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult {
|
||||||
ctx := (*visitFieldContext)(clientData)
|
ctx := (*visitFieldContext)(clientData)
|
||||||
|
|
||||||
switch cursor.Kind {
|
switch cursor.Kind {
|
||||||
case clang.CursorParmDecl, clang.CursorFieldDecl:
|
case clang.CursorParmDecl, clang.CursorFieldDecl:
|
||||||
paramName := cursor.String()
|
|
||||||
defer paramName.Dispose()
|
|
||||||
// In C language, parameter lists do not have similar parameter grouping in Go.
|
// In C language, parameter lists do not have similar parameter grouping in Go.
|
||||||
// func foo(a, b int)
|
// func foo(a, b int)
|
||||||
|
|
||||||
@@ -574,15 +611,7 @@ func visitFieldList(cursor, parent clang.Cursor, clientData unsafe.Pointer) clan
|
|||||||
// struct A {
|
// struct A {
|
||||||
// int a, b;
|
// int a, b;
|
||||||
// };
|
// };
|
||||||
field := &ast.Field{
|
field := ctx.createBaseField(cursor)
|
||||||
// todo(zzy):comment & doc
|
|
||||||
Type: ctx.converter.ProcessType(cursor.Type()),
|
|
||||||
}
|
|
||||||
|
|
||||||
if paramName.CStr() != nil {
|
|
||||||
field.Names = []*ast.Ident{{Name: c.GoString(paramName.CStr())}}
|
|
||||||
}
|
|
||||||
|
|
||||||
if cursor.Kind == clang.CursorFieldDecl {
|
if cursor.Kind == clang.CursorFieldDecl {
|
||||||
field.Access = ast.AccessSpecifier(cursor.CXXAccessSpecifier())
|
field.Access = ast.AccessSpecifier(cursor.CXXAccessSpecifier())
|
||||||
}
|
}
|
||||||
@@ -592,17 +621,9 @@ func visitFieldList(cursor, parent clang.Cursor, clientData unsafe.Pointer) clan
|
|||||||
case clang.CursorVarDecl:
|
case clang.CursorVarDecl:
|
||||||
if cursor.StorageClass() == clang.SCStatic {
|
if cursor.StorageClass() == clang.SCStatic {
|
||||||
// static member variable
|
// static member variable
|
||||||
fieldname := cursor.String()
|
field := ctx.createBaseField(cursor)
|
||||||
defer fieldname.Dispose()
|
field.Access = ast.AccessSpecifier(cursor.CXXAccessSpecifier())
|
||||||
//todo(zzy): comment & doc
|
field.IsStatic = true
|
||||||
field := &ast.Field{
|
|
||||||
Type: ctx.converter.ProcessType(cursor.Type()),
|
|
||||||
Access: ast.AccessSpecifier(cursor.CXXAccessSpecifier()),
|
|
||||||
IsStatic: true,
|
|
||||||
}
|
|
||||||
if fieldname.CStr() != nil && c.GoString(fieldname.CStr()) != "" {
|
|
||||||
field.Names = []*ast.Ident{{Name: c.GoString(fieldname.CStr())}}
|
|
||||||
}
|
|
||||||
ctx.params.List = append(ctx.params.List, field)
|
ctx.params.List = append(ctx.params.List, field)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,38 @@ void foo();`,
|
|||||||
* doc 2
|
* doc 2
|
||||||
*/
|
*/
|
||||||
void foo();`,
|
void foo();`,
|
||||||
|
`
|
||||||
|
struct Foo {
|
||||||
|
/// doc
|
||||||
|
int x;
|
||||||
|
int y; ///< comment
|
||||||
|
/**
|
||||||
|
* field doc (parse ignore with comment in same cursor)
|
||||||
|
*/
|
||||||
|
int z; /*!< comment */
|
||||||
|
};
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
class Doc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* static field doc
|
||||||
|
*/
|
||||||
|
static int x;
|
||||||
|
static int y; /*!< static field comment */
|
||||||
|
/**
|
||||||
|
* field doc
|
||||||
|
*/
|
||||||
|
int a;
|
||||||
|
int b; ///< field comment
|
||||||
|
/**
|
||||||
|
* method doc
|
||||||
|
*/
|
||||||
|
void Foo();
|
||||||
|
protected:
|
||||||
|
int value; /*!< protected field comment */
|
||||||
|
};`,
|
||||||
}
|
}
|
||||||
test.RunTest("TestDoc", testCases)
|
test.RunTest("TestDoc", testCases)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -437,6 +437,295 @@ TestDoc Case 9:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestDoc Case 10:
|
||||||
|
{
|
||||||
|
"temp.h": {
|
||||||
|
"_Type": "File",
|
||||||
|
"decls": [{
|
||||||
|
"_Type": "TypeDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": null,
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "Foo"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "RecordType",
|
||||||
|
"Tag": 0,
|
||||||
|
"Fields": {
|
||||||
|
"_Type": "FieldList",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Field",
|
||||||
|
"Type": {
|
||||||
|
"_Type": "BuiltinType",
|
||||||
|
"Kind": 6,
|
||||||
|
"Flags": 0
|
||||||
|
},
|
||||||
|
"Doc": {
|
||||||
|
"_Type": "CommentGroup",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": "/// doc"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"Comment": null,
|
||||||
|
"IsStatic": false,
|
||||||
|
"Access": 1,
|
||||||
|
"Names": [{
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "x"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"_Type": "Field",
|
||||||
|
"Type": {
|
||||||
|
"_Type": "BuiltinType",
|
||||||
|
"Kind": 6,
|
||||||
|
"Flags": 0
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Comment": {
|
||||||
|
"_Type": "CommentGroup",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": "///< comment"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"IsStatic": false,
|
||||||
|
"Access": 1,
|
||||||
|
"Names": [{
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "y"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"_Type": "Field",
|
||||||
|
"Type": {
|
||||||
|
"_Type": "BuiltinType",
|
||||||
|
"Kind": 6,
|
||||||
|
"Flags": 0
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Comment": {
|
||||||
|
"_Type": "CommentGroup",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": "/*!< comment */"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"IsStatic": false,
|
||||||
|
"Access": 1,
|
||||||
|
"Names": [{
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "z"
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"Methods": []
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"includes": [],
|
||||||
|
"macros": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TestDoc Case 11:
|
||||||
|
{
|
||||||
|
"temp.h": {
|
||||||
|
"_Type": "File",
|
||||||
|
"decls": [{
|
||||||
|
"_Type": "TypeDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": null,
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "Doc"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "RecordType",
|
||||||
|
"Tag": 3,
|
||||||
|
"Fields": {
|
||||||
|
"_Type": "FieldList",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Field",
|
||||||
|
"Type": {
|
||||||
|
"_Type": "BuiltinType",
|
||||||
|
"Kind": 6,
|
||||||
|
"Flags": 0
|
||||||
|
},
|
||||||
|
"Doc": {
|
||||||
|
"_Type": "CommentGroup",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": "/** "
|
||||||
|
}, {
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": " * static field doc"
|
||||||
|
}, {
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": " */"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"Comment": null,
|
||||||
|
"IsStatic": true,
|
||||||
|
"Access": 1,
|
||||||
|
"Names": [{
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "x"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"_Type": "Field",
|
||||||
|
"Type": {
|
||||||
|
"_Type": "BuiltinType",
|
||||||
|
"Kind": 6,
|
||||||
|
"Flags": 0
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Comment": {
|
||||||
|
"_Type": "CommentGroup",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": "/*!< static field comment */"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"IsStatic": true,
|
||||||
|
"Access": 1,
|
||||||
|
"Names": [{
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "y"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"_Type": "Field",
|
||||||
|
"Type": {
|
||||||
|
"_Type": "BuiltinType",
|
||||||
|
"Kind": 6,
|
||||||
|
"Flags": 0
|
||||||
|
},
|
||||||
|
"Doc": {
|
||||||
|
"_Type": "CommentGroup",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": "/** "
|
||||||
|
}, {
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": " * field doc"
|
||||||
|
}, {
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": " */"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"Comment": null,
|
||||||
|
"IsStatic": false,
|
||||||
|
"Access": 1,
|
||||||
|
"Names": [{
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "a"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"_Type": "Field",
|
||||||
|
"Type": {
|
||||||
|
"_Type": "BuiltinType",
|
||||||
|
"Kind": 6,
|
||||||
|
"Flags": 0
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Comment": {
|
||||||
|
"_Type": "CommentGroup",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": "///< field comment"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"IsStatic": false,
|
||||||
|
"Access": 1,
|
||||||
|
"Names": [{
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "b"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"_Type": "Field",
|
||||||
|
"Type": {
|
||||||
|
"_Type": "BuiltinType",
|
||||||
|
"Kind": 6,
|
||||||
|
"Flags": 0
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Comment": {
|
||||||
|
"_Type": "CommentGroup",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": "/*!< protected field comment */"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"IsStatic": false,
|
||||||
|
"Access": 2,
|
||||||
|
"Names": [{
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "value"
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"Methods": [{
|
||||||
|
"_Type": "FuncDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": {
|
||||||
|
"_Type": "CommentGroup",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": "/** "
|
||||||
|
}, {
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": " * method doc"
|
||||||
|
}, {
|
||||||
|
"_Type": "Comment",
|
||||||
|
"Text": " */"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "Doc"
|
||||||
|
},
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "Foo"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "FuncType",
|
||||||
|
"Params": {
|
||||||
|
"_Type": "FieldList",
|
||||||
|
"List": null
|
||||||
|
},
|
||||||
|
"Ret": {
|
||||||
|
"_Type": "BuiltinType",
|
||||||
|
"Kind": 0,
|
||||||
|
"Flags": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IsInline": false,
|
||||||
|
"IsStatic": false,
|
||||||
|
"IsConst": false,
|
||||||
|
"IsExplicit": false,
|
||||||
|
"IsConstructor": false,
|
||||||
|
"IsDestructor": false,
|
||||||
|
"IsVirtual": false,
|
||||||
|
"IsOverride": false
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"includes": [],
|
||||||
|
"macros": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#stderr
|
#stderr
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user