Пример #1
0
    public override MemberDeclarationSyntax GenerateCode(CsExpressionConstant csElement)
    {
        var typeName = ParseTypeName(csElement.Type.QualifiedName);

        return(AddDocumentationTrivia(
                   FieldDeclaration(
                       VariableDeclaration(
                           typeName,
                           SingletonSeparatedList(
                               VariableDeclarator(Identifier(csElement.Name))
                               .WithInitializer(
                                   EqualsValueClause(
                                       CheckedExpression(
                                           SyntaxKind.UncheckedExpression,
                                           GeneratorHelpers.CastExpression(typeName, ParseExpression(csElement.Value))
                                           )
                                       )
                                   )
                               )
                           )
                       )
                   .WithModifiers(csElement.VisibilityTokenList),
                   csElement
                   ));
    }
Пример #2
0
 public StatementSyntax GenerateNativeToManaged(CsMarshalBase csElement, bool singleStackFrame) =>
 ExpressionStatement(
     AssignmentExpression(
         SyntaxKind.SimpleAssignmentExpression,
         IdentifierName(csElement.Name),
         GeneratorHelpers.CastExpression(
             ParseTypeName(csElement.PublicType.QualifiedName), GetMarshalStorageLocation(csElement)
             )
         )
     );
Пример #3
0
 public ArgumentSyntax GenerateNativeArgument(CsMarshalCallableBase csElement) => Argument(
     GeneratorHelpers.CastExpression(
         VoidPtrType,
         BinaryExpression(
             SyntaxKind.CoalesceExpression,
             ConditionalAccessExpression(
                 IdentifierName(csElement.Name),
                 MemberBindingExpression(IdentifierName("NativePointer"))
                 ),
             IntPtrZero
             )
         )
     );
Пример #4
0
 public StatementSyntax GenerateManagedToNative(CsMarshalBase csElement, bool singleStackFrame) =>
 ExpressionStatement(
     AssignmentExpression(
         SyntaxKind.SimpleAssignmentExpression,
         GetMarshalStorageLocation(csElement),
         csElement is CsField
                 ? IdentifierName(csElement.IntermediateMarshalName)
                 : GeneratorHelpers.CastExpression(
             GetMarshalTypeSyntax(csElement),
             GeneratorHelpers.GenerateBoolToIntConversion(IdentifierName(csElement.Name))
             )
         )
     );
Пример #5
0
    private IEnumerable <StatementSyntax> GenerateProlog(CsMarshalCallableBase publicElement,
                                                         ExpressionSyntax nativeParameter,
                                                         TypeSyntax nativeParameterType)
    {
        ExpressionSyntax CastToPublicType(TypeSyntax targetType, ExpressionSyntax expression) =>
        targetType.IsEquivalentTo(nativeParameterType)
                ? expression
                : GeneratorHelpers.CastExpression(targetType, expression);

        var marshaller = GetMarshaller(publicElement);
        var publicType = GetPublicType(publicElement);

        var generatesMarshalVariable = marshaller.GeneratesMarshalVariable(publicElement);

        var publicTypeVariableValue = nativeParameter != null && !generatesMarshalVariable
                                          ? CastToPublicType(publicType, nativeParameter)
                                          : DefaultLiteral;

        yield return(LocalDeclarationStatement(
                         VariableDeclaration(
                             publicType,
                             SingletonSeparatedList(
                                 VariableDeclarator(Identifier(publicElement.Name))
                                 .WithInitializer(EqualsValueClause(publicTypeVariableValue))
                                 )
                             )
                         ));

        if (generatesMarshalVariable)
        {
            var marshalTypeSyntax = marshaller.GetMarshalTypeSyntax(publicElement);

            var initializerExpression = nativeParameter != null
                                            ? CastToPublicType(marshalTypeSyntax, nativeParameter)
                                            : DefaultLiteral;

            yield return(LocalDeclarationStatement(
                             VariableDeclaration(
                                 marshalTypeSyntax,
                                 SingletonSeparatedList(
                                     VariableDeclarator(
                                         MarshallerBase.GetMarshalStorageLocationIdentifier(publicElement),
                                         null,
                                         EqualsValueClause(initializerExpression)
                                         )
                                     )
                                 )
                             ));
        }
    }
Пример #6
0
 protected override StatementSyntax GenerateManagedToNative(CsField csField, bool singleStackFrame) =>
 ExpressionStatement(
     AssignmentExpression(
         SyntaxKind.OrAssignmentExpression,
         GetMarshalStorageLocation(csField),
         GeneratorHelpers.CastExpression(
             ParseTypeName(csField.MarshalType.QualifiedName),
             BinaryExpression(
                 SyntaxKind.BitwiseAndExpression,
                 IdentifierName(csField.IntermediateMarshalName),
                 LiteralExpression(
                     SyntaxKind.NumericLiteralExpression,
                     Literal(csField.BitMask << csField.BitOffset)
                     )
                 )
             )
         )
     );
