private static string GetDefinition(ParameterDefinition parameter) { var definitionBuilder = new StringBuilder(); var parameterType = parameter.ParameterType; // If the parameter is optional, but does not have a default value // display it as [Optional] attribute at the before the parameter. // If the parameter is optional AND has a default parameter, // render it as " = <VALUE>" after the parameter (see below). if (parameter.Attributes.HasFlag(ParameterAttributes.Optional) && !parameter.Attributes.HasFlag(ParameterAttributes.HasDefault)) { definitionBuilder.Append("[Optional]"); } AppendCustomAttributes(definitionBuilder, parameter.GetCustomAttributes(), singleLine: true); // add "params" prefix if method allows multiple values if (parameter.CustomAttributes.Any(a => a.AttributeType.FullName == SystemTypeNames.ParamArrayAttributeFullName)) { definitionBuilder.Append("params "); } // special handling for 'out' and 'ref' parameters // do not use the type's actual display name, but add the modified before the parameter // and use the by-reference type's element type, // i.e. display "ref string parameter" instead of "string& parameter" if (parameterType is ByReferenceType byReferenceType) { parameterType = byReferenceType.ElementType; if (parameter.Attributes.HasFlag(ParameterAttributes.Out)) { definitionBuilder.Append("out "); } else if (parameter.Attributes.HasFlag(ParameterAttributes.In)) { definitionBuilder.Append("in "); } else { definitionBuilder.Append("ref "); } } // add parameter type definitionBuilder.Append(GetDisplayName(parameterType)); definitionBuilder.Append(" "); // add parameter name definitionBuilder.Append(parameter.Name); // if parameter has a default value, include it in the definition if (parameter.Attributes.HasFlag(ParameterAttributes.Optional) && parameter.Attributes.HasFlag(ParameterAttributes.HasDefault)) { definitionBuilder.Append(" = "); definitionBuilder.Append(GetLiteral(parameter.ParameterType, parameter.Constant)); } return(definitionBuilder.ToString()); }