Пример #1
0
        protected override void VisitChild(VisitorCursor cursor, List <VisitorCursor> Parents)
        {
            if (cursor.Kind == CXCursorKind.CXCursor_EnumDecl)
            {
                var enumSpelling = string.IsNullOrWhiteSpace(cursor.Spelling) ?  Parents.ToNamespace() : cursor.Spelling;
                if (config.NativeEnums.Any(i => i.Name == enumSpelling) && !info.Enums.Any(e => e.Name == enumSpelling))
                {
                    var enumType = cursor.EnumType;
                    if (enumType == typeof(IntPtr))
                    {
                        enumType = typeof(int);
                    }

                    var enumDecl = new IDescribeEnum {
                        Name = enumSpelling, Type = enumType
                    };

                    cursor.VisitChildren((valueCursor) =>
                    {
                        if (valueCursor.Kind != CXCursorKind.CXCursor_EnumConstantDecl && valueCursor.Kind != CXCursorKind.CXCursor_EnumDecl)
                        {
                            return;
                        }
                        var enumValue = new IDescribeEnumValue {
                            Name = valueCursor.Spelling, Value = valueCursor.EnumValue
                        };
                        enumDecl.Values.Add(enumValue);
                    });

                    info.Enums.Add(enumDecl);
                }
            }
        }
Пример #2
0
 protected override void VisitChild(VisitorCursor cursor, List <VisitorCursor> parents)
 {
     if (cursor.Kind == CXCursorKind.CXCursor_ClassDecl &&
         config.NativeInterfaces.Any(i => i.Name == cursor.Spelling) &&
         !cursor.IsForwardDeclaration)
     {
         cursor.VisitChildren((childCursor) =>
         {
             if (childCursor.Kind == CXCursorKind.CXCursor_CXXBaseSpecifier)
             {
                 var definitionSpelling = childCursor.CursorDefinition.Spelling;
                 if (!config.NativeInterfaces.Any(i => i.Name == definitionSpelling))
                 {
                     config.NativeInterfaces.Add(new NativeInterface {
                         Name = definitionSpelling,
                     });
                 }
             }
         });
     }
 }
Пример #3
0
        protected override void VisitChild(VisitorCursor cursor, List <VisitorCursor> parents)
        {
            if (cursor.Kind == CXCursorKind.CXCursor_TypedefDecl)
            {
                if (config.NativeDelegates.Any(i => i.Name == cursor.Spelling) && !info.Delegates.Any(i => i.Name == cursor.Spelling))
                {
                    CXType type    = clang.getCanonicalType(clang.getTypedefDeclUnderlyingType(cursor.Cursor));
                    var    pointee = clang.getPointeeType(type);
                    if (pointee.kind == CXTypeKind.CXType_FunctionProto)
                    {
                        var callingConv = clang.getFunctionTypeCallingConv(pointee);
                        var returnType  = clang.getResultType(pointee);
                        var name        = cursor.Spelling;

                        var delegateDecl = new IDescribeMethod
                        {
                            Name    = cursor.Spelling,
                            Returns = new List <IDescribeReturn> {
                                new IDescribeReturn {
                                    Type = returnType.ToPlainType()
                                }
                            },
                        };


                        CodeAttributeArgument arg;
                        switch (callingConv)
                        {
                        case CXCallingConv.CXCallingConv_X86StdCall:
                        case CXCallingConv.CXCallingConv_X86_64Win64:
                            arg = new CodeAttributeArgument(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(CallingConvention)), "StdCall"));
                            break;

                        default:
                            arg = new CodeAttributeArgument(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(CallingConvention)), "Cdecl"));
                            break;
                        }


                        uint parmCounter = 0;
                        cursor.VisitChildren((childCursor) =>
                        {
                            if (childCursor.Kind == CXCursorKind.CXCursor_ParmDecl)
                            {
                                var paramType     = clang.getArgType(pointee, parmCounter);
                                var paramSpelling = childCursor.Spelling;
                                if (string.IsNullOrEmpty(paramSpelling))
                                {
                                    paramSpelling = "param" + parmCounter;
                                }

                                delegateDecl.Arguments.Add(new IDescribeArgument {
                                    Name = paramSpelling, Type = paramType.ToPlainType()
                                });

                                parmCounter++;
                            }
                        });

                        if (delegateDecl.Arguments.Any(a => a.Type == typeof(string)) || delegateDecl.Returns.Any(a => a.Type == typeof(string)))
                        {
                            delegateDecl.Attributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(UnmanagedFunctionPointerAttribute)), arg,
                                                                                     new CodeAttributeArgument(nameof(UnmanagedFunctionPointerAttribute.CharSet), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(CharSet)), nameof(CharSet.Ansi)))));
                        }
                        else
                        {
                            delegateDecl.Attributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(UnmanagedFunctionPointerAttribute)), arg));
                        }

                        info.Delegates.Add(delegateDecl);
                    }
                }
            }
        }
