public static string GenerateContractEventHandlerMethod(CsField sourceField, CsEvent targetEvent, NamespaceManager manager = null)
        {
            if (sourceField == null)
            {
                return(null);
            }
            if (!sourceField.IsLoaded)
            {
                return(null);
            }
            if (targetEvent == null)
            {
                return(null);
            }
            if (!targetEvent.IsLoaded)
            {
                return(null);
            }

            SourceFormatter formatter = new SourceFormatter();

            formatter.AppendCodeLine(0, "/// <summary>");
            formatter.AppendCodeLine(0, $"/// Handles the raised event {targetEvent.Name}");
            formatter.AppendCodeLine(0, "/// </summary>");
            formatter.AppendCodeLine(0, $"protected void {GenerateContractEventHandlerMethodName(sourceField,targetEvent)}{targetEvent.EventHandlerDelegate.Parameters.CSharpFormatParametersSignature(manager,false)}");
            formatter.AppendCodeLine(0, "{");
            formatter.AppendCodeLine(0);
            formatter.AppendCodeLine(1, "//TODO: Add Event handler logic");
            formatter.AppendCodeLine(0);
            formatter.AppendCodeLine(0, "}");
            formatter.AppendCodeLine(0);

            return(formatter.ReturnSource());
        }
예제 #2
0
        private static AccessorDeclarationSyntax GenerateSetter(CsField csElement,
                                                                PropertyValueSetTransform valueTransformation)
        {
            ExpressionSyntax valueExpression = IdentifierName("value");

            var storage = MemberAccessExpression(
                SyntaxKind.SimpleMemberAccessExpression,
                ThisExpression(),
                IdentifierName(csElement.IntermediateMarshalName)
                );

            return(AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                   .WithExpressionBody(
                       ArrowExpressionClause(
                           AssignmentExpression(
                               SyntaxKind.SimpleAssignmentExpression,
                               storage,
                               valueTransformation != null
                                   ? valueTransformation(storage, valueExpression)
                                   : valueExpression
                               )
                           )
                       )
                   .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
        }
예제 #3
0
        private MethodDeclarationSyntax GenerateMarshalTo(CsStruct csStruct)
        {
            IEnumerable <StatementSyntax> FieldMarshallers(CsField field)
            {
                if ((field.Relations?.Count ?? 0) == 0)
                {
                    yield return(generators.Marshalling.GetMarshaller(field).GenerateManagedToNative(field, false));

                    yield break;
                }

                foreach (var relation in field.Relations)
                {
                    var     marshaller    = generators.Marshalling.GetRelationMarshaller(relation);
                    CsField publicElement = null;

                    if (relation is LengthRelation related)
                    {
                        var relatedMarshallableName = related.Identifier;

                        publicElement = csStruct.Fields.First(fld => fld.CppElementName == relatedMarshallableName);
                    }

                    yield return(marshaller.GenerateManagedToNative(publicElement, field));
                }
            }

            return(GenerateMarshalMethod(
                       "__MarshalTo",
                       Block(
                           csStruct.Fields.SelectMany(FieldMarshallers)
                           .Where(statement => statement != null)
                           )
                       ));
        }
예제 #4
0
 protected override StatementSyntax GenerateNativeToManaged(CsField csField, bool singleStackFrame) =>
 ExpressionStatement(
     AssignmentExpression(
         SyntaxKind.SimpleAssignmentExpression,
         IdentifierName(csField.Name),
         GetMarshalStorageLocation(csField)
         )
     );
 /// <summary>
 /// Generates the name of the contract release method name for the target field.
 /// </summary>
 /// <param name="sourceField">field to generate the release name for.</param>
 /// <returns></returns>
 public static string GenerateContractReleaseMethodName(CsField sourceField)
 {
     if (sourceField == null)
     {
         return(null);
     }
     return($"{sourceField.Name.ConvertToProperCase(new[] {'_'})}_ContractRelease");
 }
    public StatementSyntax GenerateManagedToNative(CsMarshalBase csElement, bool singleStackFrame)
    {
        const ArrayCopyDirection direction = ArrayCopyDirection.ManagedToNative;

        return(csElement switch
        {
            CsParameter {
                IsLocalManagedReference : true
            } parameter => GenerateCopyBlock(parameter, direction),
            CsField field => GenerateCopyMemory(field, direction),
            _ => null
        });
예제 #7
0
        private static AccessorDeclarationSyntax GenerateGetter(CsField csElement,
                                                                PropertyValueGetTransform valueTransformation)
        {
            ExpressionSyntax valueExpression = ParseName(csElement.IntermediateMarshalName);

            return(AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                   .WithExpressionBody(
                       ArrowExpressionClause(
                           valueTransformation != null
                               ? valueTransformation(GeneratorHelpers.WrapInParentheses(valueExpression))
                               : valueExpression
                           )
                       )
                   .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
        }
예제 #8
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)
                     )
                 )
             )
         )
     );
