Exemplo n.º 1
0
        public ChildVisitResult Visit(Cursor cursor, Cursor parent)
        {
            if (!cursor.GetLocation().IsFromMainFile())
            {
                return(ChildVisitResult.Continue);
            }

            CursorKind curKind = cursor.Kind;

            if (curKind == CursorKind.EnumDecl)
            {
                var nativeName  = cursor.GetSpelling();
                var type        = cursor.GetEnumDeclIntegerType().ToClrType();
                var enumComment = this.GetComment(cursor, forType: true);

                // enumName can be empty because of typedef enum { .. } enumName;
                // so we have to find the sibling, and this is the only way I've found
                // to do with libclang, maybe there is a better way?
                if (string.IsNullOrEmpty(nativeName))
                {
                    var forwardDeclaringVisitor = new ForwardDeclarationVisitor(cursor, skipSystemHeaderCheck: true);
                    forwardDeclaringVisitor.VisitChildren(cursor.GetLexicalParent());
                    nativeName = forwardDeclaringVisitor.ForwardDeclarationCursor.GetSpelling();

                    if (string.IsNullOrEmpty(nativeName))
                    {
                        nativeName = "_";
                    }
                }

                var clrName = NameConversions.ToClrName(nativeName, NameConversion.Type);

                // if we've printed these previously, skip them
                if (this.generator.NameMapping.ContainsKey(nativeName))
                {
                    return(ChildVisitResult.Continue);
                }

                CodeTypeDeclaration enumDeclaration = new CodeTypeDeclaration();
                enumDeclaration.Attributes = MemberAttributes.Public;
                enumDeclaration.IsEnum     = true;
                enumDeclaration.Name       = clrName;
                enumDeclaration.BaseTypes.Add(type);

                if (enumComment != null)
                {
                    enumDeclaration.Comments.Add(enumComment);
                }

                // visit all the enum values
                DelegatingCursorVisitor visitor = new DelegatingCursorVisitor(
                    (c, vistor) =>
                {
                    var field =
                        new CodeMemberField()
                    {
                        Name           = NameConversions.ToClrName(c.GetSpelling(), NameConversion.Field),
                        InitExpression = new CodePrimitiveExpression(c.GetEnumConstantDeclValue())
                    };

                    var fieldComment = this.GetComment(c, forType: true);
                    if (fieldComment != null)
                    {
                        field.Comments.Add(fieldComment);
                    }

                    enumDeclaration.Members.Add(field);
                    return(ChildVisitResult.Continue);
                });
                visitor.VisitChildren(cursor);

                this.generator.AddType(nativeName, new CodeDomGeneratedType(enumDeclaration));
            }

            return(ChildVisitResult.Recurse);
        }
Exemplo n.º 2
0
        public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr data)
        {
            if (clang.Location_isFromMainFile(clang.getCursorLocation(cursor)) == 0)
            {
                return(CXChildVisitResult.CXChildVisit_Continue);
            }

            CXCursorKind curKind = clang.getCursorKind(cursor);

            if (curKind == CXCursorKind.CXCursor_StructDecl)
            {
                this.fieldPosition = 0;
                var nativeName = clang.getCursorSpelling(cursor).ToString();

                // struct names can be empty, and so we visit its sibling to find the name
                if (string.IsNullOrEmpty(nativeName))
                {
                    var forwardDeclaringVisitor = new ForwardDeclarationVisitor(cursor);
                    clang.visitChildren(clang.getCursorSemanticParent(cursor), forwardDeclaringVisitor.Visit, new CXClientData(IntPtr.Zero));
                    nativeName = clang.getCursorSpelling(forwardDeclaringVisitor.ForwardDeclarationCursor).ToString();

                    if (string.IsNullOrEmpty(nativeName))
                    {
                        nativeName = "_";
                    }
                }

                var clrName = NameConversions.ToClrName(nativeName, NameConversion.Type);

                if (!this.generator.NameMapping.ContainsKey(nativeName))
                {
                    this.current            = new CodeTypeDeclaration(clrName);
                    this.current.IsStruct   = true;
                    this.current.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                    this.generator.AddType(nativeName, this.current);

                    var layoutAttribute =
                        new CodeAttributeDeclaration(
                            new CodeTypeReference(typeof(StructLayoutAttribute)),
                            new CodeAttributeArgument(
                                new CodePropertyReferenceExpression(
                                    new CodeTypeReferenceExpression(typeof(LayoutKind)),
                                    nameof(LayoutKind.Sequential))));

                    this.current.CustomAttributes.Add(layoutAttribute);

                    clang.visitChildren(cursor, this.Visit, new CXClientData(IntPtr.Zero));
                }

                return(CXChildVisitResult.CXChildVisit_Continue);
            }

            if (curKind == CXCursorKind.CXCursor_FieldDecl)
            {
                var fieldName = clang.getCursorSpelling(cursor).ToString();
                if (string.IsNullOrEmpty(fieldName))
                {
                    fieldName = "field" + this.fieldPosition; // what if they have fields called field*? :)
                }

                this.fieldPosition++;

                foreach (var member in cursor.ToCodeTypeMember(fieldName, this.generator))
                {
                    this.current.Members.Add(member);
                }

                return(CXChildVisitResult.CXChildVisit_Continue);
            }

            return(CXChildVisitResult.CXChildVisit_Recurse);
        }