Пример #7
0
    public StatementSyntax GenerateManagedToNative(CsMarshalBase publicElement, CsMarshalBase relatedElement)
    {
        var lengthExpression = GeneratorHelpers.LengthExpression(IdentifierName(publicElement.Name));

        return(ExpressionStatement(
                   AssignmentExpression(
                       SyntaxKind.SimpleAssignmentExpression,
                       IdentifierName(relatedElement.Name),
                       GenerateNullCheckIfNeeded(
                           publicElement,
                           relatedElement is CsMarshalCallableBase lengthStorage
                        ? GeneratorHelpers.CastExpression(
                               ReverseCallablePrologCodeGenerator.GetPublicType(lengthStorage),
                               lengthExpression
                               )
                        : lengthExpression,
                           DefaultLiteral
                           )
                       )
                   ));
    }
Пример #8
0
    public override IEnumerable <MemberDeclarationSyntax> GenerateCode(CsField csElement)
    {
        if (csElement.IsBoolToInt && !csElement.IsArray)
        {
            yield return(GenerateBackingField(csElement, csElement.MarshalType));

            yield return(GenerateProperty(
                             csElement, PredefinedType(Token(SyntaxKind.BoolKeyword)),
                             GeneratorHelpers.GenerateIntToBoolConversion,
                             (_, value) => GeneratorHelpers.CastExpression(
                                 ParseTypeName(csElement.MarshalType.QualifiedName),
                                 GeneratorHelpers.GenerateBoolToIntConversion(value)
                                 )
                             ));
        }
        else if (csElement.IsArray && !csElement.IsString)
        {
            var elementType = ParseTypeName(csElement.PublicType.QualifiedName);

            yield return(GenerateBackingField(csElement, csElement.PublicType, isArray: true));

            yield return(GenerateProperty(
                             csElement, ArrayType(elementType, SingletonList(ArrayRankSpecifier())),
                             value => AssignmentExpression(
                                 SyntaxKind.CoalesceAssignmentExpression,
                                 value,
                                 ObjectCreationExpression(
                                     ArrayType(
                                         elementType,
                                         SingletonList(
                                             ArrayRankSpecifier(
                                                 SingletonSeparatedList <ExpressionSyntax>(
                                                     LiteralExpression(
                                                         SyntaxKind.NumericLiteralExpression,
                                                         Literal(csElement.ArrayDimensionValue)
                                                         )
                                                     )
                                                 )
                                             )
                                         )
                                     )
                                 ),
                             null
                             ));
        }
        else if (csElement.IsBitField)
        {
            PropertyValueGetTransform getterTransform;
            PropertyValueSetTransform setterTransform;
            TypeSyntax propertyType;

            if (csElement.IsBoolBitField)
            {
                getterTransform = GeneratorHelpers.GenerateIntToBoolConversion;
                setterTransform = (_, value) => GeneratorHelpers.GenerateBoolToIntConversion(value);
                propertyType    = PredefinedType(Token(SyntaxKind.BoolKeyword));
            }
            else
            {
                getterTransform = valueExpression => GeneratorHelpers.CastExpression(
                    ParseTypeName(csElement.PublicType.QualifiedName),
                    valueExpression
                    );
                setterTransform = null;
                propertyType    = ParseTypeName(csElement.PublicType.QualifiedName);
            }

            yield return(GenerateBackingField(csElement, csElement.PublicType));

            var bitMask   = LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(csElement.BitMask));
            var bitOffset = LiteralExpression(
                SyntaxKind.NumericLiteralExpression, Literal(csElement.BitOffset)
                );

            yield return(GenerateProperty(
                             csElement, propertyType,
                             Compose(
                                 getterTransform,
                                 value => BinaryExpression(
                                     SyntaxKind.BitwiseAndExpression,
                                     GeneratorHelpers.WrapInParentheses(
                                         BinaryExpression(SyntaxKind.RightShiftExpression, value, bitOffset)
                                         ),
                                     bitMask
                                     )
                                 ),
                             Compose(
                                 (oldValue, value) => GeneratorHelpers.CastExpression(
                                     ParseTypeName(csElement.PublicType.QualifiedName),
                                     BinaryExpression(
                                         SyntaxKind.BitwiseOrExpression,
                                         GeneratorHelpers.WrapInParentheses(
                                             BinaryExpression(
                                                 SyntaxKind.BitwiseAndExpression,
                                                 oldValue,
                                                 PrefixUnaryExpression(
                                                     SyntaxKind.BitwiseNotExpression,
                                                     GeneratorHelpers.WrapInParentheses(
                                                         BinaryExpression(SyntaxKind.LeftShiftExpression, bitMask, bitOffset)
                                                         )
                                                     )
                                                 )
                                             ),
                                         GeneratorHelpers.WrapInParentheses(
                                             BinaryExpression(
                                                 SyntaxKind.LeftShiftExpression,
                                                 GeneratorHelpers.WrapInParentheses(
                                                     BinaryExpression(SyntaxKind.BitwiseAndExpression, value, bitMask)
                                                     ),
                                                 bitOffset
                                                 )
                                             )
                                         )
                                     ),
                                 setterTransform
                                 )
                             ));
        }
        else
        {
            yield return(GenerateBackingField(
                             csElement, csElement.PublicType, propertyBacking: false, document: true
                             ));
        }
    }
