Skip to content

[API proposal] Option for displaying standalone parameter names #67478

@jjonescz

Description

@jjonescz

Background and Motivation

PR #65606 added an internal option for displaying standalone parameter names and this option is enabled in SymbolDisplayFormat.CSharpErrorMessageFormat. However, since it's internal, users cannot disable the option (reported in #67464) unless they create their own SymbolDisplayFormat from scratch. Here we propose to make the option public.

Proposed API

 namespace Microsoft.CodeAnalysis
 {
     /// <summary>
     /// Specifies how parameters are displayed in the description of a (member, property/indexer, or delegate) symbol.
     /// </summary>
     [Flags]
     public enum SymbolDisplayParameterOptions
     {
         /// <summary>
         /// Includes parameter names in symbol descriptions.
         /// </summary>
+        /// <seealso cref="IncludeNameIfStandalone" />
         IncludeName = 1 << 3,
         
+        /// <summary>
+        /// Includes parameter name in top-level parameter symbol description.
+        /// </summary>
+        /// <seealso cref="IncludeName" />
+        IncludeNameIfStandalone = 1 << 6,
     }
 }

Usage Examples

var formatBare = new SymbolDisplayFormat(
    memberOptions:
        SymbolDisplayMemberOptions.IncludeParameters |
        SymbolDisplayMemberOptions.IncludeContainingType,
    parameterOptions: SymbolDisplayParameterOptions.IncludeType);
var formatNested = formatBare.AddParameterOptions(SymbolDisplayParameterOptions.IncludeName);
var formatStandalone = formatBare.AddParameterOptions(SymbolDisplayParameterOptions.IncludeNameIfStandalone);
var formatBoth = formatBare.AddParameterOptions(
    SymbolDisplayParameterOptions.IncludeName |
    SymbolDisplayParameterOptions.IncludeNameIfStandalone);

var comp = CreateCompilation("class C { void M(int p) { } }");
var m = comp.GetTypeByMetadataName("C").GetMembers("M").OfType<IMethodSymbol>().Single();
IParameterSymbol p = m.Parameters.Single();

Assert.Equal("C.M(Int32)", m.ToDisplayString(formatBare));
Assert.Equal("C.M(Int32 p)", m.ToDisplayString(formatNested));
Assert.Equal("C.M(Int32)", m.ToDisplayString(formatStandalone));
Assert.Equal("C.M(Int32 p)", m.ToDisplayString(formatBoth));

Assert.Equal("Int32", p.ToDisplayString(formatBare));
Assert.Equal("Int32 p", p.ToDisplayString(formatNested));
Assert.Equal("Int32 p", p.ToDisplayString(formatStandalone));
Assert.Equal("Int32 p", p.ToDisplayString(formatBoth));

// using SymbolDisplayFormat.CSharpErrorMessageFormat:

// before
Assert.Equal("int p", p.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
// - we cannot force displaying only parameter types using just the format easily
// - we can special-case parameter symbols - won't work if we want to display modifiers:
Assert.Equal("int", (p is IParameterSymbol ? p.Type : p).ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
// - we can create custom format from scratch which won't have the internal option:
Assert.Equal("int", p.ToDisplayString(new SymbolDisplayFormat(
    globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining,
    typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
    propertyStyle: SymbolDisplayPropertyStyle.NameOnly,
    genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
    memberOptions:
        SymbolDisplayMemberOptions.IncludeParameters |
        SymbolDisplayMemberOptions.IncludeContainingType |
        SymbolDisplayMemberOptions.IncludeExplicitInterface,
    parameterOptions:
        SymbolDisplayParameterOptions.IncludeParamsRefOut |
        SymbolDisplayParameterOptions.IncludeType,
    miscellaneousOptions:
        SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
        SymbolDisplayMiscellaneousOptions.UseSpecialTypes |
        SymbolDisplayMiscellaneousOptions.UseAsterisksInMultiDimensionalArrays |
        SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName |
        SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier)));

// after
Assert.Equal("int p", p.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
Assert.Equal("int", p.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat.RemoveParameterOptions(SymbolDisplayParameterOptions.IncludeNameIfStandalone)));

Alternative Designs

  • Add the option to SymbolDisplayMiscellaneousOptions or elsewhere.

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions