protected override MemberDeclarationSyntax BuildType(CppTypedef cppType, string nativeName, string managedName)
        {
            if (!(cppType.ElementType is CppPointerType cppPointerType &&
                  cppPointerType.ElementType is CppFunctionType function))
            {
                return(null);
            }

            var returnType = TypeMap.GetType(function.ReturnType.GetDisplayName()).TypeSyntax;
            var @delegate  = DelegateDeclaration(returnType, managedName)
                             .AddModifiers(Token(SyntaxKind.PublicKeyword))
                             .AddParameterListParameters(function.Parameters.Select(BuildParameter).ToArray())
                             .AddUnmanagedFunctionPointerAttribute();

            if (@delegate.DescendantNodes().OfType <PointerTypeSyntax>().Any())
            {
                @delegate = @delegate.AddModifiers(Token(SyntaxKind.UnsafeKeyword));
            }

            @delegate = @delegate.AddDocumentationComments(cppType.Comment, nativeName);

            return(@delegate);
        }
示例#2
0
        protected override MemberDeclarationSyntax BuildType(CppTypedef cppType, string nativeName, string managedName)
        {
            TypeSyntax baseManagedType = null;

            if (cppType.ElementType is CppPrimitiveType primitiveType)
            {
                baseManagedType = TypeMap.GetType(primitiveType.GetDisplayName()).TypeSyntax;
            }
            else if (cppType.ElementType is CppPointerType pointerType &&
                     pointerType.ElementType is CppPrimitiveType p && p.Kind == CppPrimitiveKind.Void)
            {
                baseManagedType = QualifiedName(IdentifierName("System"), IdentifierName("IntPtr"));
            }

            if (baseManagedType == null)
            {
                return(null);
            }

            var managedType = IdentifierName(managedName);
            var field       = IdentifierName("_value");
            var param       = IdentifierName("value");

            var @struct = StructDeclaration(managedName)
                          .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.ReadOnlyKeyword), Token(SyntaxKind.PartialKeyword))
                          .AddBaseListTypes(SimpleBaseType(
                                                QualifiedName(IdentifierName("System"), GenericName("IEquatable").AddTypeArgumentListArguments(managedType))))
                          .AddMembers(
                FieldDeclaration(VariableDeclaration(baseManagedType).AddVariables(VariableDeclarator("_value")))
                .AddModifiers(Token(SyntaxKind.PrivateKeyword), Token(SyntaxKind.ReadOnlyKeyword)),

                ConstructorDeclaration(managedName)
                .AddModifiers(Token(SyntaxKind.PublicKeyword))
                .AddParameterListParameters(Parameter(Identifier("value")).WithType(baseManagedType))
                .AddAggressiveInlining()
                .WithExpressionBody(
                    ArrowExpressionClause(
                        AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, field, param)))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),

                ConversionOperatorDeclaration(Token(SyntaxKind.ImplicitKeyword), managedType)
                .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword))
                .AddParameterListParameters(Parameter(Identifier("value")).WithType(baseManagedType))
                .AddAggressiveInlining()
                .WithExpressionBody(
                    ArrowExpressionClause(
                        ObjectCreationExpression(managedType)
                        .AddArgumentListArguments(Argument(param))))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),

                ConversionOperatorDeclaration(Token(SyntaxKind.ExplicitKeyword), baseManagedType)
                .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword))
                .AddParameterListParameters(Parameter(Identifier("value")).WithType(managedType))
                .AddAggressiveInlining()
                .WithExpressionBody(
                    ArrowExpressionClause(
                        MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            IdentifierName("value"),
                            field)))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),

                MethodDeclaration(PredefinedType(Token(SyntaxKind.BoolKeyword)), nameof(Equals))
                .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.OverrideKeyword))
                .AddParameterListParameters(Parameter(Identifier("obj")).WithType(PredefinedType(Token(SyntaxKind.ObjectKeyword))))
                .AddAggressiveInlining()
                .WithExpressionBody(ArrowExpressionClause(
                                        BinaryExpression(SyntaxKind.LogicalAndExpression,
                                                         IsPatternExpression(
                                                             IdentifierName("obj"),
                                                             DeclarationPattern(
                                                                 managedType,
                                                                 SingleVariableDesignation(Identifier("other")))),
                                                         InvocationExpression(
                                                             IdentifierName("Equals")).AddArgumentListArguments(Argument(IdentifierName("other"))))))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),

                MethodDeclaration(PredefinedType(Token(SyntaxKind.IntKeyword)), nameof(GetHashCode))
                .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.OverrideKeyword))
                .AddAggressiveInlining()
                .WithExpressionBody(ArrowExpressionClause(
                                        InvocationExpression(
                                            MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, field, IdentifierName("GetHashCode")))))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),

                MethodDeclaration(PredefinedType(Token(SyntaxKind.BoolKeyword)), "Equals")
                .AddModifiers(Token(SyntaxKind.PublicKeyword))
                .AddParameterListParameters(Parameter(Identifier("other")).WithType(managedType))
                .AddAggressiveInlining()
                .WithExpressionBody(ArrowExpressionClause(
                                        BinaryExpression(SyntaxKind.EqualsExpression,
                                                         field,
                                                         MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("other"), field))))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),

                OperatorDeclaration(PredefinedType(Token(SyntaxKind.BoolKeyword)), Token(SyntaxKind.EqualsEqualsToken))
                .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword))
                .AddParameterListParameters(
                    Parameter(Identifier("left")).WithType(managedType),
                    Parameter(Identifier("right")).WithType(managedType))
                .AddAggressiveInlining()
                .WithExpressionBody(ArrowExpressionClause(
                                        InvocationExpression(
                                            MemberAccessExpression(
                                                SyntaxKind.SimpleMemberAccessExpression,
                                                IdentifierName("left"),
                                                IdentifierName("Equals")))
                                        .AddArgumentListArguments(Argument(IdentifierName("right")))))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),

                OperatorDeclaration(PredefinedType(Token(SyntaxKind.BoolKeyword)), Token(SyntaxKind.ExclamationEqualsToken))
                .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword))
                .AddParameterListParameters(
                    Parameter(Identifier("left")).WithType(managedType),
                    Parameter(Identifier("right")).WithType(managedType))
                .AddAggressiveInlining()
                .WithExpressionBody(ArrowExpressionClause(
                                        PrefixUnaryExpression(
                                            SyntaxKind.LogicalNotExpression,
                                            InvocationExpression(
                                                MemberAccessExpression(
                                                    SyntaxKind.SimpleMemberAccessExpression,
                                                    IdentifierName("left"),
                                                    IdentifierName("Equals")))
                                            .AddArgumentListArguments(Argument(IdentifierName("right"))))))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),

                MethodDeclaration(PredefinedType(Token(SyntaxKind.StringKeyword)), nameof(ToString))
                .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.OverrideKeyword))
                .AddAggressiveInlining()
                .WithExpressionBody(ArrowExpressionClause(
                                        InvocationExpression(
                                            MemberAccessExpression(
                                                SyntaxKind.SimpleMemberAccessExpression,
                                                IdentifierName("_value"),
                                                IdentifierName(nameof(ToString))))))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
                );

            @struct = @struct.AddDocumentationComments(cppType.Comment, nativeName);

            return(@struct);
        }