예제 #9
0
 private PropertyDeclarationSyntax GenerateProperty(CsField csElement, TypeSyntax propertyType,
                                                    PropertyValueGetTransform getterTransform,
                                                    PropertyValueSetTransform setterTransform) =>
 AddDocumentationTrivia(
     PropertyDeclaration(propertyType, csElement.Name)
     .WithAccessorList(
         AccessorList(
             List(
                 new[]
 {
     GenerateGetter(csElement, getterTransform),
     GenerateSetter(csElement, setterTransform)
 }
                 )
             )
         )
     .WithModifiers(csElement.VisibilityTokenList),
     csElement
     );
        /// <summary>
        /// Generates a method that releases to a target interface contract for the target field.
        /// </summary>
        /// <param name="sourceField">The field for which events to subscribe to.</param>
        /// <param name="contract">The contract to subscribe to.</param>
        /// <returns>Full source code for the subscribe method.</returns>
        public static string GenerateContractReleaseMethod(CsField sourceField, CsInterface contract)
        {
            if (sourceField == null)
            {
                return(null);
            }
            if (!sourceField.IsLoaded)
            {
                return(null);
            }
            if (contract == null)
            {
                return(null);
            }
            if (!contract.IsLoaded)
            {
                return(null);
            }

            SourceFormatter formatter = new SourceFormatter();

            formatter.AppendCodeLine(0, "/// <summary>");
            formatter.AppendCodeLine(0, $"/// Releases the events from the interface contract of {contract.Namespace}.{contract.Name} for the field {sourceField.Name}");
            formatter.AppendCodeLine(0, "/// </summary>");
            formatter.AppendCodeLine(0, $"private void {GenerateContractReleaseMethodName(sourceField)}()");
            formatter.AppendCodeLine(0, "{");
            formatter.AppendCodeLine(0);
            formatter.AppendCodeLine(1, $"if({sourceField.Name} == null) return;");
            formatter.AppendCodeLine(0);
            foreach (var contractEvent in contract.Events)
            {
                if (!contractEvent.IsLoaded)
                {
                    continue;
                }
                formatter.AppendCodeLine(1, $"{sourceField.Name}.{contractEvent.Name} -= {sourceField.Name.ConvertToProperCase(new []{'_'})}_{contractEvent.Name}_EventHandler;");
            }
            formatter.AppendCodeLine(0);
            formatter.AppendCodeLine(0, "}");
            formatter.AppendCodeLine(0);

            return(formatter.ReturnSource());
        }
        /// <summary>
        /// Generates the syntax definition of field in c# syntax. The default definition with all options turned off will return the filed signature and constants if defined and the default values.
        /// </summary>
        /// <example>
        /// With Keywords [Security] [Keywords] [FieldType] [Name];
        /// With Keywords and a constant [Security] [Keywords] [FieldType] [Name] = [Constant Value];
        /// Without Keywords [Security] [FieldType] [Name];
        /// Without Keywords and a constant [Security] [FieldType] [Name] = [Constant Value];
        /// </example>
        /// <param name="source">The source <see cref="CsField"/> model to generate.</param>
        /// <param name="manager">Namespace manager used to format type names.This is an optional parameter.</param>
        /// <param name="includeKeywords">Optional parameter that will include all keywords assigned to the field from the source model. This is true by default.</param>
        /// <param name="fieldSecurity">Optional parameter to set the target security for the field.</param>
        /// <returns>Fully formatted field definition or null if the field data could not be generated.</returns>
        public static string CSharpFormatFieldDeclaration(this CsField source, NamespaceManager manager = null,
                                                          bool includeKeywords = true, CsSecurity fieldSecurity = CsSecurity.Unknown)

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

            StringBuilder fieldFormatting = new StringBuilder();


            CsSecurity security = fieldSecurity == CsSecurity.Unknown ? source.Security : fieldSecurity;

            fieldFormatting.Append($"{security.CSharpFormatKeyword()} ");

            if (includeKeywords)
            {
                if (source.IsStatic)
                {
                    fieldFormatting.Append($"{Keywords.Static} ");
                }
                if (source.IsReadOnly)
                {
                    fieldFormatting.Append($"{Keywords.Readonly} ");
                }
            }

            if (source.IsConstant)
            {
                fieldFormatting.Append($"{Keywords.Constant} ");
            }
            fieldFormatting.Append($"{source.DataType.CSharpFormatTypeName(manager)} ");
            fieldFormatting.Append($"{source.Name}");
            if (source.IsConstant)
            {
                fieldFormatting.Append($" = {source.DataType.CSharpFormatValueSyntax(source.ConstantValue)}");
            }
            fieldFormatting.Append(";");

            return(fieldFormatting.ToString());
        }
        public static string GenerateContractEventHandlerMethodName(CsField sourceField, CsEvent targetEvent)
        {
            if (sourceField == null)
            {
                return(null);
            }
            if (!sourceField.IsLoaded)
            {
                return(null);
            }
            if (targetEvent == null)
            {
                return(null);
            }
            if (!targetEvent.IsLoaded)
            {
                return(null);
            }

            return($"{sourceField.Name.ConvertToProperCase(new[] {'_'})}_{targetEvent.Name}_EventHandler");
        }
