示例#1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TransformManager"/> class.
        /// </summary>
        public TransformManager(
            GlobalNamespaceProvider globalNamespace,
            NamingRulesManager namingRules,
            Logger logger,
            TypeRegistry typeRegistry,
            IDocumentationLinker docLinker,
            ConstantManager constantManager,
            AssemblyManager assemblyManager)
        {
            GlobalNamespace          = globalNamespace;
            Logger                   = logger;
            NamingRules              = namingRules;
            this.docLinker           = docLinker;
            this.typeRegistry        = typeRegistry;
            this.constantManager     = constantManager;
            this.assemblyManager     = assemblyManager;
            namespaceRegistry        = new NamespaceRegistry(logger, assemblyManager);
            marshalledElementFactory = new MarshalledElementFactory(Logger, GlobalNamespace, typeRegistry);

            EnumTransform = new EnumTransform(namingRules, logger, namespaceRegistry, typeRegistry);

            StructTransform = new StructTransform(namingRules, logger, namespaceRegistry, typeRegistry, marshalledElementFactory);

            FunctionTransform = new MethodTransform(namingRules, logger, groupRegistry, marshalledElementFactory, globalNamespace, typeRegistry);

            InterfaceTransform = new InterfaceTransform(namingRules, logger, globalNamespace, FunctionTransform, FunctionTransform, typeRegistry, namespaceRegistry);
        }
示例#2
0
 public DefaultGenerators(
     GlobalNamespaceProvider globalNamespace,
     IDocumentationLinker documentation,
     ExternalDocCommentsReader docReader,
     GeneratorConfig config,
     Logger logger)
 {
     Constant              = new ConstantCodeGenerator();
     Property              = new PropertyCodeGenerator(this, documentation, docReader);
     Enum                  = new EnumCodeGenerator(documentation, docReader);
     ExplicitOffsetField   = new FieldCodeGenerator(documentation, docReader, true);
     AutoLayoutField       = new FieldCodeGenerator(documentation, docReader, false);
     Struct                = new StructCodeGenerator(this, documentation, docReader);
     NativeStruct          = new NativeStructCodeGenerator(this, globalNamespace);
     NativeInvocation      = new NativeInvocationCodeGenerator(this, globalNamespace);
     Callable              = new CallableCodeGenerator(this, documentation, docReader, globalNamespace, logger);
     Method                = new MethodCodeGenerator(this);
     Function              = new FunctionCodeGenerator(this);
     Interface             = new InterfaceCodeGenerator(this, documentation, docReader, globalNamespace);
     Group                 = new GroupCodeGenerator(this, documentation, docReader);
     LocalInterop          = new LocalInteropCodeGenerator(this);
     InteropMethod         = new InteropMethodCodeGenerator();
     ShadowCallable        = new ShadowCallbackGenerator(this, globalNamespace);
     ReverseCallableProlog = new ReverseCallablePrologCodeGenerator(this, globalNamespace);
     Vtbl                  = new VtblGenerator(this, globalNamespace);
     Shadow                = new ShadowGenerator(this, globalNamespace);
     Marshalling           = new MarshallingRegistry(globalNamespace, logger);
     Config                = config;
 }