Exemplo n.º 3
0
        public ChildVisitResult Visit(Cursor cursor, Cursor parent)
        {
            if (!cursor.GetLocation().IsFromMainFile())
            {
                return(ChildVisitResult.Continue);
            }

            CursorKind curKind = cursor.Kind;

            if (curKind == CursorKind.StructDecl)
            {
                this.fieldPosition = 0;
                var nativeName = cursor.GetSpelling();

                // struct names can be empty, and so we visit its sibling to find the name
                if (string.IsNullOrEmpty(nativeName))
                {
                    var forwardDeclaringVisitor = new ForwardDeclarationVisitor(cursor, skipSystemHeaderCheck: true);
                    forwardDeclaringVisitor.VisitChildren(cursor.GetSemanticParent());
                    nativeName = forwardDeclaringVisitor.ForwardDeclarationCursor.GetSpelling();

                    if (string.IsNullOrEmpty(nativeName))
                    {
                        nativeName = "_";
                    }
                }

                var clrName = NameConversions.ToClrName(nativeName, NameConversion.Type);

                if (!this.generator.NameMapping.ContainsKey(nativeName))
                {
                    this.current            = new CodeTypeDeclaration(clrName);
                    this.current.IsStruct   = true;
                    this.current.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                    this.generator.AddType(nativeName, this.current);

                    var layoutAttribute =
                        new CodeAttributeDeclaration(
                            new CodeTypeReference(typeof(StructLayoutAttribute)),
                            new CodeAttributeArgument(
                                new CodePropertyReferenceExpression(
                                    new CodeTypeReferenceExpression(typeof(LayoutKind)),
                                    nameof(LayoutKind.Sequential))));

                    this.current.CustomAttributes.Add(layoutAttribute);

                    var visitor = new DelegatingCursorVisitor(this.Visit);
                    visitor.VisitChildren(cursor);
                }

                return(ChildVisitResult.Continue);
            }

            if (curKind == CursorKind.FieldDecl)
            {
                var fieldName = cursor.GetSpelling();
                if (string.IsNullOrEmpty(fieldName))
                {
                    fieldName = "field" + this.fieldPosition; // what if they have fields called field*? :)
                }

                this.fieldPosition++;

                foreach (var member in cursor.ToCodeTypeMember(fieldName, this.generator))
                {
                    this.current.Members.Add(member);
                }

                return(ChildVisitResult.Continue);
            }

            return(ChildVisitResult.Recurse);
        }
Exemplo n.º 4
0
        public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr data)
        {
            if (clang.Location_isFromMainFile(clang.getCursorLocation(cursor)) == 0)
            {
                return(CXChildVisitResult.CXChildVisit_Continue);
            }

            CXCursorKind curKind = clang.getCursorKind(cursor);

            if (curKind == CXCursorKind.CXCursor_EnumDecl)
            {
                var nativeName  = clang.getCursorSpelling(cursor).ToString();
                var type        = clang.getEnumDeclIntegerType(cursor).ToClrType();
                var enumComment = this.GetComment(cursor, forType: true);

                // enumName can be empty because of typedef enum { .. } enumName;
                // so we have to find the sibling, and this is the only way I've found
                // to do with libclang, maybe there is a better way?
                if (string.IsNullOrEmpty(nativeName))
                {
                    var forwardDeclaringVisitor = new ForwardDeclarationVisitor(cursor);
                    clang.visitChildren(clang.getCursorLexicalParent(cursor), forwardDeclaringVisitor.Visit, new CXClientData(IntPtr.Zero));
                    nativeName = clang.getCursorSpelling(forwardDeclaringVisitor.ForwardDeclarationCursor).ToString();

                    if (string.IsNullOrEmpty(nativeName))
                    {
                        nativeName = "_";
                    }
                }

                var clrName = NameConversions.ToClrName(nativeName, NameConversion.Type);

                // if we've printed these previously, skip them
                if (this.generator.NameMapping.ContainsKey(nativeName))
                {
                    return(CXChildVisitResult.CXChildVisit_Continue);
                }

                CodeTypeDeclaration enumDeclaration = new CodeTypeDeclaration();
                enumDeclaration.Attributes = MemberAttributes.Public;
                enumDeclaration.IsEnum     = true;
                enumDeclaration.Name       = clrName;
                enumDeclaration.BaseTypes.Add(type);

                if (enumComment != null)
                {
                    enumDeclaration.Comments.Add(enumComment);
                }

                // visit all the enum values
                clang.visitChildren(
                    cursor,
                    (cxCursor, vistor, clientData) =>
                {
                    var field =
                        new CodeMemberField()
                    {
                        Name           = NameConversions.ToClrName(clang.getCursorSpelling(cxCursor).ToString(), NameConversion.Field),
                        InitExpression = new CodePrimitiveExpression(clang.getEnumConstantDeclValue(cxCursor))
                    };

                    var fieldComment = this.GetComment(cxCursor, forType: false);
                    if (fieldComment != null)
                    {
                        field.Comments.Add(fieldComment);
                    }

                    enumDeclaration.Members.Add(field);
                    return(CXChildVisitResult.CXChildVisit_Continue);
                },
                    new CXClientData(IntPtr.Zero));

                this.generator.AddType(nativeName, enumDeclaration);
            }

            return(CXChildVisitResult.CXChildVisit_Recurse);
        }