예제 #13
0
        /// <summary>
        /// Generates the source code for a standard field definition.
        /// </summary>
        /// <param name="memberData">Event data to be loaded.</param>
        /// <param name="manager">The namespace manager to use for namespace management with type declarations.</param>
        /// <param name="fieldSecurity">Parameter to set the target security for the field.</param>
        /// <param name="includeKeywords">Optional parameter that will include all keywords assigned to the field from the source model. This is true by default.</param>
        /// <param name="implementConstant">Determines if the filed is implemented as constant is should be returned as a constant, default is true.</param>
        /// <param name="requireStaticKeyword">Adds the static keyword to the signature, default is false.</param>
        /// <param name="requireReadOnlyKeyword">Adds the readonly keyword to the signature, default is false.</param>
        /// <param name="requireConstant">Implements the field as a constant, default is false.</param>
        /// <param name="requireConstantValue">The value to set the constant to if required.</param>
        /// <returns>The fully formatted event source code or null if the member could not be implemented.</returns>
        public static string GenerateStandardFieldSourceCode(CsField memberData, NamespaceManager manager,
                                                             CsSecurity fieldSecurity, bool includeKeywords = true, bool implementConstant = true,
                                                             bool requireStaticKeyword   = false, bool requireReadOnlyKeyword = false, bool requireConstant = false,
                                                             string requireConstantValue = null)
        {
            //Bounds checking to make sure all data that is needed is provided. If any required data is missing will return null.
            if (memberData == null)
            {
                return(null);
            }
            if (!memberData.IsLoaded)
            {
                return(null);
            }
            if (manager == null)
            {
                return(null);
            }

            //C# helper used to format output syntax.
            var formatter = new CodeFactory.SourceFormatter();

            //Using the formatter helper to generate a default event signature.
            string fieldSyntax = memberData.CSharpFormatFieldDeclaration(manager, includeKeywords, fieldSecurity,
                                                                         implementConstant, requireStaticKeyword, requireReadOnlyKeyword, requireConstant, requireConstantValue);

            //If the property syntax was not created return.
            if (string.IsNullOrEmpty(fieldSyntax))
            {
                return(null);
            }

            //If the member has document then will build the documentation.
            if (memberData.HasDocumentation)
            {
                //Using a documentation helper that will generate an enumerator that will output all XML documentation for the member.
                foreach (var documentation in memberData.CSharpFormatXmlDocumentationEnumerator())
                {
                    //Appending each xml document line to the being of the member definition.
                    formatter.AppendCodeLine(0, documentation);
                }
            }

            //The member has attributes assigned to it, append the attributes.
            if (memberData.HasAttributes)
            {
                //Using a documentation helper that will generate an enumerator that will output each attribute definition.
                foreach (var attributeSyntax in memberData.Attributes.CSharpFormatAttributeDeclarationEnumerator(manager))
                {
                    //Appending each attribute definition before the member definition.
                    formatter.AppendCodeLine(0, attributeSyntax);
                }
            }

            //Adding the event declaration
            formatter.AppendCodeBlock(0, fieldSyntax);

            //Adding a extra line feed at the end of the declaration.
            formatter.AppendCodeLine(0);

            //The source formatter returning the final results.
            return(formatter.ReturnSource());
        }
