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 )); }
public StatementSyntax GenerateNativeToManaged(CsMarshalBase csElement, bool singleStackFrame) => ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(csElement.Name), GeneratorHelpers.CastExpression( ParseTypeName(csElement.PublicType.QualifiedName), GetMarshalStorageLocation(csElement) ) ) );
public ArgumentSyntax GenerateNativeArgument(CsMarshalCallableBase csElement) => Argument( GeneratorHelpers.CastExpression( VoidPtrType, BinaryExpression( SyntaxKind.CoalesceExpression, ConditionalAccessExpression( IdentifierName(csElement.Name), MemberBindingExpression(IdentifierName("NativePointer")) ), IntPtrZero ) ) );
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)) ) ) );
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) ) ) ) )); } }
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) ) ) ) ) );
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 ) ) )); }
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 )); } }
protected static ExpressionSyntax IntPtrArgumentWithOptionalCast(ExpressionSyntax name, bool cast) => cast?GeneratorHelpers.CastExpression(IntPtrType, name) : name;
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 )); }
public ArgumentSyntax GenerateNativeArgument(CsMarshalCallableBase csElement) => Argument( csElement.IsOut ? PrefixUnaryExpression(SyntaxKind.AddressOfExpression, GetMarshalStorageLocation(csElement)) : GeneratorHelpers.CastExpression(VoidPtrType, GetMarshalStorageLocation(csElement)) );