Esempio n. 1
0
    private MemberDeclarationSyntax GenerateBackingField(CsField field, CsTypeBase backingType,
                                                         bool isArray  = false, bool propertyBacking = true,
                                                         bool document = false)
    {
        var elementType = ParseTypeName(backingType.QualifiedName);

        var fieldDecl = FieldDeclaration(
            VariableDeclaration(
                isArray
                        ? ArrayType(elementType, SingletonList(ArrayRankSpecifier()))
                        : elementType,
                SingletonSeparatedList(
                    VariableDeclarator(propertyBacking ? field.IntermediateMarshalName : field.Name)
                    )
                )
            )
                        .WithModifiers(
            propertyBacking
                    ? TokenList(Token(SyntaxKind.InternalKeyword))
                    : field.VisibilityTokenList
            );

        if (explicitLayout)
        {
            fieldDecl = AddFieldOffsetAttribute(fieldDecl, field.Offset);
        }

        return(document ? AddDocumentationTrivia(fieldDecl, field) : fieldDecl);
    }
        private static MemberDeclarationSyntax GenerateBackingField(CsField field, CsTypeBase backingType, int?offset, bool isArray = false, bool propertyBacking = true, SyntaxTrivia?docTrivia = null)
        {
            var elementType = ParseTypeName(backingType.QualifiedName);

            var fieldDecl = FieldDeclaration(
                VariableDeclaration(
                    isArray
                            ? ArrayType(elementType, SingletonList(ArrayRankSpecifier()))
                            : elementType,
                    SingletonSeparatedList(
                        VariableDeclarator(propertyBacking ? field.IntermediateMarshalName : field.Name)
                        )
                    )
                )
                            .WithModifiers(
                propertyBacking
                        ? TokenList(Token(SyntaxKind.InternalKeyword))
                        : field.VisibilityTokenList
                );

            if (offset.HasValue)
            {
                fieldDecl = fieldDecl.WithAttributeLists(SingletonList(
                                                             AttributeList(
                                                                 SingletonSeparatedList(Attribute(
                                                                                            ParseName("System.Runtime.InteropServices.FieldOffset"),
                                                                                            AttributeArgumentList(
                                                                                                SingletonSeparatedList(AttributeArgument(
                                                                                                                           LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(offset.Value))))))))
                                                             ));
            }

            return(docTrivia is { } trivia?fieldDecl.WithLeadingTrivia(trivia) : fieldDecl);
        }
    private void CreateCore(CsMarshalBase csMarshallable)
    {
        var marshallable = (CppMarshallable)csMarshallable.CppElement;

        CsTypeBase publicType  = null;
        CsTypeBase marshalType = null;

        var mappingRule = marshallable.Rule;
        var publicTypeName = mappingRule is { MappingType : { } mapType } ? mapType : marshallable.TypeName;
 public override void Init(TransformManager manager, Logger logger)
 {
     base.Init(manager, logger);
     DefaultInterfaceCppObject = new CsInterface {
         Name = manager.GlobalNamespace.GetTypeName("CppObject")
     };
     DefaultCallbackable = new CsInterface {
         Name = manager.GlobalNamespace.GetTypeName("ICallbackable")
     };
     DefaultComObjectCallback = new CsInterface {
         Name = manager.GlobalNamespace.GetTypeName("ComObjectCallback")
     };
 }
Esempio n. 5
0
 public static string GetNativeImplementationQualifiedName(this CsTypeBase type) =>
 type is CsInterface iface?iface.GetNativeImplementationOrThis().QualifiedName : type.QualifiedName;
Esempio n. 6
0
        private void ProcessDefines(ConfigFile file)
        {
            foreach (var defineRule in file.Extension.OfType <DefineExtensionRule>())
            {
                CsTypeBase defineType = null;

                if (defineRule.Enum != null)
                {
                    var newEnum = new CsEnum
                    {
                        Name           = defineRule.Enum,
                        UnderlyingType = !string.IsNullOrWhiteSpace(defineRule.UnderlyingType)
                            ? (CsFundamentalType)typeRegistry.ImportType(defineRule.UnderlyingType)
                            : null
                    };
                    defineType = newEnum;

                    if (defineRule.SizeOf.HasValue && newEnum.UnderlyingType == null)
                    {
                        var size = defineRule.SizeOf.Value;

                        switch (size)
                        {
                        case 1:
                            newEnum.UnderlyingType = typeRegistry.ImportType(typeof(byte));
                            break;

                        case 2:
                            newEnum.UnderlyingType = typeRegistry.ImportType(typeof(short));
                            break;

                        case 4:
                            newEnum.UnderlyingType = typeRegistry.ImportType(typeof(int));
                            break;

                        default:
                            break;
                        }
                    }
                }
                else if (defineRule.Struct != null)
                {
                    var newStruct = new CsStruct {
                        Name = defineRule.Struct
                    };
                    defineType = newStruct;
                    if (defineRule.HasCustomMarshal.HasValue)
                    {
                        newStruct.HasMarshalType = defineRule.HasCustomMarshal.Value;
                    }

                    if (defineRule.IsStaticMarshal.HasValue)
                    {
                        newStruct.IsStaticMarshal = defineRule.IsStaticMarshal.Value;
                    }

                    if (defineRule.HasCustomNew.HasValue)
                    {
                        newStruct.HasCustomNew = defineRule.HasCustomNew.Value;
                    }

                    if (defineRule.SizeOf.HasValue)
                    {
                        newStruct.SetSize(defineRule.SizeOf.Value);
                    }

                    if (defineRule.Align.HasValue)
                    {
                        newStruct.Align = defineRule.Align.Value;
                    }
                }
                else if (defineRule.Interface != null)
                {
                    var iface = new CsInterface
                    {
                        Name       = defineRule.Interface,
                        ShadowName = defineRule.ShadowName,
                        VtblName   = defineRule.VtblName
                    };
                    if (defineRule.NativeImplementation != null)
                    {
                        iface.NativeImplementation = new CsInterface {
                            Name = defineRule.NativeImplementation, IsDualCallback = true
                        };
                        iface.IsCallback     = true;
                        iface.IsDualCallback = true;
                        typeRegistry.DefineType(iface.NativeImplementation);
                    }
                    defineType = iface;
                }
                else
                {
                    Logger.Error(LoggingCodes.MissingElementInRule, "Invalid rule [{0}]. Requires one of enum, struct, or interface", defineRule);
                    continue;
                }

                // Define this type
                typeRegistry.DefineType(defineType);
            }
        }
 public CsExpressionConstant(CppElement cppElement, string name, CsTypeBase type, string value) : base(cppElement, name)
 {
     Type  = type ?? throw new ArgumentNullException(nameof(type));
     Value = value ?? throw new ArgumentNullException(nameof(value));
 }
Esempio n. 8
0
 public BoundType(CsTypeBase csType, CsTypeBase?marshalType, string?source)
 {
     CSharpType  = csType ?? throw new ArgumentNullException(nameof(csType));
     MarshalType = marshalType;
     Source      = source;
 }
        /// <summary>
        /// Gets the C# type from a C++ type.
        /// </summary>
        /// <typeparam name="T">The C# type to return</typeparam>
        /// <param name="marshallable">The marshallable element to create the C# type from.</param>
        /// <returns>An instantiated C# type</returns>
        private T CreateCore <T>(CppMarshallable marshallable) where T : CsMarshalBase, new()
        {
            CsTypeBase publicType     = null;
            CsTypeBase marshalType    = null;
            var        csMarshallable = new T
            {
                CppElement = marshallable,
                IsArray    = marshallable.IsArray,
                HasPointer = !string.IsNullOrEmpty(marshallable.Pointer) && (marshallable.Pointer.Contains("*") || marshallable.Pointer.Contains("&")),
            };

            // TODO: handle multidimensional arrays
            // Calculate ArrayDimension
            int arrayDimensionValue = 0;

            if (marshallable.IsArray)
            {
                if (string.IsNullOrEmpty(marshallable.ArrayDimension))
                {
                    arrayDimensionValue = 0;
                }
                else if (!int.TryParse(marshallable.ArrayDimension, out arrayDimensionValue))
                {
                    arrayDimensionValue = 1;
                }
            }

            // If array Dimension is 0, then it is not an array
            if (arrayDimensionValue == 0)
            {
                marshallable.IsArray   = false;
                csMarshallable.IsArray = false;
            }
            csMarshallable.ArrayDimensionValue = arrayDimensionValue;

            string publicTypeName = marshallable.GetTypeNameWithMapping();

            switch (publicTypeName)
            {
            case "char":
                publicType = typeRegistry.ImportType(typeof(byte));
                if (csMarshallable.HasPointer)
                {
                    publicType = typeRegistry.ImportType(typeof(string));
                }
                if (csMarshallable.IsArray)
                {
                    publicType  = typeRegistry.ImportType(typeof(string));
                    marshalType = typeRegistry.ImportType(typeof(byte));
                }
                break;

            case "wchar_t":
                publicType = typeRegistry.ImportType(typeof(char));
                csMarshallable.IsWideChar = true;
                if (csMarshallable.HasPointer)
                {
                    publicType = typeRegistry.ImportType(typeof(string));
                }
                if (csMarshallable.IsArray)
                {
                    publicType  = typeRegistry.ImportType(typeof(string));
                    marshalType = typeRegistry.ImportType(typeof(char));
                }
                break;

            default:

                // If CppType is an array, try first to get the binding for this array
                if (marshallable.IsArray)
                {
                    publicType = typeRegistry.FindBoundType(publicTypeName + "[" + marshallable.ArrayDimension + "]");
                }

                // Else get the typeName
                if (publicType == null)
                {
                    // Try to get a declared type
                    // If it fails, then this type is unknown
                    publicType = typeRegistry.FindBoundType(publicTypeName);
                    if (publicType == null)
                    {
                        logger.Fatal("Unknown type found [{0}]", publicTypeName);
                    }
                }
                else
                {
                    csMarshallable.ArrayDimensionValue = 0;
                    csMarshallable.IsArray             = false;
                }

                // By default, use the underlying native type as the marshal type
                // if it differs from the public type.
                marshalType = typeRegistry.FindBoundType(marshallable.TypeName);
                if (publicType == marshalType)
                {
                    marshalType = null;
                }

                if (marshalType == null)
                {
                    // Otherwise, get the registered marshal type if one exists
                    marshalType = typeRegistry.FindBoundMarshalType(publicTypeName);
                }

                if (publicType is CsStruct csStruct)
                {
                    // If a structure was not already parsed, then parse it before going further
                    if (!csStruct.IsFullyMapped)
                    {
                        RequestStructProcessing?.Invoke(csStruct);
                    }

                    if (!csStruct.IsFullyMapped)     // No one tried to map the struct so we can't continue.
                    {
                        logger.Fatal($"No struct processor processed {csStruct.QualifiedName}. Cannot continue processing");
                    }

                    // If referenced structure has a specialized marshalling, then use the structure's built-in marshalling
                    if (csStruct.HasMarshalType && !csMarshallable.HasPointer)
                    {
                        marshalType = publicType;
                    }
                }
                else if (publicType is CsEnum referenceEnum)
                {
                    marshalType = null;     // enums don't need a marshal type. They can always marshal as their underlying type.
                }
                break;
            }

            // Set bool to int conversion case
            csMarshallable.IsBoolToInt =
                marshalType is CsFundamentalType marshalFundamental && IsIntegerFundamentalType(marshalFundamental) &&
                publicType is CsFundamentalType publicFundamental && publicFundamental.Type == typeof(bool);

            if (publicType.QualifiedName == globalNamespace.GetTypeName(WellKnownName.PointerSize))
            {
                marshalType = typeRegistry.ImportType(typeof(IntPtr));
            }

            // Present void* elements as IntPtr. Marshal strings as IntPtr
            if (csMarshallable.HasPointer)
            {
                if (publicTypeName == "void")
                {
                    publicType  = typeRegistry.ImportType(typeof(IntPtr));
                    marshalType = typeRegistry.ImportType(typeof(IntPtr));
                }
                else if (publicType == typeRegistry.ImportType(typeof(string)))
                {
                    marshalType = typeRegistry.ImportType(typeof(IntPtr));
                }
            }

            csMarshallable.PublicType  = publicType;
            csMarshallable.MarshalType = marshalType ?? publicType;

            csMarshallable.Relations = RelationParser.ParseRelation(marshallable.GetMappingRule().Relation, logger);

            return(csMarshallable);
        }
Esempio n. 10
0
        private static void DuplicateMethodSpecial(CsInterface interfaceType, CsMethod csMethod, CsTypeBase intPtrType)
        {
            bool hasComArrayLike = false;

            foreach (var csParameter in csMethod.Parameters)
            {
                if (csParameter.IsInComArrayLike)
                {
                    hasComArrayLike = true;
                    break;
                }
            }

            // Look for at least one parameter ComArray candidate
            if (hasComArrayLike)
            {
                // Create a new method and transforms all array of ComObject to ComArray<ComObject>
                var newMethod = (CsMethod)csMethod.Clone();
                foreach (var csSubParameter in newMethod.Parameters)
                {
                    if (csSubParameter.IsInComArrayLike)
                    {
                        csSubParameter.PublicType = new CsComArray((CsInterface)csSubParameter.PublicType);
                    }
                }
                interfaceType.Add(newMethod);
            }

            if (hasComArrayLike || csMethod.RequestRawPtr)
            {
                // Create private method with raw pointers for arrays, with all arrays as pure IntPtr
                // In order to be able to generate method taking single element
                var rawMethod = (CsMethod)csMethod.Clone();
                rawMethod.Visibility = Visibility.Private;
                foreach (var csSubParameter in rawMethod.Parameters)
                {
                    if (csSubParameter.IsArray || csSubParameter.IsComObject || csSubParameter.HasPointer)
                    {
                        csSubParameter.PublicType = intPtrType;
                        csSubParameter.IsArray    = false;
                        csSubParameter.Attribute  = CsParameterAttribute.In;
                    }
                }
                interfaceType.Add(rawMethod);
            }
        }