예제 #14
0
 protected override bool CanMarshal(CsField csField) => true;
        private IEnumerable <MemberDeclarationSyntax> GenerateMarshalStructField(CsStruct csStruct, CsField field)
        {
            var fieldDecl = FieldDeclaration(
                VariableDeclaration(
                    ParseTypeName(field.MarshalType.QualifiedName)))
                            .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)));

            if (csStruct.ExplicitLayout)
            {
                fieldDecl = fieldDecl.WithAttributeLists(SingletonList(
                                                             AttributeList(
                                                                 SingletonSeparatedList(Attribute(
                                                                                            ParseName("System.Runtime.InteropServices.FieldOffset"),
                                                                                            AttributeArgumentList(
                                                                                                SingletonSeparatedList(AttributeArgument(
                                                                                                                           LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(field.Offset))))))))
                                                             ));
            }
            if (field.IsArray)
            {
                yield return(fieldDecl.WithDeclaration(fieldDecl.Declaration.AddVariables(
                                                           VariableDeclarator(field.Name)
                                                           )));

                for (int i = 1; i < field.ArrayDimensionValue; i++)
                {
                    var declaration = fieldDecl.WithDeclaration(fieldDecl.Declaration.AddVariables(VariableDeclarator($"__{field.Name}{i}")));
                    if (csStruct.ExplicitLayout)
                    {
                        var offset = field.Offset + (field.Size / field.ArrayDimensionValue) * i;
                        declaration = declaration.WithAttributeLists(SingletonList(
                                                                         AttributeList(
                                                                             SingletonSeparatedList(Attribute(
                                                                                                        ParseName("System.Runtime.InteropServices.FieldOffset"),
                                                                                                        AttributeArgumentList(
                                                                                                            SingletonSeparatedList(AttributeArgument(
                                                                                                                                       LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(offset))))))))
                                                                         ));
                    }
                    yield return(declaration);
                }
            }
            else if (field.PublicType is CsStruct fieldType && fieldType.HasMarshalType)
            {
                yield return(fieldDecl.WithDeclaration(VariableDeclaration(
                                                           ParseTypeName($"{field.MarshalType.QualifiedName}.__Native"), SingletonSeparatedList(
                                                               VariableDeclarator(field.Name)))));
            }