Пример #9
0
 protected static ExpressionSyntax IntPtrArgumentWithOptionalCast(ExpressionSyntax name, bool cast) =>
 cast?GeneratorHelpers.CastExpression(IntPtrType, name) : name;
Пример #10
0
    protected override ExpressionSyntax Generate(CsCallable callable, PlatformDetectionType platform)
    {
        var interopSig        = callable.InteropSignatures[platform];
        var interopReturnType = interopSig.ReturnTypeSyntax;
        var arguments         = IterateNativeArguments(callable is CsMethod, interopSig).ToArray();

        var vtblAccess = callable switch
        {
            CsMethod method => ElementAccessExpression(
                ThisExpression(),
                BracketedArgumentList(
                    SingletonSeparatedList(
                        Argument(
                            method.CustomVtbl
                                ? MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                ThisExpression(),
                                IdentifierName($"{callable.Name}__vtbl_index")
                                )
                                : method.VTableOffsetExpression(platform)
                            )
                        )
                    )
                ),
            _ => null
        };

        ExpressionSyntax FnPtrCall()
        {
            var fnptrParameters = arguments
                                  .Select(x => x.Type)
                                  .Append(interopReturnType)
                                  .Select(FunctionPointerParameter);

            return(GeneratorHelpers.CastExpression(
                       FunctionPointerType(
                           FunctionPointerCallingConvention(
                               Token(SyntaxKind.UnmanagedKeyword),
                               FunctionPointerUnmanagedCallingConventionList(
                                   SingletonSeparatedList(
                                       FunctionPointerUnmanagedCallingConvention(
                                           Identifier(callable.CppCallingConvention.ToCallConvShortName())
                                           )
                                       )
                                   )
                               ),
                           FunctionPointerParameterList(SeparatedList(fnptrParameters))
                           ),
                       vtblAccess
                       ));
        }

        var what = callable switch
        {
            CsFunction => IdentifierName(
                callable.CppElementName + GeneratorHelpers.GetPlatformSpecificSuffix(platform)
                ),
            CsMethod => GeneratorHelpers.WrapInParentheses(FnPtrCall()),
            _ => throw new ArgumentOutOfRangeException()
        };

        ExpressionSyntax call = InvocationExpression(
            what,
            ArgumentList(SeparatedList(arguments.Select(x => x.Argument)))
            );

        if (interopSig.ForcedReturnBufferSig || !callable.HasReturnType)
        {
            return(call);
        }

        var generatesMarshalVariable = GetMarshaller(callable.ReturnValue).GeneratesMarshalVariable(callable.ReturnValue);
        var publicTypeSyntax         = ReverseCallablePrologCodeGenerator.GetPublicType(callable.ReturnValue);

        if (callable.HasReturnTypeValue && !generatesMarshalVariable && !publicTypeSyntax.IsEquivalentTo(interopSig.ReturnTypeSyntax))
        {
            call = CastExpression(publicTypeSyntax, call);
        }

        return(AssignmentExpression(
                   SyntaxKind.SimpleAssignmentExpression,
                   generatesMarshalVariable
                ? MarshallerBase.GetMarshalStorageLocation(callable.ReturnValue)
                : IdentifierName(callable.ReturnValue.Name),
                   call
                   ));
    }
Пример #11
0
 public ArgumentSyntax GenerateNativeArgument(CsMarshalCallableBase csElement) => Argument(
     csElement.IsOut
         ? PrefixUnaryExpression(SyntaxKind.AddressOfExpression, GetMarshalStorageLocation(csElement))
         : GeneratorHelpers.CastExpression(VoidPtrType, GetMarshalStorageLocation(csElement))
     );