Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SymbolDisplayMemberOptions.IncludeRef option to include ref keyword for ref-returning members #14654

Merged
merged 1 commit into from
Oct 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,9 @@ public override void VisitProperty(IPropertySymbol symbol)

if (format.MemberOptions.IncludesOption(SymbolDisplayMemberOptions.IncludeType))
{
var property = symbol as PropertySymbol;
if (property != null)
if (symbol.ReturnsByRef)
{
AddRefKindIfRequired(property.RefKind);
AddRefIfRequired();
}

symbol.Type.Accept(this.NotFirstVisitor);
Expand Down Expand Up @@ -232,10 +231,9 @@ public override void VisitMethod(IMethodSymbol symbol)
// to visualize a symbol *during its construction*, the parameters and return type might
// still be null.

var method = symbol as MethodSymbol;
if (method != null)
if (symbol.ReturnsByRef)
{
AddRefKindIfRequired(method.RefKind);
AddRefIfRequired();
}

if (symbol.ReturnsVoid)
Expand Down Expand Up @@ -718,6 +716,15 @@ private void AddCustomModifiersIfRequired(ImmutableArray<CustomModifier> customM
}
}

private void AddRefIfRequired()
{
if (format.MemberOptions.IncludesOption(SymbolDisplayMemberOptions.IncludeRef))
{
AddKeyword(SyntaxKind.RefKeyword);
AddSpace();
}
}

private void AddRefKindIfRequired(RefKind refKind)
{
if (format.ParameterOptions.IncludesOption(SymbolDisplayParameterOptions.IncludeParamsRefOut))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,9 @@ public override void VisitNamedType(INamedTypeSymbol symbol)
if (format.DelegateStyle == SymbolDisplayDelegateStyle.NameAndSignature)
{
var invokeMethod = symbol.DelegateInvokeMethod;
var invokeMethodSymbol = invokeMethod as MethodSymbol;
if (invokeMethodSymbol != null)
if (invokeMethod.ReturnsByRef)
{
AddRefKindIfRequired(invokeMethodSymbol.RefKind);
AddRefIfRequired();
}

if (invokeMethod.ReturnsVoid)
Expand Down
230 changes: 223 additions & 7 deletions src/Compilers/CSharp/Test/Symbol/SymbolDisplay/SymbolDisplayTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2115,6 +2115,49 @@ void M(ref short s, int i, params string[] args) { } }
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //args
SymbolDisplayPartKind.Punctuation);

// Without SymbolDisplayParameterOptions.IncludeParamsRefOut.
TestSymbolDescription(
text,
findSymbol,
format.WithParameterOptions(SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName),
"M(Int16 s, Int32 i, String[] args)",
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);

// Without SymbolDisplayParameterOptions.IncludeType, drops
// ref/out/params modifiers. (VB retains ByRef/ParamArray.)
TestSymbolDescription(
text,
findSymbol,
format.WithParameterOptions(SymbolDisplayParameterOptions.IncludeParamsRefOut | SymbolDisplayParameterOptions.IncludeName),
"M(s, i, args)",
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
}

[Fact()]
Expand Down Expand Up @@ -2887,12 +2930,7 @@ private static void Verify(ImmutableArray<SymbolDisplayPart> actualParts, string
Assert.Equal(expectedText, actualParts.ToDisplayString());
if (expectedKinds.Length > 0)
{
for (int i = 0; i < Math.Min(expectedKinds.Length, actualParts.Length); i++)
{
Assert.Equal(expectedKinds[i], actualParts[i].Kind);
}

Assert.Equal(expectedKinds.Length, actualParts.Length);
AssertEx.Equal(expectedKinds, actualParts.Select(p => p.Kind), itemInspector: p => $"SymbolDisplayPartKind.{p}");
}
}

Expand Down Expand Up @@ -4157,7 +4195,6 @@ class C
SymbolDisplayPartKind.EventName);
}


[WorkItem(765287, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/765287")]
[Fact]
public void TestVbSymbols()
Expand Down Expand Up @@ -5184,6 +5221,185 @@ public void DisplayFakeTupleTypeSymbol()
SymbolDisplayPartKind.Punctuation);
}

[WorkItem(11356, "https://github.com/dotnet/roslyn/issues/11356")]
[Fact]
public void RefReturn()
{
var sourceA =
@"public delegate ref int D();
public class C
{
public ref int F(ref int i) => ref i;
int _p;
public ref int P => ref _p;
public ref int this[int i] => ref _p;
}";
var compA = CreateCompilationWithMscorlib(sourceA);
compA.VerifyDiagnostics();
var refA = compA.EmitToImageReference();
// From C# symbols.
RefReturnInternal(compA);

var compB = CreateVisualBasicCompilation(GetUniqueName(), "", referencedAssemblies: new[] { MscorlibRef, refA });
compB.VerifyDiagnostics();
// From VB symbols.
RefReturnInternal(compB);
}

