|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
using Basic.Reference.Assemblies;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public class SymbolDisplayTests : CSharpTestBase
{
[Fact]
public void TestClassNameOnlySimple()
{
var text = "class A {}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("A", 0).Single();
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameOnly);
TestSymbolDescription(
text,
findSymbol,
format,
"A",
SymbolDisplayPartKind.ClassName);
}
[Fact, WorkItem(46985, "https://github.com/dotnet/roslyn/issues/46985")]
public void TestRecordNameOnlySimple()
{
var text = "record A {}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("A", 0).Single();
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameOnly);
TestSymbolDescription(
text,
findSymbol,
format,
"A",
SymbolDisplayPartKind.RecordClassName);
}
[Fact, WorkItem(46985, "https://github.com/dotnet/roslyn/issues/46985")]
public void TestRecordNameOnlyComplex()
{
var text = @"
namespace N1 {
namespace N2.N3 {
record R1 {
record R2 {} } } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetNestedNamespace("N1").
GetNestedNamespace("N2").
GetNestedNamespace("N3").
GetTypeMembers("R1").Single().
GetTypeMembers("R2").Single();
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameOnly);
TestSymbolDescription(
text,
findSymbol,
format,
"R2",
SymbolDisplayPartKind.RecordClassName);
}
[Fact]
public void TestClassNameOnlyComplex()
{
var text = @"
namespace N1 {
namespace N2.N3 {
class C1 {
class C2 {} } } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetNestedNamespace("N1").
GetNestedNamespace("N2").
GetNestedNamespace("N3").
GetTypeMembers("C1").Single().
GetTypeMembers("C2").Single();
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameOnly);
TestSymbolDescription(
text,
findSymbol,
format,
"C2",
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void TestFullyQualifiedFormat()
{
var text = @"
namespace N1 {
namespace N2.N3 {
class C1 {
class C2 {} } } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetNestedNamespace("N1").
GetNestedNamespace("N2").
GetNestedNamespace("N3").
GetTypeMembers("C1").Single().
GetTypeMembers("C2").Single();
TestSymbolDescription(
text,
findSymbol,
SymbolDisplayFormat.FullyQualifiedFormat,
"global::N1.N2.N3.C1.C2",
SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.NamespaceName, SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.NamespaceName, SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.NamespaceName, SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void TestClassNameAndContainingTypesSimple()
{
var text = "class A {}";
Func<NamespaceSymbol, Symbol> findSymbol = global => global.GetTypeMembers("A", 0).Single();
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"A",
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void TestClassNameAndContainingTypesComplex()
{
var text = @"
namespace N1 {
namespace N2.N3 {
class C1 {
class C2 {} } } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetNestedNamespace("N1").
GetNestedNamespace("N2").
GetNestedNamespace("N3").
GetTypeMembers("C1").Single().
GetTypeMembers("C2").Single();
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"C1.C2",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void TestMethodNameOnlySimple()
{
var text = @"
class A {
void M() {} }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("A", 0).Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat();
TestSymbolDescription(
text,
findSymbol,
format,
"M",
SymbolDisplayPartKind.MethodName);
}
[Fact]
public void TestMethodNameOnlyComplex()
{
var text = @"
namespace N1 {
namespace N2.N3 {
class C1 {
class C2 {
public static int[] M(int? x, C1 c) {} } } } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetNestedNamespace("N1").
GetNestedNamespace("N2").
GetNestedNamespace("N3").
GetTypeMembers("C1").Single().
GetTypeMembers("C2").Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat();
TestSymbolDescription(
text,
findSymbol,
format,
"M",
SymbolDisplayPartKind.MethodName);
}
[Fact]
public void TestMethodAndParamsSimple()
{
var text = @"
class A {
void M() {} }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("A", 0).Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeModifiers | SymbolDisplayMemberOptions.IncludeAccessibility | SymbolDisplayMemberOptions.IncludeType,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"private void M()",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestMethodAndParamsComplex()
{
var text = @"
namespace N1 {
namespace N2.N3 {
class C1 {
class C2 {
public static int[] M(int? x, C1 c) {} } } } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetNestedNamespace("N1").
GetNestedNamespace("N2").
GetNestedNamespace("N3").
GetTypeMembers("C1").Single().
GetTypeMembers("C2").Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeModifiers | SymbolDisplayMemberOptions.IncludeAccessibility | SymbolDisplayMemberOptions.IncludeType,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"public static int[] M(int? x, C1 c)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, //M
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //x
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, //C1
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //c
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestExtensionMethodAsStatic()
{
var text = @"
class C1<T> { }
class C2 {
public static TSource M<TSource>(this C1<TSource> source, int index) {} }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C2").Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
extensionMethodStyle: SymbolDisplayExtensionMethodStyle.StaticMethod,
genericsOptions:
SymbolDisplayGenericsOptions.IncludeTypeParameters |
SymbolDisplayGenericsOptions.IncludeVariance,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeExtensionThis |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"public static TSource C2.M<TSource>(this C1<TSource> source, int index)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, //C2
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName, //M
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, //C1
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //source
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //index
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestExtensionMethodAsInstance()
{
var text = @"
class C1<T> { }
class C2 {
public static TSource M<TSource>(this C1<TSource> source, int index) {} }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C2").Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
extensionMethodStyle: SymbolDisplayExtensionMethodStyle.InstanceMethod,
genericsOptions:
SymbolDisplayGenericsOptions.IncludeTypeParameters |
SymbolDisplayGenericsOptions.IncludeVariance,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeExtensionThis |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"public TSource C1<TSource>.M<TSource>(int index)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, //C1
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ExtensionMethodName, //M
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //index
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestExtensionMethodAsDefault()
{
var text = @"
class C1<T> { }
class C2 {
public static TSource M<TSource>(this C1<TSource> source, int index) {} }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C2").Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
extensionMethodStyle: SymbolDisplayExtensionMethodStyle.Default,
genericsOptions:
SymbolDisplayGenericsOptions.IncludeTypeParameters |
SymbolDisplayGenericsOptions.IncludeVariance,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeExtensionThis |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"public static TSource C2.M<TSource>(this C1<TSource> source, int index)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, //C2
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName, //M
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, //C1
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //source
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //index
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestReducedExtensionMethodAsStatic()
{
var text = @"
class C1 { }
class C2 {
public static TSource M<TSource>(this C1 source, int index) {} }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
{
var type = global.GetTypeMember("C1");
var method = (MethodSymbol)global.GetTypeMember("C2").GetMember("M");
return method.ReduceExtensionMethod(type, null!);
};
var format = new SymbolDisplayFormat(
extensionMethodStyle: SymbolDisplayExtensionMethodStyle.StaticMethod,
genericsOptions:
SymbolDisplayGenericsOptions.IncludeTypeParameters |
SymbolDisplayGenericsOptions.IncludeVariance,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeExtensionThis |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"public static TSource C2.M<TSource>(this C1 source, int index)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, //C2
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName, //M
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, //C1
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //source
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //index
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestReducedExtensionMethodAsInstance()
{
var text = @"
class C1 { }
class C2 {
public static TSource M<TSource>(this C1 source, int index) {} }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
{
var type = global.GetTypeMember("C1");
var method = (MethodSymbol)global.GetTypeMember("C2").GetMember("M");
return method.ReduceExtensionMethod(type, null!);
};
var format = new SymbolDisplayFormat(
extensionMethodStyle: SymbolDisplayExtensionMethodStyle.InstanceMethod,
genericsOptions:
SymbolDisplayGenericsOptions.IncludeTypeParameters |
SymbolDisplayGenericsOptions.IncludeVariance,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeExtensionThis |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"public TSource C1.M<TSource>(int index)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, //C1
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ExtensionMethodName, //M
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //index
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestReducedExtensionMethodAsDefault()
{
var text = @"
class C1 { }
class C2 {
public static TSource M<TSource>(this C1 source, int index) {} }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
{
var type = global.GetTypeMember("C1");
var method = (MethodSymbol)global.GetTypeMember("C2").GetMember("M");
return method.ReduceExtensionMethod(type, null!);
};
var format = new SymbolDisplayFormat(
extensionMethodStyle: SymbolDisplayExtensionMethodStyle.Default,
genericsOptions:
SymbolDisplayGenericsOptions.IncludeTypeParameters |
SymbolDisplayGenericsOptions.IncludeVariance,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeExtensionThis |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"public TSource C1.M<TSource>(int index)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, //C1
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ExtensionMethodName, //M
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName, //TSource
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //index
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestPrivateProtected()
{
var text = @"class C2 { private protected void M() {} }";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C2").Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType);
TestSymbolDescription(
text,
findSymbol,
format,
"private protected void C2.M()",
SymbolDisplayPartKind.Keyword, // private
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // protected
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // void
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, //C2
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName, //M
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestNullParameters()
{
var text = @"
class A {
int[][,][,,] f; }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("A", 0).Single().
GetMembers("f").Single();
SymbolDisplayFormat format = null;
TestSymbolDescription(
text,
findSymbol,
format,
"A.f",
SymbolDisplayPartKind.ClassName, //A
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.FieldName); //f
}
[Fact]
public void TestArrayRank()
{
var text = @"
class A {
int[][,][,,] f; }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("A", 0).Single().
GetMembers("f").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"int[][,][,,] f",
SymbolDisplayPartKind.Keyword, //int
SymbolDisplayPartKind.Punctuation, //[
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation, //[
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation, //[
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName); //f
}
[Fact]
public void TestOptionalParameters_Bool()
{
var text = @"
using System.Runtime.InteropServices;
class C
{
void F([Optional]bool arg) { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("F").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"void F(bool arg)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, // F
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // arg
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestOptionalParameters_String()
{
var text = @"
class C
{
void F(string s = ""f\t\r\noo"") { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("F").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
@"void F(string s = ""f\t\r\noo"")",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, // F
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // s
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, // =
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StringLiteral,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestOptionalParameters_ReferenceType()
{
var text = @"
using System.Runtime.InteropServices;
class C
{
void F([Optional]C arg) { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("F").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"void F(C arg)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, // F
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // arg
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestOptionalParameters_Constrained_Class()
{
var text = @"
using System.Runtime.InteropServices;
class C
{
void F<T>([Optional]T arg) where T : class { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("F").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"void F(T arg)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, // F
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // arg
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestOptionalParameters_Constrained_Struct()
{
var text = @"
using System.Runtime.InteropServices;
class C
{
void F<T>([Optional]T arg) where T : struct { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("F").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"void F(T arg)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, // F
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // arg
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestOptionalParameters_Unconstrained()
{
var text = @"
using System.Runtime.InteropServices;
class C
{
void F<T>([Optional]T arg) { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("F").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"void F(T arg)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, // F
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // arg
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestOptionalParameters_ArrayAndType()
{
var text = @"
using System.Runtime.InteropServices;
class C
{
void F<T>(int a, [Optional]double[] arg, int b, [Optional]System.Type t) { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("F").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"void F(int a, double[] arg, int b, Type t)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, // F
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword, // int
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // a
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // double
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // arg
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // int
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // b
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, // Type
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // t
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestEscapeKeywordIdentifiers()
{
var text = @"
class @true {
@true @false(@true @true, bool @bool = true) { return @true; } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("true", 0).Single().
GetMembers("false").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"@true @false(@true @true, bool @bool = true)",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, //@false
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //@true
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //@bool
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestEscapeRecordKeywordIdentifiers_EscapesTypeNames()
{
var text = @"
class @record {
@record @struct(@record @true, string name, bool @bool = true) { return @record; } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("record", 0).Single().
GetMembers("struct").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"@record @struct(@record @true, string name, bool @bool = true)",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, //@struct
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //@record
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //string
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //@bool
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestEscapeRecordKeywordIdentifiers_DoesNotEscapesMethodNames()
{
var text = @"
class C {
C record() { return default; } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("record").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"C record()",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, //record
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74117")]
public void TestRecordStructName()
{
var text = @"
public record struct @decimal {
void M(@decimal p1) { return; } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("decimal", 0).Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"void M(@decimal p1)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, //M
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.RecordStructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //p1
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestNoEscapeKeywordIdentifiers()
{
var text = @"
class @true {
@true @false(@true @true, bool @bool = true) { return @true; } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("true", 0).Single().
GetMembers("false").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"true false(true true, bool bool = true)",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, // @false
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // @true
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // @bool
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestExplicitMethodImplNameOnly()
{
var text = @"
interface I {
void M(); }
class C : I {
void I.M() { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("I.M").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.None);
TestSymbolDescription(
text,
findSymbol,
format,
"M",
SymbolDisplayPartKind.MethodName); //M
}
[Fact]
public void TestExplicitMethodImplNameAndInterface()
{
var text = @"
interface I {
void M(); }
class C : I {
void I.M() { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("I.M").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeExplicitInterface);
TestSymbolDescription(
text,
findSymbol,
format,
"I.M",
SymbolDisplayPartKind.InterfaceName, //I
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName); //M
}
[Fact]
public void TestExplicitMethodImplNameAndInterfaceAndType()
{
var text = @"
interface I {
void M(); }
class C : I {
void I.M() { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("I.M").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeExplicitInterface | SymbolDisplayMemberOptions.IncludeContainingType);
TestSymbolDescription(
text,
findSymbol,
format,
"C.I.M",
SymbolDisplayPartKind.ClassName, //C
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.InterfaceName, //I
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName); //M
}
[Fact]
public void TestGlobalNamespaceCode()
{
var text = @"
class C { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single();
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included);
TestSymbolDescription(
text,
findSymbol,
format,
"global::C",
SymbolDisplayPartKind.Keyword, //global
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName); //C
}
[Fact]
public void TestGlobalNamespaceHumanReadable()
{
var text = @"
class C { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global;
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included);
TestSymbolDescription(
text,
findSymbol,
format,
"<global namespace>",
SymbolDisplayPartKind.Text);
}
[Fact]
public void TestSpecialTypes()
{
var text = @"
class C {
int f; }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("f").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"int f",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
}
[Fact]
public void TestArrayAsterisks()
{
var text = @"
class C {
int[][,][,,] f; }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("f").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseAsterisksInMultiDimensionalArrays);
TestSymbolDescription(
text,
findSymbol,
format,
"Int32[][*,*][*,*,*] f",
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
}
[Fact]
public void TestMetadataMethodNames()
{
var text = @"
class C {
C() { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers(".ctor").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.UseMetadataMethodNames);
TestSymbolDescription(
text,
findSymbol,
format,
".ctor",
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void TestArityForGenericTypes()
{
var text = @"
class C<T, U, V> { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 3).Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.UseArityForGenericTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"C`3",
SymbolDisplayPartKind.ClassName,
InternalSymbolDisplayPartKind.Arity);
}
[Fact]
public void TestNestedType1()
{
var text = @"
class C
{
class D
{
}
}
";
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType,
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.UseArityForGenericTypes | SymbolDisplayCompilerInternalOptions.UsePlusForNestedTypes);
TestSymbolDescription(
text,
global => global.GetTypeMembers("C").Single().GetTypeMember("D"),
format,
"C+D",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void TestNestedType2()
{
var text = @"
class C
{
class D<T>
{
}
}
";
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType,
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.UseArityForGenericTypes | SymbolDisplayCompilerInternalOptions.UsePlusForNestedTypes);
TestSymbolDescription(
text,
global => global.GetTypeMembers("C").Single().GetTypeMember("D"),
format,
"C+D`1",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName,
InternalSymbolDisplayPartKind.Arity);
}
[Fact]
public void TestNestedType3()
{
var text = @"
class C<T>
{
class D
{
}
}
";
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType,
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.UseArityForGenericTypes | SymbolDisplayCompilerInternalOptions.UsePlusForNestedTypes);
TestSymbolDescription(
text,
global => global.GetTypeMembers("C").Single().GetTypeMember("D"),
format,
"C`1+D",
SymbolDisplayPartKind.ClassName,
InternalSymbolDisplayPartKind.Arity,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void TestNestedType4()
{
var text = @"
class C<T>
{
class D<U, V>
{
}
}
";
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType,
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.UseArityForGenericTypes | SymbolDisplayCompilerInternalOptions.UsePlusForNestedTypes);
TestSymbolDescription(
text,
global => global.GetTypeMembers("C").Single().GetTypeMember("D"),
format,
"C`1+D`2",
SymbolDisplayPartKind.ClassName,
InternalSymbolDisplayPartKind.Arity,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName,
InternalSymbolDisplayPartKind.Arity);
}
[Fact]
public void TestGenericTypeParameters()
{
var text = @"
class C<in T, out U, V> { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 3).Single();
var format = new SymbolDisplayFormat(
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters);
TestSymbolDescription(
text,
findSymbol,
format,
"C<T, U, V>",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestGenericTypeParametersAndVariance()
{
var text = @"
class C<in T, out U, V> { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 3).Single();
var format = new SymbolDisplayFormat(
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeVariance);
TestSymbolDescription(
text,
findSymbol,
format,
"C<in T, out U, V>",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestGenericTypeConstraints()
{
var text = @"
class C<T> where T : C<T> { }
";
Func<NamespaceSymbol, Symbol> findType = global =>
global.GetMember<NamedTypeSymbol>("C");
Func<NamespaceSymbol, Symbol> findTypeParameter = global =>
global.GetMember<NamedTypeSymbol>("C").TypeParameters.Single();
var format = new SymbolDisplayFormat(
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeTypeConstraints);
TestSymbolDescription(text, findType,
format,
"C<T> where T : C<T>",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation);
TestSymbolDescription(text, findTypeParameter,
format,
"T",
SymbolDisplayPartKind.TypeParameterName);
}
[Fact]
public void TestGenericMethodParameters()
{
var text = @"
class C {
void M<in T, out U, V>() { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters);
TestSymbolDescription(
text,
findSymbol,
format,
"M<T, U, V>",
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestGenericMethodParametersAndVariance()
{
var text = @"
class C {
void M<in T, out U, V>() { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeVariance);
TestSymbolDescription(
text,
findSymbol,
format,
"M<T, U, V>",
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestGenericMethodConstraints()
{
var text = @"
class C<T>
{
void M<U, V>() where V : class, U, T {}
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetMember<NamedTypeSymbol>("C").GetMember<MethodSymbol>("M");
var format = new SymbolDisplayFormat(
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeTypeConstraints);
TestSymbolDescription(
text,
findSymbol,
format,
"M<U, V> where V : class, U, T",
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName);
}
[Fact]
public void TestMemberMethodNone()
{
var text = @"
class C {
void M(int p) { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.None);
TestSymbolDescription(
text,
findSymbol,
format,
"M",
SymbolDisplayPartKind.MethodName);
}
[Fact]
public void TestMemberMethodAll()
{
var text = @"
class C {
void M(int p) { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType);
TestSymbolDescription(
text,
findSymbol,
format,
"private void C.M()",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestMemberFieldNone()
{
var text = @"
class C {
int f; }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("f").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.None);
TestSymbolDescription(
text,
findSymbol,
format,
"f",
SymbolDisplayPartKind.FieldName);
}
[Fact]
public void TestMemberFieldAll()
{
var text =
@"class C {
int f;
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("f").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType);
TestSymbolDescription(
text,
findSymbol,
format,
"private Int32 C.f",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.FieldName);
}
[Fact]
public void TestMemberPropertyNone()
{
var text = @"
class C {
int P { get; } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("P").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.None);
TestSymbolDescription(
text,
findSymbol,
format,
"P",
SymbolDisplayPartKind.PropertyName);
}
[Fact]
public void TestMemberPropertyAll()
{
var text = @"
class C {
int P { get; } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("P").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType);
TestSymbolDescription(
text,
findSymbol,
format,
"private Int32 C.P",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName);
}
[Fact]
public void TestMemberPropertyGetSet()
{
var text = @"
class C
{
int P { get; }
object Q { set; }
object R { get { return null; } set { } }
}
";
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType,
propertyStyle: SymbolDisplayPropertyStyle.ShowReadWriteDescriptor);
TestSymbolDescription(
text,
global => global.GetTypeMembers("C", 0).Single().GetMembers("P").Single(),
format,
"Int32 P { get; }",
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
TestSymbolDescription(
text,
global => global.GetTypeMembers("C", 0).Single().GetMembers("Q").Single(),
format,
"Object Q { set; }",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
TestSymbolDescription(
text,
global => global.GetTypeMembers("C", 0).Single().GetMembers("R").Single(),
format,
"Object R { get; set; }",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestPropertyGetAccessor()
{
var text = @"
class C {
int P { get; set; } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("get_P").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType);
TestSymbolDescription(
text,
findSymbol,
format,
"private Int32 C.P.get",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
}
[Fact]
public void TestPropertySetAccessor()
{
var text = @"
class C {
int P { get; set; } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("set_P").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType);
TestSymbolDescription(
text,
findSymbol,
format,
"private void C.P.set",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
}
[Fact]
public void TestMemberEventAll()
{
var text = @"
class C {
event System.Action E;
event System.Action F { add { } remove { } } }
";
Func<NamespaceSymbol, Symbol> findSymbol1 = global =>
global.GetMember<NamedTypeSymbol>("C").
GetMembers("E").Where(m => m.Kind == SymbolKind.Event).Single();
Func<NamespaceSymbol, Symbol> findSymbol2 = global =>
global.GetMember<NamedTypeSymbol>("C").
GetMember<EventSymbol>("F");
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType);
TestSymbolDescription(
text,
findSymbol1,
format,
"private Action C.E",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName);
TestSymbolDescription(
text,
findSymbol2,
format,
"private Action C.F",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName);
}
[Fact]
public void TestMemberEventAddRemove()
{
var text = @"
class C {
event System.Action E;
event System.Action F { add { } remove { } } }
";
Func<NamespaceSymbol, Symbol> findSymbol1 = global =>
global.GetMember<NamedTypeSymbol>("C").
GetMembers("E").Where(m => m.Kind == SymbolKind.Event).Single();
Func<NamespaceSymbol, Symbol> findSymbol2 = global =>
global.GetMember<NamedTypeSymbol>("C").
GetMember<EventSymbol>("F");
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType,
propertyStyle: SymbolDisplayPropertyStyle.ShowReadWriteDescriptor); // Does not affect events (did before rename).
TestSymbolDescription(
text,
findSymbol1,
format,
"Action E",
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EventName);
TestSymbolDescription(
text,
findSymbol2,
format,
"Action F",
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EventName);
}
[Fact]
public void TestEventAddAccessor()
{
var text = @"
class C {
event System.Action E { add { } remove { } } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetMember<NamedTypeSymbol>("C").
GetMembers("add_E").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType);
TestSymbolDescription(
text,
findSymbol,
format,
"private void C.E.add",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
}
[Fact]
public void TestEventRemoveAccessor()
{
var text = @"
class C {
event System.Action E { add { } remove { } } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetMember<NamedTypeSymbol>("C").
GetMembers("remove_E").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType);
TestSymbolDescription(
text,
findSymbol,
format,
"private void C.E.remove",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
}
[Fact]
public void TestParameterMethodNone()
{
var text = @"
static class C {
static void M(this object obj, ref short s, int i = 1) { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.None);
TestSymbolDescription(
text,
findSymbol,
format,
"M()",
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestMethodReturnType1()
{
var text = @"
static class C {
static int M() { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType);
TestSymbolDescription(
text,
findSymbol,
format,
"System.Int32 M()",
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestMethodReturnType2()
{
var text = @"
static class C {
static void M() { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType);
TestSymbolDescription(
text,
findSymbol,
format,
"void M()",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestParameterMethodNameTypeModifiers()
{
var text = @"
class C {
void M(ref short s, int i, params string[] args) { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions:
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeName);
TestSymbolDescription(
text,
findSymbol,
format,
"M(ref Int16 s, Int32 i, params String[] args)",
SymbolDisplayPartKind.MethodName, //M
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //s
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //i
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
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()]
public void TestParameterMethodNameAll()
{
var text = @"
static class C {
static void M(this object self, ref short s, int i = 1, params string[] args) { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions:
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeExtensionThis |
SymbolDisplayParameterOptions.IncludeDefaultValue);
TestSymbolDescription(
text,
findSymbol,
format,
"M(this Object self, ref Int16 s, Int32 i = 1, params String[] args)",
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //self
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //s
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //i
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NumericLiteral,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //args
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestOptionalParameterBrackets()
{
var text = @"
class C {
void M(int i = 0) { } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions:
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeOptionalBrackets);
TestSymbolDescription(
text,
findSymbol,
format,
"M([Int32 i])",
SymbolDisplayPartKind.MethodName, //M
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, //i
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
}
/// <summary>
/// "public" and "abstract" should not be included for interface members.
/// </summary>
[Fact]
public void TestInterfaceMembers()
{
var text = @"
interface I
{
int P { get; }
object F();
}
abstract class C
{
public abstract object F();
interface I
{
void M();
}
}";
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType,
propertyStyle: SymbolDisplayPropertyStyle.ShowReadWriteDescriptor,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
global => global.GetTypeMembers("I", 0).Single().GetMembers("P").Single(),
format,
"int P { get; }");
TestSymbolDescription(
text,
global => global.GetTypeMembers("I", 0).Single().GetMembers("F").Single(),
format,
"object F()");
TestSymbolDescription(
text,
global => global.GetTypeMembers("C", 0).Single().GetMembers("F").Single(),
format,
"public abstract object F()");
TestSymbolDescription(
text,
global => global.GetTypeMembers("C", 0).Single().GetTypeMembers("I", 0).Single().GetMembers("M").Single(),
format,
"void M()");
}
[WorkItem(537447, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537447")]
[Fact]
public void TestBug2239()
{
var text = @"
public class GC1<T> {}
public class X : GC1<BOGUS> {}
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("X", 0).Single().
BaseType();
var format = new SymbolDisplayFormat(
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters);
TestSymbolDescription(
text,
findSymbol,
format,
"GC1<BOGUS>",
SymbolDisplayPartKind.ClassName, //GC1
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ErrorTypeName, //BOGUS
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestAlias1()
{
var text = @"
using Goo = N1.N2.N3;
namespace N1 {
namespace N2.N3 {
class C1 {
class C2 {} } } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetNestedNamespace("N1").
GetNestedNamespace("N2").
GetNestedNamespace("N3").
GetTypeMembers("C1").Single().
GetTypeMembers("C2").Single();
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers);
TestSymbolDescription(
text,
findSymbol,
format,
"Goo.C1.C2",
text.IndexOf("namespace", StringComparison.Ordinal),
true,
SymbolDisplayPartKind.AliasName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void TestAliases_AliasesNamedRecordAreEscaped()
{
var text = @"
using @record = N1;
namespace N1 {
class C1 {} }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetNestedNamespace("N1").
GetTypeMembers("C1").Single();
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers);
TestSymbolDescription(
text,
findSymbol,
format,
"@record.C1",
text.IndexOf("namespace", StringComparison.Ordinal),
true,
SymbolDisplayPartKind.AliasName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void TestAlias2()
{
var text = @"
using Goo = N1.N2.N3.C1;
namespace N1 {
namespace N2.N3 {
class C1 {
class C2 {} } } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetNestedNamespace("N1").
GetNestedNamespace("N2").
GetNestedNamespace("N3").
GetTypeMembers("C1").Single().
GetTypeMembers("C2").Single();
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces);
TestSymbolDescription(
text,
findSymbol,
format,
"Goo.C2",
text.IndexOf("namespace", StringComparison.Ordinal),
true,
SymbolDisplayPartKind.AliasName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Theory, MemberData(nameof(FileScopedOrBracedNamespace))]
public void TestAlias3(string ob, string cb)
{
var text = @"
using Goo = N1.C1;
namespace N1 " + ob + @"
class Goo { }
class C1 { }
" + cb + @"
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetNestedNamespace("N1").
GetTypeMembers("C1").Single();
var format = SymbolDisplayFormat.MinimallyQualifiedFormat;
TestSymbolDescription(
text,
findSymbol,
format,
"C1",
text.IndexOf("class Goo", StringComparison.Ordinal),
true,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void TestMinimalNamespace1()
{
var text = @"
namespace N1 {
namespace N2 {
namespace N3 {
class C1 {
class C2 {} } } } }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetNestedNamespace("N1").
GetNestedNamespace("N2").
GetNestedNamespace("N3");
var format = new SymbolDisplayFormat();
TestSymbolDescription(text, findSymbol, format,
"N1.N2.N3",
text.IndexOf("N1", StringComparison.Ordinal),
true,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.NamespaceName);
TestSymbolDescription(text, findSymbol, format,
"N2.N3",
text.IndexOf("N2", StringComparison.Ordinal),
true,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.NamespaceName);
TestSymbolDescription(text, findSymbol, format,
"N3",
text.IndexOf("N3", StringComparison.Ordinal),
true,
SymbolDisplayPartKind.NamespaceName);
TestSymbolDescription(text, findSymbol, format,
"N3",
text.IndexOf("C1", StringComparison.Ordinal),
true,
SymbolDisplayPartKind.NamespaceName);
TestSymbolDescription(text, findSymbol, format,
"N3",
text.IndexOf("C2", StringComparison.Ordinal),
true,
SymbolDisplayPartKind.NamespaceName);
}
public class ScriptGlobals
{
public void Method(int p) { Event.Invoke(); }
public delegate void MyDelegate(int x);
public int Field;
public int Property => 1;
public event Action Event;
public class NestedType
{
public void Method(int p) { Event.Invoke(); }
public delegate void MyDelegate(int x);
public int Field;
public int Property => 1;
public event Action Event;
}
}
[Fact]
public void TestMembersInScriptGlobals()
{
var text = @"1";
var tree = SyntaxFactory.ParseSyntaxTree(text, TestOptions.Script);
var hostReference = MetadataReference.CreateFromFile(typeof(ScriptGlobals).Assembly.Location);
var comp = CSharpCompilation.CreateScriptCompilation(
"submission1",
tree,
TargetFrameworkUtil.GetReferences(TargetFramework.Standard).Concat(hostReference),
returnType: typeof(object),
globalsType: typeof(ScriptGlobals));
var model = comp.GetSemanticModel(tree);
var hostTypeSymbol = comp.GetHostObjectTypeSymbol();
var methodSymbol = hostTypeSymbol.GetMember("Method");
var delegateSymbol = hostTypeSymbol.GetMember("MyDelegate");
var fieldSymbol = hostTypeSymbol.GetMember("Field");
var propertySymbol = hostTypeSymbol.GetMember("Property");
var eventSymbol = hostTypeSymbol.GetMember("Event");
var nestedTypeSymbol = (TypeSymbol)hostTypeSymbol.GetMember("NestedType");
var nestedMethodSymbol = nestedTypeSymbol.GetMember("Method");
var nestedDelegateSymbol = nestedTypeSymbol.GetMember("MyDelegate");
var nestedFieldSymbol = nestedTypeSymbol.GetMember("Field");
var nestedPropertySymbol = nestedTypeSymbol.GetMember("Property");
var nestedEventSymbol = nestedTypeSymbol.GetMember("Event");
Verify(methodSymbol.ToMinimalDisplayParts(model, position: 0, s_memberSignatureDisplayFormat),
"void Method(int p)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(delegateSymbol.ToMinimalDisplayParts(model, position: 0, s_memberSignatureDisplayFormat),
"MyDelegate(int x)",
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(fieldSymbol.ToMinimalDisplayParts(model, position: 0, s_memberSignatureDisplayFormat),
"int Field",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
Verify(propertySymbol.ToMinimalDisplayParts(model, position: 0, s_memberSignatureDisplayFormat),
"int Property { get; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
Verify(eventSymbol.ToMinimalDisplayParts(model, position: 0, s_memberSignatureDisplayFormat),
"event System.Action Event",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EventName);
Verify(nestedTypeSymbol.ToMinimalDisplayParts(model, position: 0, s_memberSignatureDisplayFormat),
"NestedType",
SymbolDisplayPartKind.ClassName);
Verify(nestedMethodSymbol.ToMinimalDisplayParts(model, position: 0, s_memberSignatureDisplayFormat),
"void NestedType.Method(int p)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(nestedDelegateSymbol.ToMinimalDisplayParts(model, position: 0, s_memberSignatureDisplayFormat),
"NestedType.MyDelegate(int x)",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(nestedFieldSymbol.ToMinimalDisplayParts(model, position: 0, s_memberSignatureDisplayFormat),
"int NestedType.Field",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.FieldName);
Verify(nestedPropertySymbol.ToMinimalDisplayParts(model, position: 0, s_memberSignatureDisplayFormat),
"int NestedType.Property { get; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
Verify(nestedEventSymbol.ToMinimalDisplayParts(model, position: 0, s_memberSignatureDisplayFormat),
"event System.Action NestedType.Event",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName);
}
private static readonly SymbolDisplayFormat s_memberSignatureDisplayFormat =
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Omitted,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeTypeConstraints,
memberOptions:
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeRef |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeContainingType,
delegateStyle:
SymbolDisplayDelegateStyle.NameAndSignature,
kindOptions:
SymbolDisplayKindOptions.IncludeMemberKeyword,
propertyStyle:
SymbolDisplayPropertyStyle.ShowReadWriteDescriptor,
parameterOptions:
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeExtensionThis |
SymbolDisplayParameterOptions.IncludeDefaultValue |
SymbolDisplayParameterOptions.IncludeOptionalBrackets,
localOptions:
SymbolDisplayLocalOptions.IncludeRef |
SymbolDisplayLocalOptions.IncludeType,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes |
SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName |
SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier |
SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral);
[Fact]
public void TestRemoveAttributeSuffix1()
{
var text = @"
class class1Attribute : System.Attribute { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("class1Attribute").Single();
TestSymbolDescription(text, findSymbol,
new SymbolDisplayFormat(),
"class1Attribute",
SymbolDisplayPartKind.ClassName);
TestSymbolDescription(text, findSymbol,
new SymbolDisplayFormat(miscellaneousOptions: SymbolDisplayMiscellaneousOptions.RemoveAttributeSuffix),
"class1",
0,
true,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void TestRemoveAttributeSuffix2()
{
var text = @"
class classAttribute : System.Attribute { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("classAttribute").Single();
TestSymbolDescription(text, findSymbol,
new SymbolDisplayFormat(),
"classAttribute",
SymbolDisplayPartKind.ClassName);
TestSymbolDescription(text, findSymbol,
new SymbolDisplayFormat(miscellaneousOptions: SymbolDisplayMiscellaneousOptions.RemoveAttributeSuffix),
"classAttribute",
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void TestRemoveAttributeSuffix3()
{
var text = @"
class class1Attribute { }
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("class1Attribute").Single();
TestSymbolDescription(text, findSymbol,
new SymbolDisplayFormat(),
"class1Attribute",
SymbolDisplayPartKind.ClassName);
TestSymbolDescription(text, findSymbol,
new SymbolDisplayFormat(miscellaneousOptions: SymbolDisplayMiscellaneousOptions.RemoveAttributeSuffix),
"class1Attribute",
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void TestMinimalClass1()
{
var text = @"
using System.Collections.Generic;
class C1 {
private System.Collections.Generic.IDictionary<System.Collections.Generic.IList<System.Int32>, System.String> goo;
}
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
((FieldSymbol)global.GetTypeMembers("C1").Single().GetMembers("goo").Single()).Type;
var format = SymbolDisplayFormat.MinimallyQualifiedFormat;
TestSymbolDescription(text, findSymbol, format,
"IDictionary<IList<int>, string>",
text.IndexOf("goo", StringComparison.Ordinal),
true,
SymbolDisplayPartKind.InterfaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.InterfaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestMethodCustomModifierPositions()
{
var assemblies = MetadataTestHelpers.GetSymbolsForReferences(new[]
{
TestReferences.SymbolsTests.CustomModifiers.Modifiers.dll,
Net40.References.mscorlib
});
var globalNamespace = assemblies[0].GlobalNamespace;
var @class = globalNamespace.GetMember<NamedTypeSymbol>("MethodCustomModifierCombinations");
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeCustomModifiers);
Verify(@class.GetMember<MethodSymbol>("Method1111").ToDisplayParts(format),
"int modopt(IsConst) [] modopt(IsConst) Method1111(int modopt(IsConst) [] modopt(IsConst) a)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(@class.GetMember<MethodSymbol>("Method1000").ToDisplayParts(format),
"int modopt(IsConst) [] Method1000(int[] a)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(@class.GetMember<MethodSymbol>("Method0100").ToDisplayParts(format),
"int[] modopt(IsConst) Method0100(int[] a)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(@class.GetMember<MethodSymbol>("Method0010").ToDisplayParts(format),
"int[] Method0010(int modopt(IsConst) [] a)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(@class.GetMember<MethodSymbol>("Method0001").ToDisplayParts(format),
"int[] Method0001(int[] modopt(IsConst) a)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(@class.GetMember<MethodSymbol>("Method0000").ToDisplayParts(format),
"int[] Method0000(int[] a)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestPropertyCustomModifierPositions()
{
var assemblies = MetadataTestHelpers.GetSymbolsForReferences(new[]
{
TestReferences.SymbolsTests.CustomModifiers.Modifiers.dll,
Net40.References.mscorlib
});
var globalNamespace = assemblies[0].GlobalNamespace;
var @class = globalNamespace.GetMember<NamedTypeSymbol>("PropertyCustomModifierCombinations");
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeCustomModifiers);
Verify(@class.GetMember<PropertySymbol>("Property11").ToDisplayParts(format),
"int modopt(IsConst) [] modopt(IsConst) Property11",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.PropertyName);
Verify(@class.GetMember<PropertySymbol>("Property10").ToDisplayParts(format),
"int modopt(IsConst) [] Property10",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.PropertyName);
Verify(@class.GetMember<PropertySymbol>("Property01").ToDisplayParts(format),
"int[] modopt(IsConst) Property01",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.PropertyName);
Verify(@class.GetMember<PropertySymbol>("Property00").ToDisplayParts(format),
"int[] Property00",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.PropertyName);
}
[Fact]
public void TestFieldCustomModifierPositions()
{
var assemblies = MetadataTestHelpers.GetSymbolsForReferences(new[]
{
TestReferences.SymbolsTests.CustomModifiers.Modifiers.dll,
Net40.References.mscorlib
});
var globalNamespace = assemblies[0].GlobalNamespace;
var @class = globalNamespace.GetMember<NamedTypeSymbol>("FieldCustomModifierCombinations");
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeCustomModifiers);
Verify(@class.GetMember<FieldSymbol>("field11").ToDisplayParts(format),
"int modopt(IsConst) [] modopt(IsConst) field11",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
Verify(@class.GetMember<FieldSymbol>("field10").ToDisplayParts(format),
"int modopt(IsConst) [] field10",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
Verify(@class.GetMember<FieldSymbol>("field01").ToDisplayParts(format),
"int[] modopt(IsConst) field01",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
Verify(@class.GetMember<FieldSymbol>("field00").ToDisplayParts(format),
"int[] field00",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
}
[Fact]
public void TestMultipleCustomModifier()
{
var assemblies = MetadataTestHelpers.GetSymbolsForReferences(new[]
{
TestReferences.SymbolsTests.CustomModifiers.Modifiers.dll,
Net40.References.mscorlib
});
var globalNamespace = assemblies[0].GlobalNamespace;
var @class = globalNamespace.GetMember<NamedTypeSymbol>("Modifiers");
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeCustomModifiers);
Verify(@class.GetMember<MethodSymbol>("F3").ToDisplayParts(format),
"void F3(int modopt(int) modopt(IsConst) modopt(IsConst) p)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
InternalSymbolDisplayPartKind.Other, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName, SymbolDisplayPartKind.Punctuation, //modopt
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
}
private static void TestSymbolDescription(
string source,
Func<NamespaceSymbol, Symbol> findSymbol,
SymbolDisplayFormat format,
string expectedText,
int position,
bool minimal,
params SymbolDisplayPartKind[] expectedKinds)
{
var comp = CreateCompilation(source);
var tree = comp.SyntaxTrees.First();
var model = comp.GetSemanticModel(tree);
var global = comp.GlobalNamespace;
var symbol = findSymbol(global);
var description = minimal
? symbol.ToMinimalDisplayParts(model, position, format)
: symbol.ToDisplayParts(format);
Verify(description, expectedText, expectedKinds);
}
private static void TestSymbolDescription(
string source,
Func<NamespaceSymbol, Symbol> findSymbol,
SymbolDisplayFormat format,
string expectedText,
params SymbolDisplayPartKind[] expectedKinds)
{
TestSymbolDescription(source, findSymbol, format, null, expectedText, expectedKinds);
}
private static void TestSymbolDescription(
string source,
Func<NamespaceSymbol, Symbol> findSymbol,
SymbolDisplayFormat format,
CSharpParseOptions parseOptions,
string expectedText,
params SymbolDisplayPartKind[] expectedKinds)
{
var comp = CreateCompilation(source, parseOptions: parseOptions);
var global = comp.GlobalNamespace;
var symbol = findSymbol(global);
var description = symbol.ToDisplayParts(format);
Verify(description, expectedText, expectedKinds);
}
private static void Verify(ImmutableArray<SymbolDisplayPart> actualParts, string expectedText, params SymbolDisplayPartKind[] expectedKinds)
{
AssertEx.Equal(expectedText, actualParts.ToDisplayString());
if (expectedKinds.Length > 0)
{
AssertEx.Equal(expectedKinds, actualParts.Select(p => p.Kind), itemInspector: p => $" SymbolDisplayPartKind.{p}");
}
}
[Fact]
public void DelegateStyleRecursive()
{
var text = "public delegate void D(D param);";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("D", 0).Single();
var format = new SymbolDisplayFormat(globalNamespaceStyle: SymbolDisplayFormat.CSharpErrorMessageFormat.GlobalNamespaceStyle,
typeQualificationStyle: SymbolDisplayFormat.CSharpErrorMessageFormat.TypeQualificationStyle,
genericsOptions: SymbolDisplayFormat.CSharpErrorMessageFormat.GenericsOptions,
memberOptions: SymbolDisplayFormat.CSharpErrorMessageFormat.MemberOptions,
parameterOptions: SymbolDisplayFormat.CSharpErrorMessageFormat.ParameterOptions,
propertyStyle: SymbolDisplayFormat.CSharpErrorMessageFormat.PropertyStyle,
localOptions: SymbolDisplayFormat.CSharpErrorMessageFormat.LocalOptions,
kindOptions: SymbolDisplayKindOptions.IncludeNamespaceKeyword | SymbolDisplayKindOptions.IncludeTypeKeyword,
delegateStyle: SymbolDisplayDelegateStyle.NameAndSignature,
miscellaneousOptions: SymbolDisplayFormat.CSharpErrorMessageFormat.MiscellaneousOptions);
TestSymbolDescription(
text,
findSymbol,
format,
"delegate void D(D)",
SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.DelegateName, SymbolDisplayPartKind.Punctuation);
format = new SymbolDisplayFormat(parameterOptions: SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeType,
delegateStyle: SymbolDisplayDelegateStyle.NameAndSignature,
miscellaneousOptions: SymbolDisplayFormat.CSharpErrorMessageFormat.MiscellaneousOptions);
TestSymbolDescription(
text,
findSymbol,
format,
"void D(D param)",
SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.DelegateName, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.ParameterName, SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void GlobalNamespace1()
{
var text = @"public class Test
{
public class System
{
public class Action
{
}
}
public global::System.Action field;
public System.Action field2;
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
{
var field = global.GetTypeMembers("Test", 0).Single().GetMembers("field").Single() as FieldSymbol;
return field.Type;
};
var format =
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeDefaultValue,
localOptions: SymbolDisplayLocalOptions.IncludeType,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"global::System.Action",
text.IndexOf("global::System.Action", StringComparison.Ordinal),
true /* minimal */,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.DelegateName);
}
[Fact]
public void GlobalNamespace2()
{
var text = @"public class Test
{
public class System
{
public class Action
{
}
}
public global::System.Action field;
public System.Action field2;
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
{
var field = global.GetTypeMembers("Test", 0).Single().GetMembers("field").Single() as FieldSymbol;
return field.Type;
};
var format =
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeDefaultValue,
localOptions: SymbolDisplayLocalOptions.IncludeType,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"System.Action",
text.IndexOf("global::System.Action", StringComparison.Ordinal),
true /* minimal */,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.DelegateName);
}
[Fact]
public void GlobalNamespace3()
{
var text = @"public class Test
{
public class System
{
public class Action
{
}
}
public System.Action field2;
public global::System.Action field;
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
{
var field = global.GetTypeMembers("Test", 0).Single().GetMembers("field2").Single() as FieldSymbol;
return field.Type;
};
var format =
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeDefaultValue,
localOptions: SymbolDisplayLocalOptions.IncludeType,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
"System.Action",
text.IndexOf("System.Action", StringComparison.Ordinal),
true /* minimal */,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void DefaultParameterValues()
{
var text = @"
struct S
{
void M(
int i = 1,
string str = ""hello"",
object o = null
S s = default(S))
{
}
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetMember<NamedTypeSymbol>("S").GetMember<MethodSymbol>("M");
var format =
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeDefaultValue,
localOptions: SymbolDisplayLocalOptions.IncludeType,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(text, findSymbol,
format,
@"void S.M(int i = 1, string str = ""hello"", object o = null, S s = default(S))",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation, //(
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NumericLiteral,
SymbolDisplayPartKind.Punctuation, //,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StringLiteral,
SymbolDisplayPartKind.Punctuation, //,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation, //,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation, //(
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation, //)
SymbolDisplayPartKind.Punctuation); //)
}
[Fact]
public void DefaultParameterValues_TypeParameter()
{
var text = @"
struct S
{
void M<T>(T t = default(T))
{
}
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetMember<NamedTypeSymbol>("S").GetMember<MethodSymbol>("M");
var format =
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeDefaultValue,
localOptions: SymbolDisplayLocalOptions.IncludeType,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(text, findSymbol,
format,
@"void S.M<T>(T t = default(T))",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation, //<
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation, //>
SymbolDisplayPartKind.Punctuation, //(
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation, //(
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation, //)
SymbolDisplayPartKind.Punctuation); //)
}
[Fact]
public void DefaultParameterValues_Enum()
{
var text = @"
enum E
{
A = 1,
B = 2,
C = 5,
}
struct S
{
void P(E e = (E)1)
{
}
void Q(E e = (E)3)
{
}
void R(E e = (E)5)
{
}
}";
Func<NamespaceSymbol, Symbol> findSymbol1 = global =>
global.GetMember<NamedTypeSymbol>("S").GetMember<MethodSymbol>("P");
Func<NamespaceSymbol, Symbol> findSymbol2 = global =>
global.GetMember<NamedTypeSymbol>("S").GetMember<MethodSymbol>("Q");
Func<NamespaceSymbol, Symbol> findSymbol3 = global =>
global.GetMember<NamedTypeSymbol>("S").GetMember<MethodSymbol>("R");
var format =
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeDefaultValue,
localOptions: SymbolDisplayLocalOptions.IncludeType,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(text, findSymbol1,
format,
@"void S.P(E e = E.A)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation, //(
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Punctuation); //)
TestSymbolDescription(text, findSymbol2,
format,
@"void S.Q(E e = (E)3)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation, //(
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //(
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //)
SymbolDisplayPartKind.NumericLiteral,
SymbolDisplayPartKind.Punctuation); //)
TestSymbolDescription(text, findSymbol3,
format,
@"void S.R(E e = E.C)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation, //(
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Punctuation); //)
}
[Fact]
public void DefaultParameterValues_FlagsEnum()
{
var text = @"
[System.FlagsAttribute]
enum E
{
A = 1,
B = 2,
C = 5,
}
struct S
{
void P(E e = (E)1)
{
}
void Q(E e = (E)3)
{
}
void R(E e = (E)5)
{
}
}";
Func<NamespaceSymbol, Symbol> findSymbol1 = global =>
global.GetMember<NamedTypeSymbol>("S").GetMember<MethodSymbol>("P");
Func<NamespaceSymbol, Symbol> findSymbol2 = global =>
global.GetMember<NamedTypeSymbol>("S").GetMember<MethodSymbol>("Q");
Func<NamespaceSymbol, Symbol> findSymbol3 = global =>
global.GetMember<NamedTypeSymbol>("S").GetMember<MethodSymbol>("R");
var format =
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeDefaultValue,
localOptions: SymbolDisplayLocalOptions.IncludeType,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(text, findSymbol1,
format,
@"void S.P(E e = E.A)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation, //(
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Punctuation); //)
TestSymbolDescription(text, findSymbol2,
format,
@"void S.Q(E e = E.A | E.B)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation, //(
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //|
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Punctuation); //)
TestSymbolDescription(text, findSymbol3,
format,
@"void S.R(E e = E.C)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation, //(
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void DefaultParameterValues_NegativeEnum()
{
var text = @"
[System.FlagsAttribute]
enum E : sbyte
{
A = -2,
A1 = -2,
B = 1,
B1 = 1,
C = 0,
C1 = 0,
}
struct S
{
void P(E e = (E)(-2), E f = (E)(-1), E g = (E)0, E h = (E)(-3))
{
}
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetMember<NamedTypeSymbol>("S").GetMember<MethodSymbol>("P");
var format =
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeDefaultValue,
localOptions: SymbolDisplayLocalOptions.IncludeType,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(text, findSymbol,
format,
@"void S.P(E e = E.A, E f = E.A | E.B, E g = E.C, E h = (E)-3)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation, //(
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Punctuation, //,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //|
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Punctuation, //,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Punctuation, //,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, // =
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, // (
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, // )
SymbolDisplayPartKind.NumericLiteral,
SymbolDisplayPartKind.Punctuation); //)
}
[Fact]
public void DefaultParameterValues_NullableEnum()
{
var text = @"
[System.FlagsAttribute]
enum E : sbyte
{
A = -2,
A1 = -2,
B = 1,
B1 = 1,
C = 0,
C1 = 0,
}
struct S
{
void P(E? e = null, E? f = E.A, E? g = E.A | E.B, E?h = 0, E? i = (E)(-3))
{
}
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetMember<NamedTypeSymbol>("S").GetMember<MethodSymbol>("P");
var format =
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType,
parameterOptions:
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeDefaultValue,
localOptions: SymbolDisplayLocalOptions.IncludeType,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(text, findSymbol,
format,
@"void S.P(E? e = null, E? f = E.A, E? g = E.A | E.B, E? h = E.C, E? i = (E)-3)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation, //(
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //?
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation, //,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //?
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Punctuation, //,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //?
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //|
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Punctuation, //,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //?
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, //=
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //.
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Punctuation, //,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, //?
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, // =
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation, // (
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation, // )
SymbolDisplayPartKind.NumericLiteral,
SymbolDisplayPartKind.Punctuation); //)
}
[Fact]
public void TestConstantFieldValue()
{
var text =
@"class C {
const int f = 1;
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("f").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeConstantValue);
TestSymbolDescription(
text,
findSymbol,
format,
"private const Int32 C.f = 1",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ConstantName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NumericLiteral);
}
[Fact]
public void TestConstantFieldValue_EnumMember()
{
var text =
@"
enum E { A, B, C }
class C {
const E f = E.B;
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("f").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeConstantValue);
TestSymbolDescription(
text,
findSymbol,
format,
"private const E C.f = E.B",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ConstantName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EnumMemberName);
}
[Fact]
public void TestConstantFieldValue_EnumMember_Flags()
{
var text =
@"
[System.FlagsAttribute]
enum E { A = 1, B = 2, C = 4, D = A | B | C }
class C {
const E f = E.D;
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C", 0).Single().
GetMembers("f").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeConstantValue);
TestSymbolDescription(
text,
findSymbol,
format,
"private const E C.f = E.D",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ConstantName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EnumMemberName);
}
[Fact]
public void TestEnumMember()
{
var text =
@"enum E { A, B, C }";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("E", 0).Single().
GetMembers("B").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeConstantValue);
TestSymbolDescription(
text,
findSymbol,
format,
"E.B = 1",
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NumericLiteral);
}
[Fact]
public void TestEnumMember_Flags()
{
var text =
@"[System.FlagsAttribute]
enum E { A = 1, B = 2, C = 4, D = A | B | C }";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("E", 0).Single().
GetMembers("D").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeConstantValue);
TestSymbolDescription(
text,
findSymbol,
format,
"E.D = E.A | E.B | E.C",
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EnumMemberName);
}
[Fact]
public void TestEnumMember_FlagsWithoutAttribute()
{
var text =
@"enum E { A = 1, B = 2, C = 4, D = A | B | C }";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("E", 0).Single().
GetMembers("D").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeConstantValue);
TestSymbolDescription(
text,
findSymbol,
format,
"E.D = 7",
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NumericLiteral);
}
[Fact, WorkItem(545462, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545462")]
public void DateTimeDefaultParameterValue()
{
var text = @"
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
class C
{
static void Goo([Optional][DateTimeConstant(100)] DateTime d) { }
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetMember<NamedTypeSymbol>("C").
GetMember<MethodSymbol>("Goo");
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeDefaultValue);
TestSymbolDescription(
text,
findSymbol,
format,
"Goo(DateTime d)",
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
}
[Fact, WorkItem(545681, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545681")]
public void TypeParameterFromMetadata()
{
var src1 = @"
public class LibG<T>
{
}
";
var src2 = @"
public class Gen<V>
{
public void M(LibG<V> p)
{
}
}
";
var complib = CreateCompilation(src1, assemblyName: "Lib");
var compref = new CSharpCompilationReference(complib);
var comp1 = CreateCompilation(src2, references: new MetadataReference[] { compref }, assemblyName: "Comp1");
var mtdata = comp1.EmitToArray();
var mtref = MetadataReference.CreateFromImage(mtdata);
var comp2 = CreateCompilation("", references: new MetadataReference[] { mtref }, assemblyName: "Comp2");
var tsym1 = comp1.SourceModule.GlobalNamespace.GetMember<NamedTypeSymbol>("Gen");
Assert.NotNull(tsym1);
var msym1 = tsym1.GetMember<MethodSymbol>("M");
Assert.NotNull(msym1);
Assert.Equal("Gen<V>.M(LibG<V>)", msym1.ToDisplayString());
var tsym2 = comp2.GlobalNamespace.GetMember<NamedTypeSymbol>("Gen");
Assert.NotNull(tsym2);
var msym2 = tsym2.GetMember<MethodSymbol>("M");
Assert.NotNull(msym2);
Assert.Equal(msym1.ToDisplayString(), msym2.ToDisplayString());
}
[Fact, WorkItem(545625, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545625")]
public void ReverseArrayRankSpecifiers()
{
var text = @"
public class C
{
C[][,] F;
}
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetMember<NamedTypeSymbol>("C").GetMember<FieldSymbol>("F").Type;
var normalFormat = new SymbolDisplayFormat();
var reverseFormat = new SymbolDisplayFormat(
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.ReverseArrayRankSpecifiers);
TestSymbolDescription(
text,
findSymbol,
normalFormat,
"C[][,]",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
TestSymbolDescription(
text,
findSymbol,
reverseFormat,
"C[,][]",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
}
[Fact, WorkItem(546638, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546638")]
public void InvariantCultureNegatives()
{
var text = @"
public class C
{
void M(
sbyte p1 = (sbyte)-1,
short p2 = (short)-1,
int p3 = (int)-1,
long p4 = (long)-1,
float p5 = (float)-0.5,
double p6 = (double)-0.5,
decimal p7 = (decimal)-0.5)
{
}
}
";
var newCulture = (CultureInfo)CultureInfo.CurrentUICulture.Clone();
newCulture.NumberFormat.NegativeSign = "~";
newCulture.NumberFormat.NumberDecimalSeparator = ",";
using (new CultureContext(newCulture))
{
var compilation = CreateCompilation(text);
compilation.VerifyDiagnostics();
var symbol = compilation.GlobalNamespace.GetMember<NamedTypeSymbol>("C").GetMember<MethodSymbol>("M");
Assert.Equal("void C.M(" +
"[System.SByte p1 = -1], " +
"[System.Int16 p2 = -1], " +
"[System.Int32 p3 = -1], " +
"[System.Int64 p4 = -1], " +
"[System.Single p5 = -0.5], " +
"[System.Double p6 = -0.5], " +
"[System.Decimal p7 = -0.5])", symbol.ToTestDisplayString());
}
}
[Fact]
public void TestMethodVB()
{
var text = @"
Class A
Public Sub Goo(a As Integer)
End Sub
End Class";
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeModifiers | SymbolDisplayMemberOptions.IncludeAccessibility | SymbolDisplayMemberOptions.IncludeType,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
var comp = CreateVisualBasicCompilation("c", text);
var a = (ITypeSymbol)comp.GlobalNamespace.GetMembers("A").Single();
var goo = a.GetMembers("Goo").Single();
var parts = Microsoft.CodeAnalysis.CSharp.SymbolDisplay.ToDisplayParts(goo, format);
Verify(
parts,
"public void Goo(int a)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestWindowsRuntimeEvent()
{
var source = @"
class C
{
event System.Action E;
}
";
var format = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes,
memberOptions: SymbolDisplayMemberOptions.IncludeContainingType | SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeExplicitInterface);
var comp = CreateEmptyCompilation(source, WinRtRefs, TestOptions.ReleaseWinMD);
var eventSymbol = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("C").GetMember<EventSymbol>("E");
Assert.True(eventSymbol.IsWindowsRuntimeEvent);
Verify(
eventSymbol.ToDisplayParts(format),
"Action C.E",
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName);
Verify(
eventSymbol.AddMethod.ToDisplayParts(format),
"EventRegistrationToken C.E.add",
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(
eventSymbol.RemoveMethod.ToDisplayParts(format),
"void C.E.remove",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
}
[WorkItem(791756, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/791756")]
[Theory]
[MemberData(nameof(FileScopedOrBracedNamespace))]
public void KindOptions(string ob, string cb)
{
var source = @"
namespace N
" + ob + @"
class C
{
event System.Action E;
}
" + cb + @"
";
var memberFormat = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
memberOptions: SymbolDisplayMemberOptions.IncludeContainingType,
kindOptions: SymbolDisplayKindOptions.IncludeMemberKeyword);
var typeFormat = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeContainingType,
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
kindOptions: SymbolDisplayKindOptions.IncludeTypeKeyword);
var namespaceFormat = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
memberOptions: SymbolDisplayMemberOptions.IncludeContainingType,
kindOptions: SymbolDisplayKindOptions.IncludeNamespaceKeyword);
var comp = CreateCompilation(source);
var namespaceSymbol = comp.GlobalNamespace.GetMember<NamespaceSymbol>("N");
var typeSymbol = namespaceSymbol.GetMember<NamedTypeSymbol>("C");
var eventSymbol = typeSymbol.GetMember<EventSymbol>("E");
Verify(
namespaceSymbol.ToDisplayParts(memberFormat),
"N",
SymbolDisplayPartKind.NamespaceName);
Verify(
namespaceSymbol.ToDisplayParts(typeFormat),
"N",
SymbolDisplayPartKind.NamespaceName);
Verify(
namespaceSymbol.ToDisplayParts(namespaceFormat),
"namespace N",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName);
Verify(
typeSymbol.ToDisplayParts(memberFormat),
"N.C",
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
Verify(
typeSymbol.ToDisplayParts(typeFormat),
"class N.C",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
Verify(
typeSymbol.ToDisplayParts(namespaceFormat),
"N.C",
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
Verify(
eventSymbol.ToDisplayParts(memberFormat),
"event N.C.E",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName);
Verify(
eventSymbol.ToDisplayParts(typeFormat),
"N.C.E",
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName);
Verify(
eventSymbol.ToDisplayParts(namespaceFormat),
"N.C.E",
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName);
}
[WorkItem(765287, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/765287")]
[Fact]
public void TestVbSymbols()
{
var vbComp = CreateVisualBasicCompilation(@"
Class Outer
Class Inner(Of T)
End Class
Sub M(Of U)()
End Sub
WriteOnly Property P() As String
Set(value)
End Set
End Property
Private F As Integer
Event E()
Delegate Sub D()
Function [Error]() As Missing
End Function
End Class
", assemblyName: "VB");
var outer = (INamedTypeSymbol)vbComp.GlobalNamespace.GetMembers("Outer").Single();
var type = outer.GetMembers("Inner").Single();
var method = outer.GetMembers("M").Single();
var property = outer.GetMembers("P").Single();
var field = outer.GetMembers("F").Single();
var @event = outer.GetMembers("E").Single();
var @delegate = outer.GetMembers("D").Single();
var error = outer.GetMembers("Error").Single();
Assert.False(type is Symbol);
Assert.False(method is Symbol);
Assert.False(property is Symbol);
Assert.False(field is Symbol);
Assert.False(@event is Symbol);
Assert.False(@delegate is Symbol);
Assert.False(error is Symbol);
// 1) Looks like C#.
// 2) Doesn't blow up.
Assert.Equal("Outer.Inner<T>", CSharp.SymbolDisplay.ToDisplayString(type, SymbolDisplayFormat.TestFormat));
Assert.Equal("void Outer.M<U>()", CSharp.SymbolDisplay.ToDisplayString(method, SymbolDisplayFormat.TestFormat));
Assert.Equal("System.String Outer.P { set; }", CSharp.SymbolDisplay.ToDisplayString(property, SymbolDisplayFormat.TestFormat));
Assert.Equal("System.Int32 Outer.F", CSharp.SymbolDisplay.ToDisplayString(field, SymbolDisplayFormat.TestFormat));
Assert.Equal("event Outer.EEventHandler Outer.E", CSharp.SymbolDisplay.ToDisplayString(@event, SymbolDisplayFormat.TestFormat));
Assert.Equal("Outer.D", CSharp.SymbolDisplay.ToDisplayString(@delegate, SymbolDisplayFormat.TestFormat));
Assert.Equal("Missing Outer.Error()", CSharp.SymbolDisplay.ToDisplayString(error, SymbolDisplayFormat.TestFormat));
}
[Fact]
public void FormatPrimitive()
{
// basic tests, more cases are covered by ObjectFormatterTests
Assert.Equal("1", SymbolDisplay.FormatPrimitive(1, quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("1", SymbolDisplay.FormatPrimitive((uint)1, quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("1", SymbolDisplay.FormatPrimitive((byte)1, quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("1", SymbolDisplay.FormatPrimitive((sbyte)1, quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("1", SymbolDisplay.FormatPrimitive((short)1, quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("1", SymbolDisplay.FormatPrimitive((ushort)1, quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("1", SymbolDisplay.FormatPrimitive((long)1, quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("1", SymbolDisplay.FormatPrimitive((ulong)1, quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("x", SymbolDisplay.FormatPrimitive('x', quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("true", SymbolDisplay.FormatPrimitive(true, quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("1.5", SymbolDisplay.FormatPrimitive(1.5, quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("1.5", SymbolDisplay.FormatPrimitive((float)1.5, quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("1.5", SymbolDisplay.FormatPrimitive((decimal)1.5, quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("null", SymbolDisplay.FormatPrimitive(null, quoteStrings: false, useHexadecimalNumbers: false));
Assert.Equal("abc", SymbolDisplay.FormatPrimitive("abc", quoteStrings: false, useHexadecimalNumbers: false));
Assert.Null(SymbolDisplay.FormatPrimitive(SymbolDisplayFormat.TestFormat, quoteStrings: false, useHexadecimalNumbers: false));
}
[WorkItem(879984, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/879984")]
[Fact]
public void EnumAmbiguityResolution()
{
var source = @"
using System;
class Program
{
static void M(E1 e1 = (E1)1, E2 e2 = (E2)1)
{
}
}
enum E1
{
B = 1,
A = 1,
}
[Flags]
enum E2 // Identical to E1, but has [Flags]
{
B = 1,
A = 1,
}
";
var comp = CreateCompilation(source);
var method = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("Program").GetMember<MethodSymbol>("M");
var memberFormat = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue);
Assert.Equal("M(e1 = A, e2 = A)", method.ToDisplayString(memberFormat)); // Alphabetically first candidate chosen for both enums.
}
[Fact, WorkItem(1028003, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1028003")]
public void UnconventionalExplicitInterfaceImplementation()
{
var il = @"
.class public auto ansi sealed DTest
extends [mscorlib]System.MulticastDelegate
{
.method public hidebysig specialname rtspecialname
instance void .ctor(object 'object',
native int 'method') runtime managed
{
} // end of method DTest::.ctor
.method public hidebysig newslot virtual
instance void Invoke() runtime managed
{
} // end of method DTest::Invoke
.method public hidebysig newslot virtual
instance class [mscorlib]System.IAsyncResult
BeginInvoke(class [mscorlib]System.AsyncCallback callback,
object 'object') runtime managed
{
} // end of method DTest::BeginInvoke
.method public hidebysig newslot virtual
instance void EndInvoke(class [mscorlib]System.IAsyncResult result) runtime managed
{
} // end of method DTest::EndInvoke
} // end of class DTest
.class interface public abstract auto ansi ITest
{
.method public hidebysig newslot abstract virtual
instance void M1() cil managed
{
} // end of method ITest::M1
.method public hidebysig newslot specialname abstract virtual
instance int32 get_P1() cil managed
{
} // end of method ITest::get_P1
.method public hidebysig newslot specialname abstract virtual
instance void set_P1(int32 'value') cil managed
{
} // end of method ITest::set_P1
.method public hidebysig newslot specialname abstract virtual
instance void add_E1(class DTest 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
} // end of method ITest::add_E1
.method public hidebysig newslot specialname abstract virtual
instance void remove_E1(class DTest 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
} // end of method ITest::remove_E1
.event DTest E1
{
.addon instance void ITest::add_E1(class DTest)
.removeon instance void ITest::remove_E1(class DTest)
} // end of event ITest::E1
.property instance int32 P1()
{
.get instance int32 ITest::get_P1()
.set instance void ITest::set_P1(int32)
} // end of property ITest::P1
} // end of class ITest
.class public auto ansi beforefieldinit CTest
extends [mscorlib]System.Object
implements ITest
{
.method public hidebysig newslot specialname virtual final
instance int32 get_P1() cil managed
{
.override ITest::get_P1
// Code size 7 (0x7)
.maxstack 8
IL_0000: nop
IL_0001: newobj instance void [mscorlib]System.NotImplementedException::.ctor()
IL_0006: throw
} // end of method CTest::ITest.get_P1
.method public hidebysig newslot specialname virtual final
instance void set_P1(int32 'value') cil managed
{
.override ITest::set_P1
// Code size 7 (0x7)
.maxstack 8
IL_0000: nop
IL_0001: newobj instance void [mscorlib]System.NotImplementedException::.ctor()
IL_0006: throw
} // end of method CTest::ITest.set_P1
.method public hidebysig newslot specialname virtual final
instance void add_E1(class DTest 'value') cil managed
{
.override ITest::add_E1
// Code size 7 (0x7)
.maxstack 8
IL_0000: nop
IL_0001: newobj instance void [mscorlib]System.NotImplementedException::.ctor()
IL_0006: throw
} // end of method CTest::ITest.add_E1
.method public hidebysig newslot specialname virtual final
instance void remove_E1(class DTest 'value') cil managed
{
.override ITest::remove_E1
// Code size 7 (0x7)
.maxstack 8
IL_0000: nop
IL_0001: newobj instance void [mscorlib]System.NotImplementedException::.ctor()
IL_0006: throw
} // end of method CTest::ITest.remove_E1
.method public hidebysig newslot virtual final
instance void M1() cil managed
{
.override ITest::M1
// Code size 7 (0x7)
.maxstack 8
IL_0000: nop
IL_0001: newobj instance void [mscorlib]System.NotImplementedException::.ctor()
IL_0006: throw
} // end of method CTest::ITest.M1
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method CTest::.ctor
.event DTest E1
{
.addon instance void CTest::add_E1(class DTest)
.removeon instance void CTest::remove_E1(class DTest)
} // end of event CTest::ITest.E1
.property instance int32 P1()
{
.get instance int32 CTest::get_P1()
.set instance void CTest::set_P1(int32)
} // end of property CTest::ITest.P1
} // end of class CTest
";
var text = @"";
var comp = CreateCompilationWithILAndMscorlib40(text, il);
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeExplicitInterface);
var cTest = comp.GetTypeByMetadataName("CTest");
var m1 = cTest.GetMember("M1");
Assert.Equal("M1", m1.Name);
Assert.Equal("M1", m1.ToDisplayString(format));
var p1 = cTest.GetMember("P1");
Assert.Equal("P1", p1.Name);
Assert.Equal("P1", p1.ToDisplayString(format));
var e1 = cTest.GetMember("E1");
Assert.Equal("E1", e1.Name);
Assert.Equal("E1", e1.ToDisplayString(format));
}
[WorkItem(6262, "https://github.com/dotnet/roslyn/issues/6262")]
[Fact]
public void FormattedSymbolEquality()
{
var source =
@"class A { }
class B { }
class C<T> { }";
var compilation = CreateCompilation(source);
var sA = compilation.GetMember<NamedTypeSymbol>("A");
var sB = compilation.GetMember<NamedTypeSymbol>("B");
var sC = compilation.GetMember<NamedTypeSymbol>("C");
var f1 = new SymbolDisplayFormat();
var f2 = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeParameters);
Assert.False(new FormattedSymbol(sA, f1).Equals((object)sA));
Assert.False(new FormattedSymbol(sA, f1).Equals(null));
Assert.True(new FormattedSymbol(sA, f1).Equals(new FormattedSymbol(sA, f1)));
Assert.False(new FormattedSymbol(sA, f1).Equals(new FormattedSymbol(sA, f2)));
Assert.False(new FormattedSymbol(sA, f1).Equals(new FormattedSymbol(sB, f1)));
Assert.False(new FormattedSymbol(sA, f1).Equals(new FormattedSymbol(sB, f2)));
Assert.False(new FormattedSymbol(sC, f1).Equals(new FormattedSymbol(sC.Construct(sA), f1)));
Assert.True(new FormattedSymbol(sC.Construct(sA), f1).Equals(new FormattedSymbol(sC.Construct(sA), f1)));
Assert.False(new FormattedSymbol(sA, new SymbolDisplayFormat()).Equals(new FormattedSymbol(sA, new SymbolDisplayFormat())));
Assert.True(new FormattedSymbol(sA, f1).GetHashCode().Equals(new FormattedSymbol(sA, f1).GetHashCode()));
}
[Fact, CompilerTrait(CompilerFeature.Tuples)]
public void Tuple()
{
var text = @"
public class C
{
public (int, string) f;
}
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.
GetTypeMembers("C").Single().
GetMembers("f").Single();
var format = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeType);
TestSymbolDescription(
text,
findSymbol,
format,
TestOptions.Regular,
"(Int32, String) f",
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName, // Int32
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, // String
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
}
[Fact, CompilerTrait(CompilerFeature.Tuples)]
public void TupleCollapseTupleTypes()
{
var text = @"
public class C
{
public (int, string) f;
}
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.
GetTypeMembers("C").Single().
GetMembers("f").Single();
var format = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeType, miscellaneousOptions: SymbolDisplayMiscellaneousOptions.CollapseTupleTypes);
var comp = CreateCompilation(text, parseOptions: TestOptions.Regular);
var global = comp.GlobalNamespace;
var symbol = findSymbol(global);
var description = symbol.ToDisplayParts(format);
var firstPart = description[0];
Assert.True(((ITypeSymbol)firstPart.Symbol).IsTupleType);
Assert.Equal(SymbolDisplayPartKind.StructName, firstPart.Kind);
Assert.Equal(SymbolDisplayPartKind.Space, description[1].Kind);
Assert.Equal(SymbolDisplayPartKind.FieldName, description[2].Kind);
}
[WorkItem(18311, "https://github.com/dotnet/roslyn/issues/18311")]
[Fact, CompilerTrait(CompilerFeature.Tuples)]
public void TupleWith1Arity()
{
var text = @"
using System;
public class C
{
public ValueTuple<int> f;
}
" + TestResources.NetFX.ValueTuple.tuplelib_cs;
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.
GetTypeMembers("C").Single().
GetMembers("f").Single();
var format = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeType,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters);
TestSymbolDescription(
text,
findSymbol,
format,
TestOptions.Regular,
"ValueTuple<Int32> f",
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
}
[Fact, CompilerTrait(CompilerFeature.Tuples)]
public void TupleWithNames()
{
var text = @"
public class C
{
public (int x, string y) f;
}
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.
GetTypeMembers("C").Single().
GetMembers("f").Single();
var format = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeType);
TestSymbolDescription(
text,
findSymbol,
format,
TestOptions.Regular,
"(Int32 x, String y) f",
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName, // Int32
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName, // x
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, // String
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName, // y
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
}
[Fact, CompilerTrait(CompilerFeature.Tuples)]
public void LongTupleWithSpecialTypes()
{
var text = @"
public class C
{
public (int, string, bool, byte, long, ulong, short, ushort) f;
}
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.
GetTypeMembers("C").Single().
GetMembers("f").Single();
var format = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeType,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
TestOptions.Regular,
"(int, string, bool, byte, long, ulong, short, ushort) f",
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword, // int
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // string
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // bool
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // byte
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // long
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // ulong
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // short
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // ushort
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
}
[Fact, CompilerTrait(CompilerFeature.Tuples)]
public void TupleProperty()
{
var text = @"
class C
{
(int Item1, string Item2) P { get; set; }
}
";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.
GetTypeMembers("C").Single().
GetMembers("P").Single();
var format = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeType,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
TestSymbolDescription(
text,
findSymbol,
format,
TestOptions.Regular,
"(int Item1, string Item2) P",
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword, // int
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName, // Item1
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // string
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName, // Item2
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.PropertyName);
}
[Fact, CompilerTrait(CompilerFeature.Tuples)]
public void TupleQualifiedNames()
{
var text =
@"using NAB = N.A.B;
namespace N
{
class A
{
internal class B {}
}
class C<T>
{
// offset 1
}
}
class C
{
#pragma warning disable CS0169
(int One, N.C<(object[], NAB Two)>, int, object Four, int, object, int, object, N.A Nine) f;
#pragma warning restore CS0169
// offset 2
}";
var format = new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included,
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
memberOptions: SymbolDisplayMemberOptions.IncludeType,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
var comp = (Compilation)CreateCompilationWithMscorlib46(text, references: new[] { SystemRuntimeFacadeRef, ValueTupleRef });
comp.VerifyDiagnostics();
var symbol = comp.GetMember("C.f");
// Fully qualified format.
Verify(
SymbolDisplay.ToDisplayParts(symbol, format),
"(int One, global::N.C<(object[], global::N.A.B Two)>, int, object Four, int, object, int, object, global::N.A Nine) f");
// Minimally qualified format.
Verify(
SymbolDisplay.ToDisplayParts(symbol, SymbolDisplayFormat.MinimallyQualifiedFormat),
"(int One, C<(object[], B Two)>, int, object Four, int, object, int, object, A Nine) C.f");
// ToMinimalDisplayParts.
var model = comp.GetSemanticModel(comp.SyntaxTrees.First());
Verify(
SymbolDisplay.ToMinimalDisplayParts(symbol, model, text.IndexOf("offset 1"), format),
"(int One, C<(object[], NAB Two)>, int, object Four, int, object, int, object, A Nine) f");
Verify(
SymbolDisplay.ToMinimalDisplayParts(symbol, model, text.IndexOf("offset 2"), format),
"(int One, N.C<(object[], NAB Two)>, int, object Four, int, object, int, object, N.A Nine) f");
}
[Fact]
[WorkItem(23970, "https://github.com/dotnet/roslyn/pull/23970")]
public void ThisDisplayParts()
{
var text =
@"
class A
{
void M(int @this)
{
this.M(@this);
}
}";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics();
var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree);
var invocation = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
Assert.Equal("this.M(@this)", invocation.ToString());
var actualThis = ((MemberAccessExpressionSyntax)invocation.Expression).Expression;
Assert.Equal("this", actualThis.ToString());
Verify(
SymbolDisplay.ToDisplayParts(model.GetSymbolInfo(actualThis).Symbol, SymbolDisplayFormat.MinimallyQualifiedFormat),
"A this",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword);
var escapedThis = invocation.ArgumentList.Arguments[0].Expression;
Assert.Equal("@this", escapedThis.ToString());
Verify(
SymbolDisplay.ToDisplayParts(model.GetSymbolInfo(escapedThis).Symbol, SymbolDisplayFormat.MinimallyQualifiedFormat),
"int @this",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName);
}
[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 = CreateEmptyCompilation(sourceA, new[] { MscorlibRef });
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);
}
[Fact]
[CompilerTrait(CompilerFeature.ReadOnlyReferences)]
public void RefReadonlyReturn()
{
var sourceA =
@"public delegate ref readonly int D();
public class C
{
public ref readonly int F(in int i) => ref i;
int _p;
public ref readonly int P => ref _p;
public ref readonly int this[in int i] => ref _p;
}";
var compA = CreateCompilation(sourceA);
compA.VerifyDiagnostics();
var refA = compA.EmitToImageReference();
// From C# symbols.
RefReadonlyReturnInternal(compA);
var compB = CreateVisualBasicCompilation(GetUniqueName(), "", referencedAssemblies: new[] { MscorlibRef, refA });
compB.VerifyDiagnostics();
// From VB symbols.
//RefReadonlyReturnInternal(compB);
}
[Fact]
[CompilerTrait(CompilerFeature.ReadOnlyReferences)]
public void RefReadonlyReturn1()
{
var sourceA =
@"public delegate ref readonly int D();
public class C
{
public ref readonly int F(in int i) => ref i;
int _p;
public ref readonly int P => ref _p;
public ref readonly int this[in int i] => ref _p;
}";
var compA = CreateCompilation(sourceA);
compA.VerifyDiagnostics();
var refA = compA.EmitToImageReference();
// From C# symbols.
RefReadonlyReturnInternal(compA);
var compB = CreateVisualBasicCompilation(GetUniqueName(), "", referencedAssemblies: new[] { MscorlibRef, refA });
compB.VerifyDiagnostics();
// From VB symbols.
//RefReadonlyReturnInternal(compB);
}
private static void RefReadonlyReturnInternal(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(in 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[in int] { get; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
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 readonly int F(in int)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
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 readonly int P { get; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
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 readonly int this[in int] { get; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
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 readonly int D()",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
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(in 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()
{
var text =
@"using A = N.M;
namespace N.M
{
class B
{
}
}
class C
{
static void M()
{
}
}";
var comp = CreateCompilation(text);
var tree = comp.SyntaxTrees.First();
var model = comp.GetSemanticModel(tree);
var methodDecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().First();
int position = methodDecl.Body.SpanStart;
tree = CSharpSyntaxTree.ParseText(@"
class C
{
static void M()
{
}
}");
methodDecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().First();
Assert.True(model.TryGetSpeculativeSemanticModelForMethodBody(position, methodDecl, out model));
var symbol = comp.GetMember<NamedTypeSymbol>("N.M.B");
position = methodDecl.Body.SpanStart;
var description = symbol.ToMinimalDisplayParts(model, position, SymbolDisplayFormat.MinimallyQualifiedFormat);
Verify(description, "A.B", SymbolDisplayPartKind.AliasName, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.ClassName);
}
[Fact]
public void NullableReferenceTypes()
{
var source = @"
class A<T>
{
}
class B
{
static object F1(object? o) => null!;
static object?[] F2(object[]? o) => null;
static A<object>? F3(A<object?> o) => null;
}";
var comp = (Compilation)CreateCompilation(new[] { source }, parseOptions: TestOptions.Regular8, options: WithNullableEnable());
var formatWithoutNonNullableModifier = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeModifiers,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeParamsRefOut,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
var formatWithNonNullableModifier = formatWithoutNonNullableModifier
.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier | SymbolDisplayMiscellaneousOptions.IncludeNotNullableReferenceTypeModifier)
.WithCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.None);
var method = comp.GetMember<IMethodSymbol>("B.F1");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithoutNonNullableModifier),
"static object F1(object? o)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithNonNullableModifier),
"static object! F1(object? o)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
method = comp.GetMember<IMethodSymbol>("B.F2");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithoutNonNullableModifier),
"static object?[] F2(object[]? o)");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithNonNullableModifier),
"static object?[]! F2(object![]? o)");
method = comp.GetMember<IMethodSymbol>("B.F3");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithoutNonNullableModifier),
"static A<object>? F3(A<object?> o)");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithNonNullableModifier),
"static A<object!>? F3(A<object?>! o)");
}
[Fact]
public void NullableReferenceTypes2()
{
var source =
@"class A<T>
{
}
class B
{
static object F1(object? o) => null!;
static object?[] F2(object[]? o) => null;
static A<object>? F3(A<object?> o) => null;
}";
var comp = (Compilation)CreateCompilation(source, parseOptions: TestOptions.Regular8);
var formatWithoutNullableModifier = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeModifiers,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeParamsRefOut,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
var formatWithNullableModifier = formatWithoutNullableModifier
.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier)
.WithCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.None);
var method = comp.GetMember<IMethodSymbol>("B.F1");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithoutNullableModifier),
"static object F1(object o)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithNullableModifier),
"static object F1(object? o)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
method = comp.GetMember<IMethodSymbol>("B.F2");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithoutNullableModifier),
"static object[] F2(object[] o)");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithNullableModifier),
"static object?[] F2(object[]? o)");
method = comp.GetMember<IMethodSymbol>("B.F3");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithoutNullableModifier),
"static A<object> F3(A<object> o)");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithNullableModifier),
"static A<object>? F3(A<object?> o)");
}
[WorkItem(31700, "https://github.com/dotnet/roslyn/issues/31700")]
[Fact]
public void NullableArrays()
{
var source =
@"#nullable enable
class C
{
static object?[,][] F1;
static object[,]?[] F2;
static object[,][]? F3;
}";
var comp = (Compilation)CreateCompilation(source, parseOptions: TestOptions.Regular8);
var formatWithoutModifiers = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeModifiers,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
var formatWithNullableModifier = formatWithoutModifiers.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
var formatWithBothModifiers = formatWithNullableModifier.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNotNullableReferenceTypeModifier);
var member = comp.GetMember("C.F1");
Verify(
SymbolDisplay.ToDisplayParts(member, formatWithoutModifiers),
"static object[,][] F1",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
Verify(
SymbolDisplay.ToDisplayParts(member, formatWithNullableModifier),
"static object?[,][] F1",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
Verify(
SymbolDisplay.ToDisplayParts(member, formatWithBothModifiers),
"static object?[]![,]! F1",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
member = comp.GetMember("C.F2");
Verify(
SymbolDisplay.ToDisplayParts(member, formatWithoutModifiers),
"static object[][,] F2");
Verify(
SymbolDisplay.ToDisplayParts(member, formatWithNullableModifier),
"static object[,]?[] F2");
Verify(
SymbolDisplay.ToDisplayParts(member, formatWithBothModifiers),
"static object![,]?[]! F2");
member = comp.GetMember("C.F3");
Verify(
SymbolDisplay.ToDisplayParts(member, formatWithoutModifiers),
"static object[,][] F3");
Verify(
SymbolDisplay.ToDisplayParts(member, formatWithNullableModifier),
"static object[,][]? F3");
Verify(
SymbolDisplay.ToDisplayParts(member, formatWithBothModifiers),
"static object![]![,]? F3");
}
[Fact]
public void AllowDefaultLiteral()
{
var source =
@"using System.Threading;
class C
{
void Method(CancellationToken cancellationToken = default(CancellationToken)) => throw null;
}
";
var compilation = (Compilation)CreateCompilation(source);
var formatWithoutAllowDefaultLiteral = SymbolDisplayFormat.MinimallyQualifiedFormat;
Assert.False(formatWithoutAllowDefaultLiteral.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral));
var formatWithAllowDefaultLiteral = formatWithoutAllowDefaultLiteral.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral);
Assert.True(formatWithAllowDefaultLiteral.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral));
var method = compilation.GetMember<IMethodSymbol>("C.Method");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithoutAllowDefaultLiteral),
"void C.Method(CancellationToken cancellationToken = default(CancellationToken))");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithAllowDefaultLiteral),
"void C.Method(CancellationToken cancellationToken = default)");
}
[Fact]
public void TypeParameterAnnotations_01()
{
var source =
@"#nullable enable
class C
{
T F0<T>() => default;
T? F1<T>() => default;
T F2<T>() where T : class => default;
T? F3<T>() where T : class => default;
T F4<T>() where T : class? => default;
T? F5<T>() where T : class? => default;
T F6<T>() where T : struct => default;
T? F7<T>() where T : struct => default;
T F8<T>() where T : notnull => default;
T F9<T>() where T : unmanaged => default;
}";
var comp = (Compilation)CreateCompilation(source, parseOptions: TestOptions.Regular8);
var formatWithoutModifiers = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeTypeConstraints,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
var formatWithNullableModifier = formatWithoutModifiers.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
var formatWithBothModifiers = formatWithNullableModifier.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNotNullableReferenceTypeModifier);
verify("C.F0", "T F0<T>()", "T F0<T>()", "T F0<T>()");
verify("C.F1", "T F1<T>()", "T? F1<T>()", "T? F1<T>()");
verify("C.F2", "T F2<T>() where T : class", "T F2<T>() where T : class", "T! F2<T>() where T : class!");
verify("C.F3", "T F3<T>() where T : class", "T? F3<T>() where T : class", "T? F3<T>() where T : class!");
verify("C.F4", "T F4<T>() where T : class", "T F4<T>() where T : class?", "T F4<T>() where T : class?");
verify("C.F5", "T F5<T>() where T : class", "T? F5<T>() where T : class?", "T? F5<T>() where T : class?");
verify("C.F6", "T F6<T>() where T : struct", "T F6<T>() where T : struct", "T F6<T>() where T : struct");
verify("C.F7", "T? F7<T>() where T : struct", "T? F7<T>() where T : struct", "T? F7<T>() where T : struct");
verify("C.F8", "T F8<T>() where T : notnull", "T F8<T>() where T : notnull", "T F8<T>() where T : notnull");
verify("C.F9", "T F9<T>() where T : unmanaged", "T F9<T>() where T : unmanaged", "T F9<T>() where T : unmanaged");
void verify(string memberName, string withoutModifiers, string withNullableModifier, string withBothModifiers)
{
var member = comp.GetMember(memberName);
Verify(SymbolDisplay.ToDisplayParts(member, formatWithoutModifiers), withoutModifiers);
Verify(SymbolDisplay.ToDisplayParts(member, formatWithNullableModifier), withNullableModifier);
Verify(SymbolDisplay.ToDisplayParts(member, formatWithBothModifiers), withBothModifiers);
}
}
[Fact]
public void TypeParameterAnnotations_02()
{
var source =
@"#nullable enable
interface I<T> { }
class C
{
T? F<T>(T?[] x, I<T?> y) => default;
}";
var comp = (Compilation)CreateCompilation(source, parseOptions: TestOptions.Regular8);
var format = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeTypeConstraints,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
var method = (IMethodSymbol)comp.GetMember("C.F");
Verify(
SymbolDisplay.ToDisplayParts(method, format),
"T? F<T>(T?[] x, I<T?> y)",
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.InterfaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
var type = method.GetSymbol<MethodSymbol>().ReturnTypeWithAnnotations;
Assert.Equal("T?", type.ToDisplayString(format));
}
[Theory]
[InlineData("int", "0")]
[InlineData("string", "null")]
public void AllowDefaultLiteralNotNeeded(string type, string defaultValue)
{
var source =
$@"
class C
{{
void Method1({type} parameter = {defaultValue}) => throw null;
void Method2({type} parameter = default({type})) => throw null;
void Method3({type} parameter = default) => throw null;
}}
";
var compilation = (Compilation)CreateCompilation(source);
var formatWithoutAllowDefaultLiteral = SymbolDisplayFormat.MinimallyQualifiedFormat;
Assert.False(formatWithoutAllowDefaultLiteral.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral));
var formatWithAllowDefaultLiteral = formatWithoutAllowDefaultLiteral.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral);
Assert.True(formatWithAllowDefaultLiteral.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral));
var method1 = compilation.GetMember<IMethodSymbol>("C.Method1");
Verify(
SymbolDisplay.ToDisplayParts(method1, formatWithoutAllowDefaultLiteral),
$"void C.Method1({type} parameter = {defaultValue})");
Verify(
SymbolDisplay.ToDisplayParts(method1, formatWithAllowDefaultLiteral),
$"void C.Method1({type} parameter = {defaultValue})");
var method2 = compilation.GetMember<IMethodSymbol>("C.Method2");
Verify(
SymbolDisplay.ToDisplayParts(method2, formatWithoutAllowDefaultLiteral),
$"void C.Method2({type} parameter = {defaultValue})");
Verify(
SymbolDisplay.ToDisplayParts(method2, formatWithAllowDefaultLiteral),
$"void C.Method2({type} parameter = {defaultValue})");
var method3 = compilation.GetMember<IMethodSymbol>("C.Method3");
Verify(
SymbolDisplay.ToDisplayParts(method3, formatWithoutAllowDefaultLiteral),
$"void C.Method3({type} parameter = {defaultValue})");
Verify(
SymbolDisplay.ToDisplayParts(method3, formatWithAllowDefaultLiteral),
$"void C.Method3({type} parameter = {defaultValue})");
}
[Theory]
[InlineData("int", "2")]
[InlineData("string", "\"value\"")]
public void AllowDefaultLiteralNotApplicable(string type, string defaultValue)
{
var source =
$@"
class C
{{
void Method({type} parameter = {defaultValue}) => throw null;
}}
";
var compilation = (Compilation)CreateCompilation(source);
var formatWithoutAllowDefaultLiteral = SymbolDisplayFormat.MinimallyQualifiedFormat;
Assert.False(formatWithoutAllowDefaultLiteral.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral));
var formatWithAllowDefaultLiteral = formatWithoutAllowDefaultLiteral.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral);
Assert.True(formatWithAllowDefaultLiteral.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral));
var method = compilation.GetMember<IMethodSymbol>("C.Method");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithoutAllowDefaultLiteral),
$"void C.Method({type} parameter = {defaultValue})");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithAllowDefaultLiteral),
$"void C.Method({type} parameter = {defaultValue})");
}
[Fact]
public void UseLongHandValueTuple()
{
var source =
@"
class B
{
static (int, (string, long)) F1((int, int)[] t) => throw null;
}";
var comp = (Compilation)CreateCompilation(source);
var formatWithoutLongHandValueTuple = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeModifiers,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeParamsRefOut,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
var formatWithLongHandValueTuple = formatWithoutLongHandValueTuple.AddMiscellaneousOptions(
SymbolDisplayMiscellaneousOptions.ExpandValueTuple);
var method = comp.GetMember<IMethodSymbol>("B.F1");
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithoutLongHandValueTuple),
"static (int, (string, long)) F1((int, int)[] t)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(
SymbolDisplay.ToDisplayParts(method, formatWithLongHandValueTuple),
"static ValueTuple<int, ValueTuple<string, long>> F1(ValueTuple<int, int>[] t)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
[CompilerTrait(CompilerFeature.LocalFunctions)]
public void LocalFunction()
{
var srcTree = SyntaxFactory.ParseSyntaxTree(@"
class C
{
void M()
{
void Local() {}
}
}");
var root = srcTree.GetRoot();
var comp = CreateCompilation(srcTree);
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var local = root.DescendantNodes()
.Where(n => n.Kind() == SyntaxKind.LocalFunctionStatement)
.Single();
var localSymbol = (IMethodSymbol)semanticModel.GetDeclaredSymbol(local);
Assert.Equal(MethodKind.LocalFunction, localSymbol.MethodKind);
Verify(localSymbol.ToDisplayParts(SymbolDisplayFormat.TestFormat),
"void Local()",
SymbolDisplayPartKind.Keyword, // void
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, // Local
SymbolDisplayPartKind.Punctuation, // (
SymbolDisplayPartKind.Punctuation); // )
}
[Fact]
[CompilerTrait(CompilerFeature.LocalFunctions)]
public void LocalFunctionForChangeSignature()
{
SymbolDisplayFormat changeSignatureFormat = new SymbolDisplayFormat(
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes,
extensionMethodStyle: SymbolDisplayExtensionMethodStyle.StaticMethod,
memberOptions:
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeRef);
var srcTree = SyntaxFactory.ParseSyntaxTree(@"
class C
{
void M()
{
void Local() {}
}
}");
var root = srcTree.GetRoot();
var comp = CreateCompilation(srcTree);
var semanticModel = comp.GetSemanticModel(srcTree);
var local = root.DescendantNodes()
.Where(n => n.Kind() == SyntaxKind.LocalFunctionStatement)
.Single();
var localSymbol = (IMethodSymbol)semanticModel.GetDeclaredSymbol(local);
Assert.Equal(MethodKind.LocalFunction, localSymbol.MethodKind);
Verify(localSymbol.ToDisplayParts(changeSignatureFormat),
"void Local",
SymbolDisplayPartKind.Keyword, // void
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName // Local
);
}
[Fact]
[CompilerTrait(CompilerFeature.LocalFunctions)]
public void LocalFunction2()
{
var srcTree = SyntaxFactory.ParseSyntaxTree(@"
using System.Threading.Tasks;
class C
{
void M()
{
async unsafe Task<int> Local(ref int* x, out char? c)
{
}
}
}");
var root = srcTree.GetRoot();
var comp = CreateCompilationWithMscorlib461(new[] { srcTree });
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var local = root.DescendantNodes()
.Where(n => n.Kind() == SyntaxKind.LocalFunctionStatement)
.Single();
var localSymbol = (IMethodSymbol)semanticModel.GetDeclaredSymbol(local);
Assert.Equal(MethodKind.LocalFunction, localSymbol.MethodKind);
Verify(localSymbol.ToDisplayParts(SymbolDisplayFormat.TestFormat),
"System.Threading.Tasks.Task<System.Int32> Local(ref System.Int32* x, out System.Char? c)",
SymbolDisplayPartKind.NamespaceName, // System
SymbolDisplayPartKind.Punctuation, // .
SymbolDisplayPartKind.NamespaceName, // Threading
SymbolDisplayPartKind.Punctuation, // .
SymbolDisplayPartKind.NamespaceName, // Tasks
SymbolDisplayPartKind.Punctuation, // .
SymbolDisplayPartKind.ClassName, // Task
SymbolDisplayPartKind.Punctuation, // <
SymbolDisplayPartKind.NamespaceName, // System
SymbolDisplayPartKind.Punctuation, // .
SymbolDisplayPartKind.StructName, // Int32
SymbolDisplayPartKind.Punctuation, // >
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, // Local
SymbolDisplayPartKind.Punctuation, // (
SymbolDisplayPartKind.Keyword, // ref
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName, // System
SymbolDisplayPartKind.Punctuation, // .
SymbolDisplayPartKind.StructName, // Int32
SymbolDisplayPartKind.Punctuation, // *
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // x
SymbolDisplayPartKind.Punctuation, // ,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // out
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName, // System
SymbolDisplayPartKind.Punctuation, // .
SymbolDisplayPartKind.StructName, // Char
SymbolDisplayPartKind.Punctuation, // ?
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // c
SymbolDisplayPartKind.Punctuation); // )
}
[Fact]
public void RangeVariable()
{
var srcTree = SyntaxFactory.ParseSyntaxTree(@"
using System.Linq;
class C
{
void M()
{
var q = from x in new[] { 1, 2, 3 } where x < 3 select x;
}
}");
var root = srcTree.GetRoot();
var comp = CreateCompilation(srcTree);
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var queryExpression = root.DescendantNodes().OfType<QueryExpressionSyntax>().First();
var fromClauseRangeVariableSymbol = (IRangeVariableSymbol)semanticModel.GetDeclaredSymbol(queryExpression.FromClause);
Verify(
fromClauseRangeVariableSymbol.ToMinimalDisplayParts(
semanticModel,
queryExpression.FromClause.Identifier.SpanStart,
SymbolDisplayFormat.MinimallyQualifiedFormat),
"int x",
SymbolDisplayPartKind.Keyword, //int
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.RangeVariableName); // x
}
[Fact]
[CompilerTrait(CompilerFeature.LocalFunctions)]
public void LocalFunction3()
{
var srcTree = SyntaxFactory.ParseSyntaxTree(@"
using System.Threading.Tasks;
class C
{
void M()
{
async unsafe Task<int> Local(in int* x, out char? c)
{
}
}
}");
var root = srcTree.GetRoot();
var comp = CreateCompilationWithMscorlib461(new[] { srcTree });
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var local = root.DescendantNodes()
.Where(n => n.Kind() == SyntaxKind.LocalFunctionStatement)
.Single();
var localSymbol = (IMethodSymbol)semanticModel.GetDeclaredSymbol(local);
Assert.Equal(MethodKind.LocalFunction, localSymbol.MethodKind);
Verify(localSymbol.ToDisplayParts(SymbolDisplayFormat.TestFormat),
"System.Threading.Tasks.Task<System.Int32> Local(in System.Int32* x, out System.Char? c)",
SymbolDisplayPartKind.NamespaceName, // System
SymbolDisplayPartKind.Punctuation, // .
SymbolDisplayPartKind.NamespaceName, // Threading
SymbolDisplayPartKind.Punctuation, // .
SymbolDisplayPartKind.NamespaceName, // Tasks
SymbolDisplayPartKind.Punctuation, // .
SymbolDisplayPartKind.ClassName, // Task
SymbolDisplayPartKind.Punctuation, // <
SymbolDisplayPartKind.NamespaceName, // System
SymbolDisplayPartKind.Punctuation, // .
SymbolDisplayPartKind.StructName, // Int32
SymbolDisplayPartKind.Punctuation, // >
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName, // Local
SymbolDisplayPartKind.Punctuation, // (
SymbolDisplayPartKind.Keyword, // in
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName, // System
SymbolDisplayPartKind.Punctuation, // .
SymbolDisplayPartKind.StructName, // Int32
SymbolDisplayPartKind.Punctuation, // *
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // x
SymbolDisplayPartKind.Punctuation, // ,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // out
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName, // System
SymbolDisplayPartKind.Punctuation, // .
SymbolDisplayPartKind.StructName, // Char
SymbolDisplayPartKind.Punctuation, // ?
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName, // c
SymbolDisplayPartKind.Punctuation); // )
}
[Fact]
public void LocalVariable_01()
{
var srcTree = SyntaxFactory.ParseSyntaxTree(@"
class C
{
void M()
{
int x = 0;
x++;
}
}");
var root = srcTree.GetRoot();
var comp = CreateCompilation(srcTree);
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var declarator = root.DescendantNodes().OfType<VariableDeclaratorSyntax>().Single();
var local = (ILocalSymbol)semanticModel.GetDeclaredSymbol(declarator);
Verify(
local.ToMinimalDisplayParts(
semanticModel,
declarator.SpanStart,
SymbolDisplayFormat.MinimallyQualifiedFormat.AddLocalOptions(SymbolDisplayLocalOptions.IncludeRef)),
"int x",
SymbolDisplayPartKind.Keyword, //int
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.LocalName); // x
Assert.False(local.IsRef);
Assert.Equal(RefKind.None, local.RefKind);
}
[Fact]
public void LocalVariable_02()
{
var srcTree = SyntaxFactory.ParseSyntaxTree(@"
class C
{
void M(int y)
{
ref int x = y;
x++;
}
}");
var root = srcTree.GetRoot();
var comp = CreateCompilation(srcTree);
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var declarator = root.DescendantNodes().OfType<VariableDeclaratorSyntax>().Single();
var local = (ILocalSymbol)semanticModel.GetDeclaredSymbol(declarator);
Verify(
local.ToMinimalDisplayParts(
semanticModel,
declarator.SpanStart,
SymbolDisplayFormat.MinimallyQualifiedFormat.AddLocalOptions(SymbolDisplayLocalOptions.IncludeRef)),
"ref int x",
SymbolDisplayPartKind.Keyword, //ref
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, //int
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.LocalName); // x
Verify(
local.ToMinimalDisplayParts(
semanticModel,
declarator.SpanStart,
SymbolDisplayFormat.MinimallyQualifiedFormat),
"int x",
SymbolDisplayPartKind.Keyword, //int
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.LocalName); // x
Assert.True(local.IsRef);
Assert.Equal(RefKind.Ref, local.RefKind);
}
[Fact]
public void LocalVariable_03()
{
var srcTree = SyntaxFactory.ParseSyntaxTree(@"
class C
{
void M(int y)
{
ref readonly int x = y;
x++;
}
}");
var root = srcTree.GetRoot();
var comp = CreateCompilation(srcTree);
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var declarator = root.DescendantNodes().OfType<VariableDeclaratorSyntax>().Single();
var local = (ILocalSymbol)semanticModel.GetDeclaredSymbol(declarator);
Verify(
local.ToMinimalDisplayParts(
semanticModel,
declarator.SpanStart,
SymbolDisplayFormat.MinimallyQualifiedFormat.AddLocalOptions(SymbolDisplayLocalOptions.IncludeRef)),
"ref readonly int x",
SymbolDisplayPartKind.Keyword, //ref
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, //readonly
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, //int
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.LocalName); // x
Verify(
local.ToMinimalDisplayParts(
semanticModel,
declarator.SpanStart,
SymbolDisplayFormat.MinimallyQualifiedFormat),
"int x",
SymbolDisplayPartKind.Keyword, //int
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.LocalName); // x
Assert.True(local.IsRef);
Assert.Equal(RefKind.RefReadOnly, local.RefKind);
}
[Fact]
[WorkItem(22507, "https://github.com/dotnet/roslyn/issues/22507")]
public void EdgeCasesForEnumFieldComparer()
{
// A bad comparer could cause sorting the enum fields
// to throw an exception due to inconsistency. See Repro22507
// for an example of this problem.
var lhs = new EnumField("E1", 0);
var rhs = new EnumField("E2", 0x1000_0000_0000_0000);
// This is a "reverse" comparer, so if lhs < rhs, return
// value should be > 0
// If the comparer subtracts and converts, result will be zero since
// the bottom 32 bits are zero
Assert.InRange(EnumField.Comparer.Compare(lhs, rhs), 1, int.MaxValue);
lhs = new EnumField("E1", 0);
rhs = new EnumField("E2", 0x1000_0000_0000_0001);
Assert.InRange(EnumField.Comparer.Compare(lhs, rhs), 1, int.MaxValue);
lhs = new EnumField("E1", 0x1000_0000_0000_000);
rhs = new EnumField("E2", 0);
Assert.InRange(EnumField.Comparer.Compare(lhs, rhs), int.MinValue, -1);
lhs = new EnumField("E1", 0);
rhs = new EnumField("E2", 0x1000_0000_8000_0000);
Assert.InRange(EnumField.Comparer.Compare(lhs, rhs), 1, int.MaxValue);
}
[Fact]
[WorkItem(22507, "https://github.com/dotnet/roslyn/issues/22507")]
public void Repro22507()
{
var text = @"
using System;
[Flags]
enum E : long
{
A = 0x0,
B = 0x400,
C = 0x100000,
D = 0x200000,
E = 0x2000000,
F = 0x4000000,
G = 0x8000000,
H = 0x40000000,
I = 0x80000000,
J = 0x20000000000,
K = 0x40000000000,
L = 0x4000000000000,
M = 0x8000000000000,
N = 0x10000000000000,
O = 0x20000000000000,
P = 0x40000000000000,
Q = 0x2000000000000000,
}
";
TestSymbolDescription(
text,
g => g.GetTypeMembers("E").Single().GetField("A"),
SymbolDisplayFormat.MinimallyQualifiedFormat
.AddMemberOptions(SymbolDisplayMemberOptions.IncludeConstantValue),
"E.A = 0",
SymbolDisplayPartKind.EnumName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EnumMemberName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NumericLiteral);
}
[Fact]
public void TestRefStructs()
{
var source = @"
ref struct X { }
namespace Nested
{
ref struct Y { }
}
";
var comp = CreateCompilation(source).VerifyDiagnostics();
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var declarations = semanticModel.SyntaxTree.GetRoot().DescendantNodes().Where(n => n.Kind() == SyntaxKind.StructDeclaration).Cast<BaseTypeDeclarationSyntax>().ToArray();
Assert.Equal(2, declarations.Length);
var format = SymbolDisplayFormat.TestFormat.AddKindOptions(SymbolDisplayKindOptions.IncludeTypeKeyword);
Verify(semanticModel.GetDeclaredSymbol(declarations[0]).ToDisplayParts(format),
"ref struct X",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName);
Verify(semanticModel.GetDeclaredSymbol(declarations[1]).ToDisplayParts(format),
"ref struct Nested.Y",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName);
}
[Fact]
public void TestReadOnlyStructs()
{
var source = @"
readonly struct X { }
namespace Nested
{
readonly struct Y { }
}
";
var comp = CreateCompilation(source).VerifyDiagnostics();
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var declarations = semanticModel.SyntaxTree.GetRoot().DescendantNodes().Where(n => n.Kind() == SyntaxKind.StructDeclaration).Cast<BaseTypeDeclarationSyntax>().ToArray();
Assert.Equal(2, declarations.Length);
var format = SymbolDisplayFormat.TestFormat.AddKindOptions(SymbolDisplayKindOptions.IncludeTypeKeyword);
Verify(semanticModel.GetDeclaredSymbol(declarations[0]).ToDisplayParts(format),
"readonly struct X",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName);
Verify(semanticModel.GetDeclaredSymbol(declarations[1]).ToDisplayParts(format),
"readonly struct Nested.Y",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName);
}
[Fact]
public void TestReadOnlyRefStructs()
{
var source = @"
readonly ref struct X { }
namespace Nested
{
readonly ref struct Y { }
}
";
var comp = CreateCompilation(source).VerifyDiagnostics();
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var declarations = semanticModel.SyntaxTree.GetRoot().DescendantNodes().Where(n => n.Kind() == SyntaxKind.StructDeclaration).Cast<BaseTypeDeclarationSyntax>().ToArray();
Assert.Equal(2, declarations.Length);
var format = SymbolDisplayFormat.TestFormat.AddKindOptions(SymbolDisplayKindOptions.IncludeTypeKeyword);
Verify(semanticModel.GetDeclaredSymbol(declarations[0]).ToDisplayParts(format),
"readonly ref struct X",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName);
Verify(semanticModel.GetDeclaredSymbol(declarations[1]).ToDisplayParts(format),
"readonly ref struct Nested.Y",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName);
}
[Fact]
public void TestReadOnlyMembers_Malformed()
{
var source = @"
struct X
{
int P1 { }
readonly int P2 { }
readonly event System.Action E1 { }
readonly event System.Action E2 { remove { } }
}
";
var format = SymbolDisplayFormat.TestFormat
.AddMemberOptions(SymbolDisplayMemberOptions.IncludeModifiers)
.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
var comp = CreateCompilation(source).VerifyDiagnostics(
// (4,9): error CS0548: 'X.P1': property or indexer must have at least one accessor
// int P1 { }
Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "P1").WithArguments("X.P1").WithLocation(4, 9),
// (5,18): error CS0548: 'X.P2': property or indexer must have at least one accessor
// readonly int P2 { }
Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "P2").WithArguments("X.P2").WithLocation(5, 18),
// (6,34): error CS0065: 'X.E1': event property must have both add and remove accessors
// readonly event System.Action E1 { }
Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("X.E1").WithLocation(6, 34),
// (7,34): error CS0065: 'X.E2': event property must have both add and remove accessors
// readonly event System.Action E2 { remove { } }
Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E2").WithArguments("X.E2").WithLocation(7, 34));
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var declaration = (BaseTypeDeclarationSyntax)semanticModel.SyntaxTree.GetRoot().DescendantNodes().Single(n => n.Kind() == SyntaxKind.StructDeclaration);
var members = semanticModel.GetDeclaredSymbol(declaration).GetMembers();
Verify(members[0].ToDisplayParts(format), "int X.P1 { }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
Verify(members[1].ToDisplayParts(format), "int X.P2 { }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
Verify(members[2].ToDisplayParts(format), "event System.Action X.E1",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName);
Verify(members[3].ToDisplayParts(format), "readonly event System.Action X.E2",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName);
}
[Fact]
public void TestReadOnlyMembers()
{
var source = @"
struct X
{
readonly void M() { }
readonly int P1 { get => 123; }
readonly int P2 { set {} }
readonly int P3 { get => 123; set {} }
int P4 { readonly get => 123; set {} }
int P5 { get => 123; readonly set {} }
readonly event System.Action E { add {} remove {} }
}
";
var format = SymbolDisplayFormat.TestFormat
.AddMemberOptions(SymbolDisplayMemberOptions.IncludeModifiers)
.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
var comp = CreateCompilation(source).VerifyDiagnostics();
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var declaration = (BaseTypeDeclarationSyntax)semanticModel.SyntaxTree.GetRoot().DescendantNodes().Single(n => n.Kind() == SyntaxKind.StructDeclaration);
var members = semanticModel.GetDeclaredSymbol(declaration).GetMembers();
Verify(members[0].ToDisplayParts(format),
"readonly void X.M()",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
Verify(members[1].ToDisplayParts(format),
"readonly int X.P1 { get; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
Verify(members[2].ToDisplayParts(format),
"readonly int X.P1.get",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[3].ToDisplayParts(format),
"readonly int X.P2 { set; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
Verify(members[4].ToDisplayParts(format),
"readonly void X.P2.set",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[5].ToDisplayParts(format),
"readonly int X.P3 { get; set; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
Verify(members[6].ToDisplayParts(format),
"readonly int X.P3.get",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[7].ToDisplayParts(format),
"readonly void X.P3.set",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[8].ToDisplayParts(format),
"int X.P4 { readonly get; set; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
Verify(members[9].ToDisplayParts(format),
"readonly int X.P4.get",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[10].ToDisplayParts(format),
"void X.P4.set",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[11].ToDisplayParts(format),
"int X.P5 { get; readonly set; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
Verify(members[12].ToDisplayParts(format),
"int X.P5.get",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[13].ToDisplayParts(format),
"readonly void X.P5.set",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[14].ToDisplayParts(format),
"readonly event System.Action X.E",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName);
Verify(members[15].ToDisplayParts(format),
"readonly void X.E.add",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[16].ToDisplayParts(format),
"readonly void X.E.remove",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
}
[Fact]
public void TestReadOnlyStruct_Members()
{
var source = @"
readonly struct X
{
void M() { }
int P1 { get => 123; }
int P2 { set {} }
int P3 { get => 123; readonly set {} }
event System.Action E { add {} remove {} }
}
";
var format = SymbolDisplayFormat.TestFormat
.AddMemberOptions(SymbolDisplayMemberOptions.IncludeModifiers)
.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
var comp = CreateCompilation(source).VerifyDiagnostics();
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var declaration = (BaseTypeDeclarationSyntax)semanticModel.SyntaxTree.GetRoot().DescendantNodes().Single(n => n.Kind() == SyntaxKind.StructDeclaration);
var members = semanticModel.GetDeclaredSymbol(declaration).GetMembers();
Verify(members[0].ToDisplayParts(format),
"void X.M()",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
Verify(members[1].ToDisplayParts(format),
"int X.P1 { get; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
Verify(members[2].ToDisplayParts(format),
"int X.P1.get",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[3].ToDisplayParts(format),
"int X.P2 { set; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
Verify(members[4].ToDisplayParts(format),
"void X.P2.set",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[5].ToDisplayParts(format),
"int X.P3 { get; set; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
Verify(members[6].ToDisplayParts(format),
"int X.P3.get",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[7].ToDisplayParts(format),
"void X.P3.set",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[8].ToDisplayParts(format),
"event System.Action X.E",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName);
Verify(members[9].ToDisplayParts(format),
"void X.E.add",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
Verify(members[10].ToDisplayParts(format),
"void X.E.remove",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.EventName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword);
}
[Theory, MemberData(nameof(FileScopedOrBracedNamespace))]
public void TestReadOnlyStruct_Nested(string ob, string cb)
{
var source = @"
namespace Nested
" + ob + @"
struct X
{
readonly void M() { }
}
" + cb + @"
";
var format = SymbolDisplayFormat.TestFormat
.AddMemberOptions(SymbolDisplayMemberOptions.IncludeModifiers)
.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithFileScopedNamespaces).VerifyDiagnostics();
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var declaration = (BaseTypeDeclarationSyntax)semanticModel.SyntaxTree.GetRoot().DescendantNodes().Single(n => n.Kind() == SyntaxKind.StructDeclaration);
var members = semanticModel.GetDeclaredSymbol(declaration).GetMembers();
Verify(members[0].ToDisplayParts(format),
"readonly void Nested.X.M()",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestPassingVBSymbolsToStructSymbolDisplay()
{
var source = @"
Structure X
End Structure";
var comp = CreateVisualBasicCompilation(source).VerifyDiagnostics();
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var structure = semanticModel.SyntaxTree.GetRoot().DescendantNodes().Single(n => n.RawKind == (int)VisualBasic.SyntaxKind.StructureStatement);
var format = SymbolDisplayFormat.TestFormat.AddKindOptions(SymbolDisplayKindOptions.IncludeTypeKeyword);
Verify(SymbolDisplay.ToDisplayParts(semanticModel.GetDeclaredSymbol(structure), format),
"struct X",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName);
}
[Fact]
public void EnumConstraint_Type()
{
TestSymbolDescription(
"class X<T> where T : System.Enum { }",
global => global.GetTypeMember("X"),
SymbolDisplayFormat.TestFormat.WithGenericsOptions(SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeTypeConstraints),
"X<T> where T : System.Enum",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void EnumConstraint()
{
TestSymbolDescription(
"class X<T> where T : System.Enum { }",
global => global.GetTypeMember("X").TypeParameters.Single().ConstraintTypes().Single(),
SymbolDisplayFormat.TestFormat,
"System.Enum",
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void DelegateConstraint_Type()
{
TestSymbolDescription(
"class X<T> where T : System.Delegate { }",
global => global.GetTypeMember("X"),
SymbolDisplayFormat.TestFormat.WithGenericsOptions(SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeTypeConstraints),
"X<T> where T : System.Delegate",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void DelegateConstraint()
{
TestSymbolDescription(
"class X<T> where T : System.Delegate { }",
global => global.GetTypeMember("X").TypeParameters.Single().ConstraintTypes().Single(),
SymbolDisplayFormat.TestFormat,
"System.Delegate",
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void MulticastDelegateConstraint_Type()
{
TestSymbolDescription(
"class X<T> where T : System.MulticastDelegate { }",
global => global.GetTypeMember("X"),
SymbolDisplayFormat.TestFormat.WithGenericsOptions(SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeTypeConstraints),
"X<T> where T : System.MulticastDelegate",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void MulticastDelegateConstraint()
{
TestSymbolDescription(
"class X<T> where T : System.MulticastDelegate { }",
global => global.GetTypeMember("X").TypeParameters.Single().ConstraintTypes().Single(),
SymbolDisplayFormat.TestFormat,
"System.MulticastDelegate",
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void UnmanagedConstraint_Type()
{
TestSymbolDescription(
"class X<T> where T : unmanaged { }",
global => global.GetTypeMember("X"),
SymbolDisplayFormat.TestFormat.AddGenericsOptions(SymbolDisplayGenericsOptions.IncludeTypeConstraints),
"X<T> where T : unmanaged",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword);
}
[Fact]
public void UnmanagedConstraint_Method()
{
TestSymbolDescription(@"
class X
{
void M<T>() where T : unmanaged, System.IDisposable { }
}",
global => global.GetTypeMember("X").GetMethod("M"),
SymbolDisplayFormat.TestFormat.AddGenericsOptions(SymbolDisplayGenericsOptions.IncludeTypeConstraints),
"void X.M<T>() where T : unmanaged, System.IDisposable",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.InterfaceName);
}
[Fact]
public void UnmanagedConstraint_Delegate()
{
TestSymbolDescription(
"delegate void D<T>() where T : unmanaged;",
global => global.GetTypeMember("D"),
SymbolDisplayFormat.TestFormat.AddGenericsOptions(SymbolDisplayGenericsOptions.IncludeTypeConstraints),
"D<T> where T : unmanaged",
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword);
}
[Fact, WorkItem(27104, "https://github.com/dotnet/roslyn/issues/27104")]
public void BadDiscardInForeachLoop_01()
{
var source = @"
class C
{
void M()
{
foreach(_ in """")
{
}
}
}";
var compilation = CreateCompilation(source);
compilation.VerifyDiagnostics(
// (6,17): error CS8186: A foreach loop must declare its iteration variables.
// foreach(_ in "")
Diagnostic(ErrorCode.ERR_MustDeclareForeachIteration, "_").WithLocation(6, 17)
);
var tree = compilation.SyntaxTrees[0];
var variable = tree.GetRoot().DescendantNodes().OfType<ForEachVariableStatementSyntax>().Single().Variable;
var model = compilation.GetSemanticModel(tree);
var symbol = model.GetSymbolInfo(variable).Symbol;
Verify(
symbol.ToMinimalDisplayParts(model, variable.SpanStart),
"var _",
SymbolDisplayPartKind.ErrorTypeName, // var
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation); // _
}
[Fact]
public void ClassConstructorDeclaration()
{
TestSymbolDescription(
@"class C
{
C() { }
}",
global => global.GetTypeMember("C").Constructors[0],
new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeContainingType),
"C.C",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void ClassDestructorDeclaration()
{
TestSymbolDescription(
@"class C
{
~C() { }
}",
global => global.GetTypeMember("C").GetMember("Finalize"),
new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeContainingType),
"C.~C",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void ClassStaticConstructorDeclaration()
{
TestSymbolDescription(
@"class C
{
static C() { }
}",
global => global.GetTypeMember("C").Constructors[0],
new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeContainingType),
"C.C",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void ClassStaticDestructorDeclaration()
{
TestSymbolDescription(
@"class C
{
static ~C() { }
}",
global => global.GetTypeMember("C").GetMember("Finalize"),
new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeContainingType),
"C.~C",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void ClassConstructorInvocation()
{
var format = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeContainingType);
var source =
@"class C
{
C()
{
var c = new C();
}
}";
var compilation = CreateCompilation(source);
var tree = compilation.SyntaxTrees[0];
var model = compilation.GetSemanticModel(tree);
var constructor = tree.GetRoot().DescendantNodes().OfType<ObjectCreationExpressionSyntax>().Single();
var symbol = model.GetSymbolInfo(constructor).Symbol;
Verify(
symbol.ToMinimalDisplayParts(model, constructor.SpanStart, format),
"C.C",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.ClassName);
}
[Fact]
public void StructConstructorDeclaration()
{
TestSymbolDescription(
@"struct S
{
int i;
S(int i)
{
this.i = i;
}
}",
global => global.GetTypeMember("S").Constructors[0],
new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeContainingType),
"S.S",
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName);
}
[Fact]
public void StructConstructorInvocation()
{
var format = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeContainingType);
var source =
@"struct S
{
int i;
public S(int i)
{
this.i = i;
}
}
class C
{
C()
{
var s = new S(1);
}
}";
var compilation = CreateCompilation(source);
var tree = compilation.SyntaxTrees[0];
var model = compilation.GetSemanticModel(tree);
var constructor = tree.GetRoot().DescendantNodes().OfType<ObjectCreationExpressionSyntax>().Single();
var symbol = model.GetSymbolInfo(constructor).Symbol;
Verify(
symbol.ToMinimalDisplayParts(model, constructor.SpanStart, format),
"S.S",
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName);
}
[Fact]
[WorkItem(38794, "https://github.com/dotnet/roslyn/issues/38794")]
public void LinqGroupVariableDeclaration()
{
var source =
@"using System.Linq;
class C
{
void M(string[] a)
{
var v = from x in a
group x by x.Length into g
select g;
}
}";
var compilation = CreateCompilation(source);
var tree = compilation.SyntaxTrees[0];
var model = compilation.GetSemanticModel(tree);
var continuation = tree.GetRoot().DescendantNodes().OfType<QueryContinuationSyntax>().Single();
var symbol = model.GetDeclaredSymbol(continuation);
Verify(
symbol.ToMinimalDisplayParts(model, continuation.Identifier.SpanStart),
"IGrouping<int, string> g",
SymbolDisplayPartKind.InterfaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.RangeVariableName);
}
[Fact]
public void NativeInt()
{
var source =
@"using System;
class A<T>
{
}
class B
{
static void F1(nint x, nuint y) { }
static void F2(nint x, IntPtr y) { }
static void F3(nint? x, UIntPtr? y) { }
static void F4(nint[] x, A<nuint> y) { }
}";
var comp = CreateCompilation(new[] { source }, parseOptions: TestOptions.Regular9);
var formatWithoutOptions = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeModifiers,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters);
var formatWithUnderlyingTypes = formatWithoutOptions.WithCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.UseNativeIntegerUnderlyingType);
var method = comp.GetMember<MethodSymbol>("B.F1");
Verify(
method.ToDisplayParts(formatWithUnderlyingTypes),
"static void F1(IntPtr x, UIntPtr y)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(
method.ToDisplayParts(formatWithoutOptions),
"static void F1(nint x, nuint y)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(
method.ToDisplayParts(formatWithoutOptions.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes)),
"static void F1(nint x, nuint y)");
method = comp.GetMember<MethodSymbol>("B.F2");
Verify(
method.ToDisplayParts(formatWithUnderlyingTypes),
"static void F2(IntPtr x, IntPtr y)");
Verify(
method.ToDisplayParts(formatWithoutOptions),
"static void F2(nint x, IntPtr y)");
method = comp.GetMember<MethodSymbol>("B.F3");
Verify(
method.ToDisplayParts(formatWithUnderlyingTypes),
"static void F3(IntPtr? x, UIntPtr? y)");
Verify(
method.ToDisplayParts(formatWithoutOptions),
"static void F3(nint? x, UIntPtr? y)");
method = comp.GetMember<MethodSymbol>("B.F4");
Verify(
method.ToDisplayParts(formatWithUnderlyingTypes),
"static void F4(IntPtr[] x, A<UIntPtr> y)");
Verify(
method.ToDisplayParts(formatWithoutOptions),
"static void F4(nint[] x, A<nuint> y)");
}
[Fact]
public void RecordDeclaration()
{
var text = @"
record Person(string First, string Last);
";
Func<NamespaceSymbol, Symbol> findSymbol = global => global.GetTypeMembers("Person").Single();
var format = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeType, kindOptions: SymbolDisplayKindOptions.IncludeTypeKeyword);
TestSymbolDescription(
text,
findSymbol,
format,
TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9),
"record Person",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.RecordClassName);
}
[Fact]
public void RecordClassDeclaration()
{
var text = @"
record class Person(string First, string Last);
";
Func<NamespaceSymbol, Symbol> findSymbol = global => global.GetTypeMembers("Person").Single();
var format = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeType, kindOptions: SymbolDisplayKindOptions.IncludeTypeKeyword);
TestSymbolDescription(
text,
findSymbol,
format,
TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9),
"record Person",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.RecordClassName);
}
[Fact]
public void RecordStructDeclaration()
{
var text = @"
record struct Person(string First, string Last);
";
Func<NamespaceSymbol, Symbol> findSymbol = global => global.GetTypeMembers("Person").Single();
var format = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeType, kindOptions: SymbolDisplayKindOptions.IncludeTypeKeyword);
TestSymbolDescription(
text,
findSymbol,
format,
TestOptions.Regular10,
"record struct Person",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.RecordStructName);
}
[Fact]
public void ReadOnlyRecordStructDeclaration()
{
var text = @"
readonly record struct Person(string First, string Last);
";
Func<NamespaceSymbol, Symbol> findSymbol = global => global.GetTypeMembers("Person").Single();
var format = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeType, kindOptions: SymbolDisplayKindOptions.IncludeTypeKeyword);
TestSymbolDescription(
text,
findSymbol,
format,
TestOptions.Regular10,
"readonly record struct Person",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.RecordStructName);
}
[Fact, WorkItem(51222, "https://github.com/dotnet/roslyn/issues/51222")]
public void TestFunctionPointerWithoutIncludeTypesInParameterOptions()
{
var text = @"
class A {
delegate*<int, string> f;
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
((FieldSymbol)global.GetTypeMembers("A", 0).Single()
.GetMembers("f").Single()).Type;
var format = new SymbolDisplayFormat();
TestSymbolDescription(
text,
findSymbol,
format,
"delegate*<Int32, String>");
}
[Fact, WorkItem(51222, "https://github.com/dotnet/roslyn/issues/51222")]
public void TestFunctionPointerWithTupleParameter()
{
var text = @"
class A {
delegate*<(int, string), void> f;
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
((FieldSymbol)global.GetTypeMembers("A", 0).Single()
.GetMembers("f").Single()).Type;
var format = new SymbolDisplayFormat();
TestSymbolDescription(
text,
findSymbol,
format,
"delegate*<(Int32, String), Void>");
}
[Fact, WorkItem(51222, "https://github.com/dotnet/roslyn/issues/51222")]
public void TestFunctionPointerWithTupleParameterWithNames()
{
var text = @"
class A {
delegate*<(int i, string s), (int i, string s)> f;
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
((FieldSymbol)global.GetTypeMembers("A", 0).Single()
.GetMembers("f").Single()).Type;
var format = new SymbolDisplayFormat();
TestSymbolDescription(
text,
findSymbol,
format,
"delegate*<(Int32 i, String s), (Int32 i, String s)>");
}
[Fact, WorkItem(51222, "https://github.com/dotnet/roslyn/issues/51222")]
public void TestFunctionPointerWithRefParameters()
{
var text = @"
class A {
delegate*<in int, ref readonly string> f;
}";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
((FieldSymbol)global.GetTypeMembers("A", 0).Single()
.GetMembers("f").Single()).Type;
var format = new SymbolDisplayFormat();
TestSymbolDescription(
text,
findSymbol,
format,
"delegate*<in Int32, ref readonly String>");
}
private static readonly SymbolDisplayFormat s_fullDelegateFormat = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
delegateStyle: SymbolDisplayDelegateStyle.NameAndSignature,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeVariance | SymbolDisplayGenericsOptions.IncludeTypeConstraints,
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeParamsRefOut,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes,
kindOptions: SymbolDisplayKindOptions.IncludeNamespaceKeyword | SymbolDisplayKindOptions.IncludeTypeKeyword);
[Fact]
public void TestInferredDelegateType()
{
var source = @"
class C
{
void M()
{
var v = (int i) => i.ToString();
}
}
";
var comp = CreateCompilation(source);
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var syntaxTree = semanticModel.SyntaxTree;
var declaration = (LocalDeclarationStatementSyntax)semanticModel.SyntaxTree.GetRoot().DescendantNodes().Single(n => n.Kind() == SyntaxKind.LocalDeclarationStatement);
var type = semanticModel.GetTypeInfo(declaration.Declaration.Type).Type;
Verify(type.ToDisplayParts(), "System.Func<int, string>",
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation);
Verify(type.ToDisplayParts(s_fullDelegateFormat), "delegate string System.Func<int, string>(int arg)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestSynthesizedAnonymousDelegateType1()
{
var source = @"
class C
{
void M()
{
var v = (ref int i) => i.ToString();
}
}
";
var comp = CreateCompilation(source);
var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single());
var syntaxTree = semanticModel.SyntaxTree;
var declaration = (LocalDeclarationStatementSyntax)semanticModel.SyntaxTree.GetRoot().DescendantNodes().Single(n => n.Kind() == SyntaxKind.LocalDeclarationStatement);
var type = semanticModel.GetTypeInfo(declaration.Declaration.Type).Type;
Verify(type.ToDisplayParts(), "<anonymous delegate>",
SymbolDisplayPartKind.DelegateName);
Verify(type.ToDisplayParts(s_fullDelegateFormat), "delegate string <anonymous delegate>(ref int arg)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestSynthesizedAnonymousDelegateType2()
{
var source =
@"Class Program
Shared Sub Main
Dim f = Function(ByRef i As Integer) i.ToString()
End Sub
End Class";
var comp = CreateVisualBasicCompilation(source);
var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree);
var name = tree.GetRoot().DescendantNodes().OfType<VisualBasic.Syntax.VariableDeclaratorSyntax>().Single();
var type = ((ILocalSymbol)model.GetDeclaredSymbol(name.Names[0])).Type;
Verify(SymbolDisplay.ToDisplayParts(type), "<anonymous delegate>",
SymbolDisplayPartKind.DelegateName);
Verify(SymbolDisplay.ToDisplayParts(type, s_fullDelegateFormat), "delegate string <anonymous delegate>(ref int i)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.DelegateName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestNullCheckedParameter()
{
var source = @"
class C
{
void M(string s!!)
{
}
}
";
var comp = CreateCompilation(source);
var methodSymbol = comp.GetMember<MethodSymbol>("C.M").GetPublicSymbol();
Verify(methodSymbol.ToDisplayParts(s_memberSignatureDisplayFormat), "void C.M(string s)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67464")]
public void Parameter_Standalone()
{
var source = """
class C
{
void M(ref int p) { }
}
""";
var comp = CreateCompilation(source);
var methodSymbol = comp.GetMember<MethodSymbol>("C.M").GetPublicSymbol();
var parameterSymbol = methodSymbol.Parameters.Single();
var format = s_memberSignatureDisplayFormat.RemoveParameterOptions(SymbolDisplayParameterOptions.IncludeName);
Verify(methodSymbol.ToDisplayParts(format), "void C.M(ref int)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation);
Verify(methodSymbol.ToDisplayParts(SymbolDisplayFormat.CSharpErrorMessageFormat), "C.M(ref int)",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation);
Verify(methodSymbol.ToDisplayParts(SymbolDisplayFormat.CSharpErrorMessageNoParameterNamesFormat), "C.M(ref int)",
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation);
Verify(parameterSymbol.ToDisplayParts(format), "ref int p",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName);
Verify(parameterSymbol.ToDisplayParts(SymbolDisplayFormat.CSharpErrorMessageFormat), "ref int p",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName);
Verify(parameterSymbol.ToDisplayParts(SymbolDisplayFormat.CSharpErrorMessageNoParameterNamesFormat), "ref int",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword);
}
[Fact]
public void TestRequiredProperty()
{
var source = @"
class C
{
required int Prop { get; set; }
}
";
var comp = CreateCompilation(source);
var propertySymbol = comp.GetMember<PropertySymbol>("C.Prop").GetPublicSymbol();
Verify(propertySymbol.ToDisplayParts(s_memberSignatureDisplayFormat), "required int C.Prop { get; set; }",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.PropertyName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void RefFields()
{
var source =
@"#pragma warning disable 169
ref struct S<T>
{
ref T F1;
ref readonly T F2;
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (4,11): error CS9064: Target runtime doesn't support ref fields.
// ref T F1;
Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportRefFields, "F1").WithLocation(4, 11),
// (5,20): error CS9064: Target runtime doesn't support ref fields.
// ref readonly T F2;
Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportRefFields, "F2").WithLocation(5, 20)
);
Verify(comp.GetMember<FieldSymbol>("S.F1").ToDisplayParts(SymbolDisplayFormat.TestFormat),
"ref T S<T>.F1",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.FieldName);
Verify(comp.GetMember<FieldSymbol>("S.F2").ToDisplayParts(SymbolDisplayFormat.TestFormat),
"ref readonly T S<T>.F2",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.TypeParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.FieldName);
}
[Fact]
public void ScopedParameter_01()
{
var source =
@"ref struct R { }
class Program
{
static void F(scoped R r1, scoped ref R r2, scoped in R r3, scoped out R r4) { }
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
var method = comp.GetMember<MethodSymbol>("Program.F");
var formatTypeOnly = SymbolDisplayFormat.TestFormat.WithParameterOptions(SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName);
var formatTypeRefAndScoped = formatTypeOnly.AddParameterOptions(SymbolDisplayParameterOptions.IncludeParamsRefOut);
Verify(method.ToDisplayParts(formatTypeOnly),
"void Program.F(R r1, R r2, R r3, R r4)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
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.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
Verify(method.ToDisplayParts(formatTypeRefAndScoped),
"void Program.F(scoped R r1, scoped ref R r2, scoped in R r3, out R r4)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void ScopedParameter_02()
{
var source =
@"ref struct R { }
delegate void D(scoped R r1, scoped ref R r2, scoped in R r3, scoped out R r4);
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
var delegateType = comp.GetMember<NamedTypeSymbol>("D");
var formatTypeOnly = s_fullDelegateFormat.WithParameterOptions(SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName);
var formatTypeRefAndScoped = formatTypeOnly.AddParameterOptions(SymbolDisplayParameterOptions.IncludeParamsRefOut);
Verify(delegateType.ToDisplayParts(formatTypeOnly),
"delegate void D(R r1, R r2, R r3, R r4)");
Verify(delegateType.ToDisplayParts(formatTypeRefAndScoped),
"delegate void D(scoped R r1, scoped ref R r2, scoped in R r3, out R r4)");
}
[Fact]
public void ScopedParameter_03()
{
var source =
@"#pragma warning disable 169
ref struct R { }
unsafe class Program
{
delegate*<scoped R, scoped in R, scoped ref R, scoped out R, void> D;
}
";
var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll);
comp.VerifyDiagnostics(
// (5,15): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
// delegate*<scoped R, scoped in R, scoped ref R, scoped out R, void> D;
Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(5, 15),
// (5,25): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
// delegate*<scoped R, scoped in R, scoped ref R, scoped out R, void> D;
Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(5, 25),
// (5,38): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
// delegate*<scoped R, scoped in R, scoped ref R, scoped out R, void> D;
Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(5, 38),
// (5,52): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
// delegate*<scoped R, scoped in R, scoped ref R, scoped out R, void> D;
Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(5, 52));
var type = comp.GetMember<FieldSymbol>("Program.D").Type;
var formatMinimal = new SymbolDisplayFormat();
var formatTypeRefAndScoped = s_fullDelegateFormat.
WithParameterOptions(SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeParamsRefOut);
Verify(type.ToDisplayParts(formatMinimal),
"delegate*<R, in R, ref R, out R, Void>");
Verify(type.ToDisplayParts(formatTypeRefAndScoped),
"delegate*<R, in R, ref R, out R, void>");
}
[Fact]
public void ScopedParameter_04()
{
var source =
@"using System.Diagnostics.CodeAnalysis;
ref struct R { }
class Program
{
static void F1(out int i1, [UnscopedRef] out int i2) => throw null;
static void F2(ref R r1, ref R r2) => throw null;
}";
var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
comp.VerifyDiagnostics();
var format = SymbolDisplayFormat.TestFormat.
WithParameterOptions(SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeParamsRefOut);
Verify(comp.GetMember<MethodSymbol>("Program.F1").ToDisplayParts(format),
"void Program.F1(out System.Int32 i1, out System.Int32 i2)");
Verify(comp.GetMember<MethodSymbol>("Program.F2").ToDisplayParts(format),
"void Program.F2(ref R r1, ref R r2)");
}
[Fact]
public void ScopedLocal()
{
var source =
@"ref struct R { }
class Program
{
static void M(R r0)
{
scoped R r1 = r0;
scoped ref readonly R r3 = ref r0;
}
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
var tree = comp.SyntaxTrees[0];
var model = comp.GetSemanticModel(tree);
var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
var locals = decls.Select(d => model.GetDeclaredSymbol(d)).ToArray();
var formatTypeOnly = SymbolDisplayFormat.TestFormat.WithLocalOptions(SymbolDisplayLocalOptions.IncludeType);
var formatTypeRefAndScoped = formatTypeOnly.AddLocalOptions(SymbolDisplayLocalOptions.IncludeRef);
Verify(locals[0].ToDisplayParts(formatTypeOnly),
"R r1",
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.LocalName);
Verify(locals[0].ToDisplayParts(formatTypeRefAndScoped),
"scoped R r1",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.LocalName);
Verify(locals[1].ToDisplayParts(formatTypeOnly),
"R r3",
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.LocalName);
Verify(locals[1].ToDisplayParts(formatTypeRefAndScoped),
"scoped ref readonly R r3",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.LocalName);
}
[Fact, WorkItem(38783, "https://github.com/dotnet/roslyn/issues/38783")]
public void Operator1()
{
var source = """
class Program
{
void M()
{
_ = 1 == 1;
}
}
""";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
var tree = comp.SyntaxTrees[0];
var model = comp.GetSemanticModel(tree);
var binaryExpression = tree.GetRoot().DescendantNodes().OfType<BinaryExpressionSyntax>().Single();
var op = model.GetSymbolInfo(binaryExpression).Symbol;
// When asking for metadata names, this should show up as a method-name.
Verify(op.ToDisplayParts(SymbolDisplayFormat.TestFormat),
"System.Boolean System.Int32.op_Equality(System.Int32 left, System.Int32 right)",
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName, // Should be MethodName because of 'op_Equality'
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.NamespaceName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
var ideFormat = new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Omitted,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeTypeConstraints,
memberOptions:
SymbolDisplayMemberOptions.IncludeRef |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeContainingType,
kindOptions:
SymbolDisplayKindOptions.IncludeMemberKeyword,
propertyStyle:
SymbolDisplayPropertyStyle.ShowReadWriteDescriptor,
parameterOptions:
SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeExtensionThis |
SymbolDisplayParameterOptions.IncludeDefaultValue |
SymbolDisplayParameterOptions.IncludeOptionalBrackets,
localOptions:
SymbolDisplayLocalOptions.IncludeRef |
SymbolDisplayLocalOptions.IncludeType,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes |
SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName |
SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier |
SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral |
SymbolDisplayMiscellaneousOptions.CollapseTupleTypes);
// When not asking for metadata names, this should show up as an operator.
Verify(op.ToDisplayParts(ideFormat),
"bool int.operator ==(int left, int right)",
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Operator, // Should be MethodName because of '=='
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ParameterName,
SymbolDisplayPartKind.Punctuation);
}
}
}
|