Cursor.ChildVisitResult ClassVisitor(Cursor cursor, Cursor parent)
        {
            switch (cursor.Kind)
            {
                case CursorKind.CxxAccessSpecifier:
                    _context.MemberAccess = cursor.AccessSpecifier;
                    return Cursor.ChildVisitResult.Continue;
                case CursorKind.CxxBaseSpecifier:
                    string baseName = TypeRefDefinition.GetFullyQualifiedName(cursor.Type.Declaration);
                    ClassDefinition baseClass;
                    if (!project.ClassDefinitions.TryGetValue(baseName, out baseClass))
                    {
                        Console.WriteLine("Base {0} for {1} not found! Missing header?", baseName, _context.Class.Name);
                        return Cursor.ChildVisitResult.Continue;
                    }
                    _context.Class.BaseClass = baseClass;
                    return Cursor.ChildVisitResult.Continue;
                case CursorKind.TemplateTypeParameter:
                    var classTemplate = _context.Class as ClassTemplateDefinition;
                    if (!classTemplate.TemplateParameters.Contains(cursor.Spelling))
                    {
                        classTemplate.TemplateParameters.Add(cursor.Spelling);
                    }
                    return Cursor.ChildVisitResult.Continue;
            }

            // We usually only care about public members
            if (_context.MemberAccess != AccessSpecifier.Public)
            {
                if (cursor.IsVirtualCxxMethod && !cursor.IsPureVirtualCxxMethod)
                {
                    // private/protected virtual method that may override public abstract methods,
                    // necessary for checking whether a class is abstract or not.
                }
                else if (cursor.Kind == CursorKind.Constructor)
                {
                    // class has a private/protected constructor,
                    // no need to create a default constructor
                }
                else
                {
                    return Cursor.ChildVisitResult.Continue;
                }
            }

            switch (cursor.Kind)
            {
                case CursorKind.ClassDecl:
                case CursorKind.StructDecl:
                case CursorKind.ClassTemplate:
                case CursorKind.EnumDecl:
                    if (cursor.IsDefinition)
                    {
                        ParseClassCursor(cursor);
                    }
                    break;


                case CursorKind.CxxMethod:
                case CursorKind.Constructor:
                    ParseMethodCursor(cursor);
                    break;
                case CursorKind.ConversionFunction:
                case CursorKind.FunctionTemplate:
                case CursorKind.Destructor:
                    break;

                case CursorKind.FieldDecl:
                    var field = new FieldDefinition(cursor.Spelling,
                        new TypeRefDefinition(cursor.Type, cursor), _context.Class);
                    break;

                case CursorKind.TypedefDecl:
                    ParseTypedefCursor(cursor);
                    break;

                case CursorKind.UnionDecl:
                    return Cursor.ChildVisitResult.Recurse;

                default:
                    //Console.WriteLine(cursor.Spelling);
                    break;
            }

            return Cursor.ChildVisitResult.Continue;
        }
 public static string GetTypeMarshalFieldSetCppCli(FieldDefinition field, ManagedParameter parameter, string nativePointer)
 {
     switch (field.Type.Name)
     {
         case "btQuaternion":
             return "Math::QuaternionToBtQuat(" + parameter.Name + ", &" + nativePointer + "->" + field.Name + ')';
         case "btTransform":
             return "Math::MatrixToBtTransform(" + parameter.Name + ", &" + nativePointer + "->" + field.Name + ')';
         case "btVector4":
             return "Math::Vector4ToBtVector4(" + parameter.Name + ", &" + nativePointer + "->" + field.Name + ')';
         default:
             return null;
     }
 }
        private void CreateFieldSetter(FieldDefinition field, ClassDefinition @class, string setterName)
        {
            var type = field.Type;
            var typeCanonical = type.Canonical;

            // Can't assign value to reference or constant array
            switch (typeCanonical.Kind)
            {
                case TypeKind.LValueReference:
                case TypeKind.ConstantArray:
                    return;
                case TypeKind.Record:
                    if (typeCanonical.Target == null) return;
                    if (!typeCanonical.Target.MarshalAsStruct) return;

                    type = new TypeRefDefinition
                    {
                        IsConst = true,
                        Kind = TypeKind.Pointer,
                        Referenced = type.Copy()
                    };
                    break;
                default:
                    type = type.Copy();
                    break;
            }

            var setter = new MethodDefinition(setterName, @class, 1)
            {
                Field = field,
                ReturnType = new TypeRefDefinition("void")
            };
            setter.Parameters[0] = new ParameterDefinition("value", type)
            {
                MarshalDirection = MarshalDirection.In
            };

            field.Setter = setter;
        }
        private void CreateFieldGetter(FieldDefinition field, ClassDefinition @class, string getterName, MethodDefinition setter)
        {
            MethodDefinition getter;

            // Use getter with an out parameter for structs
            if (field.Type.Target != null && field.Type.Target.MarshalAsStruct)
            {
                getter = new MethodDefinition(getterName, @class, 1);
                getter.ReturnType = new TypeRefDefinition("void");

                string paramName = setter != null ? setter.Parameters[0].Name : "value";
                var paramType = new TypeRefDefinition(field.Type.Name)
                {
                    Kind = TypeKind.Pointer,
                    Referenced = field.Type.Copy()
                };
                getter.Parameters[0] = new ParameterDefinition(paramName, paramType)
                {
                    MarshalDirection = MarshalDirection.Out
                };
            }
            else
            {
                TypeRefDefinition type;
                if (field.Type.Canonical.Kind == TypeKind.Record)
                {
                    type = new TypeRefDefinition()
                    {
                        Kind = TypeKind.Pointer,
                        Referenced = field.Type.Copy()
                    };
                }
                else if (field.Type.Canonical.Kind == TypeKind.Unexposed)
                {
                    // TODO:
                    type = field.Type;
                }
                else
                {
                    type = field.Type;
                }

                getter = new MethodDefinition(getterName, @class, 0);
                getter.ReturnType = type;
            }

            getter.Field = field;
            field.Getter = getter;
        }
 public static string GetFieldSetterMarshal(ParameterDefinition parameter, FieldDefinition field)
 {
     switch (parameter.Type.ManagedName)
     {
         case "Quaternion":
             return "QUATERNION_IN(" + parameter.Name + ", &obj->" + field.Name + ");";
         case "Matrix3x3":
             return "MATRIX3X3_IN(" + parameter.Name + ", &obj->" + field.Name + ");";
         case "Transform":
             return "TRANSFORM_IN(" + parameter.Name + ", &obj->" + field.Name + ");";
         case "Vector3":
             return "VECTOR3_IN(" + parameter.Name + ", &obj->" + field.Name + ");";
         case "Vector4":
             return "VECTOR4_IN(" + parameter.Name + ", &obj->" + field.Name + ");";
         default:
             return null;
     }
 }
        Cursor.ChildVisitResult ClassVisitor(Cursor cursor, Cursor parent)
        {
            if (cursor.Kind == CursorKind.CxxAccessSpecifier)
            {
                currentMemberAccess = cursor.AccessSpecifier;
                return Cursor.ChildVisitResult.Continue;
            }
            else if (cursor.Kind == CursorKind.CxxBaseSpecifier)
            {
                currentClass.BaseClass = new TypeRefDefinition(cursor.Type);
                return Cursor.ChildVisitResult.Continue;
            }

            if (currentMemberAccess != AccessSpecifier.Public)
            {
                return Cursor.ChildVisitResult.Continue;
            }

            if ((cursor.Kind == CursorKind.ClassDecl || cursor.Kind == CursorKind.StructDecl ||
                cursor.Kind == CursorKind.ClassTemplate || cursor.Kind == CursorKind.TypedefDecl ||
                cursor.Kind == CursorKind.EnumDecl) && cursor.IsDefinition)
            {
                ParseClassCursor(cursor);
            }
            else if (cursor.Kind == CursorKind.CxxMethod || cursor.Kind == CursorKind.Constructor)
            {
                string methodName = cursor.Spelling;
                if (excludedMethods.ContainsKey(methodName))
                {
                    return Cursor.ChildVisitResult.Continue;
                }

                currentMethod = new MethodDefinition(methodName, currentClass, cursor.NumArguments);
                currentMethod.ReturnType = new TypeRefDefinition(cursor.ResultType);
                currentMethod.IsStatic = cursor.IsStaticCxxMethod;
                currentMethod.IsConstructor = cursor.Kind == CursorKind.Constructor;

                if (cursor.IsVirtualCxxMethod)
                {
                    currentMethod.IsVirtual = true;
                    if (cursor.IsPureVirtualCxxMethod)
                    {
                        currentMethod.IsAbstract = true;
                        currentClass.IsAbstract = true;
                    }
                }

                // Check if the return type is a template
                cursor.VisitChildren(MethodTemplateTypeVisitor);

                // Parse arguments
                for (uint i = 0; i < cursor.NumArguments; i++)
                {
                    Cursor arg = cursor.GetArgument(i);

                    string parameterName = arg.Spelling;
                    if (parameterName.Length == 0)
                    {
                        parameterName = "__unnamed" + i;
                    }
                    currentParameter = new ParameterDefinition(parameterName, new TypeRefDefinition(arg.Type));
                    currentMethod.Parameters[i] = currentParameter;
                    arg.VisitChildren(MethodTemplateTypeVisitor);
                    currentParameter = null;

                    // Check if it's a const or optional parameter
                    IEnumerable<Token> argTokens = currentTU.Tokenize(arg.Extent);
                    foreach (Token token in argTokens)
                    {
                        if (token.Spelling.Equals("="))
                        {
                            currentMethod.Parameters[i].IsOptional = true;
                        }
                    }
                }

                currentMethod = null;
            }
            else if (cursor.Kind == CursorKind.FieldDecl)
            {
                currentField = new FieldDefinition(cursor.Spelling,
                    new TypeRefDefinition(cursor.Type), currentClass);
                currentFieldHasSpecializedParameter = false;
                cursor.VisitChildren(FieldTemplateTypeVisitor);
                currentField = null;
            }
            else if (cursor.Kind == CursorKind.UnionDecl)
            {
                return Cursor.ChildVisitResult.Recurse;
            }
            else
            {
                //Console.WriteLine(cursor.Spelling);
            }
            return Cursor.ChildVisitResult.Continue;
        }