Beispiel #1
0
        /// <inheritdoc />
        public override void VisitField(CppField cppField)
        {
            // Always serialize fixed part of the type.
            //
            WriteLine($"// Fixed variable length field : {cppField.FieldInfo.Name} {cppField.CppType.Name}");
            WriteLine("//");

            if (cppField.FieldInfo.IsFixedSizedArray())
            {
                // Serialize fixed length array.
                //
                FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>();

                WriteLine(cppField.CppType.IsCodegenType
                    ? $"this.{cppField.FieldInfo.Name}.SerializeFixedPartCodegenTypeArray({arrayAttribute.Length}, buffer, objectOffset + {cppField.CppStructOffset});"
                    : $"this.{cppField.FieldInfo.Name}.SerializeFixedPartPrimitiveTypeArray({arrayAttribute.Length}, buffer, objectOffset + {cppField.CppStructOffset});");
            }
            else
            {
                WriteLine(cppField.CppType.IsCodegenType
                    ? $"((global::Mlos.Core.ICodegenType)this.{cppField.FieldInfo.Name}).SerializeFixedPart(buffer, objectOffset + {cppField.CppStructOffset});"
                    : $"CodegenTypeExtensions.SerializeFixedPart(this.{cppField.FieldInfo.Name}, buffer, objectOffset + {cppField.CppStructOffset});");
            }

            WriteLine();
        }
        /// <inheritdoc />
        public override void VisitField(CppField cppField)
        {
            if (!cppField.CppType.HasVariableData)
            {
                // Ignore field with sized size.
                //
                return;
            }

            // Variable data field.
            //
            WriteLine($"// Serialize variable data field : {cppField.FieldInfo.Name} {cppField.CppType.Name}");
            WriteLine("//");

            if (cppField.FieldInfo.IsFixedSizedArray())
            {
                // Serialize fixed length array.
                //
                FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>();

                WriteLine($"dataSize = this.{cppField.FieldInfo.Name}.SerializeVariableData({arrayAttribute.Length}, buffer, objectOffset + {cppField.CppStructOffset}, dataOffset);");
            }
            else
            {
                WriteLine($"dataSize = ((global::Mlos.Core.ICodegenType)this.{cppField.FieldInfo.Name}).SerializeVariableData(buffer, objectOffset + {cppField.CppStructOffset}, dataOffset);");
            }

            WriteLine("totalDataSize += dataSize;");
            WriteLine("dataOffset += dataSize;");
            WriteLine();
        }
Beispiel #3
0
        /// <inheritdoc />
        public override void VisitField(CppField cppField)
        {
            string fieldName   = cppField.FieldInfo.Name;
            string fieldOffset = $"{cppField.CppStructOffset}";

            Type fieldType = cppField.FieldInfo.FieldType;

            if (cppField.FieldInfo.IsFixedSizedArray())
            {
                // When field is array, get element type to use correct proxy type.
                //
                fieldType = fieldType.GetElementType();
            }

            // Get the proxy type name.
            //
            string cppProxyTypeFullName = CppTypeMapper.GetCppProxyFullTypeName(fieldType);

            // Write the property, for arrays, use PropertyArrayProxy.
            //
            if (cppField.FieldInfo.IsFixedSizedArray())
            {
                // Get the fixed array length and write the property.
                //
                FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>();
                WriteLine($"::Mlos::Core::PropertyArrayProxy<{cppProxyTypeFullName}, {arrayAttribute.Length}> {fieldName}() {{ return ::Mlos::Core::PropertyArrayProxy<{cppProxyTypeFullName}, {arrayAttribute.Length}>(buffer, {fieldOffset}); }}");
            }
            else
            {
                WriteLine($"{cppProxyTypeFullName} {fieldName}() {{ return {cppProxyTypeFullName}(buffer, {fieldOffset}); }}");
            }

            WriteLine();
        }
        /// <inheritdoc />
        public override void VisitField(CppField cppField)
        {
            string fieldName = cppField.FieldInfo.Name;

            if (cppField.FieldInfo.IsFixedSizedArray())
            {
                // Copy fixed length array.
                //
                FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>();

                // Use different routine if copying array of primitive elements or array of ICodegenType.
                //
                if (cppField.CppType.IsCodegenType)
                {
                    WriteLine($"{fieldName}.UpdatePropertyProxyArray(proxy.{fieldName}, {arrayAttribute.Length});");
                }
                else
                {
                    WriteLine($"{fieldName}.UpdateProxyArray(proxy.{fieldName}, {arrayAttribute.Length});");
                }
            }
            else if (cppField.CppType.IsCodegenType)
            {
                WriteLine($"{fieldName}.Update(proxy.{fieldName});");
            }
            else
            {
                WriteLine($"{fieldName} = proxy.{fieldName};");
            }
        }
