/// <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> /// 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 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> /// <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) { if (source == null) { return(null); } StringBuilder methodFormatting = new StringBuilder(); if (includeSecurity) { var formattedSecurity = methodSecurity == CsSecurity.Unknown ? source.Security.CSharpFormatKeyword() : methodSecurity.CSharpFormatKeyword(); methodFormatting.Append($"{formattedSecurity} "); } if (includeKeywords) { if (source.IsStatic) { methodFormatting.Append($"{Keywords.Static} "); } if (source.IsSealed) { methodFormatting.Append($"{Keywords.Sealed} "); } if (includeAbstractKeyword & source.IsAbstract) { methodFormatting.Append($"{Keywords.Abstract} "); } if (source.IsOverride) { methodFormatting.Append($"{Keywords.Override} "); } if (source.IsVirtual) { 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 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="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, 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, 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> /// 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> /// 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> /// 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> /// 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> /// <returns>The fully formatted parameters signature or null if data was missing.</returns> public static string CSharpFormatParametersSignature(this IReadOnlyList <CsParameter> source, NamespaceManager manager = null) { 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) { 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> /// Formats a type name to match the C# syntax for a type deceleration in C#. /// </summary> /// <param name="source">The type model to use to generate the type signature for c#</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 formatted type definition for C#</returns> public static string CSharpFormatTypeName(this CsType source, NamespaceManager manager = null) { if (source == null) { return(null); } if (!source.IsLoaded) { return(null); } var namespaceManager = manager ?? new NamespaceManager(null); string returnValue = null; string typeName = null; if (source.IsWellKnownType) { switch (source.WellKnownType) { case CsKnownLanguageType.NotWellKnown: typeName = null; break; case CsKnownLanguageType.Object: typeName = WellKnownTypes.Object; break; case CsKnownLanguageType.Void: typeName = Keywords.Void; break; case CsKnownLanguageType.Boolean: typeName = WellKnownTypes.Boolean; break; case CsKnownLanguageType.Character: typeName = WellKnownTypes.Character; break; case CsKnownLanguageType.Signed8BitInteger: typeName = WellKnownTypes.SByte; break; case CsKnownLanguageType.UnSigned8BitInteger: typeName = WellKnownTypes.Byte; break; case CsKnownLanguageType.Signed16BitInteger: typeName = WellKnownTypes.Short; break; case CsKnownLanguageType.Unsigned16BitInteger: typeName = WellKnownTypes.Ushort; break; case CsKnownLanguageType.Signed32BitInteger: typeName = WellKnownTypes.Int; break; case CsKnownLanguageType.Unsigned32BitInteger: typeName = WellKnownTypes.Uint; break; case CsKnownLanguageType.Signed64BitInteger: typeName = WellKnownTypes.Long; break; case CsKnownLanguageType.Unsigned64BitInteger: typeName = WellKnownTypes.Ulong; break; case CsKnownLanguageType.Decimal: typeName = WellKnownTypes.Decimal; break; case CsKnownLanguageType.Single: typeName = WellKnownTypes.Float; break; case CsKnownLanguageType.Double: typeName = WellKnownTypes.Double; break; case CsKnownLanguageType.Pointer: typeName = WellKnownTypes.Pointer; break; case CsKnownLanguageType.PlatformPointer: typeName = WellKnownTypes.PlatformPointer; break; case CsKnownLanguageType.DateTime: typeName = WellKnownTypes.Datetime; break; case CsKnownLanguageType.String: typeName = WellKnownTypes.String; break; default: typeName = null; break; } } else { var targetNamespace = namespaceManager.AppendingNamespace(source.Namespace); typeName = targetNamespace == null ? source.Name : $"{targetNamespace}.{source.Name}"; } returnValue = typeName; if (source.IsGeneric) { returnValue = $"{typeName}{source.GenericParameters.CSharpFormatGenericParametersSignature(namespaceManager)}"; } if (source.IsArray) { returnValue = $"{typeName}{source.CSharpFormatArraySignature()}"; } if (source.IsTuple) { returnValue = source.CSharpFormatTupleSignature(namespaceManager); } return(returnValue); }