private CodeTypeDeclaration GenerateDelegate(IDescribeMethod declaration) { var newType = new CodeTypeDelegate { Name = declaration.Name, }; newType.CustomAttributes.AddRange(declaration.Attributes.ToArray()); if (declaration.Returns.Count == 1) { newType.ReturnType = new CodeTypeReference(declaration.Returns[0].Type); } foreach (var argumentDeclaration in declaration.Arguments) { var param = new CodeParameterDeclarationExpression(argumentDeclaration.Type, argumentDeclaration.Name); newType.Parameters.Add(param); } return(newType); }
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); } } } }
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); } }