未验证 提交 83a550f2 编写于 作者: J Julien Couvreur 提交者: GitHub

QuickInfo should display symbols with nullability information (#26652)

上级 5b24516b
......@@ -27,7 +27,7 @@ private void VisitTypeSymbolWithAnnotations(TypeSymbolWithAnnotations type, Abst
switch (isNullable)
{
case true:
if (!typeSymbol.IsNullableType() && format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier))
if (!typeSymbol.IsNullableType() && format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier))
{
AddPunctuation(SyntaxKind.QuestionToken);
}
......@@ -102,7 +102,7 @@ private void VisitArrayType(IArrayTypeSymbol symbol, bool? isNullable)
switch (isNullable)
{
case true:
if (format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier))
if (format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier))
{
AddPunctuation(SyntaxKind.QuestionToken);
}
......
......@@ -94,7 +94,8 @@ private static void Add(TypeSymbol type, StringBuilder builder)
type.ToDisplayString(
SymbolDisplayFormat.CSharpErrorMessageFormat
.RemoveMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes)
.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier)
// displaying tuple syntax causes to load the members of ValueTuple, which can cause a cycle, so we use long-hand format instead
.WithCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier | SymbolDisplayCompilerInternalOptions.UseValueTuple)));
.WithCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.UseValueTuple)));
}
}
......@@ -752,7 +752,8 @@ public virtual string GetDocumentationCommentId()
}
private static readonly SymbolDisplayFormat s_debuggerDisplayFormat =
SymbolDisplayFormat.TestFormat.WithCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.IncludeNonNullableTypeModifier | SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier);
SymbolDisplayFormat.TestFormat.WithCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.IncludeNonNullableTypeModifier)
.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
internal string GetDebuggerDisplay()
{
......
......@@ -176,8 +176,8 @@ internal abstract class TypeSymbolWithAnnotations : NamespaceOrTypeSymbolWithAnn
internal static readonly SymbolDisplayFormat DebuggerDisplayFormat = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeNonNullableTypeModifier | SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier);
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeNonNullableTypeModifier);
internal static TypeSymbolWithAnnotations Create(CSharpCompilation compilation, TypeSymbol typeSymbol)
{
......@@ -660,7 +660,7 @@ public override string ToDisplayString(SymbolDisplayFormat format)
switch (_isNullable)
{
case true:
if ((format.CompilerInternalOptions & SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier) != 0)
if ((format.MiscellaneousOptions & SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier) != 0)
{
return str + "?";
}
......
......@@ -12875,7 +12875,7 @@ class F : C<F?>, I1<C<B?>>, I2<C<B>?>
Assert.Equal("String? D1()", compilation.GetTypeByMetadataName("D1")
.ToDisplayString(new SymbolDisplayFormat(delegateStyle: SymbolDisplayDelegateStyle.NameAndSignature,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier)));
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier)));
var f = compilation.GetTypeByMetadataName("F");
Assert.Equal("C<F?>", f.BaseType().ToTestDisplayString());
......@@ -12963,7 +12963,7 @@ public class F : C<F?>, I1<C<B?>>, I2<C<B>?>
Assert.Equal("String? D1()", compilation.GetTypeByMetadataName("D1")
.ToDisplayString(new SymbolDisplayFormat(delegateStyle: SymbolDisplayDelegateStyle.NameAndSignature,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier)));
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier)));
var f = ((PEModuleSymbol)m).GlobalNamespace.GetTypeMember("F");
Assert.Equal("C<F?>", f.BaseType().ToTestDisplayString());
......
......@@ -5841,11 +5841,11 @@ class B
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeModifiers,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeParamsRefOut,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
var formatWithNonNullableModifier = formatWithoutNonNullableModifier.WithCompilerInternalOptions(
SymbolDisplayCompilerInternalOptions.IncludeNonNullableTypeModifier | SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier);
var formatWithNonNullableModifier = formatWithoutNonNullableModifier
.WithCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.IncludeNonNullableTypeModifier)
.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
var method = comp.GetMember<MethodSymbol>("B.F1");
Verify(
......@@ -5916,8 +5916,7 @@ class B
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
var formatWithNullableModifier = formatWithoutNullableModifier
.WithCompilerInternalOptions(
SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier);
.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
var method = comp.GetMember<MethodSymbol>("B.F1");
Verify(
......
......@@ -34,6 +34,7 @@ Microsoft.CodeAnalysis.Operations.ITupleBinaryOperation.OperatorKind.get -> Micr
Microsoft.CodeAnalysis.Operations.ITupleBinaryOperation.RightOperand.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Operations.ITupleOperation.NaturalType.get -> Microsoft.CodeAnalysis.ITypeSymbol
Microsoft.CodeAnalysis.Platform.Arm64 = 6 -> Microsoft.CodeAnalysis.Platform
Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier = 64 -> Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions
abstract Microsoft.CodeAnalysis.DataFlowAnalysis.CapturedInside.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ISymbol>
abstract Microsoft.CodeAnalysis.DataFlowAnalysis.CapturedOutside.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ISymbol>
const Microsoft.CodeAnalysis.WellKnownMemberNames.DeconstructMethodName = "Deconstruct" -> string
......
......@@ -55,15 +55,9 @@ internal enum SymbolDisplayCompilerInternalOptions
/// </summary>
IncludeNonNullableTypeModifier = 1 << 6,
/// <summary>
/// Append '?' to nullable reference types.
/// PROTOTYPE(NullableReferenceTypes): review design for this option before shipping. See https://github.com/dotnet/roslyn/issues/26198
/// </summary>
IncludeNullableReferenceTypeModifier = 1 << 7,
/// <summary>
/// Display `System.ValueTuple` instead of tuple syntax `(...)`.
/// </summary>
UseValueTuple = 1 << 8,
UseValueTuple = 1 << 7,
}
}
......@@ -25,14 +25,14 @@ public class SymbolDisplayFormat
parameterOptions:
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeType,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier,
// Not showing the name is important because we visit parameters to display their
// types. If we visited their types directly, we wouldn't get ref/out/params.
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes |
SymbolDisplayMiscellaneousOptions.UseAsterisksInMultiDimensionalArrays |
SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName);
SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName |
SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
/// <summary>
/// Formats a symbol description as in a C# compiler short error message.
......@@ -50,14 +50,14 @@ public class SymbolDisplayFormat
parameterOptions:
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeType,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier,
// Not showing the name is important because we visit parameters to display their
// types. If we visited their types directly, we wouldn't get ref/out/params.
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes |
SymbolDisplayMiscellaneousOptions.UseAsterisksInMultiDimensionalArrays |
SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName);
SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName |
SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
/// <summary>
/// Formats a symbol description as in a Visual Basic compiler error message.
......@@ -157,10 +157,10 @@ public class SymbolDisplayFormat
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeDefaultValue,
localOptions: SymbolDisplayLocalOptions.IncludeType,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
SymbolDisplayMiscellaneousOptions.UseSpecialTypes |
SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
/// <summary>
/// A verbose format for displaying symbols (useful for testing).
......@@ -189,13 +189,13 @@ public class SymbolDisplayFormat
SymbolDisplayParameterOptions.IncludeName,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName,
SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName |
SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier,
compilerInternalOptions:
SymbolDisplayCompilerInternalOptions.IncludeScriptType |
SymbolDisplayCompilerInternalOptions.UseMetadataMethodNames |
SymbolDisplayCompilerInternalOptions.FlagMissingMetadataTypes |
SymbolDisplayCompilerInternalOptions.IncludeCustomModifiers |
SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier);
SymbolDisplayCompilerInternalOptions.IncludeCustomModifiers);
/// <summary>
/// this.QualifiedNameOnly = containingSymbol.QualifiedNameOnly + "." + this.Name
......@@ -223,10 +223,10 @@ public class SymbolDisplayFormat
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameOnly,
propertyStyle: SymbolDisplayPropertyStyle.NameOnly,
parameterOptions: SymbolDisplayParameterOptions.IncludeName,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
SymbolDisplayMiscellaneousOptions.UseSpecialTypes |
SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
/// <summary>
/// The format used for displaying symbols when visualizing IL.
......@@ -398,7 +398,7 @@ public class SymbolDisplayFormat
SymbolDisplayMiscellaneousOptions miscellaneousOptions = default(SymbolDisplayMiscellaneousOptions))
{
// If we want to display `!`, then we surely also want to display `?`
Debug.Assert(compilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier)
Debug.Assert(miscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier)
|| !compilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.IncludeNonNullableTypeModifier));
this.GlobalNamespaceStyle = globalNamespaceStyle;
......
......@@ -55,5 +55,11 @@ public enum SymbolDisplayMiscellaneousOptions
/// the special question mark syntax.
/// </summary>
ExpandNullable = 1 << 5,
/// <summary>
/// Append '?' to nullable reference types.
/// PROTOTYPE(NullableReferenceTypes): review design for this option before shipping. See https://github.com/dotnet/roslyn/issues/26198
/// </summary>
IncludeNullableReferenceTypeModifier = 1 << 6,
}
}
......@@ -456,7 +456,8 @@ internal static void VerifyUsesOfNullability(Symbol symbol, ImmutableArray<strin
UsesIsNullableVisitor.GetUses(builder, symbol);
var format = SymbolDisplayFormat.TestFormat
.WithCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.IncludeNonNullableTypeModifier | SymbolDisplayCompilerInternalOptions.IncludeNullableReferenceTypeModifier)
.WithCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.IncludeNonNullableTypeModifier)
.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier)
.RemoveParameterOptions(SymbolDisplayParameterOptions.IncludeName);
var symbols = builder.SelectAsArray(s => s.ToDisplayString(format));
......
......@@ -2202,6 +2202,30 @@ static void M()
MainDescription($"({FeaturesResources.local_variable}) A<B?>? y"));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
[WorkItem(26648, "https://github.com/dotnet/roslyn/issues/26648")]
public async Task NullableReference_InMethod()
{
var code = @"
class G
{
void M()
{
C c;
c.Go$$o();
}
}
public class C
{
public string? Goo(IEnumerable<object?> arg)
{
}
}";
await TestWithOptionsAsync(
Options.Regular.WithLanguageVersion(LanguageVersion.CSharp8),
code, MainDescription("string? C.Goo(IEnumerable<object?> arg)"));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task NestedInGeneric()
{
......
......@@ -58,7 +58,8 @@ protected abstract partial class AbstractSymbolDescriptionBuilder
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes |
SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName);
SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName |
SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
private static readonly SymbolDisplayFormat s_descriptionStyle =
new SymbolDisplayFormat(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册