예제 #16
0
        private async Task <CsSource> UpdateSubscriptionAsync(CsField subscriptionField, CsClass sourceClass, VsCSharpSource source)
        {
            SourceFormatter formatter        = new SourceFormatter();
            string          injectSourceCode = null;

            var contract = subscriptionField.DataType.GetInterfaceModel();

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

            CsSource sourceCode = source.SourceCode;

            try
            {
                CsClass currentClass = sourceClass;

                var events = contract.Events;

                var subscribePath = ContractHelper.GetSubscribeFilePath(currentClass);


                if (!subscribePath.hasFile)
                {
                    var manager = sourceCode.LoadNamespaceManager(sourceClass.Namespace);

                    var parent = await source.GetParentAsync();

                    if (parent == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }

                    VsDocument generatedDocument  = null;
                    string     partialClassSource = CSharpSourceGenerationCommon.GeneratePartialClass(currentClass, manager);
                    if (parent.ModelType == VisualStudioModelType.ProjectFolder)
                    {
                        var parentFolder = parent as VsProjectFolder;

                        if (parentFolder == null)
                        {
                            throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                        }

                        generatedDocument = await parentFolder.AddDocumentAsync(Path.GetFileName(subscribePath.filePath),
                                                                                partialClassSource);
                    }
                    else
                    {
                        var parentProject = parent as VsProject;

                        if (parentProject == null)
                        {
                            throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                        }

                        generatedDocument = await parentProject.AddDocumentAsync(subscribePath.filePath,
                                                                                 partialClassSource);
                    }
                    sourceCode = await generatedDocument.GetCSharpSourceModelAsync();

                    sourceCode = await sourceCode.AddMissingNamespaces(contract.Events, currentClass.Namespace);

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;

                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }
                else
                {
                    var parent = await source.GetParentAsync();

                    VsCSharpSource sourceDocument = null;
                    if (parent.ModelType == VisualStudioModelType.ProjectFolder)
                    {
                        var parentFolder = parent as VsProjectFolder;

                        if (parentFolder == null)
                        {
                            throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                        }

                        var children = await parentFolder.GetChildrenAsync(false, true);

                        sourceDocument = children.Where(c => c.ModelType == VisualStudioModelType.CSharpSource)
                                         .Cast <VsCSharpSource>()
                                         .FirstOrDefault(s => s.SourceCode.SourceDocument == subscribePath.filePath);
                    }
                    else
                    {
                        var parentProject = parent as VsProject;

                        if (parentProject == null)
                        {
                            throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                        }

                        var children = await parentProject.GetChildrenAsync(false, true);

                        sourceDocument = children.Where(c => c.ModelType == VisualStudioModelType.CSharpSource)
                                         .Cast <VsCSharpSource>()
                                         .FirstOrDefault(s => s.SourceCode.SourceDocument == subscribePath.filePath);;
                    }

                    if (sourceDocument == null)
                    {
                        throw new CodeFactoryException("Could load the contract document.");
                    }

                    sourceCode = sourceDocument.SourceCode;

                    sourceCode = await sourceCode.AddMissingNamespaces(contract.Events, currentClass.Namespace);

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }

                var namespaceManager = sourceCode.LoadNamespaceManager(currentClass.Namespace);

                foreach (var contractEvent in contract.Events)
                {
                    var eventHandlerName =
                        CSharpSourceGenerationWPF.GenerateContractEventHandlerMethodName(subscriptionField, contractEvent);

                    if (eventHandlerName == null)
                    {
                        throw new CodeFactoryException($"Could not create the source code for a contract event handler.");
                    }

                    if (currentClass.Methods.Any(m => m.Name == eventHandlerName))
                    {
                        continue;
                    }

                    var eventHandlerSource = CSharpSourceGenerationWPF.GenerateContractEventHandlerMethod(subscriptionField, contractEvent,
                                                                                                          namespaceManager);

                    if (eventHandlerSource == null)
                    {
                        throw new CodeFactoryException($"Could not create the source code for the event handler {eventHandlerName}");
                    }

                    sourceCode = await currentClass.AddToEndAsync(subscribePath.filePath, InjectSourceCodeAtLevel(2, eventHandlerSource));

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }

                var subscriptionName   = CSharpSourceGenerationWPF.GenerateContractSubscriptionMethodName(subscriptionField);
                var subscriptionMethod = currentClass.Methods.FirstOrDefault(m => m.Name == subscriptionName);

                if (subscriptionMethod != null)
                {
                    sourceCode = await subscriptionMethod.DeleteAsync();

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }

                var subscriptionSource = CSharpSourceGenerationWPF.GenerateContractSubscriptionMethod(subscriptionField, contract);

                if (subscriptionSource == null)
                {
                    throw new CodeFactoryException("Cannot generate the subscription contract source code.");
                }

                sourceCode = await currentClass.AddToEndAsync(subscribePath.filePath, InjectSourceCodeAtLevel(2, subscriptionSource));

                currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                if (currentClass == null)
                {
                    throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                }

                var releaseName   = CSharpSourceGenerationWPF.GenerateContractReleaseMethodName(subscriptionField);
                var releaseMethod = currentClass.Methods.FirstOrDefault(m => m.Name == releaseName);

                if (releaseMethod != null)
                {
                    sourceCode = await releaseMethod.DeleteAsync();

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }

                var releaseSource = CSharpSourceGenerationWPF.GenerateContractReleaseMethod(subscriptionField, contract);

                if (releaseSource == null)
                {
                    throw new CodeFactoryException("Cannot generate the release contract source code.");
                }

                sourceCode = await currentClass.AddToEndAsync(subscribePath.filePath, InjectSourceCodeAtLevel(2, releaseSource));
            }
            catch (CodeFactoryException)
            {
                throw;
            }
            catch (Exception unhandledException)
            {
                throw new CodeFactoryException("The following unhandledException occured", unhandledException);
            }

            return(sourceCode);
        }
