dotnet / dotnet/roslyn

VB SymbolDisplay.ToDisplayString doesn't use `Optional` keyword when `IncludeDefaultValue` and not `IncludeOptionalBrackets`

Offen
#77,458 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Area-Compilers
Vorherrschende Sprache
C#
Sterne
20.7k
Forks
4.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

I use `Microsoft.CodeAnalysis.VisualBasic.SymbolDisplay.ToDisplayString` to generate VB declarations from dll files and xml files in my API docs. I found that the `Optional` keyword is missing when generating optional parameters in method declarations when the `SymbolDisplayParameterOptions.IncludeDefaultValue` flag is set and `SymbolDisplayParameterOptions.IncludeOptionalBrackets` is not set.
I need to display VB declarations with the exactly the same format as Microsoft Learn. To work around this bug, I have to use `ToDisplayParts` and adjust the return value, which is very inconvenient.

**Version Used**:
4.13.0

**Steps to Reproduce**:

Create a VB console project

**VbSymbolDisplayCsOptional.vbproj**
```xml


Exe
VbSymbolDisplayCsOptional
net9.0




```

Edit `Program.vb`

**Program.vb**
```vbnet
Imports System.IO
Imports Microsoft.CodeAnalysis
Imports CS = Microsoft.CodeAnalysis.CSharp
Imports VB = Microsoft.CodeAnalysis.VisualBasic

Module Program

Sub Main()
' Create C# code with optional parameter
Dim csharpCode As String = "
using System;

public class Example
{
public void MethodWithOptional(string required, string str1 = ""default"", int number = 42)
{
Console.WriteLine($""{required}, {str1}, {number}"");
}
}"

' Compile the C# code
Dim compilation = CreateCompilationFromCSharpCode(csharpCode, "OptionalParamExample")

' Get the symbol for the method with optional parameters
Dim exampleClass = compilation.GetTypeByMetadataName("Example")
Dim methodSymbol = exampleClass.GetMembers().OfType(Of IMethodSymbol)().First(Function(m) m.Name = "MethodWithOptional")

' Create a VB symbol display format
Dim format = SymbolDisplayFormat.FullyQualifiedFormat.
WithMemberOptions(
SymbolDisplayMemberOptions.IncludeParameters).
WithParameterOptions(
SymbolDisplayParameterOptions.IncludeName Or
SymbolDisplayParameterOptions.IncludeType Or
SymbolDisplayParameterOptions.IncludeDefaultValue Or
SymbolDisplayParameterOptions.IncludeModifiers)

' Display the symbol using VB SymbolDisplay
Dim formattedSymbol = VB.SymbolDisplay.ToDisplayString(methodSymbol, format)
Console.WriteLine("Method signature in VB format:")
Console.WriteLine(formattedSymbol)

' Also display the parameter info separately for clarity
Console.WriteLine("Parameters:")
For Each parameter In methodSymbol.Parameters
Dim paramStr = VB.SymbolDisplay.ToDisplayString(parameter, format)
Dim hasDefaultValue = parameter.HasExplicitDefaultValue
Console.WriteLine($"- {paramStr} (Optional: {parameter.IsOptional}, Has Default: {hasDefaultValue})")
Next
End Sub

Public Function CreateCompilationFromCSharpCode(
code As String,
name As String,
ParamArray references As MetadataReference()) As Compilation

Dim parserOption As New CS.CSharpParseOptions
Dim syntaxTree = CS.CSharpSyntaxTree.ParseText(code, parserOption)

Return CS.CSharpCompilation.Create(
name,
options:=New CS.CSharpCompilationOptions(
OutputKind.DynamicallyLinkedLibrary,
xmlReferenceResolver:=XmlFileResolver.Default),
syntaxTrees:={syntaxTree},
references:=GetDefaultMetadataReferences().
Concat(If(references, Array.Empty(Of MetadataReference))))
End Function

Private Function GetDefaultMetadataReferences() As IEnumerable(Of MetadataReference)
Dim dirPath = Path.GetDirectoryName(GetType(Object).Assembly.Location)

Return From dll In Directory.EnumerateFiles(dirPath, "*.dll", SearchOption.TopDirectoryOnly)
Select MetadataReference.CreateFromFile(dll)
End Function

End Module
```

Run the project.

**Diagnostic Id**:

N/A

**Expected Behavior**:
The program produces the following output:
```console
Method signature in VB format:
MethodWithOptional(required As String, Optional str1 As String = "default", Optional number As Integer = 42)
Parameters:
- required As String (Optional: False, Has Default: False)
- Optional str1 As String = "default" (Optional: True, Has Default: True)
- Optional number As Integer = 42 (Optional: True, Has Default: True)
```

**Actual Behavior**:
The program produces the following output:
```console
Method signature in VB format:
MethodWithOptional(required As String, str1 As String = "default", number As Integer = 42)
Parameters:
- required As String (Optional: False, Has Default: False)
- str1 As String = "default" (Optional: True, Has Default: True)
- number As Integer = 42 (Optional: True, Has Default: True)
```

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginnen Sie damit, das Problem mit Program.vb zu reproduzieren, und verfolgen Sie Microsoft.CodeAnalysis.VisualBasic.SymbolDisplay.ToDisplayString mit IncludeDefaultValue ohne IncludeOptionalBrackets. Vergleichen Sie die generierte Deklaration mit der erwarteten Ausgabe und überprüfen Sie, dass optionale Parameter das Schlüsselwort Optional enthalten, während das bestehende Verhalten der Klammern unverändert bleibt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
csharp, visualbasic
Bereich
compilers
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Veraltet
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
50/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.