From db8d5cabb2f735edc6c55e68f825628ea3bd8f94 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Sun, 17 Jun 2018 19:31:08 -0500 Subject: [PATCH 1/3] Only qualify the first symbol in Quick Info Fixes #547 --- .../SymbolDisplayVisitor.Types.cs | 4 +-- .../SymbolDisplay/SymbolDisplayVisitor.cs | 18 ++++++++++ .../Core/Portable/PublicAPI.Unshipped.txt | 1 + .../AbstractSymbolDisplayVisitor.cs | 16 +++++++++ .../AbstractSymbolDisplayVisitor_Minimal.cs | 33 ++++++++++++++++++- .../SymbolDisplayMiscellaneousOptions.cs | 8 +++++ .../SymbolDisplayVisitor.Types.vb | 4 +-- .../SymbolDisplay/SymbolDisplayVisitor.vb | 15 +++++++++ .../QuickInfo/SemanticQuickInfoSourceTests.cs | 25 ++++++++++++-- .../QuickInfo/SemanticQuickInfoSourceTests.vb | 30 +++++++++++++++-- ...ervice.AbstractSymbolDescriptionBuilder.cs | 26 ++++----------- 11 files changed, 149 insertions(+), 31 deletions(-) diff --git a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.cs b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.cs index 5bca412bb5615..6aa2f1136c5d6 100644 --- a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.cs +++ b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.cs @@ -128,7 +128,7 @@ public override void VisitNamedType(INamedTypeSymbol symbol) return; } - if (format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.UseSpecialTypes)) + if (CanUseSpecialTypes) { if (AddSpecialTypeKeyword(symbol)) { @@ -212,7 +212,7 @@ public override void VisitNamedType(INamedTypeSymbol symbol) { if (IncludeNamedType(symbol.ContainingType)) { - symbol.ContainingType.Accept(this.NotFirstVisitor); + symbol.ContainingType.Accept(this.FirstSymbolContainingTypeVisitor); AddPunctuation(SyntaxKind.DotToken); } } diff --git a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.cs b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.cs index 7708e24809637..5b2a2a9ab67fa 100644 --- a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.cs +++ b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.cs @@ -39,6 +39,24 @@ private SymbolDisplayVisitor( _lazyAliasMap = aliasMap; } + protected override AbstractSymbolDisplayVisitor MakeFirstSymbolContainingTypeVisitor() + { + if (!isFirstSymbolVisited || format.KindOptions == SymbolDisplayKindOptions.None) + { + return this; + } + + return new SymbolDisplayVisitor( + this.builder, + this.format.WithKindOptions(SymbolDisplayKindOptions.None), + this.semanticModelOpt, + this.positionOpt, + _escapeKeywordIdentifiers, + _lazyAliasMap, + isFirstSymbolVisited: true, + inNamespaceOrType); + } + protected override AbstractSymbolDisplayVisitor MakeNotFirstVisitor(bool inNamespaceOrType = false) { return new SymbolDisplayVisitor( diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index f9dec4b85e2b4..183aa21632873 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -11,6 +11,7 @@ Microsoft.CodeAnalysis.FlowAnalysis.IIsNullOperation.Operand.get -> Microsoft.Co Microsoft.CodeAnalysis.FlowAnalysis.IStaticLocalInitializationSemaphoreOperation Microsoft.CodeAnalysis.FlowAnalysis.IStaticLocalInitializationSemaphoreOperation.Local.get -> Microsoft.CodeAnalysis.ILocalSymbol Microsoft.CodeAnalysis.Operations.CommonConversion.IsImplicit.get -> bool +Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions.QualifyFirstSymbol = 64 -> Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions abstract Microsoft.CodeAnalysis.Compilation.ClassifyCommonConversion(Microsoft.CodeAnalysis.ITypeSymbol source, Microsoft.CodeAnalysis.ITypeSymbol destination) -> Microsoft.CodeAnalysis.Operations.CommonConversion abstract Microsoft.CodeAnalysis.Compilation.ContainsSymbolsWithName(string name, Microsoft.CodeAnalysis.SymbolFilter filter = Microsoft.CodeAnalysis.SymbolFilter.TypeAndMember, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> bool abstract Microsoft.CodeAnalysis.Compilation.GetSymbolsWithName(string name, Microsoft.CodeAnalysis.SymbolFilter filter = Microsoft.CodeAnalysis.SymbolFilter.TypeAndMember, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IEnumerable diff --git a/src/Compilers/Core/Portable/SymbolDisplay/AbstractSymbolDisplayVisitor.cs b/src/Compilers/Core/Portable/SymbolDisplay/AbstractSymbolDisplayVisitor.cs index 307d44d322d62..0155d6721f625 100644 --- a/src/Compilers/Core/Portable/SymbolDisplay/AbstractSymbolDisplayVisitor.cs +++ b/src/Compilers/Core/Portable/SymbolDisplay/AbstractSymbolDisplayVisitor.cs @@ -17,6 +17,7 @@ internal abstract partial class AbstractSymbolDisplayVisitor : SymbolVisitor protected readonly SemanticModel semanticModelOpt; protected readonly int positionOpt; + private AbstractSymbolDisplayVisitor _lazyFirstSymbolContainingTypeVisitor; private AbstractSymbolDisplayVisitor _lazyNotFirstVisitor; private AbstractSymbolDisplayVisitor _lazyNotFirstVisitorNamespaceOrType; @@ -45,6 +46,19 @@ protected AbstractSymbolDisplayVisitor( } } + protected AbstractSymbolDisplayVisitor FirstSymbolContainingTypeVisitor + { + get + { + if (_lazyFirstSymbolContainingTypeVisitor == null) + { + _lazyFirstSymbolContainingTypeVisitor = MakeFirstSymbolContainingTypeVisitor(); + } + + return _lazyFirstSymbolContainingTypeVisitor; + } + } + protected AbstractSymbolDisplayVisitor NotFirstVisitor { get @@ -71,6 +85,8 @@ protected AbstractSymbolDisplayVisitor NotFirstVisitorNamespaceOrType } } + protected abstract AbstractSymbolDisplayVisitor MakeFirstSymbolContainingTypeVisitor(); + protected abstract AbstractSymbolDisplayVisitor MakeNotFirstVisitor(bool inNamespaceOrType = false); protected abstract void AddLiteralValue(SpecialType type, object value); diff --git a/src/Compilers/Core/Portable/SymbolDisplay/AbstractSymbolDisplayVisitor_Minimal.cs b/src/Compilers/Core/Portable/SymbolDisplay/AbstractSymbolDisplayVisitor_Minimal.cs index d3bdf397bf719..b1374683d0af7 100644 --- a/src/Compilers/Core/Portable/SymbolDisplay/AbstractSymbolDisplayVisitor_Minimal.cs +++ b/src/Compilers/Core/Portable/SymbolDisplay/AbstractSymbolDisplayVisitor_Minimal.cs @@ -12,7 +12,38 @@ internal abstract partial class AbstractSymbolDisplayVisitor : SymbolVisitor protected bool IsMinimizing { - get { return this.semanticModelOpt != null; } + get + { + if (semanticModelOpt == null) + { + return false; + } + + if (isFirstSymbolVisited && format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.QualifyFirstSymbol)) + { + return false; + } + + return true; + } + } + + protected bool CanUseSpecialTypes + { + get + { + if (!format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.UseSpecialTypes)) + { + return false; + } + + if (isFirstSymbolVisited && format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.QualifyFirstSymbol)) + { + return false; + } + + return true; + } } protected bool NameBoundSuccessfullyToSameSymbol(INamedTypeSymbol symbol) diff --git a/src/Compilers/Core/Portable/SymbolDisplay/SymbolDisplayMiscellaneousOptions.cs b/src/Compilers/Core/Portable/SymbolDisplay/SymbolDisplayMiscellaneousOptions.cs index a71737cbe4bf7..9b77ec1883fb4 100644 --- a/src/Compilers/Core/Portable/SymbolDisplay/SymbolDisplayMiscellaneousOptions.cs +++ b/src/Compilers/Core/Portable/SymbolDisplay/SymbolDisplayMiscellaneousOptions.cs @@ -55,5 +55,13 @@ public enum SymbolDisplayMiscellaneousOptions /// the special question mark syntax. /// ExpandNullable = 1 << 5, + + /// + /// Suppresses minimization of the first visited symbol. + /// + /// + /// Has no effect outside . + /// + QualifyFirstSymbol = 1 << 6, } } diff --git a/src/Compilers/VisualBasic/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.vb b/src/Compilers/VisualBasic/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.vb index c9d368fd5c826..45764eb282ad6 100644 --- a/src/Compilers/VisualBasic/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.vb +++ b/src/Compilers/VisualBasic/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.vb @@ -89,7 +89,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return End If - If format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.UseSpecialTypes) Then + If CanUseSpecialTypes Then If AddSpecialTypeKeyword(symbol) Then Return End If @@ -157,7 +157,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Dim containingType = symbol.ContainingType If containingType IsNot Nothing Then visitedParents = True - containingType.Accept(Me.NotFirstVisitor()) + containingType.Accept(Me.FirstSymbolContainingTypeVisitor()) AddOperator(SyntaxKind.DotToken) End If End If diff --git a/src/Compilers/VisualBasic/Portable/SymbolDisplay/SymbolDisplayVisitor.vb b/src/Compilers/VisualBasic/Portable/SymbolDisplay/SymbolDisplayVisitor.vb index bde273f3056da..6d0d573d554a7 100644 --- a/src/Compilers/VisualBasic/Portable/SymbolDisplay/SymbolDisplayVisitor.vb +++ b/src/Compilers/VisualBasic/Portable/SymbolDisplay/SymbolDisplayVisitor.vb @@ -43,6 +43,21 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Me._escapeKeywordIdentifiers = escapeKeywordIdentifiers End Sub + Protected Overrides Function MakeFirstSymbolContainingTypeVisitor() As AbstractSymbolDisplayVisitor + If Not isFirstSymbolVisited OrElse format.KindOptions = SymbolDisplayKindOptions.None Then + Return Me + End If + + Return New SymbolDisplayVisitor( + Me.builder, + Me.format.WithKindOptions(SymbolDisplayKindOptions.None), + Me.semanticModelOpt, + Me.positionOpt, + Me._escapeKeywordIdentifiers, + isFirstSymbolVisited:=True, + inNamespaceOrType) + End Function + ' in case the display of a symbol is different for a type that acts as a container, use this visitor Protected Overrides Function MakeNotFirstVisitor(Optional inNamespaceOrType As Boolean = False) As AbstractSymbolDisplayVisitor Return New SymbolDisplayVisitor( diff --git a/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs b/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs index 42e40a249f537..1088b825d4add 100644 --- a/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs +++ b/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs @@ -745,7 +745,7 @@ public async Task TestEventHandler() { await TestInClassAsync( @"event $$EventHandler e;", - MainDescription("delegate void System.EventHandler(object sender, System.EventArgs e)")); + MainDescription("delegate void System.EventHandler(object sender, EventArgs e)")); } [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] @@ -913,6 +913,25 @@ await TestAsync(@"class C where $$T : IEnumerable", MainDescription($"T {FeaturesResources.in_} C where T : IEnumerable")); } + [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] + [WorkItem(547, "https://github.com/dotnet/roslyn/issues/547")] + public async Task TestMinimallyQualifiedConstraint2() + { + await TestAsync(@"using System.Collections.Generic; + +class C where T : struct where U : List +{ + void M() + { + v$$ar x = new C>(); + } +}", + MainDescription("class C where T : struct where U : List"), + TypeParameterMap(Lines( + $"\r\nT {FeaturesResources.is_} int", + $"U {FeaturesResources.is_} List"))); + } + [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] public async Task FullyQualifiedConstraint() { @@ -5747,7 +5766,7 @@ void M() } } " + TestResources.NetFX.ValueTuple.tuplelib_cs, - MainDescription("ValueTuple")); + MainDescription("ValueTuple")); } [WorkItem(18311, "https://github.com/dotnet/roslyn/issues/18311")] @@ -5783,7 +5802,7 @@ void M() } } " + TestResources.NetFX.ValueTuple.tuplelib_cs, - MainDescription("(System.Int32, System.Int32)")); + MainDescription("(int, int)")); } [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] diff --git a/src/EditorFeatures/VisualBasicTest/QuickInfo/SemanticQuickInfoSourceTests.vb b/src/EditorFeatures/VisualBasicTest/QuickInfo/SemanticQuickInfoSourceTests.vb index 42eb617599cad..b6841dc278eb3 100644 --- a/src/EditorFeatures/VisualBasicTest/QuickInfo/SemanticQuickInfoSourceTests.vb +++ b/src/EditorFeatures/VisualBasicTest/QuickInfo/SemanticQuickInfoSourceTests.vb @@ -287,7 +287,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.QuickInfo Public Async Function TestEventHandler() As Task Await TestInClassAsync("Dim e As $$EventHandler", - MainDescription("Delegate Sub System.EventHandler(sender As Object, e As System.EventArgs)", + MainDescription("Delegate Sub System.EventHandler(sender As Object, e As EventArgs)", ExpectedClassifications( Keyword("Delegate"), WhiteSpace(" "), @@ -308,8 +308,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.QuickInfo WhiteSpace(" "), Keyword("As"), WhiteSpace(" "), - Identifier("System"), - Operators.Dot, [Class]("EventArgs"), Punctuation.CloseParen))) End Function @@ -353,6 +351,32 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.QuickInfo MainDescription($"T1 {FeaturesResources.in_} C.Meth1(Of T1 As Class)")) End Function + + + Public Async Function TestMinimallyQualifiedConstraint() As Task + Await TestAsync( + Class C(Of T As Structure, U As List(Of T)) + Sub M() + D$$im x = New C(Of Integer, List(Of Integer))() + End Sub + End Class + .NormalizedValue, + MainDescription($"Class C(Of T As Structure, U As List(Of T))"), + TypeParameterMap(Lines( + vbCrLf & $"T {FeaturesResources.is_} Integer", + $"U {FeaturesResources.is_} List(Of Integer)"))) + End Function + + + + Public Async Function TestNestedInGeneric() As Task + Await TestInMethodAsync( + Dim e As List(Of Integer).Enu$$merator + .NormalizedValue, + MainDescription($"Structure System.Collections.Generic.List(Of T).Enumerator"), + TypeParameterMap(vbCrLf & $"T {FeaturesResources.is_} Integer")) + End Function + Public Async Function TestParameter() As Task diff --git a/src/Features/Core/Portable/LanguageServices/SymbolDisplayService/AbstractSymbolDisplayService.AbstractSymbolDescriptionBuilder.cs b/src/Features/Core/Portable/LanguageServices/SymbolDisplayService/AbstractSymbolDisplayService.AbstractSymbolDescriptionBuilder.cs index 8798088ce24cc..fa422e89ab955 100644 --- a/src/Features/Core/Portable/LanguageServices/SymbolDisplayService/AbstractSymbolDisplayService.AbstractSymbolDescriptionBuilder.cs +++ b/src/Features/Core/Portable/LanguageServices/SymbolDisplayService/AbstractSymbolDisplayService.AbstractSymbolDescriptionBuilder.cs @@ -66,12 +66,13 @@ protected abstract partial class AbstractSymbolDescriptionBuilder delegateStyle: SymbolDisplayDelegateStyle.NameAndSignature, genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeVariance | SymbolDisplayGenericsOptions.IncludeTypeConstraints, parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeParamsRefOut, - miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers, + miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.QualifyFirstSymbol, kindOptions: SymbolDisplayKindOptions.IncludeNamespaceKeyword | SymbolDisplayKindOptions.IncludeTypeKeyword); private static readonly SymbolDisplayFormat s_globalNamespaceStyle = new SymbolDisplayFormat( - globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included); + globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included, + miscellaneousOptions: SymbolDisplayMiscellaneousOptions.QualifyFirstSymbol); private readonly ISymbolDisplayService _displayService; private readonly SemanticModel _semanticModel; @@ -394,17 +395,7 @@ private async Task AddDescriptionForNamedTypeAsync(INamedTypeSymbol symbol) } } - if (symbol.TypeKind == TypeKind.Delegate) - { - var style = s_descriptionStyle.WithMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes); - AddToGroup(SymbolDescriptionGroups.MainDescription, - ToDisplayParts(symbol.OriginalDefinition, style)); - } - else - { - AddToGroup(SymbolDescriptionGroups.MainDescription, - ToDisplayParts(symbol.OriginalDefinition, s_descriptionStyle)); - } + AddToGroup(SymbolDescriptionGroups.MainDescription, ToMinimalDisplayParts(symbol.OriginalDefinition, s_descriptionStyle)); if (!symbol.IsUnboundGenericType && !TypeArgumentsAndParametersAreSame(symbol)) { @@ -440,12 +431,12 @@ private void AddDescriptionForNamespace(INamespaceSymbol symbol) if (symbol.IsGlobalNamespace) { AddToGroup(SymbolDescriptionGroups.MainDescription, - ToDisplayParts(symbol, s_globalNamespaceStyle)); + ToMinimalDisplayParts(symbol, s_globalNamespaceStyle)); } else { AddToGroup(SymbolDescriptionGroups.MainDescription, - ToDisplayParts(symbol, s_descriptionStyle)); + ToMinimalDisplayParts(symbol, s_descriptionStyle)); } } @@ -727,11 +718,6 @@ protected ImmutableArray ToMinimalDisplayParts(ISymbol symbol return _displayService.ToMinimalDisplayParts(_semanticModel, _position, symbol, format); } - protected IEnumerable ToDisplayParts(ISymbol symbol, SymbolDisplayFormat format = null) - { - return _displayService.ToDisplayParts(symbol, format); - } - private IEnumerable Part(SymbolDisplayPartKind kind, ISymbol symbol, string text) { yield return new SymbolDisplayPart(kind, symbol, text); From b26f9a3aadc9c3462838088ac6e6d744707b219e Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Wed, 20 Jun 2018 16:17:11 -0500 Subject: [PATCH 2/3] Fix failure to preserve CompilerInternalOptions during transformations --- .../SymbolDisplay/SymbolDisplayFormat.cs | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Compilers/Core/Portable/SymbolDisplay/SymbolDisplayFormat.cs b/src/Compilers/Core/Portable/SymbolDisplay/SymbolDisplayFormat.cs index c0014a834c14d..023730046ea3a 100644 --- a/src/Compilers/Core/Portable/SymbolDisplay/SymbolDisplayFormat.cs +++ b/src/Compilers/Core/Portable/SymbolDisplay/SymbolDisplayFormat.cs @@ -414,13 +414,14 @@ internal SymbolDisplayFormat( public SymbolDisplayFormat WithMiscellaneousOptions(SymbolDisplayMiscellaneousOptions options) { return new SymbolDisplayFormat( + this.CompilerInternalOptions, this.GlobalNamespaceStyle, this.TypeQualificationStyle, this.GenericsOptions, this.MemberOptions, + this.ParameterOptions, this.DelegateStyle, this.ExtensionMethodStyle, - this.ParameterOptions, this.PropertyStyle, this.LocalOptions, this.KindOptions, @@ -462,13 +463,14 @@ public SymbolDisplayFormat RemoveMiscellaneousOptions(SymbolDisplayMiscellaneous public SymbolDisplayFormat WithGenericsOptions(SymbolDisplayGenericsOptions options) { return new SymbolDisplayFormat( + this.CompilerInternalOptions, this.GlobalNamespaceStyle, this.TypeQualificationStyle, options, this.MemberOptions, + this.ParameterOptions, this.DelegateStyle, this.ExtensionMethodStyle, - this.ParameterOptions, this.PropertyStyle, this.LocalOptions, this.KindOptions, @@ -511,13 +513,14 @@ public SymbolDisplayFormat RemoveGenericsOptions(SymbolDisplayGenericsOptions op public SymbolDisplayFormat WithMemberOptions(SymbolDisplayMemberOptions options) { return new SymbolDisplayFormat( + this.CompilerInternalOptions, this.GlobalNamespaceStyle, this.TypeQualificationStyle, this.GenericsOptions, options, + this.ParameterOptions, this.DelegateStyle, this.ExtensionMethodStyle, - this.ParameterOptions, this.PropertyStyle, this.LocalOptions, this.KindOptions, @@ -564,13 +567,14 @@ public SymbolDisplayFormat RemoveMemberOptions(SymbolDisplayMemberOptions option public SymbolDisplayFormat WithKindOptions(SymbolDisplayKindOptions options) { return new SymbolDisplayFormat( + this.CompilerInternalOptions, this.GlobalNamespaceStyle, this.TypeQualificationStyle, this.GenericsOptions, this.MemberOptions, + this.ParameterOptions, this.DelegateStyle, this.ExtensionMethodStyle, - this.ParameterOptions, this.PropertyStyle, this.LocalOptions, options, @@ -615,13 +619,14 @@ public SymbolDisplayFormat RemoveKindOptions(SymbolDisplayKindOptions options) public SymbolDisplayFormat WithParameterOptions(SymbolDisplayParameterOptions options) { return new SymbolDisplayFormat( + this.CompilerInternalOptions, this.GlobalNamespaceStyle, this.TypeQualificationStyle, this.GenericsOptions, this.MemberOptions, + options, this.DelegateStyle, this.ExtensionMethodStyle, - options, this.PropertyStyle, this.LocalOptions, this.KindOptions, @@ -666,13 +671,14 @@ public SymbolDisplayFormat RemoveParameterOptions(SymbolDisplayParameterOptions public SymbolDisplayFormat WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle style) { return new SymbolDisplayFormat( + this.CompilerInternalOptions, style, this.TypeQualificationStyle, this.GenericsOptions, this.MemberOptions, + this.ParameterOptions, this.DelegateStyle, this.ExtensionMethodStyle, - this.ParameterOptions, this.PropertyStyle, this.LocalOptions, this.KindOptions, @@ -689,13 +695,14 @@ public SymbolDisplayFormat WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespace public SymbolDisplayFormat WithLocalOptions(SymbolDisplayLocalOptions options) { return new SymbolDisplayFormat( + this.CompilerInternalOptions, this.GlobalNamespaceStyle, this.TypeQualificationStyle, this.GenericsOptions, this.MemberOptions, + this.ParameterOptions, this.DelegateStyle, this.ExtensionMethodStyle, - this.ParameterOptions, this.PropertyStyle, options, this.KindOptions, From e282986d3326a1dbb778cae1e264a1e379a04948 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 21 Jun 2018 07:37:44 -0500 Subject: [PATCH 3/3] Fix expected error messages for nested types Previously, containing types of a nested type were not treated as the "first type" by the symbol display visitor, so generic type constraints were omitted from the displayed result even when SymbolDisplayGenericsOptions.IncludeTypeConstraints was specified in the format. In the new code, containing types of a nested type are still treated as part of the "first type", so the generic constraints are included in the symbol display text. --- .../VisualBasic/Test/Semantic/Semantics/AccessCheck.vb | 4 ++-- .../Test/Symbol/SymbolsTests/GenericConstraintTests.vb | 8 ++++---- .../Test/Symbol/SymbolsTests/InstantiatingGenerics.vb | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/AccessCheck.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/AccessCheck.vb index 3b1c8580012d4..a13d67e0515e2 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/AccessCheck.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/AccessCheck.vb @@ -1864,10 +1864,10 @@ End Class CompilationUtils.AssertTheseDiagnostics(compilation, -BC30508: 'B' cannot expose type 'A.B(Of T).C' in class 'A' through class 'B'. +BC30508: 'B' cannot expose type 'A.B(Of T As A.B(Of T).C).C' in class 'A' through class 'B'. Private Class B(Of T As B(Of T).C) ~~~~~~~~~ -BC30508: 'D' cannot expose type 'A.B(Of T).C' in class 'A' through class 'B'. +BC30508: 'D' cannot expose type 'A.B(Of T As A.B(Of T).C).C' in class 'A' through class 'B'. Public Sub D(Of S As C)() ~ ) diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/GenericConstraintTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/GenericConstraintTests.vb index c973e61567213..1ea8cddbc0986 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/GenericConstraintTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/GenericConstraintTests.vb @@ -363,7 +363,7 @@ End Class BC30909: 'B' cannot expose type 'A' outside the project through class 'B'. Public Class B(Of T As A, U As C) ~ -BC30508: 'B' cannot expose type 'B(Of T, U).C' in namespace '' through class 'B'. +BC30508: 'B' cannot expose type 'B(Of T As A, U As B(Of T, U).C).C' in namespace '' through class 'B'. Public Class B(Of T As A, U As C) ~ ]]> @@ -2931,7 +2931,7 @@ BC36739: Type 'IT(Of T).IAI' does not inherit the generic type parameters of its BC36739: Type 'IT(Of T).IAI.IAI' does not inherit the generic type parameters of its container. Implements IT(Of Object).IAI.IAI ' BC36739 (not reported by Dev11) ~~~~~~~~~~~~~~~~~~~~~ -BC36739: Type 'ITU(Of T, U).ITU2' does not inherit the generic type parameters of its container. +BC36739: Type 'ITU(Of T, U As T).ITU2' does not inherit the generic type parameters of its container. Implements ITU(Of Object, Object).ITU2 ' BC36739 (not reported by Dev11) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ BC36739: Type 'IT(Of T).IF' does not inherit the generic type parameters of its container. @@ -2940,10 +2940,10 @@ BC36739: Type 'IT(Of T).IF' does not inherit the generic type parameters of its BC36739: Type 'IT(Of T).IIn' does not inherit the generic type parameters of its container. Implements IT(Of Object).IIn ' BC36739 ~~~~~~~~~~~~~~~~~ -BC36739: Type 'IAI(Of T).IT' does not inherit the generic type parameters of its container. +BC36739: Type 'IAI(Of T As {A, I}).IT' does not inherit the generic type parameters of its container. Implements IAI(Of C).IT ' BC36739 (not reported by Dev11) ~~~~~~~~~~~~ -BC36739: Type 'CF(Of T).CT' does not inherit the generic type parameters of its container. +BC36739: Type 'CF(Of T As {Class, New}).CT' does not inherit the generic type parameters of its container. Inherits CF(Of C).CT ' BC36739 ~~~~~~~~~~~ BC36739: Type 'IIn(Of In T).IT' does not inherit the generic type parameters of its container. diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/InstantiatingGenerics.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/InstantiatingGenerics.vb index d5a4b903789eb..527572faf55fa 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/InstantiatingGenerics.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/InstantiatingGenerics.vb @@ -704,7 +704,7 @@ End Class Assert.Equal("C1(Of C1T1, C1T2) : {C1T1->Integer, C1T2->Integer}", substitution1.ToString()) substitution2 = TypeSubstitution.Create(c4, {c3.TypeParameters(0), c4.TypeParameters(0)}, {bte, chr}) - Assert.Equal("C1(Of C1T1, C1T2).C2(Of C2T1, C2T2).C3(Of C3T1, C3T2).C4(Of C4T1) : {C3T1->Byte}, {C4T1->Char}", substitution2.ToString()) + Assert.Equal("C1(Of C1T1, C1T2).C2(Of C2T1, C2T2).C3(Of C3T1, C3T2 As C1T1).C4(Of C4T1) : {C3T1->Byte}, {C4T1->Char}", substitution2.ToString()) Assert.Same(substitution1, TypeSubstitution.Concat(c1, Nothing, substitution1)) Assert.Same(substitution1, TypeSubstitution.Concat(c1, substitution1, Nothing)) @@ -714,7 +714,7 @@ End Class Assert.Equal("C1(Of C1T1, C1T2).C2(Of C2T1, C2T2) : {C1T1->Integer, C1T2->Integer}, {}", substitution3.ToString()) substitution3 = TypeSubstitution.Concat(c4, substitution1, substitution2) - Assert.Equal("C1(Of C1T1, C1T2).C2(Of C2T1, C2T2).C3(Of C3T1, C3T2).C4(Of C4T1) : {C1T1->Integer, C1T2->Integer}, {}, {C3T1->Byte}, {C4T1->Char}", substitution3.ToString()) + Assert.Equal("C1(Of C1T1, C1T2).C2(Of C2T1, C2T2).C3(Of C3T1, C3T2 As C1T1).C4(Of C4T1) : {C1T1->Integer, C1T2->Integer}, {}, {C3T1->Byte}, {C4T1->Char}", substitution3.ToString()) Assert.Null(TypeSubstitution.Create(c4, {c1.TypeParameters(0)}, {c1.TypeParameters(0)})) End Sub