public void BoolToIntSetForAllIntegerTypes(PrimitiveTypeCode integerType)
        {
            var cppMarshallable = new CppParameter("param")
            {
                TypeName       = "Integer",
                ArrayDimension = "0",
                IsArray        = true,
                Rule           =
                {
                    MappingType = "bool"
                }
            };

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

            typeRegistry.BindType("bool", TypeRegistry.Boolean);
            typeRegistry.BindType("Integer", TypeRegistry.ImportPrimitiveType(integerType));

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(cppMarshallable, cppMarshallable.Name);

            Assert.Equal(TypeRegistry.Boolean, csMarshallable.PublicType);
            Assert.Equal(TypeRegistry.ImportPrimitiveType(integerType), csMarshallable.MarshalType);
            Assert.True(csMarshallable.IsBoolToInt);
            Assert.False(csMarshallable.HasPointer);
            Assert.False(csMarshallable.IsArray);
            Assert.Equal(0, csMarshallable.ArrayDimensionValue);
        }
        public void BoolToIntSetForAllIntegerTypes(Type integerType)
        {
            var cppMarshallable = new CppMarshallable
            {
                TypeName       = "Integer",
                ArrayDimension = "0",
                IsArray        = true,
                Rule           = new MappingRule
                {
                    MappingType = "bool"
                }
            };

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

            typeRegistry.BindType("bool", typeRegistry.ImportType(typeof(bool)));
            typeRegistry.BindType("Integer", typeRegistry.ImportType(integerType));

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(cppMarshallable);

            Assert.Equal(typeRegistry.ImportType(typeof(bool)), csMarshallable.PublicType);
            Assert.Equal(typeRegistry.ImportType(integerType), csMarshallable.MarshalType);
            Assert.True(csMarshallable.IsBoolToInt);
        }
        public void NativeTypeTakesPrecedenceOverMarshalTypeForMappedType()
        {
            var cppMarshallable = new CppParameter("param")
            {
                TypeName       = "short",
                ArrayDimension = "0",
                IsArray        = true,
                Rule           =
                {
                    MappingType = "bool"
                }
            };

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

            typeRegistry.BindType("bool", TypeRegistry.Boolean, TypeRegistry.Int32);
            typeRegistry.BindType("short", TypeRegistry.Int16);

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(cppMarshallable, cppMarshallable.Name);

            Assert.Equal(TypeRegistry.Boolean, csMarshallable.PublicType);
            Assert.Equal(TypeRegistry.Int16, csMarshallable.MarshalType);
            Assert.False(csMarshallable.HasPointer);
            Assert.False(csMarshallable.IsArray);
            Assert.Equal(0, csMarshallable.ArrayDimensionValue);
        }
        public void NativeTypeTakesPrecedenceOverMarshalTypeForMappedType()
        {
            var cppMarshallable = new CppMarshallable
            {
                TypeName       = "short",
                ArrayDimension = "0",
                IsArray        = true,
                Rule           = new MappingRule
                {
                    MappingType = "bool"
                }
            };

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

            typeRegistry.BindType("bool", typeRegistry.ImportType(typeof(bool)), typeRegistry.ImportType(typeof(int)));
            typeRegistry.BindType("short", typeRegistry.ImportType(typeof(short)));

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(cppMarshallable);

            Assert.Equal(typeRegistry.ImportType(typeof(bool)), csMarshallable.PublicType);
            Assert.Equal(typeRegistry.ImportType(typeof(short)), csMarshallable.MarshalType);
        }
    public void BoolToIntSetForAllIntegerTypes(PrimitiveTypeCode integerType)
    {
        var cppMarshallable = new CppParameter("param")
        {
            TypeName       = "Integer",
            ArrayDimension = "0",
            Rule           =
            {
                MappingType = "bool"
            }
        };

        var integerPrimitiveType = TypeRegistry.ImportPrimitiveType(integerType);

        TypeRegistry.BindType("bool", TypeRegistry.Boolean);
        TypeRegistry.BindType("Integer", integerPrimitiveType);


        var csMarshallable = marshalledElementFactory.Create(cppMarshallable, cppMarshallable.Name);

        Assert.Equal(TypeRegistry.Boolean, csMarshallable.PublicType);
        Assert.Equal(integerPrimitiveType, csMarshallable.MarshalType);
        Assert.True(csMarshallable.IsBoolToInt);
        Assert.False(csMarshallable.HasPointer);
        Assert.False(csMarshallable.IsArray);
        Assert.Equal(0, csMarshallable.ArrayDimensionValue);
    }
        public void BoundTypeForArrayType(string elementType)
        {
            var cppMarshallable = new CppParameter("param")
            {
                TypeName       = elementType,
                IsArray        = true,
                ArrayDimension = "ANYSIZE_ARRAY"
            };

            var         typeRegistry      = new TypeRegistry(Logger, A.Fake <IDocumentationLinker>());
            CsInterface dynamicStringType = new(null, "DynamicString");

            typeRegistry.BindType(elementType + "[ANYSIZE_ARRAY]", dynamicStringType);

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(cppMarshallable, cppMarshallable.Name);

            Assert.Equal(dynamicStringType, csMarshallable.PublicType);
            Assert.Equal(dynamicStringType, csMarshallable.MarshalType);
            Assert.Equal(0, csMarshallable.ArrayDimensionValue);
            Assert.False(csMarshallable.IsArray);
            Assert.False(csMarshallable.IsString);
            Assert.False(csMarshallable.IsWideChar);
        }
    public void ParamWithNoTypeMappingShouldHaveMarshalTypeEqualToPublic()
    {
        var marshallable = new CppParameter("param")
        {
            TypeName = "int"
        };

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

        var csMarshallable = marshalledElementFactory.Create(marshallable, marshallable.Name);

        Assert.Equal(csMarshallable.PublicType, csMarshallable.MarshalType);
    }
    public void DoublePointerParameterMappedAsOut()
    {
        var cppParameter = new CppParameter("param")
        {
            TypeName = "Interface",
            Pointer  = "**"
        };

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

        var csParameter = marshalledElementFactory.Create(cppParameter, cppParameter.Name);

        Assert.Equal(CsParameterAttribute.Out, csParameter.Attribute);
    }
    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 void PointerNonInterfaceReturnValueMappedAsIntPtr()
    {
        var cppReturnValue = new CppReturnValue
        {
            TypeName = "int",
            Pointer  = "*"
        };

        TypeRegistry.BindType("int", TypeRegistry.Int32);
        var csReturnValue = marshalledElementFactory.Create(cppReturnValue);

        Assert.Equal(TypeRegistry.IntPtr, csReturnValue.PublicType);
        Assert.Equal(TypeRegistry.IntPtr, csReturnValue.MarshalType);
        Assert.True(csReturnValue.HasPointer);
        Assert.False(csReturnValue.IsArray);
        Assert.Equal(0, csReturnValue.ArrayDimensionValue);
    }
    public void DoublePointerNonInterfaceParameterMappedAsIntPtr()
    {
        var cppParameter = new CppParameter("param")
        {
            TypeName = "int",
            Pointer  = "**"
        };

        TypeRegistry.BindType("int", TypeRegistry.Int32);
        var csParameter = marshalledElementFactory.Create(cppParameter, cppParameter.Name);

        Assert.Equal(TypeRegistry.IntPtr, csParameter.PublicType);
        Assert.Equal(TypeRegistry.IntPtr, csParameter.MarshalType);
        Assert.True(csParameter.HasPointer);
        Assert.False(csParameter.IsArray);
        Assert.Equal(0, csParameter.ArrayDimensionValue);
    }
    public void PointerParameterMarkedAsHasPointer()
    {
        var cppParameter = new CppParameter("param")
        {
            TypeName = "int",
            Pointer  = "*"
        };

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

        var csParameter = marshalledElementFactory.Create(cppParameter, cppParameter.Name);

        Assert.False(csParameter.IsArray);
        Assert.False(csParameter.IsString);
        Assert.True(csParameter.HasPointer);
        Assert.Equal(0, csParameter.ArrayDimensionValue);
    }
    public void PointerToTypeWithMarshallingMarshalsAsUnderlyingType()
    {
        var cppMarshallable = new CppParameter("param")
        {
            TypeName = "bool",
            Pointer  = "*"
        };

        TypeRegistry.BindType("bool", TypeRegistry.Boolean, TypeRegistry.Int32);

        var csMarshallable = marshalledElementFactory.Create(cppMarshallable, cppMarshallable.Name);

        Assert.Equal(TypeRegistry.Int32, csMarshallable.MarshalType);
        Assert.Equal(0, csMarshallable.ArrayDimensionValue);
        Assert.False(csMarshallable.IsArray);
        Assert.True(csMarshallable.HasPointer);
    }
        public void ParamWithNoTypeMappingShouldHaveMarshalTypeEqualToPublic()
        {
            var marshallable = new CppMarshallable
            {
                TypeName = "int"
            };

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

            typeRegistry.BindType("int", typeRegistry.ImportType(typeof(int)));

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider("SharpGen.Runtime"), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(marshallable);

            Assert.Equal(csMarshallable.PublicType, csMarshallable.MarshalType);
        }
        public void ParameterWithStructSizeRelationLogsError()
        {
            var cppParameter = new CppParameter
            {
                TypeName = "int"
            };

            cppParameter.GetMappingRule().Relation = "struct_size()";

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

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

            AssertLoggingCodeLogged(LoggingCodes.InvalidRelation);
        }
        public void PointerParameterMarkedAsHasPointer()
        {
            var cppParameter = new CppParameter
            {
                TypeName = "int",
                Pointer  = "*"
            };

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

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

            var csParameter = marshalledElementFactory.Create(cppParameter);

            Assert.True(csParameter.HasPointer);
        }
        public void ParamWithNoTypeMappingShouldHaveMarshalTypeEqualToPublic()
        {
            var marshallable = new CppParameter("param")
            {
                TypeName = "int"
            };

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

            typeRegistry.BindType("int", TypeRegistry.Int32);

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(marshallable, marshallable.Name);

            Assert.Equal(csMarshallable.PublicType, csMarshallable.MarshalType);
        }
        public void PointerToTypeWithMarshallingMarshalsAsUnderlyingType()
        {
            var cppMarshallable = new CppMarshallable
            {
                TypeName = "bool",
                Pointer  = "*"
            };

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

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

            var csMarshallable = marshalledElementFactory.Create(cppMarshallable);

            Assert.Equal(typeRegistry.ImportType(typeof(int)), csMarshallable.MarshalType);
        }
        public void DoublePointerParameterMappedAsOut()
        {
            var cppParameter = new CppParameter("param")
            {
                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 csParameter = marshalledElementFactory.Create(cppParameter, cppParameter.Name);

            Assert.Equal(CsParameterAttribute.Out, csParameter.Attribute);
        }
        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 ZeroDimensionArrayMappedAsSingleElement()
    {
        var cppMarshallable = new CppParameter("param")
        {
            TypeName       = "int",
            ArrayDimension = "0"
        };

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

        var csMarshallable = marshalledElementFactory.Create(cppMarshallable, cppMarshallable.Name);

        Assert.Equal(TypeRegistry.Int32, csMarshallable.PublicType);
        Assert.Equal(TypeRegistry.Int32, csMarshallable.MarshalType);
        Assert.False(csMarshallable.IsArray);
        Assert.False(csMarshallable.HasPointer);
        Assert.Equal(0, csMarshallable.ArrayDimensionValue);
    }
    public void BoolToIntArray()
    {
        var cppParameter = new CppParameter("param")
        {
            TypeName  = "bool", Pointer = "*",
            Attribute = ParamAttribute.In | ParamAttribute.Buffer
        };

        TypeRegistry.BindType("bool", TypeRegistry.Boolean, TypeRegistry.UInt8);

        var csParameter = marshalledElementFactory.Create(cppParameter, cppParameter.Name);

        Assert.Equal(TypeRegistry.Boolean, csParameter.PublicType);
        Assert.Equal(TypeRegistry.UInt8, csParameter.MarshalType);
        Assert.True(csParameter.IsArray);
        Assert.True(csParameter.IsBoolToInt);
        Assert.Equal(0, csParameter.ArrayDimensionValue);
    }
        public void PointerNonInterfaceReturnValueMappedAsIntPtr()
        {
            var cppReturnValue = new CppReturnValue
            {
                TypeName = "int",
                Pointer  = "*"
            };

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

            typeRegistry.BindType("int", typeRegistry.ImportType(typeof(int)));
            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);
            var csReturnValue            = marshalledElementFactory.Create(cppReturnValue);

            Assert.Equal(typeRegistry.ImportType(typeof(IntPtr)), csReturnValue.PublicType);
            Assert.Equal(typeRegistry.ImportType(typeof(IntPtr)), csReturnValue.MarshalType);
            Assert.True(csReturnValue.HasPointer);
        }
        public void DoublePointerNonInterfaceParameterMappedAsIntPtr()
        {
            var cppParameter = new CppParameter
            {
                TypeName = "int",
                Pointer  = "**"
            };

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

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

            Assert.Equal(typeRegistry.ImportType(typeof(IntPtr)), csParameter.PublicType);
            Assert.Equal(typeRegistry.ImportType(typeof(IntPtr)), csParameter.MarshalType);
            Assert.True(csParameter.HasPointer);
        }
        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 DoubleVoidPointerParameterPreserved()
    {
        var cppParameter = new CppParameter("param")
        {
            TypeName  = "void",
            Pointer   = "**",
            Attribute = ParamAttribute.Out
        };

        TypeRegistry.BindType("void", TypeRegistry.Void);
        var csParameter = marshalledElementFactory.Create(cppParameter, cppParameter.Name);

        Assert.Equal(TypeRegistry.IntPtr, csParameter.PublicType);
        Assert.Equal(TypeRegistry.IntPtr, csParameter.MarshalType);
        Assert.True(csParameter.HasPointer);
        Assert.False(csParameter.IsArray);
        Assert.True(csParameter.IsOut);
        Assert.Equal(0, csParameter.ArrayDimensionValue);
    }
        public void ZeroDimensionArrayMappedAsSingleElement()
        {
            var cppMarshallable = new CppMarshallable
            {
                TypeName       = "int",
                ArrayDimension = "0",
                IsArray        = true
            };

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

            typeRegistry.BindType("int", typeRegistry.ImportType(typeof(int)));

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(cppMarshallable);

            Assert.False(csMarshallable.IsArray);
        }
        public void DoublePointerNonInterfaceParameterMappedAsIntPtr()
        {
            var cppParameter = new CppParameter("param")
            {
                TypeName = "int",
                Pointer  = "**"
            };

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

            typeRegistry.BindType("int", TypeRegistry.Int32);
            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);
            var csParameter = marshalledElementFactory.Create(cppParameter, cppParameter.Name);

            Assert.Equal(TypeRegistry.IntPtr, csParameter.PublicType);
            Assert.Equal(TypeRegistry.IntPtr, csParameter.MarshalType);
            Assert.True(csParameter.HasPointer);
            Assert.False(csParameter.IsArray);
            Assert.Equal(0, csParameter.ArrayDimensionValue);
        }