private static void RefReturnInternal(Compilation comp)
{
var formatBase = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeParamsRefOut,
propertyStyle: SymbolDisplayPropertyStyle.ShowReadWriteDescriptor,
delegateStyle: SymbolDisplayDelegateStyle.NameAndSignature,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
var formatWithoutRef = formatBase.WithMemberOptions(
SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType);
var formatWithRef = formatBase.WithMemberOptions(
SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeRef);
var formatWithoutTypeWithRef = formatBase.WithMemberOptions(
SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeRef);

var global = comp.GlobalNamespace;
var type = global.GetTypeMembers("C").Single();
var method = type.GetMembers("F").Single();
var property = type.GetMembers("P").Single();
var indexer = type.GetMembers().Where(m => m.Kind == SymbolKind.Property && ((IPropertySymbol)m).IsIndexer).Single();
var @delegate = global.GetTypeMembers("D").Single();

// Method without IncludeRef.
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithoutRef),
"int F(ref int)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation);

// Property without IncludeRef.
Verify(
SymbolDisplay.ToDisplayParts(property, formatWithoutRef),
"int P { get; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);

// Indexer without IncludeRef.
Verify(
SymbolDisplay.ToDisplayParts(indexer, formatWithoutRef),
"int this[int] { get; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);

// Delegate without IncludeRef.
Verify(
SymbolDisplay.ToDisplayParts(@delegate, formatWithoutRef),
"int D()",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);

// Method with IncludeRef.
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithRef),
"ref int F(ref int)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation);

// Property with IncludeRef.
Verify(
SymbolDisplay.ToDisplayParts(property, formatWithRef),
"ref int P { get; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);

// Indexer with IncludeRef.
Verify(
SymbolDisplay.ToDisplayParts(indexer, formatWithRef),
"ref int this[int] { get; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);

// Delegate with IncludeRef.
Verify(
SymbolDisplay.ToDisplayParts(@delegate, formatWithRef),
"ref int D()",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);

// Method without IncludeType, with IncludeRef.
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithoutTypeWithRef),
"F(ref int)",
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation);
}

[WorkItem(5002, "https://github.com/dotnet/roslyn/issues/5002")]
[Fact]
public void AliasInSpeculativeSemanticModel()
Expand Down
1 change: 1 addition & 0 deletions src/Compilers/Core/Portable/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ Microsoft.CodeAnalysis.Semantics.UnaryOperationKind.UnsignedPrefixIncrement = 77
Microsoft.CodeAnalysis.SymbolDisplayFormat.RemoveGenericsOptions(Microsoft.CodeAnalysis.SymbolDisplayGenericsOptions options) -> Microsoft.CodeAnalysis.SymbolDisplayFormat
Microsoft.CodeAnalysis.SymbolDisplayFormat.RemoveLocalOptions(Microsoft.CodeAnalysis.SymbolDisplayLocalOptions options) -> Microsoft.CodeAnalysis.SymbolDisplayFormat
Microsoft.CodeAnalysis.SymbolDisplayFormat.RemoveMiscellaneousOptions(Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions options) -> Microsoft.CodeAnalysis.SymbolDisplayFormat
Microsoft.CodeAnalysis.SymbolDisplayMemberOptions.IncludeRef = 128 -> Microsoft.CodeAnalysis.SymbolDisplayMemberOptions
Microsoft.CodeAnalysis.Text.SourceText.CanBeEmbedded.get -> bool
Microsoft.CodeAnalysis.Text.SourceText.GetChecksum() -> System.Collections.Immutable.ImmutableArray<byte>
abstract Microsoft.CodeAnalysis.CompilationOptions.Language.get -> string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ public class SymbolDisplayFormat
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeRef |
SymbolDisplayMemberOptions.IncludeExplicitInterface,
kindOptions:
SymbolDisplayKindOptions.IncludeMemberKeyword,
Expand Down Expand Up @@ -224,7 +225,7 @@ public class SymbolDisplayFormat
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Omitted,
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
memberOptions: SymbolDisplayMemberOptions.IncludeContainingType | SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType,
memberOptions: SymbolDisplayMemberOptions.IncludeContainingType | SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeRef,
kindOptions: SymbolDisplayKindOptions.IncludeMemberKeyword,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeParamsRefOut | SymbolDisplayParameterOptions.IncludeType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,10 @@ public enum SymbolDisplayMemberOptions
/// Includes the value of the member if is a constant.
/// </summary>
IncludeConstantValue = 1 << 6,

/// <summary>
/// Includes the <c>ref</c> keyword for ref-returning methods and properties/indexers. C# only.
/// </summary>
IncludeRef = 1 << 7,
}
}
Loading