示例#3
0
        private static StatementSyntax PlatformSpecificStatement(GlobalNamespaceProvider globalNamespace, PlatformDetectionType allPlatformBitmap, PlatformDetectionType platform, StatementSyntax statement)
        {
            if ((platform & allPlatformBitmap) == allPlatformBitmap)
            {
                return(statement);
            }

            ExpressionSyntax condition = null;

            foreach (PlatformDetectionType flag in platforms)
            {
                if ((platform & flag) == flag && flag != PlatformDetectionType.Any)
                {
                    var newCondition = MemberAccessExpression(
                        Microsoft.CodeAnalysis.CSharp.SyntaxKind.SimpleMemberAccessExpression,
                        globalNamespace.GetTypeNameSyntax(WellKnownName.PlatformDetection),
                        IdentifierName(flag.ToString()));
                    condition = condition is null ?
                                (ExpressionSyntax)newCondition
                        : BinaryExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.LogicalAndExpression,
                                           condition,
                                           newCondition);
                }
            }

            return(condition is null ?
                   statement
                : IfStatement(
                       condition,
                       statement));
        }
        public InteropSignatureTransform(GlobalNamespaceProvider provider, Logger logger)
        {
            this.provider = provider;
            this.logger   = logger;

            returnTypeOverrides = new Dictionary <string, SignatureInteropTypeOverride>
            {
                { provider.GetTypeName(WellKnownName.Result), typeof(int) },
                { provider.GetTypeName(WellKnownName.PointerSize), typeof(void *) }
            };

            windowsOnlyReturnTypeOverrides = new Dictionary <string, SignatureInteropTypeOverride>
            {
                {
                    provider.GetTypeName(WellKnownName.NativeLong),
                    new SignatureInteropTypeOverride(typeof(int), InteropMethodSignatureFlags.CastToNativeLong)
                },
                {
                    provider.GetTypeName(WellKnownName.NativeULong),
                    new SignatureInteropTypeOverride(typeof(uint), InteropMethodSignatureFlags.CastToNativeULong)
                }
            };

            systemvOnlyReturnTypeOverrides = new Dictionary <string, SignatureInteropTypeOverride>
            {
                {
                    provider.GetTypeName(WellKnownName.NativeLong),
                    new SignatureInteropTypeOverride(typeof(IntPtr), InteropMethodSignatureFlags.CastToNativeLong)
                },
                {
                    provider.GetTypeName(WellKnownName.NativeULong),
                    new SignatureInteropTypeOverride(typeof(UIntPtr), InteropMethodSignatureFlags.CastToNativeULong)
                }
            };
        }
        public InterfaceTransform(
            NamingRulesManager namingRules,
            Logger logger,
            GlobalNamespaceProvider globalNamespace,
            ITransformPreparer <CppMethod, CsMethod> methodPreparer,
            ITransformer <CsMethod> methodTransformer,
            TypeRegistry typeRegistry,
            NamespaceRegistry namespaceRegistry)
            : base(namingRules, logger)
        {
            MethodPreparer         = methodPreparer;
            MethodTransformer      = methodTransformer;
            this.typeRegistry      = typeRegistry;
            this.namespaceRegistry = namespaceRegistry;
            propertyBuilder        = new PropertyBuilder(globalNamespace);
            methodOverloadBuilder  = new MethodOverloadBuilder(globalNamespace, typeRegistry);

            CppObjectType = new CsInterface {
                Name = globalNamespace.GetTypeName(WellKnownName.CppObject)
            };
            DefaultCallbackable = new CsInterface
            {
                Name       = globalNamespace.GetTypeName(WellKnownName.ICallbackable),
                ShadowName = globalNamespace.GetTypeName(WellKnownName.CppObjectShadow),
                VtblName   = globalNamespace.GetTypeName(WellKnownName.CppObjectVtbl)
            };
        }
 public MarshallingRegistry(GlobalNamespaceProvider globalNamespace, Logger logger)
 {
     Marshallers = new List <IMarshaller>
     {
         new InterfaceArrayMarshaller(globalNamespace),
         new ArrayOfInterfaceMarshaller(globalNamespace),
         new BoolToIntArrayMarshaller(globalNamespace),
         new BoolToIntMarshaller(globalNamespace),
         new EnumParameterMarshaller(globalNamespace),
         new InterfaceMarshaller(globalNamespace),
         new PointerSizeMarshaller(globalNamespace),
         new StringMarshaller(globalNamespace),
         new RemappedTypeMarshaller(globalNamespace),
         new StructWithNativeTypeMarshaller(globalNamespace),
         new StructWithNativeTypeArrayMarshaller(globalNamespace),
         new NullableInstanceMarshaller(globalNamespace),
         new BitfieldMarshaller(globalNamespace),
         new ValueTypeArrayFieldMarshaller(globalNamespace),
         new FallbackFieldMarshaller(globalNamespace),
         new ValueTypeArrayMarshaller(globalNamespace),
         new ValueTypeMarshaller(globalNamespace)
     };
     RelationMarshallers = new Dictionary <Type, IRelationMarshaller>
     {
         { typeof(StructSizeRelation), new StructSizeRelationMarshaller(globalNamespace) },
         { typeof(LengthRelation), new LengthRelationMarshaller(globalNamespace) },
         { typeof(ConstantValueRelation), new ConstantValueRelationMarshaller(globalNamespace) }
     };
     this.logger = logger;
 }
 public InterfaceCodeGenerator(IGeneratorRegistry generators, IDocumentationLinker documentation,
                               ExternalDocCommentsReader docReader, GlobalNamespaceProvider globalNamespace, Logger logger)
     : base(documentation, docReader)
 {
     Generators           = generators;
     this.globalNamespace = globalNamespace;
     this.logger          = logger;
 }