Beispiel #5
0
        private MemberDeclarationSyntax BuildField(CppField cppField)
        {
            if (TypeMap.TryResolveType(cppField.Type, out var typeInfo))
            {
                if (typeInfo.IsFunction)
                {
                    return(FieldDeclaration(
                               VariableDeclaration(IdentifierName(nameof(IntPtr)))
                               .AddVariables(VariableDeclarator(cppField.Name)))
                           .AddModifiers(Token(SyntaxKind.PublicKeyword))
                           .AddManagedTypeAttribute(typeInfo.TypeSyntax));
                }

                return(FieldDeclaration(
                           VariableDeclaration(typeInfo.TypeSyntax)
                           .AddVariables(VariableDeclarator(cppField.Name)))
                       .AddModifiers(Token(SyntaxKind.PublicKeyword)));
            }

            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }
            throw new NotImplementedException();
        }
Beispiel #6
0
        /// <inheritdoc />
        public override void VisitField(CppField cppField)
        {
            AlignAttribute alignmentAttribute = cppField.FieldInfo.GetCustomAttribute <AlignAttribute>();
            string         fieldCodeString    = alignmentAttribute == null
                ? string.Empty
                : $"alignas({alignmentAttribute.Size}) ";

            if (cppField.FieldInfo.IsFixedSizedArray())
            {
                // Field is a fixed size array.
                //
                string cppElementTypeFullName = CppTypeMapper.GetCppFullTypeName(cppField.FieldInfo.FieldType.GetElementType());

                FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>();

                fieldCodeString += $"std::array<{cppElementTypeFullName}, {arrayAttribute.Length}> {cppField.FieldInfo.Name} = {{ }};";
            }
            else
            {
                string cppTypeFullName = CppTypeMapper.GetCppFullTypeName(cppField.FieldInfo.FieldType);
                fieldCodeString += $"{cppTypeFullName} {cppField.FieldInfo.Name};";
            }

            WriteLine(fieldCodeString);
            WriteLine();
        }
        /// <inheritdoc />
        public override void VisitField(CppField cppField)
        {
            if (!cppField.CppType.HasVariableData)
            {
                // Ignore field with sized size.
                //
                return;
            }

            if (cppField.FieldInfo.IsFixedSizedArray())
            {
                // Serialize fixed length array.
                //
                var arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>();

                WriteLine($"dataSize = this.{cppField.FieldInfo.Name}.GetVariableDataSize({arrayAttribute.Length});");
            }
            else
            {
                string fieldName = cppField.FieldInfo.Name;

                WriteLine($"dataSize += ((global::Mlos.Core.ICodegenType){fieldName}).GetVariableDataSize();");
            }

            WriteLine();
        }
        /// <inheritdoc />
        public override void VisitField(CppField cppField)
        {
            if (!cppField.CppType.HasVariableData)
            {
                // Ignore field with sized size.
                //
                return;
            }

            // Variable length field.
            //
            WriteLine($"// Update variable length field : {cppField.FieldInfo.Name} {cppField.CppType.Name}");
            WriteLine("//");

            if (cppField.FieldInfo.IsFixedSizedArray())
            {
                // Serialize fixed length array.
                //
                FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>();

                WriteBlock($@"
                    if (isValid)
                    {{
                        isValid = this.{cppField.FieldInfo.Name}.VerifyVariableData({arrayAttribute.Length}, objectOffset + {cppField.CppStructOffset}, totalDataSize, ref expectedDataOffset);
                    }}");
            }
            else
            {
                WriteBlock($@"
                    if (isValid)
                    {{
                        isValid = ((global::Mlos.Core.ICodegenProxy)this.{cppField.FieldInfo.Name}).VerifyVariableData(objectOffset + {cppField.CppStructOffset}, totalDataSize, ref expectedDataOffset);
                    }}");
            }
        }
Beispiel #9
0
        /// <inheritdoc />
        public override void VisitField(CppField cppField)
        {
            // Nothing.
            //
            if (!cppField.FieldInfo.FieldType.IsClass &&
                !cppField.FieldInfo.IsFixedSizedArray())
            {
                // Primitive types and structures does not need to be allocated.
                //
                return;
            }

            Type fieldType = cppField.FieldInfo.FieldType;

            if (cppField.FieldInfo.IsFixedSizedArray())
            {
                // Create fixed length array.
                //
                fieldType = fieldType.GetElementType();

                FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>();

                WriteBlock($@"this.{cppField.FieldInfo.Name} = new {fieldType.FullName}[{arrayAttribute.Length}];");

                if (fieldType.IsClass)
                {
                    WriteBlock($@"this.{cppField.FieldInfo.Name}.Create();");
                }
            }
            else
            {
                WriteBlock($@"this.{cppField.FieldInfo.Name} = new {fieldType.FullName}();");
            }
        }
Beispiel #10
0
        private static string PostprocessFieldName(CppField element, string name, bool isFinal)
        {
            if (char.IsDigit(name[0]))
            {
                name = "Field" + name;
            }

            return(UnKeyword(name));
        }
Beispiel #11
0
        public CsField(CppField cppElement, string name) : base(cppElement, name)
        {
            if (cppElement == null)
            {
                return;
            }

            IsBitField = cppElement.IsBitField;
        }
Beispiel #12
0
        /// <inheritdoc />
        public override void VisitField(CppField cppField)
        {
            string cppDeclaringTypeFullName = CppTypeMapper.GetCppFullTypeName(cppField.FieldInfo.DeclaringType);
            string fieldName             = cppField.FieldInfo.Name;
            string actualOffsetText      = $@"offsetof(struct {cppDeclaringTypeFullName}, {fieldName})";
            string assertionErrorMessage = $@"""Invalid offset""";

            WriteLine($@"static_assert({actualOffsetText} == {cppField.CppStructOffset}, {assertionErrorMessage});");
        }
Beispiel #13
0
        public static string GetSourceFile(this CppClass @class)
        {
            CppField field = @class.Fields.FirstOrDefault();

            if (field is null)
            {
                return(@class.Span.Start.File);
            }
            return(field.Span.Start.File);
        }
        public CsField Create(CppField cppField)
        {
            var field = CreateCore <CsField>(cppField);

            MakeGeneralPointersBeIntPtr(field);

            field.IsBitField = cppField.IsBitField;

            return(field);
        }
        /// <inheritdoc />
        public override void VisitField(CppField cppField)
        {
            if (!cppField.FieldInfo.IsPrimaryKey())
            {
                // The field is not a primary key, ignore it.
                //
                return;
            }

            string fieldName = cppField.FieldInfo.Name;

            WriteLine($"hashValue = THash::CombineHashValue(hashValue, v.{fieldName});");
        }
Beispiel #16
0
        /// <summary>
        /// For each variable data field, increase total size required to serialize the structure.
        /// </summary>
        /// <param name="cppField"></param>
        public override void VisitField(CppField cppField)
        {
            if (!cppField.CppType.HasVariableData)
            {
                // Ignore the fixed size fields.
                //
                return;
            }

            string fieldName = cppField.FieldInfo.Name;

            WriteLine($"dataSize += {Constants.ObjectSerializationNamespace}::GetVariableDataSize(object.{fieldName});");
        }
        /// <inheritdoc />
        public override void VisitField(CppField cppField)
        {
            if (!cppField.FieldInfo.IsPrimaryKey())
            {
                // The field is not a primary key, ignore it.
                //
                return;
            }

            string fieldName = cppField.FieldInfo.Name;

            WriteLine($"result &= other.{fieldName} == this.{fieldName};");
        }
Beispiel #18
0
        private CXChildVisitResult VisitField(CXCursor cursor, CXCursor parent, IntPtr data)
        {
            Unit     unitParent = units[parent];
            string   unitName   = clang.getCString(clang.getCursorSpelling(cursor));
            CppField unit       = new CppField(unitParent, unitName);

            CXType type = clang.getCursorType(cursor);

            uint isVolatile = clang.isVolatileQualifiedType(type);             // property = const volatile
            uint isConst    = clang.isConstQualifiedType(type);

            if (isVolatile > 0 && isConst > 0)
            {
                properties.Add(unit);

                if (unitParent is Type)
                {
                    unit.getAccessor = (unitParent as Type).Methods.FirstOrDefault(m => m.Name == "Get" + unit.Name);
                    unit.setAccessor = (unitParent as Type).Methods.FirstOrDefault(m => m.Name == "Set" + unit.Name);
                }
            }

            unit.type = FromCXType(type);

            CXCursor parentTypeCursor = units.First(u => u.Value == unitParent).Key;
            CXType   parentType       = clang.getCursorType(parentTypeCursor);

            unit.offset = clang.Type_getOffsetOf(parentType, unitName);

            if (unitParent is Type && modifiers.ContainsKey(unitParent as Type))
            {
                unit.modifiers = modifiers[unitParent as Type];
            }
            if (clang.CXXMethod_isStatic(cursor) > 0) // FIXME ?
            {
                unit.modifiers |= Modifiers.Static;
            }

            if (!units.ContainsKey(cursor))
            {
                units.Add(cursor, unit);
            }

            if (unitParent is CppType)
            {
                (unitParent as CppType).fields.Add(unit);
            }

            return(CXChildVisitResult.CXChildVisit_Recurse);
        }
        /// <inheritdoc />
        public override void VisitField(CppField cppField)
        {
            if (!cppField.FieldInfo.IsPrimaryKey())
            {
                // This field is not a primary key, ignore it.
                //
                return;
            }

            string fieldName     = cppField.FieldInfo.Name;
            Type   fieldType     = cppField.FieldInfo.FieldType;
            string fieldTypeName = $"global::{fieldType.FullName}";

            WriteLine($"public {fieldTypeName} {fieldName};");
        }
Beispiel #20
0
        private CXChildVisitResult VisitEnumConstant(CXCursor cursor, CXCursor parent, IntPtr data)
        {
            Unit     unitParent = units[parent];
            string   unitName   = clang.getCString(clang.getCursorSpelling(cursor));
            CppField unit       = new CppField(unitParent, unitName);

            units.Add(cursor, unit);

            if (unitParent is CppType)
            {
                (unitParent as CppType).fields.Add(unit);
            }

            return(CXChildVisitResult.CXChildVisit_Continue);
        }
    public void FieldWithPointerTypeMarshalledAsIntPtr()
    {
        var cppField = new CppField("field")
        {
            TypeName = "int",
            Pointer  = "*"
        };

        TypeRegistry.BindType("int", TypeRegistry.IntPtr);

        var csField = marshalledElementFactory.Create(cppField, cppField.Name);

        Assert.Equal(TypeRegistry.IntPtr, csField.PublicType);
        Assert.Equal(csField.PublicType, csField.MarshalType);
    }
    public void FieldWithPointerToInterfaceTypeHasPublicTypeOfInterface()
    {
        var cppField = new CppField("field")
        {
            TypeName = "Interface",
            Pointer  = "*"
        };

        TypeRegistry.BindType("Interface", new CsInterface(null, "Interface"));

        var csField = marshalledElementFactory.Create(cppField, cppField.Name);

        Assert.Equal(TypeRegistry.FindBoundType("Interface"), csField.PublicType);
        Assert.Equal(TypeRegistry.IntPtr, csField.MarshalType);
        Assert.True(csField.IsInterface);
    }
        public CsField Create(CppField cppField)
        {
            var field = CreateCore <CsField>(cppField);

            if (field.HasPointer)
            {
                field.MarshalType = typeRegistry.ImportType(typeof(IntPtr));
                if (field.PublicType != typeRegistry.ImportType(typeof(string)) && !field.IsInterface)
                {
                    field.PublicType = typeRegistry.ImportType(typeof(IntPtr));
                }
            }

            field.IsBitField = cppField.IsBitField;

            return(field);
        }
Beispiel #24
0
        /// <summary>
        /// For each variable data field, increase total size required to serialize the structure.
        /// </summary>
        /// <param name="cppField"></param>
        public override void VisitField(CppField cppField)
        {
            if (!cppField.CppType.HasVariableData)
            {
                // Ignore field with sized size.
                //
                return;
            }

            string fieldName = cppField.FieldInfo.Name;

            WriteBlock($@"
                if (isValid)
                {{
                    isValid = {Constants.ObjectSerializationNamespace}::VerifyVariableData(object.{fieldName}(), objectOffset + {cppField.CppStructOffset}, totalDataSize, expectedDataOffset);
                }}");
        }
        public void FieldWithPointerTypeMarshalledAsIntPtr()
        {
            var cppField = new CppField
            {
                TypeName = "int",
                Pointer  = "*"
            };

            var typeRegistry = new TypeRegistry(Logger, A.Fake <IDocumentationLinker>());

            typeRegistry.BindType("int", typeRegistry.ImportType(typeof(IntPtr)));
            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider("SharpGen.Runtime"), typeRegistry);

            var csField = marshalledElementFactory.Create(cppField);

            Assert.Equal(typeRegistry.ImportType(typeof(IntPtr)), csField.PublicType);
            Assert.Equal(csField.PublicType, csField.MarshalType);
        }
        public void FieldWithPointerTypeMarshalledAsIntPtr()
        {
            var cppField = new CppField("field")
            {
                TypeName = "int",
                Pointer  = "*"
            };

            var typeRegistry = new TypeRegistry(Logger, A.Fake <IDocumentationLinker>());

            typeRegistry.BindType("int", TypeRegistry.IntPtr);
            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csField = marshalledElementFactory.Create(cppField, cppField.Name);

            Assert.Equal(TypeRegistry.IntPtr, csField.PublicType);
            Assert.Equal(csField.PublicType, csField.MarshalType);
        }
        public void FieldWithPointerToInterfaceTypeHasPublicTypeOfInterface()
        {
            var cppField = new CppField("field")
            {
                TypeName = "Interface",
                Pointer  = "*"
            };

            var typeRegistry = new TypeRegistry(Logger, A.Fake <IDocumentationLinker>());

            typeRegistry.BindType("Interface", new CsInterface(null, "Interface"));
            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csField = marshalledElementFactory.Create(cppField, cppField.Name);

            Assert.Equal(typeRegistry.FindBoundType("Interface"), csField.PublicType);
            Assert.Equal(TypeRegistry.IntPtr, csField.MarshalType);
            Assert.True(csField.IsInterface);
        }
        public void FieldWithPointerToInterfaceTypeHasPublicTypeOfInterface()
        {
            var cppField = new CppField
            {
                TypeName = "Interface",
                Pointer  = "*"
            };

            var typeRegistry = new TypeRegistry(Logger, A.Fake <IDocumentationLinker>());

            typeRegistry.BindType("Interface", new CsInterface {
                Name = "Interface"
            });
            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider("SharpGen.Runtime"), typeRegistry);

            var csField = marshalledElementFactory.Create(cppField);

            Assert.Equal(typeRegistry.FindBoundType("Interface"), csField.PublicType);
            Assert.Equal(typeRegistry.ImportType(typeof(IntPtr)), csField.MarshalType);
            Assert.True(csField.IsInterface);
        }
Beispiel #29
0
        /// <summary>
        /// Parses a C++ field declaration.
        /// </summary>
        private CppField ParseField(XElement xElement)
        {
            CppField cppField = new CppField();

            cppField.Name = xElement.Attribute("name") != null?xElement.Attribute("name").Value : String.Empty;

            // Handle bitfield info
            string bitField = xElement.Attribute("bits") != null?xElement.Attribute("bits").Value : String.Empty;

            if (!string.IsNullOrEmpty(bitField))
            {
                cppField.IsBitField = true;
                cppField.BitOffset  = int.Parse(bitField);
            }

            string fieldType = xElement.Attribute("type") != null?xElement.Attribute("type").Value : String.Empty;

            ResolveAndFillType(fieldType, cppField);

            return(cppField);
        }
Beispiel #30
0
        private static void CompareEventsUnion(CppField union1, CppField union2)
        {
            var c1 = (CppClass)union1.Type;
            var c2 = (CppClass)union2.Type;
            var r1 = c1.Fields.Where(t1 => !c2.Fields.Any(t2 => t1.Name == t2.Name)).ToList(); // in v1 but not in v2
            var r2 = c2.Fields.Where(t2 => !c1.Fields.Any(t1 => t2.Name == t1.Name)).ToList(); // in v2 but not in v1

            WriteLine("Events change");
            WriteLine(Environment.NewLine);
            WriteLine("fields in v1 but not v2:");
            foreach (var r in r1)
            {
                WriteLine(r.Name);
            }

            WriteLine(Environment.NewLine);
            WriteLine("fields in v2 but not in v1:");
            foreach (var r in r2)
            {
                WriteLine(r.Name);
            }
        }