示例#1
0
        protected override void BuildTypedef(CodeNamespace ns, CppTypedef typedef)
        {
            TypeDesc fieldType     = GetTypeDesc(typedef.ElementType);
            string   baseTypeName  = ResolveCefType(fieldType.ToString());
            string   aliasTypeName = GetClassName(typedef.Name);

            if (aliasTypeName == baseTypeName)
            {
                throw new InvalidOperationException();
            }

            var decl = new CodeStruct(aliasTypeName);

            decl.Attributes = CodeAttributes.Public | CodeAttributes.Unsafe | CodeAttributes.Partial;
            decl.Comments.AddVSDocComment(typedef.Comment, "summary");

            var attr = new CustomCodeAttribute(typeof(StructLayoutAttribute));

            attr.AddParameter(LayoutKind.Sequential);
            decl.CustomAttributes.Add(attr);


            var field = new CodeField(baseTypeName, "Base");

            field.Attributes = CodeAttributes.Public;
            //field.CustomAttributes.Add(new CustomCodeAttribute(typeof(FieldOffsetAttribute)) { Parameters = { "0" } });
            decl.Members.Add(field);

            ns.Types.Add(decl);
        }
示例#2
0
        public static bool IsFunctionType(this CppTypedef typedef)
        {
            // search the ElementType hiearchy for CppTypedefs and CppPointers until we finally get to a CppFunction or not
            if (typedef.ElementType is CppTypedef td)
            {
                return(td.IsFunctionType());
            }

            if (typedef.ElementType is CppPointerType ptr)
            {
                if (ptr.ElementType.TypeKind == CppTypeKind.Function)
                {
                    return(true);
                }
            }

            if (typedef.ElementType.TypeKind == CppTypeKind.Function)
            {
                return(true);
            }

            return(false);
        }
示例#3
0
        public void TestNamespacedTypedef()
        {
            ParseAssert(@"
namespace A
{
    typedef int (*a)(int b);
}
A::a c;
",
                        compilation => {
                Assert.False(compilation.HasErrors);

                Assert.AreEqual(1, compilation.Namespaces.Count);
                ICppGlobalDeclarationContainer container = compilation.Namespaces[0];
                Assert.AreEqual(1, container.Typedefs.Count);
                Assert.AreEqual(1, compilation.Fields.Count);

                CppTypedef typedef = container.Typedefs[0];
                CppField field     = compilation.Fields[0];

                Assert.AreEqual(typedef, field.Type);
            }
                        );
        }
示例#4
0
        private CSharpElement ConvertTypedef(CSharpConverter converter, CppTypedef cppTypedef, CSharpElement context)
        {
            var elementType = cppTypedef.ElementType;

            if (DefaultFunctionTypeConverter.IsFunctionType(elementType, out var cppFunctionType))
            {
                return(DefaultFunctionTypeConverter.ConvertNamedFunctionType(converter, cppFunctionType, context, cppTypedef));
            }

            var isFromSystemIncludes = converter.IsFromSystemIncludes(cppTypedef);

            var csElementType = converter.GetCSharpType(elementType, context, true);

            var noWrap = converter.Options.TypedefCodeGenKind == CppTypedefCodeGenKind.NoWrap && !converter.Options.TypedefWrapWhiteList.Contains(cppTypedef.Name);

            // If:
            // - the typedef is from system includes and the underlying type is not a pointer
            // - or the typedef mode is "no-wrap" and is not in the whitelist
            // then we bypass entirely the typedef and return immediately the element type
            bool is_size_t = isFromSystemIncludes && cppTypedef.Name == "size_t";

            if (noWrap || (isFromSystemIncludes && elementType.TypeKind != CppTypeKind.Pointer && !is_size_t))
            {
                return(csElementType);
            }

            // Otherwise we generate a small wrapper struct
            var csStructName = converter.GetCSharpName(cppTypedef, context);
            var csStruct     = new CSharpStruct(csStructName)
            {
                CppElement = cppTypedef,
            };

            var container = converter.GetCSharpContainer(cppTypedef, context);

            converter.ApplyDefaultVisibility(csStruct, container);
            container.Members.Add(csStruct);

            csStruct.Comment = converter.GetCSharpComment(cppTypedef, csStruct);

            // Requires System.Runtime.InteropServices
            csStruct.Attributes.Add(new CSharpStructLayoutAttribute(LayoutKind.Sequential)
            {
                CharSet = converter.Options.DefaultCharSet
            });

            // Required by StructLayout
            converter.AddUsing(container, "System.Runtime.InteropServices");

            var name = csStruct.Name;

            csStruct.Modifiers |= CSharpModifiers.ReadOnly;
            csStruct.BaseTypes.Add(new CSharpFreeType($"IEquatable<{name}>"));

            // Dump the type name and attached attributes for the element type
            var attachedAttributes = string.Empty;
            var csElementTypeName  = is_size_t ? "IntPtr" : converter.ConvertTypeReferenceToString(csElementType, out attachedAttributes);

            csStruct.Members.Add(new CSharpLineElement($"public {name}({csElementTypeName} value) => this.Value = value;"));
            csStruct.Members.Add(new CSharpLineElement($"{attachedAttributes}public readonly {csElementTypeName} Value;"));
            csStruct.Members.Add(new CSharpLineElement($"public bool Equals({name} other) =>  Value.Equals(other.Value);"));
            csStruct.Members.Add(new CSharpLineElement($"public override bool Equals(object obj) => obj is {name} other && Equals(other);"));
            csStruct.Members.Add(new CSharpLineElement($"public override int GetHashCode() => Value.GetHashCode();"));
            csStruct.Members.Add(new CSharpLineElement($"public override string ToString() => Value.ToString();"));
            csStruct.Members.Add(new CSharpLineElement($"public static implicit operator {csElementTypeName}({name} from) => from.Value;"));
            csStruct.Members.Add(new CSharpLineElement($"public static implicit operator {name}({csElementTypeName} from) => new {name}(from);"));
            csStruct.Members.Add(new CSharpLineElement($"public static bool operator ==({name} left, {name} right) => left.Equals(right);"));
            csStruct.Members.Add(new CSharpLineElement($"public static bool operator !=({name} left, {name} right) => !left.Equals(right);"));

            return(csStruct);
        }