예제 #17
0
 protected abstract StatementSyntax GenerateNativeToManaged(CsField csField, bool singleStackFrame);
예제 #18
0
 protected abstract bool CanMarshal(CsField csField);
예제 #19
0
        /// <summary>
        /// Generates the syntax definition of field in c# syntax. The default definition with all options turned off will return the filed signature and constants if defined and the default values.
        /// </summary>
        /// <example>
        /// With Keywords [Security] [Keywords] [FieldType] [Name];
        /// With Keywords and a constant [Security] [Keywords] [FieldType] [Name] = [Constant Value];
        /// Without Keywords [Security] [FieldType] [Name];
        /// Without Keywords and a constant [Security] [FieldType] [Name] = [Constant Value];
        /// </example>
        /// <param name="source">The source <see cref="CsField"/> model to generate.</param>
        /// <param name="manager">Namespace manager used to format type names.This is an optional parameter.</param>
        /// <param name="includeKeywords">Optional parameter that will include all keywords assigned to the field from the source model. This is true by default.</param>
        /// <param name="fieldSecurity">Optional parameter to set the target security for the field.</param>
        /// <param name="implementConstant">Determines if the filed is implemented as constant is should be returned as a constant, default is true.</param>
        /// <param name="requireStaticKeyword">Adds the static keyword to the signature, default is false.</param>
        /// <param name="requireReadOnlyKeyword">Adds the readonly keyword to the signature, default is false.</param>
        /// <param name="requireConstant">Implements the field as a constant, default is false.</param>
        /// <param name="requireConstantValue">The value to set the constant to if required.</param>
        /// <returns>Fully formatted field definition or null if the field data could not be generated.</returns>
        public static string CSharpFormatFieldDeclaration(this CsField source, NamespaceManager manager = null,
                                                          bool includeKeywords        = true, CsSecurity fieldSecurity     = CsSecurity.Unknown, bool implementConstant = true,
                                                          bool requireStaticKeyword   = false, bool requireReadOnlyKeyword = false, bool requireConstant                = false,
                                                          string requireConstantValue = null)
        {
            if (source == null)
            {
                return(null);
            }

            StringBuilder fieldFormatting = new StringBuilder();


            CsSecurity security = fieldSecurity == CsSecurity.Unknown ? source.Security : fieldSecurity;

            fieldFormatting.Append($"{security.CSharpFormatKeyword()} ");

            string constantValue = null;

            bool staticKeyword   = false;
            bool readOnlyKeyword = false;
            bool constantKeyword = false;

            if (includeKeywords)
            {
                if (source.IsStatic)
                {
                    staticKeyword = true;
                }
                if (source.IsReadOnly)
                {
                    readOnlyKeyword = true;
                }
            }

            if (source.IsConstant & implementConstant)
            {
                constantKeyword = true;
                constantValue   = source.ConstantValue;
            }

            if (!staticKeyword)
            {
                staticKeyword = requireStaticKeyword;
            }
            if (!readOnlyKeyword)
            {
                readOnlyKeyword = requireReadOnlyKeyword;
            }
            if (!constantKeyword)
            {
                constantKeyword = requireConstant;
            }

            if (constantKeyword & string.IsNullOrEmpty(constantValue))
            {
                constantValue = requireConstantValue;
            }


            if (staticKeyword)
            {
                fieldFormatting.Append($"{Keywords.Static} ");
            }
            if (readOnlyKeyword)
            {
                fieldFormatting.Append($"{Keywords.Readonly} ");
            }
            if (constantKeyword)
            {
                fieldFormatting.Append($"{Keywords.Constant} ");
            }

            fieldFormatting.Append($"{source.DataType.CSharpFormatTypeName(manager)} ");
            fieldFormatting.Append($"{source.Name}");
            if (constantKeyword)
            {
                fieldFormatting.Append($" = {source.DataType.CSharpFormatValueSyntax(constantValue)}");
            }
            fieldFormatting.Append(";");

            return(fieldFormatting.ToString());
        }
예제 #20
0
 protected override bool CanMarshal(CsField csField) => csField.IsBitField;