Пример #4
0
        protected override void VisitChild(VisitorCursor cursor, List <VisitorCursor> parents)
        {
            if (cursor.Kind == CXCursorKind.CXCursor_StructDecl)
            {
                this.fieldPosition = 0;
                if (config.NativeStructs.Any(s => s.Name == cursor.Spelling) &&
                    !this.info.Structs.Any((s) => { return(s.Name == cursor.Spelling); }) &&
                    !cursor.IsForwardDeclaration)
                {
                    var structDecl = new IDescribeStruct {
                        Name = cursor.Spelling
                    };

                    cursor.VisitChildren((childCursor) =>
                    {
                        if (childCursor.Kind == CXCursorKind.CXCursor_FieldDecl)
                        {
                            var fieldName = childCursor.Spelling;
                            if (string.IsNullOrEmpty(fieldName))
                            {
                                fieldName = "field" + this.fieldPosition; // what if they have fields called field*? :)
                            }
                            var fieldDecl = new IDescribeField {
                                Name = fieldName
                            };
                            var canonical = childCursor.CanonicalType;
                            switch (childCursor.CanonicalType.kind)
                            {
                            case CXTypeKind.CXType_ConstantArray:
                                long arraySize  = clang.getArraySize(canonical);
                                var elementType = clang.getCanonicalType(clang.getArrayElementType(canonical));

                                fieldDecl.Type = elementType.ToPlainType().MakeArrayType();

                                fieldDecl.Attributes.Add(new CodeAttributeDeclaration(
                                                             new CodeTypeReference(typeof(MarshalAsAttribute)),
                                                             new CodeAttributeArgument(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(UnmanagedType)), "ByValArray")),
                                                             new CodeAttributeArgument("SizeConst", new CodePrimitiveExpression(arraySize))));

                                break;

                            case CXTypeKind.CXType_Pointer:
                                var pointeeType = clang.getCanonicalType(clang.getPointeeType(canonical));
                                switch (pointeeType.kind)
                                {
                                case CXTypeKind.CXType_Char_S:
                                    fieldDecl.Type = typeof(string);
                                    fieldDecl.Attributes.Add(new CodeAttributeDeclaration(
                                                                 new CodeTypeReference(typeof(MarshalAsAttribute)),
                                                                 new CodeAttributeArgument(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(UnmanagedType)), "LPTStr"))));

                                    break;

                                case CXTypeKind.CXType_WChar:
                                    fieldDecl.Type = typeof(string);
                                    fieldDecl.Attributes.Add(new CodeAttributeDeclaration(
                                                                 new CodeTypeReference(typeof(MarshalAsAttribute)),
                                                                 new CodeAttributeArgument(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(UnmanagedType)), "LPWStr"))));
                                    break;

                                default:
                                    fieldDecl.Type = typeof(IntPtr);
                                    break;
                                }
                                break;

                            case CXTypeKind.CXType_Record:
                            case CXTypeKind.CXType_Enum:
                                Console.WriteLine("Struct field type dunno: " + canonical.ToString());
                                fieldDecl.Type = typeof(IntPtr);
                                break;

                            default:
                                fieldDecl.Type = canonical.ToPlainType();
                                break;
                            }

                            structDecl.Fields.Add(fieldDecl);
                        }
                    });
                    info.Structs.Add(structDecl);
                }
            }
        }
Пример #5
0
        protected override void VisitChild(VisitorCursor cursor, List <VisitorCursor> parents)
        {
            if (cursor.Kind == CXCursorKind.CXCursor_ClassDecl)
            {
                if (!config.NativeInterfaces.Any(i => i.Name == cursor.Spelling) || cursor.IsForwardDeclaration)
                {
                    return;
                }

                var classInfo = new IDescribeInterface
                {
                    Name = cursor.Spelling
                };


                cursor.VisitChildren((methodCursor) =>
                {
                    if (methodCursor.Kind == CXCursorKind.CXCursor_CXXMethod ||
                        methodCursor.Kind == CXCursorKind.CXCursor_Destructor ||
                        methodCursor.Kind == CXCursorKind.CXCursor_Constructor)
                    {
                        var methodName = methodCursor.Spelling;
                        if (methodCursor.Kind == CXCursorKind.CXCursor_Constructor)
                        {
                            methodName = "ctor" + methodName;
                        }
                        if (methodCursor.Kind == CXCursorKind.CXCursor_Destructor)
                        {
                            methodName = "dtor" + (methodName.Replace("~", ""));
                        }
                        if (methodCursor.IsVirtual)
                        {
                            var methodInfo = new IDescribeMethod
                            {
                                Name    = methodName,
                                Returns = { new IDescribeReturn {
                                                Type = methodCursor.ReturnTypeCSharp
                                            } }
                            };

                            for (uint index = 0; index < methodCursor.NumArgs; ++index)
                            {
                                var paramSpelling = methodCursor.GetArgSpelling(index);

                                if (string.IsNullOrEmpty(paramSpelling))
                                {
                                    paramSpelling = "param" + index;
                                }

                                var info = new IDescribeArgument
                                {
                                    Type = methodCursor.GetArgType(index),
                                    Name = paramSpelling
                                };


                                var tokens      = methodCursor.GetArgCursor(index).GetTokens();
                                var foundEquals = false;
                                for (int i = 0; i < tokens.Length - 1; i++)
                                {
                                    var token = tokens[i];
                                    if (token.Kind == CXTokenKind.CXToken_Punctuation && token.Spelling == "=")
                                    {
                                        foundEquals = true;
                                        continue;
                                    }
                                    if (foundEquals && token.Kind == CXTokenKind.CXToken_Identifier)
                                    {
                                        info.Default = ""; break;
                                    }                                                                                             //probably an enum dont support this(yet(maybe))
                                    if (foundEquals)
                                    {
                                        info.Default += token.Spelling;
                                    }
                                }


                                methodInfo.Arguments.Add(info);
                            }
                            classInfo.Methods.Add(methodInfo);
                        }
                    }

                    if (methodCursor.Kind == CXCursorKind.CXCursor_CXXBaseSpecifier)
                    {
                        var definitionSpelling = methodCursor.CursorDefinition.Spelling;
                        classInfo.Parents.Add(definitionSpelling);
                    }
                });

                this.info.Interfaces.Add(classInfo);
            }
        }