示例#5
0
 protected abstract void BuildTypedef(CodeNamespace ns, CppTypedef typedef);
示例#6
0
        private GenerateResult GenerateTypedef(CppTypedef cppTypedef)
        {
            var elementType = cppTypedef.ElementType;
            var array       = false;

            if (elementType is CppPointerType pointerType)
            {
                array       = true;
                elementType = pointerType.ElementType;
            }

            if (elementType.TypeKind != CppTypeKind.StructOrClass)
            {
                throw new NotSupportedException(elementType.GetDisplayName());
            }

            var csElementType   = ConvertToCSharpType(elementType);
            var usingDirectives = new List <UsingDirectiveSyntax>();

            var csClass = new ClassDeclarationSyntax
            {
                Modifiers  = Modifiers.Internal,
                Identifier = cppTypedef.Name
            };

            if (array)
            {
                if (_config.NodeTypes.Contains(csClass.Identifier))
                {
                    AddPgNodeAttribute(usingDirectives, csClass);
                    usingDirectives.Add(Syntax.UsingDirective("System.Collections.Generic"));

                    csClass.BaseList = new BaseListSyntax
                    {
                        Types =
                        {
                            Syntax.ParseName($"List<{csElementType}>"),
                            Syntax.ParseName(nodeInterfaceName)
                        }
                    };
                }

                AddPgNodeTypeProperty(csClass, Modifiers.None);
            }
            else
            {
                csClass.BaseList = new BaseListSyntax
                {
                    Types =
                    {
                        Syntax.ParseName(csElementType)
                    }
                };

                AddPgNodeAttribute(usingDirectives, csClass);

                AddPgNodeTypeProperty(csClass, _config.NodeTypes.Contains(csElementType) ? Modifiers.Override : Modifiers.None);
            }

            _typeMap[cppTypedef.Name] = cppTypedef.Name;

            return(new GenerateResult(cppTypedef)
            {
                UsingDirectives = usingDirectives.ToArray(),
                Type = csClass
            });
        }
示例#7
0
 public static CppPrimitiveType ElementTypeAsPrimitive(this CppTypedef typedef)
 => typedef.ElementType as CppPrimitiveType;
示例#8
0
 public static bool IsPrimitiveType(this CppTypedef typedef)
 => typedef.ElementType.TypeKind == CppTypeKind.Primitive;
示例#9
0
        private async Task ProcessAsync(CppTypedef item)
        {
            await _handleBuilder.BuildAsync(new[] { item });

            await _delegateBuilder.BuildAsync(new[] { item });
        }