/// <summary> /// Extension method that generates the where clause for a generic parameter if one exists. This will not generate if the generic parameter is not a place holder type, or if no where clause conditions have been provided. /// </summary> /// <param name="source">Generic parameter to generate the where clause from.</param> /// <param name="manager">Optional parameter that contains all the using statements from the source code, when used will replace namespaces on type definition in code.</param> /// <returns>Null if the where clause was not generated, or the C# syntax for the where clause.</returns> public static string CSharpFormatGenericWhereClauseSignature(this CsGenericParameter source, NamespaceManager manager = null) { if (source == null) { return(null); } if (!source.Type.IsGenericPlaceHolder) { return(null); } if (!source.HasClassConstraint & !source.HasConstraintTypes & !source.HasNewConstraint & !source.HasStructConstraint) { return(null); } var whereBuilder = new StringBuilder($"{CommonContextualKeywords.Where} {source.Type.Name}: "); bool hasValue = false; if (source.HasClassConstraint) { whereBuilder.Append($"{Keywords.Class}"); hasValue = true; } if (source.HasStructConstraint) { whereBuilder.Append($"{Keywords.Structure}"); hasValue = true; } if (source.HasConstraintTypes) { foreach (var sourceConstrainingType in source.ConstrainingTypes) { whereBuilder.Append(hasValue ? $",{sourceConstrainingType.CSharpFormatTypeName(manager)}" : sourceConstrainingType.CSharpFormatTypeName(manager)); hasValue = true; } } if (source.HasNewConstraint) { whereBuilder.Append(hasValue ? $", {Keywords.New}{Symbols.ParametersDefinitionStart}{Symbols.ParametersDefinitionEnd}" : $"{Keywords.New}{Symbols.ParametersDefinitionStart}{Symbols.ParametersDefinitionEnd}"); } whereBuilder.Append(" "); return(whereBuilder.ToString()); }
/// <summary> /// Generates a default property definition with a backing field. Will determine security modifiers and append to get and set statements when needed. /// </summary> /// <example> /// With Keywords [security] [keywords] [property type] [property name] { [get when used] => [backingField]; [set when used] =>[backingField] = value; } /// Without Keywords [security] [property type] [property name] { [get when used] => [backingField]; [set when used] =>[backingField] = value; } /// </example> /// <param name="source">Property model used for generation.</param> /// <param name="backingFieldName">the name of the backing field to be managed by the property.</param> /// <param name="manager">Namespace manager used to format type names.</param> /// <param name="includeKeyword">Optional parameter that determines if the keywords will be appended. Default is false.</param> /// <param name="includeAbstractKeyword">Will include the definition for the abstract keyword in the definition if it is defined. default is false.</param> /// <param name="requireStaticKeyword">Adds the static keyword to the signature, default is false.</param> /// <param name="requireSealedKeyword">Adds the sealed keyword to the signature, default is false.</param> /// <param name="requireAbstractKeyword">Adds the abstract keyword to the signature, default is false.</param> /// <param name="requireOverrideKeyword">Adds the override keyword to the signature, default is false.</param> /// <param name="requireVirtualKeyword">Adds the virtual keyword to the signature, default is false.</param> /// <param name="propertySecurity">Optional parameter that overrides the models property security and sets a new security access level.</param> /// <param name="setSecurity">Optional parameter that overrides the models set security level with a new access level. Will also define a set statement even if it is not defined.</param> /// <param name="getSecurity">Optional parameter that overrides the models get security level with a new access level. Will also define a get statement even if it is not defined.</param> /// <returns>Formatted property or null if model data was missing.</returns> public static string CSharpFormatDefaultExpressionBodyPropertySignatureWithBackingField(this CsProperty source, string backingFieldName, NamespaceManager manager = null, bool includeKeyword = false, bool includeAbstractKeyword = false, bool requireStaticKeyword = false, bool requireSealedKeyword = false, bool requireAbstractKeyword = false, bool requireOverrideKeyword = false, bool requireVirtualKeyword = false, CsSecurity propertySecurity = CsSecurity.Unknown, CsSecurity setSecurity = CsSecurity.Unknown, CsSecurity getSecurity = CsSecurity.Unknown) { if (!source.IsLoaded) { return(null); } if (string.IsNullOrEmpty(backingFieldName)) { return(null); } string propertyDeclaration = CSharpFormatPropertyDeclaration(source, manager, true, includeKeyword, includeAbstractKeyword, requireStaticKeyword, requireSealedKeyword, requireAbstractKeyword, requireOverrideKeyword, requireVirtualKeyword, propertySecurity); if (string.IsNullOrEmpty(propertyDeclaration)) { return(null); } StringBuilder propertyDefinition = new StringBuilder($"{propertyDeclaration} {{ "); if (source.HasGet | getSecurity != CsSecurity.Unknown) { var getStatement = source.CSharpFormatGetStatement(propertySecurity, getSecurity); if (getStatement == null) { return(null); } propertyDefinition.Append($"{getStatement} => {backingFieldName}; "); } if (source.HasSet | setSecurity != CsSecurity.Unknown) { var setStatement = source.CSharpFormatSetStatement(propertySecurity, setSecurity); if (setStatement == null) { return(null); } propertyDefinition.Append($"{setStatement} => {backingFieldName} = value; "); } propertyDefinition.Append("}"); return(propertyDefinition.ToString()); }
/// <summary> /// Extension method that generates the generics definition part of a signature in the C# format. /// </summary> /// <param name="source">The target types that make up the generics signature.</param> /// <param name="manager">Optional parameter that contains all the using statements from the source code, when used will replace namespaces on type definition in code.</param> /// <returns>The fully formatted definition of the generics signature, or null if the source is not provided. </returns> public static string CSharpFormatGenericParametersSignature(this IReadOnlyList <CsGenericParameter> source, NamespaceManager manager = null) { //bounds check if (source == null) { return(null); } if (!source.Any()) { return(null); } StringBuilder genericsSignature = new StringBuilder(Symbols.GenericDefinitionStart); int totalParameters = source.Count; int currentParameter = 0; //Parsing each generic parameters and formatting output foreach (var sourceGenericParameter in source) { currentParameter++; genericsSignature.Append(sourceGenericParameter.Type.IsGenericPlaceHolder ? sourceGenericParameter.Type.Name :sourceGenericParameter.Type.CSharpFormatTypeName(manager)); if (totalParameters > currentParameter) { genericsSignature.Append(", "); } } genericsSignature.Append(Symbols.GenericDefinitionEnd); return(genericsSignature.ToString()); }
/// <summary> /// Generates a C# method signature from model data. This provides a fully customizable method for generating the signature. /// </summary> /// <param name="source">The source method data to generate the signature from.</param> /// <param name="includeAsyncKeyword">Include the async keyword if the return type is Task</param> /// <param name="includeSecurity">Includes the security scope which was defined in the model.</param> /// <param name="methodSecurity">Optional parameter that allows you to set the security scope for the method.</param> /// <param name="includeKeywords">Includes all keywords assigned to the source model.</param> /// <param name="includeAbstractKeyword">Will include the definition for the abstract keyword in the definition if it is defined. default is false.</param> /// <param name="manager">Optional parameter that contains all the using statements from the source code, when used will replace namespaces on type definition in code.</param> /// <param name="requireStaticKeyword">Adds the static keyword to the signature, default is false.</param> /// <param name="requireSealedKeyword">Adds the sealed keyword to the signature, default is false.</param> /// <param name="requireAbstractKeyword">Adds the abstract keyword to the signature, default is false.</param> /// <param name="requireOverrideKeyword">Adds the override keyword to the signature, default is false.</param> /// <param name="requireVirtualKeyword">Adds the virtual keyword to the signature, default is false.</param> /// <returns>Fully formatted method deceleration or null if the method data was missing.</returns> public static string CSharpFormatMethodSignature(this CsMethod source, NamespaceManager manager = null, bool includeAsyncKeyword = true, bool includeSecurity = true, CsSecurity methodSecurity = CsSecurity.Unknown, bool includeKeywords = true, bool includeAbstractKeyword = false, bool requireStaticKeyword = false, bool requireSealedKeyword = false, bool requireAbstractKeyword = false, bool requireOverrideKeyword = false, bool requireVirtualKeyword = false) { if (source == null) { return(null); } StringBuilder methodFormatting = new StringBuilder(); if (includeSecurity) { var formattedSecurity = methodSecurity == CsSecurity.Unknown ? source.Security.CSharpFormatKeyword() : methodSecurity.CSharpFormatKeyword(); methodFormatting.Append($"{formattedSecurity} "); } bool staticKeyword = false; bool sealedKeyword = false; bool abstractKeyword = false; bool overrideKeyword = false; bool virtualKeyword = false; if (includeKeywords) { if (source.IsStatic) { staticKeyword = true; } if (source.IsSealed) { sealedKeyword = true; } if (includeAbstractKeyword & source.IsAbstract) { abstractKeyword = true; } if (source.IsOverride) { overrideKeyword = true; } if (source.IsVirtual) { virtualKeyword = true; } } if (!staticKeyword) { staticKeyword = requireStaticKeyword; } if (!sealedKeyword) { sealedKeyword = requireSealedKeyword; } if (!abstractKeyword) { abstractKeyword = requireAbstractKeyword; } if (!overrideKeyword) { overrideKeyword = requireOverrideKeyword; } if (!virtualKeyword) { virtualKeyword = requireVirtualKeyword; } if (staticKeyword) { methodFormatting.Append($"{Keywords.Static} "); } if (sealedKeyword) { methodFormatting.Append($"{Keywords.Sealed} "); } if (abstractKeyword) { methodFormatting.Append($"{Keywords.Abstract} "); } if (overrideKeyword) { methodFormatting.Append($"{Keywords.Override} "); } if (virtualKeyword) { methodFormatting.Append($"{Keywords.Virtual} "); } if (includeAsyncKeyword) { //Bug fix for issue #14 if (source.ReturnType != null) { if (source.ReturnType.Name == "Task" & source.ReturnType.Namespace == "System.Threading.Tasks") { methodFormatting.Append("async "); } } } methodFormatting.Append(source.IsVoid ? $"{Keywords.Void} {source.Name}" : $"{source.ReturnType.CSharpFormatTypeName(manager)} {source.Name}"); if (source.IsGeneric) { methodFormatting.Append($"{source.GenericParameters.CSharpFormatGenericParametersSignature(manager)}"); } methodFormatting.Append(source.HasParameters ? source.Parameters.CSharpFormatParametersSignature(manager) : $"{Symbols.ParametersDefinitionStart}{Symbols.ParametersDefinitionEnd}"); if (!source.IsGeneric) { return(methodFormatting.ToString()); } foreach (var sourceGenericParameter in source.GenericParameters) { var whereClause = sourceGenericParameter.CSharpFormatGenericWhereClauseSignature(manager); if (!string.IsNullOrEmpty(whereClause)) { methodFormatting.Append($" {whereClause}"); } } return(methodFormatting.ToString()); }
/// <summary> /// Generates the initial definition portion of a property. /// </summary> /// <example> /// Format with Keywords [Security] [Keywords*] [ReturnType] [PropertyName] = public static string FirstName /// Format without Keywords [Security] [ReturnType] [PropertyName] = public string FirstName /// </example> /// <param name="manager">Namespace manager used to format type names.</param> /// <param name="source">The source property to use for formatting.</param> /// <param name="includeSecurity">Optional flag that determines if the security scope will be applied to the property definition. Default is true.</param> /// <param name="includeKeyWords">Optional flag that determines if keywords assigned to the property should be included in the signature. Default is false.</param> /// <param name="includeAbstractKeyword">Will include the definition for the abstract keyword in the definition if it is defined. default is false.</param> /// <param name="requireStaticKeyword">Adds the static keyword to the signature, default is false.</param> /// <param name="requireSealedKeyword">Adds the sealed keyword to the signature, default is false.</param> /// <param name="requireAbstractKeyword">Adds the abstract keyword to the signature, default is false.</param> /// <param name="requireOverrideKeyword">Adds the override keyword to the signature, default is false.</param> /// <param name="requireVirtualKeyword">Adds the virtual keyword to the signature, default is false.</param> /// <param name="propertySecurity">Optional parameter to override the models security and set your own security.</param> /// <returns>The formatted signature or null if the model data was not loaded.</returns> public static string CSharpFormatPropertyDeclaration(this CsProperty source, NamespaceManager manager = null, bool includeSecurity = true, bool includeKeyWords = false, bool includeAbstractKeyword = false, bool requireStaticKeyword = false, bool requireSealedKeyword = false, bool requireAbstractKeyword = false, bool requireOverrideKeyword = false, bool requireVirtualKeyword = false, CsSecurity propertySecurity = CsSecurity.Unknown) { if (!source.IsLoaded) { return(null); } StringBuilder propertyBuilder = new StringBuilder(); if (includeKeyWords & source.IsSealed) { propertyBuilder.Append($"{Keywords.Sealed} "); } if (includeSecurity) { propertyBuilder.Append(propertySecurity == CsSecurity.Unknown ? source.Security.CSharpFormatKeyword() : propertySecurity.CSharpFormatKeyword()); } bool staticKeyword = false; bool sealedKeyword = false; bool abstractKeyword = false; bool overrideKeyword = false; bool virtualKeyword = false; if (includeKeyWords) { if (source.IsStatic) { staticKeyword = true; } if (source.IsSealed) { sealedKeyword = true; } if (includeAbstractKeyword & source.IsAbstract) { abstractKeyword = true; } if (source.IsOverride) { overrideKeyword = true; } if (source.IsVirtual) { virtualKeyword = true; } } if (!staticKeyword) { staticKeyword = requireStaticKeyword; } if (!sealedKeyword) { sealedKeyword = requireSealedKeyword; } if (!abstractKeyword) { abstractKeyword = requireAbstractKeyword; } if (!overrideKeyword) { overrideKeyword = requireOverrideKeyword; } if (!virtualKeyword) { virtualKeyword = requireVirtualKeyword; } if (staticKeyword) { propertyBuilder.Append($"{Keywords.Static} "); } if (sealedKeyword) { propertyBuilder.Append($"{Keywords.Sealed} "); } if (abstractKeyword) { propertyBuilder.Append($"{Keywords.Abstract} "); } if (overrideKeyword) { propertyBuilder.Append($"{Keywords.Override} "); } if (virtualKeyword) { propertyBuilder.Append($"{Keywords.Virtual} "); } propertyBuilder.Append($" {source.PropertyType.CSharpFormatTypeName(manager)}"); propertyBuilder.Append($" {source.Name}"); return(propertyBuilder.ToString()); }
/// <summary> /// Returns a standard C# method signature the the async keyword when supported. /// </summary> /// <param name="source">The source method to extract the signature from. </param> /// <param name="manager">Optional parameter that contains all the using statements from the source code, when used will replace namespaces on type definition in code.</param> /// <returns>The c# formatted signature of a standard method signature with the async keyword when supported</returns> public static string CSharpFormatStandardMethodSignatureWithAsync(this CsMethod source, NamespaceManager manager = null) { return(source.CSharpFormatMethodSignature(manager, true, true, CsSecurity.Unknown, true, false)); }
/// <summary> /// Returns a standard C# method signature for use in interface definitions /// </summary> /// <param name="source">The source method to extract the signature from. </param> /// <param name="manager">Optional parameter that contains all the using statements from the source code, when used will replace namespaces on type definition in code.</param> /// <returns>The c# formatted signature of a standard method signature with the async keyword when supported</returns> public static string CSharpFormatInterfaceMethodSignature(this CsMethod source, NamespaceManager manager = null) { return(source.CSharpFormatMethodSignature(manager, false, false, CsSecurity.Unknown, false, false)); }
/// <summary> /// Extension method that create the fully formatted parameters section in c# syntax. /// </summary> /// <param name="source">The source list of parameters to be turned into a parameters signature.</param> /// <param name="manager">Optional parameter that contains all the using statements from the source code, when used will replace namespaces on type definition in code.</param> /// <param name="includeAttributes">Determines if the attributes that are assigned to a parameter should be included in the definition</param> /// <returns>The fully formatted parameters signature or null if data was missing.</returns> public static string CSharpFormatParametersSignature(this IReadOnlyList <CsParameter> source, NamespaceManager manager = null, bool includeAttributes = true) { if (source == null) { return(null); } if (!source.Any()) { return(null); } StringBuilder parameterSignature = new StringBuilder(Symbols.ParametersDefinitionStart); int totalParameters = source.Count; int currentParameter = 0; foreach (var sourceParameter in source) { currentParameter++; if (sourceParameter.HasAttributes & includeAttributes) { foreach (var sourceParameterAttribute in sourceParameter.Attributes) { parameterSignature.Append($"{sourceParameterAttribute.CSharpFormatAttributeSignature(manager)} "); } } if (sourceParameter.IsOut) { parameterSignature.Append($"{Keywords.Out} "); } if (sourceParameter.IsRef) { parameterSignature.Append($"{Keywords.Ref} "); } if (sourceParameter.IsParams) { parameterSignature.Append($"{Keywords.Params} "); } parameterSignature.Append(!sourceParameter.IsOptional ? $"{sourceParameter.ParameterType.CSharpFormatTypeName(manager)} {sourceParameter.Name}" : $"{sourceParameter.ParameterType.CSharpFormatTypeName(manager)} {sourceParameter.Name} = {sourceParameter.DefaultValue.CSharpFormatParameterDefaultValue(sourceParameter.ParameterType)}"); if (totalParameters > currentParameter) { parameterSignature.Append(", "); } } parameterSignature.Append(Symbols.ParametersDefinitionEnd); return(parameterSignature.ToString()); }
/// <summary> /// An iterator that returns fully formatted declaration syntax for a attribute in the C# language /// </summary> /// <param name="source">List of attributes to be processed.</param> /// <param name="manager">Namespace manager used to format type names.This is an optional parameter.</param> /// <returns>Fully formatted syntax for the attribute.</returns> public static IEnumerable <string> CSharpFormatAttributeDeclarationEnumerator(this IReadOnlyList <CsAttribute> source, NamespaceManager manager = null) { //No documentation was found for the model, stop the enumeration. if (source == null) { yield break; } if (!source.Any()) { yield break; } //iterate over each attribute and confirm it can be formatted as c# attribute syntax. foreach (CsAttribute attributeData in source) { if (attributeData == null) { continue; } if (!attributeData.IsLoaded) { continue; } var declaration = attributeData.CSharpFormatAttributeSignature(manager); if (string.IsNullOrEmpty(declaration)) { continue; } yield return(declaration); } }
/// <summary> /// Extension method that generates a the full structure declaration syntax based on the provided model. /// </summary> /// <example> /// Format with no generics [security] struct [name] [:[inherited interfaces*]] /// Format with generics [security] struct [name] <[generic parameters]> [: [inherited interfaces*]] [Generic Where Clauses*] /// </example> /// <param name="source">The source structure model to format.</param> /// <param name="security">The security level the structure should be implemented as.</param> /// <param name="manager">Namespace manager used to format type names.This is an optional parameter.</param> /// <param name="interfaceName">Optional parameter that allows you to specify a new name for the structure.</param> /// <returns>The full structure declaration or null if model data was missing.</returns> public static string CSharpFormatDeclaration(this CsStructure source, CsSecurity security, NamespaceManager manager = null, string interfaceName = null) { if (source == null) { return(null); } if (!source.IsLoaded) { return(null); } var name = interfaceName ?? source.Name; StringBuilder interfaceBuilder = new StringBuilder($"{security.CSharpFormatKeyword()} {Keywords.Interface} {name}"); if (source.IsGeneric) { interfaceBuilder.Append(source.GenericParameters.CSharpFormatGenericParametersSignature(manager)); } if (source.InheritedInterfaces.Any()) { var interfaces = source.InheritedInterfaces; int totalCount = interfaces.Count; int currentInterface = 0; interfaceBuilder.Append(": "); foreach (var csInterface in interfaces) { currentInterface++; var interfaceType = csInterface.CSharpFormatInheritanceTypeName(manager); if (interfaceType == null) { continue; } interfaceBuilder.Append(interfaceType); if (totalCount > currentInterface) { interfaceBuilder.Append(", "); } } } if (source.IsGeneric) { interfaceBuilder.Append(" "); foreach (var sourceGenericParameter in source.GenericParameters) { var whereClause = sourceGenericParameter.CSharpFormatGenericWhereClauseSignature(manager); if (string.IsNullOrEmpty(whereClause)) { continue; } interfaceBuilder.Append($"{whereClause} "); } } return(interfaceBuilder.ToString()); }
/// <summary> /// Defines a standard event declaration for a interface. /// </summary> /// <param name="source">Event model to load.</param> /// <param name="manager">Namespace manager used to format type names.This is an optional parameter.</param> /// <returns>Fully formatted event definition or null if the event data could not be generated.</returns> public static string CSharpFormatInterfaceEventDeclaration(this CsEvent source, NamespaceManager manager = null) { return(source.CSharpFormatEventDeclaration(manager, false, CsSecurity.Unknown, false, false)); }
/// <summary> /// Generates the signature of an event in c# syntax. /// </summary> /// <example> /// With Keywords [security] [keywords] event [event handler type] [name] /// Without Keywords [security] [keywords] event [event handler type] [name] /// </example> /// <param name="source">The source <see cref="CsEvent"/> model to generate.</param> /// <param name="manager">Namespace manager used to format type names.This is an optional parameter.</param> /// <param name="includeSecurity">Includes the security scope which was defined in the model.</param> /// <param name="eventSecurity">Optional parameter that sets the target security scope for the event.</param> /// <param name="includeKeywords">Optional parameter that determines if it will include all keywords assigned to the source model, default is false.</param> /// <param name="includeAbstractKeyword">Optional parameter that determines if it will include the definition for the abstract keyword in the definition if it is defined. default is false.</param> /// <param name="requireStaticKeyword">Adds the static keyword to the signature, default is false.</param> /// <param name="requireSealedKeyword">Adds the sealed keyword to the signature, default is false.</param> /// <param name="requireAbstractKeyword">Adds the abstract keyword to the signature, default is false.</param> /// <param name="requireOverrideKeyword">Adds the override keyword to the signature, default is false.</param> /// <param name="requireVirtualKeyword">Adds the virtual keyword to the signature, default is false.</param> /// <returns>Fully formatted event definition or null if the event data could not be generated.</returns> public static string CSharpFormatEventSignature(this CsEvent source, NamespaceManager manager = null, bool includeSecurity = true, CsSecurity eventSecurity = CsSecurity.Unknown, bool includeKeywords = true, bool includeAbstractKeyword = false, bool requireStaticKeyword = false, bool requireSealedKeyword = false, bool requireAbstractKeyword = false, bool requireOverrideKeyword = false, bool requireVirtualKeyword = false) { if (source == null) { return(null); } if (!source.IsLoaded) { return(null); } StringBuilder eventFormatting = new StringBuilder(); CsSecurity security = eventSecurity == CsSecurity.Unknown ? security = source.Security : security = eventSecurity; if (includeKeywords & source.IsSealed) { eventFormatting.Append($"{Keywords.Sealed} "); } if (includeSecurity) { eventFormatting.Append($"{security.CSharpFormatKeyword()} "); } bool staticKeyword = false; bool sealedKeyword = false; bool abstractKeyword = false; bool overrideKeyword = false; bool virtualKeyword = false; if (includeKeywords) { if (source.IsStatic) { staticKeyword = true; } if (source.IsSealed) { sealedKeyword = true; } if (includeAbstractKeyword & source.IsAbstract) { abstractKeyword = true; } if (source.IsOverride) { overrideKeyword = true; } if (source.IsVirtual) { virtualKeyword = true; } } if (!staticKeyword) { staticKeyword = requireStaticKeyword; } if (!sealedKeyword) { sealedKeyword = requireSealedKeyword; } if (!abstractKeyword) { abstractKeyword = requireAbstractKeyword; } if (!overrideKeyword) { overrideKeyword = requireOverrideKeyword; } if (!virtualKeyword) { virtualKeyword = requireVirtualKeyword; } if (staticKeyword) { eventFormatting.Append($"{Keywords.Static} "); } if (sealedKeyword) { eventFormatting.Append($"{Keywords.Sealed} "); } if (abstractKeyword) { eventFormatting.Append($"{Keywords.Abstract} "); } if (overrideKeyword) { eventFormatting.Append($"{Keywords.Override} "); } if (virtualKeyword) { eventFormatting.Append($"{Keywords.Virtual} "); } eventFormatting.Append($"{Keywords.Event} {source.EventType.CSharpFormatTypeName(manager)} {source.Name}"); return(eventFormatting.ToString()); }