示例#8
0
        public static StatementSyntax GetPlatformSpecificStatements(GlobalNamespaceProvider globalNamespace,
                                                                    GeneratorConfig config,
                                                                    IEnumerable <PlatformDetectionType> types,
                                                                    Func <PlatformDetectionType, StatementSyntax> syntaxBuilder)
        {
            List <IfStatementSyntax> ifStatements = new();

            var allPlatformBitmap = config.Platforms;

            foreach (var platform in types)
            {
                var platformStatement = syntaxBuilder(platform);

                if ((platform & allPlatformBitmap) == allPlatformBitmap)
                {
                    return(platformStatement);
                }

                ExpressionSyntax condition = null;

                foreach (var flag in PlatformsNoAny)
                {
                    if ((platform & flag) != flag)
                    {
                        continue;
                    }

                    var newCondition = MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        globalNamespace.GetTypeNameSyntax(WellKnownName.PlatformDetection),
                        IdentifierName("Is" + flag)
                        );

                    condition = condition is null
                                    ? newCondition
                                    : BinaryExpression(SyntaxKind.LogicalAndExpression, condition, newCondition);
                }

                ifStatements.Add(
                    condition is null
                        ? (IfStatementSyntax)platformStatement
                        : IfStatement(condition, platformStatement)
                    );
            }

            IfStatementSyntax platformDetectionIfStatement = null;

            for (var i = ifStatements.Count - 1; i >= 0; i--)
            {
                platformDetectionIfStatement = ifStatements[i].WithElse(
                    platformDetectionIfStatement is null
                        ? ElseClause(ThrowPlatformNotSupportedStatement)
                        : ElseClause(platformDetectionIfStatement)
                    );
            }

            return(platformDetectionIfStatement);
        }
示例#9
0
 public MethodTransform(NamingRulesManager namingRules,
                        Logger logger,
                        GroupRegistry groupRegistry,
                        MarshalledElementFactory factory,
                        GlobalNamespaceProvider globalNamespace,
                        IInteropSignatureTransform interopSignatureTransform)
     : base(namingRules, logger)
 {
     this.groupRegistry   = groupRegistry;
     this.factory         = factory;
     this.globalNamespace = globalNamespace;
     signatureTransform   = interopSignatureTransform;
 }
