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; }