示例#10
0
 public MethodTransform(
     NamingRulesManager namingRules,
     Logger logger,
     GroupRegistry groupRegistry,
     MarshalledElementFactory factory,
     GlobalNamespaceProvider globalNamespace,
     TypeRegistry typeRegistry)
     : base(namingRules, logger)
 {
     this.groupRegistry   = groupRegistry;
     this.factory         = factory;
     this.globalNamespace = globalNamespace;
     this.typeRegistry    = typeRegistry;
 }
 public StatementSyntax GenerateNativeCleanup(CsMarshalBase csElement, bool singleStackFrame)
 {
     if (!csElement.IsWideChar || !singleStackFrame)
     {
         return(ExpressionStatement(
                    InvocationExpression(
                        MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            GlobalNamespaceProvider.GetTypeNameSyntax(BuiltinType.Marshal),
                            IdentifierName("FreeHGlobal")),
                        ArgumentList(
                            SingletonSeparatedList(
                                Argument(GetMarshalStorageLocation(csElement)))))));
     }
     return(null);
 }
        private static InteropType GetInteropTypeForParameter(GlobalNamespaceProvider nsProvider, CsParameter param)
        {
            if (param.HasPointer)
            {
                return(TypeRegistry.VoidPtr);
            }

            if (param.PublicType.IsWellKnownType(nsProvider, WellKnownName.PointerSize))
            {
                return(TypeRegistry.VoidPtr);
            }

            if (param.MarshalType is CsFundamentalType marshalFundamental)
            {
                return marshalFundamental switch
                       {
                           { IsIntPtr : true } => TypeRegistry.VoidPtr,
        public InteropSignatureTransform(GlobalNamespaceProvider provider, Logger logger)
        {
            this.provider = provider;
            this.logger   = logger;

            returnTypeOverrides = new Dictionary <string, SignatureInteropTypeOverride>
            {
                {
                    provider.GetTypeName(WellKnownName.Result),
                    TypeRegistry.Int32
                },
                {
                    provider.GetTypeName(WellKnownName.PointerSize),
                    TypeRegistry.VoidPtr
                }
            };

            const InteropMethodSignatureFlags castToNativeLong  = InteropMethodSignatureFlags.CastToNativeLong;
            const InteropMethodSignatureFlags castToNativeULong = InteropMethodSignatureFlags.CastToNativeULong;

            windowsOnlyReturnTypeOverrides = new Dictionary <string, SignatureInteropTypeOverride>
            {
                {
                    provider.GetTypeName(WellKnownName.NativeLong),
                    new SignatureInteropTypeOverride(TypeRegistry.Int32, castToNativeLong)
                },
                {
                    provider.GetTypeName(WellKnownName.NativeULong),
                    new SignatureInteropTypeOverride(TypeRegistry.UInt32, castToNativeULong)
                }
            };

            systemvOnlyReturnTypeOverrides = new Dictionary <string, SignatureInteropTypeOverride>
            {
                {
                    provider.GetTypeName(WellKnownName.NativeLong),
                    new SignatureInteropTypeOverride(TypeRegistry.IntPtr, castToNativeLong)
                },
                {
                    provider.GetTypeName(WellKnownName.NativeULong),
                    new SignatureInteropTypeOverride(TypeRegistry.UIntPtr, castToNativeULong)
                }
            };
        }
示例#14
0
        public StatementSyntax GenerateManagedToNative(CsMarshalBase csElement, bool singleStackFrame)
        {
            if (csElement.IsArray) // Fixed-length character array
            {
                if (!csElement.IsWideChar)
                {
                    return(GenerateAnsiStringToArray(csElement));
                }

                if (!singleStackFrame)
                {
                    return(GenerateStringToArray(csElement));
                }

                return(null);
            }

            // Variable-length string represented as a pointer.

            if (!csElement.IsWideChar || !singleStackFrame)
            {
                return(ExpressionStatement(
                           AssignmentExpression(
                               SyntaxKind.SimpleAssignmentExpression,
                               GetMarshalStorageLocation(csElement),
                               InvocationExpression(
                                   MemberAccessExpression(
                                       SyntaxKind.SimpleMemberAccessExpression,
                                       GlobalNamespaceProvider.GetTypeNameSyntax(BuiltinType.Marshal),
                                       IdentifierName(
                                           csElement.IsWideChar
                                        ? nameof(Marshal.StringToHGlobalUni)
                                        : nameof(Marshal.StringToHGlobalAnsi)
                                           )
                                       ),
                                   ArgumentList(SingletonSeparatedList(Argument(IdentifierName(csElement.Name))))
                                   )
                               )
                           ));
            }

            return(null);
        }
示例#15
0
        public static StatementSyntax GetPlatformSpecificStatements(GlobalNamespaceProvider globalNamespace, GeneratorConfig config, IEnumerable <PlatformDetectionType> types, Func <PlatformDetectionType, StatementSyntax> syntaxBuilder)
        {
            List <IfStatementSyntax> ifStatements = new List <IfStatementSyntax>();

            var allPlatformBitmap = config.Platforms;

            foreach (var platform in types)
            {
                if ((platform & allPlatformBitmap) == allPlatformBitmap)
                {
                    return(PlatformSpecificStatement(globalNamespace, allPlatformBitmap, platform, syntaxBuilder(platform)));
                }

                IfStatementSyntax statement = (IfStatementSyntax)PlatformSpecificStatement(globalNamespace, allPlatformBitmap, platform, syntaxBuilder(platform));
                ifStatements.Add(statement);
            }

            IfStatementSyntax platformDetectionIfStatement = null;

            for (int i = ifStatements.Count - 1; i >= 0; i--)
            {
                if (platformDetectionIfStatement is null)
                {
                    platformDetectionIfStatement = ifStatements[i]
                                                   .WithElse(
                        ElseClause(
                            ThrowStatement(
                                ObjectCreationExpression(ParseTypeName("System.PlatformNotSupportedException"))
                                .WithArgumentList(ArgumentList()))));
                }
                else
                {
                    platformDetectionIfStatement = ifStatements[i].WithElse(ElseClause(platformDetectionIfStatement));
                }
            }

            return(platformDetectionIfStatement);
        }
示例#16
0
 public MarshallingRegistry(GlobalNamespaceProvider globalNamespace, Logger logger)
 {
     Marshallers = new List <IMarshaller>
     {
         new InterfaceArrayMarshaller(globalNamespace),
         new ArrayOfInterfaceMarshaller(globalNamespace),
         new BoolToIntArrayMarshaller(globalNamespace),
         new BoolToIntMarshaller(globalNamespace),
         new EnumParameterMarshaller(globalNamespace),
         new InterfaceMarshaller(globalNamespace),
         new PointerSizeMarshaller(globalNamespace),
         new StringMarshaller(globalNamespace),
         new RemappedTypeMarshaller(globalNamespace),
         new StructWithNativeTypeMarshaller(globalNamespace),
         new StructWithNativeTypeArrayMarshaller(globalNamespace),
         new NullableInstanceMarshaller(globalNamespace),
         new BitfieldMarshaller(globalNamespace),
         new ValueTypeArrayFieldMarshaller(globalNamespace),
         new FallbackFieldMarshaller(globalNamespace),
         new ValueTypeArrayMarshaller(globalNamespace),
         new ValueTypeMarshaller(globalNamespace)
     };
     this.logger = logger;
 }
示例#17
0
        public override bool Execute()
        {
            var documentationFiles = new Dictionary <string, XmlDocument>();

            foreach (var file in ExternalDocumentation ?? Enumerable.Empty <ITaskItem>())
            {
                using (var stream = File.OpenRead(file.ItemSpec))
                {
                    var xml = new XmlDocument();
                    xml.Load(stream);
                    documentationFiles.Add(file.ItemSpec, xml);
                }
            }

            var globalNamespace = new GlobalNamespaceProvider(GlobalNamespace);

            foreach (var nameOverride in GlobalNamespaceOverrides ?? Enumerable.Empty <ITaskItem>())
            {
                var wellKnownName = nameOverride.ItemSpec;
                var overridenName = nameOverride.GetMetadata("Override");
                if (overridenName != null && Enum.TryParse(wellKnownName, out WellKnownName name))
                {
                    globalNamespace.OverrideName(name, overridenName);
                }
            }

            var generator = new RoslynGenerator(
                new Logger(new MsBuildSharpGenLogger(Log), null),
                globalNamespace,
                new CachedDocumentationLinker(DocLinkCache.ItemSpec),
                new ExternalDocCommentsReader(documentationFiles));

            generator.Run(CsSolution.Read(Model.ItemSpec), OutputDirectory, GeneratedCodeFolder, IncludeAssemblyNameFolder);

            return(true);
        }
示例#18
0
 public RemappedTypeMarshaller(GlobalNamespaceProvider globalNamespace) : base(globalNamespace)
 {
 }
 public BoolToIntArrayMarshaller(GlobalNamespaceProvider globalNamespace) : base(globalNamespace)
 {
 }
示例#20
0
 public NullableInstanceMarshaller(GlobalNamespaceProvider globalNamespace) : base(globalNamespace)
 {
 }
示例#21
0
 public InterfaceArrayMarshaller(GlobalNamespaceProvider globalNamespace) : base(globalNamespace)
 {
 }
示例#22
0
 public ShadowGenerator(IGeneratorRegistry generators, GlobalNamespaceProvider globalNamespace)
 {
     this.generators      = generators;
     this.globalNamespace = globalNamespace;
 }
示例#23
0
 public RoslynGenerator(Logger logger, GlobalNamespaceProvider globalNamespace, IDocumentationLinker documentation, ExternalDocCommentsReader docReader)
 {
     Logger = logger;
     this.globalNamespace = globalNamespace;
     Generators = new DefaultGenerators(globalNamespace, documentation, docReader, logger);
 }
示例#24
0
 public BitfieldMarshaller(GlobalNamespaceProvider globalNamespace) : base(globalNamespace)
 {
 }
        public override bool Execute()
        {
            var documentationFiles = new Dictionary <string, XmlDocument>();

            foreach (var file in ExternalDocumentation ?? Enumerable.Empty <ITaskItem>())
            {
                using (var stream = File.OpenRead(file.ItemSpec))
                {
                    var xml = new XmlDocument();
                    xml.Load(stream);
                    documentationFiles.Add(file.ItemSpec, xml);
                }
            }

            var globalNamespace = new GlobalNamespaceProvider();

            foreach (var nameOverride in GlobalNamespaceOverrides ?? Enumerable.Empty <ITaskItem>())
            {
                var wellKnownName = nameOverride.ItemSpec;
                var overridenName = nameOverride.GetMetadata("Override");
                if (overridenName != null && Enum.TryParse(wellKnownName, out WellKnownName name))
                {
                    globalNamespace.OverrideName(name, overridenName);
                }
            }

            PlatformDetectionType platformMask = 0;

            foreach (var platform in Platforms ?? Enumerable.Empty <ITaskItem>())
            {
                if (!Enum.TryParse <PlatformDetectionType>("Is" + platform.ItemSpec, out var parsedPlatform))
                {
                    Log.LogWarning(null, LoggingCodes.InvalidPlatformDetectionType, null, null, 0, 0, 0, 0, $"The platform type {platform} is an unknown platform to SharpGenTools. Falling back to Any platform detection.");
                    platformMask = PlatformDetectionType.Any;
                }
                else
                {
                    platformMask |= parsedPlatform;
                }
            }

            if (platformMask == 0)
            {
                platformMask = PlatformDetectionType.Any;
            }

            var config = new GeneratorConfig
            {
                Platforms = platformMask
            };

            var generator = new RoslynGenerator(
                new Logger(new MSBuildSharpGenLogger(Log), null),
                globalNamespace,
                new CachedDocumentationLinker(DocLinkCache.ItemSpec),
                new ExternalDocCommentsReader(documentationFiles),
                config);

            generator.Run(CsAssembly.Read(Model.ItemSpec), GeneratedCodeFolder);

            return(true);
        }
示例#26
0
 public PointerSizeMarshaller(GlobalNamespaceProvider globalNamespace) : base(globalNamespace)
 {
 }
 public StructWithNativeTypeArrayMarshaller(GlobalNamespaceProvider globalNamespace) : base(globalNamespace)
 {
 }
示例#28
0
 public ShadowCallbackGenerator(IGeneratorRegistry generators, GlobalNamespaceProvider globalNamespace)
 {
     this.generators      = generators ?? throw new ArgumentNullException(nameof(generators));
     this.globalNamespace = globalNamespace ?? throw new ArgumentNullException(nameof(globalNamespace));
 }
示例#29
0
 public ConstantValueRelationMarshaller(GlobalNamespaceProvider globalNamespace) : base(globalNamespace)
 {
 }
示例#30
0
 public MarshallerBase(GlobalNamespaceProvider globalNamespace)
 {
     this.globalNamespace = globalNamespace;
 }