diff --git a/src/EditorFeatures/CSharp/NavigationBar/CSharpNavigationBarItemService.cs b/src/EditorFeatures/CSharp/NavigationBar/CSharpNavigationBarItemService.cs index 37cc600e7653f5a84b4ac3efe544635c4efa0bcc..b349eb0226105f5fa4b9eb43ea6824a53b597d25 100644 --- a/src/EditorFeatures/CSharp/NavigationBar/CSharpNavigationBarItemService.cs +++ b/src/EditorFeatures/CSharp/NavigationBar/CSharpNavigationBarItemService.cs @@ -36,7 +36,9 @@ internal class CSharpNavigationBarItemService : AbstractNavigationBarItemService SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeDefaultValue | SymbolDisplayParameterOptions.IncludeParamsRefOut, - miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral); + miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes | + SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral | + SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier); [ImportingConstructor] public CSharpNavigationBarItemService() diff --git a/src/EditorFeatures/Test2/NavigationBar/CSharpNavigationBarTests.vb b/src/EditorFeatures/Test2/NavigationBar/CSharpNavigationBarTests.vb index fe420ad744d330036594d8768969304705dbfbe1..6f8d6ae8e90d9f1d3a2a66c440d5143824730912 100644 --- a/src/EditorFeatures/Test2/NavigationBar/CSharpNavigationBarTests.vb +++ b/src/EditorFeatures/Test2/NavigationBar/CSharpNavigationBarTests.vb @@ -240,5 +240,19 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.NavigationBar Item("M()", Glyph.MethodPrivate), Item("M()", Glyph.MethodPrivate, grayed:=True)})) End Function + + + Public Async Function TestNullableReferenceTypesInParameters() As Task + Await AssertItemsAreAsync( + + + #nullable enable + using System.Collections.Generic; + class C { void M(string? s, IEnumerable<string?> e) { } + + , + Item("C", Glyph.ClassInternal, children:={ + Item("M(string? s, IEnumerable e)", Glyph.MethodPrivate)})) + End Function End Class End Namespace diff --git a/src/VisualStudio/Core/Def/Implementation/ExtractInterface/ExtractInterfaceDialog.xaml b/src/VisualStudio/Core/Def/Implementation/ExtractInterface/ExtractInterfaceDialog.xaml index 8b4ffea60e232de6aa9cc810bcf8ff8c21bc2489..1b2b6b5eaabb544b2a8197be577c13684eaae8fc 100644 --- a/src/VisualStudio/Core/Def/Implementation/ExtractInterface/ExtractInterfaceDialog.xaml +++ b/src/VisualStudio/Core/Def/Implementation/ExtractInterface/ExtractInterfaceDialog.xaml @@ -136,17 +136,17 @@ + AutomationProperties.AutomationId="{Binding SymbolName}"> + Text="{Binding SymbolName}"/> diff --git a/src/VisualStudio/Core/Def/Implementation/ExtractInterface/ExtractInterfaceDialogViewModel.cs b/src/VisualStudio/Core/Def/Implementation/ExtractInterface/ExtractInterfaceDialogViewModel.cs index cd61d0a8e98d413850cce3d597e6b9a207b66990..19f7480a1165953e536f73315cba306f030797a1 100644 --- a/src/VisualStudio/Core/Def/Implementation/ExtractInterface/ExtractInterfaceDialogViewModel.cs +++ b/src/VisualStudio/Core/Def/Implementation/ExtractInterface/ExtractInterfaceDialogViewModel.cs @@ -4,15 +4,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Windows.Media; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.Notification; -using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.VisualStudio.Language.Intellisense; using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities; -using Microsoft.VisualStudio.LanguageServices.Utilities; using Roslyn.Utilities; namespace Microsoft.VisualStudio.LanguageServices.Implementation.ExtractInterface @@ -55,7 +51,7 @@ internal class ExtractInterfaceDialogViewModel : AbstractNotifyPropertyChanged _generatedNameTypeParameterSuffix = generatedNameTypeParameterSuffix; _languageName = languageName; - MemberContainers = extractableMembers.Select(m => new MemberSymbolViewModel(m, glyphService)).OrderBy(s => s.MemberName).ToList(); + MemberContainers = extractableMembers.Select(m => new MemberSymbolViewModel(m, glyphService)).OrderBy(s => s.SymbolName).ToList(); } internal bool TrySubmit() @@ -173,45 +169,10 @@ public InterfaceDestination Destination public bool FileNameEnabled => Destination == InterfaceDestination.NewFile; - internal class MemberSymbolViewModel : AbstractNotifyPropertyChanged + internal class MemberSymbolViewModel : SymbolViewModel { - private readonly IGlyphService _glyphService; - - public ISymbol MemberSymbol { get; } - - private static readonly SymbolDisplayFormat s_memberDisplayFormat = new SymbolDisplayFormat( - genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, - memberOptions: SymbolDisplayMemberOptions.IncludeParameters, - parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeParamsRefOut | SymbolDisplayParameterOptions.IncludeOptionalBrackets, - miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes); - - public MemberSymbolViewModel(ISymbol symbol, IGlyphService glyphService) - { - MemberSymbol = symbol; - _glyphService = glyphService; - _isChecked = true; - } - - private bool _isChecked; - public bool IsChecked - { - get { return _isChecked; } - set { SetProperty(ref _isChecked, value); } - } - - public string MemberName - { - get { return MemberSymbol.ToDisplayString(s_memberDisplayFormat); } - } - - public ImageSource Glyph - { - get { return MemberSymbol.GetGlyph().GetImageSource(_glyphService); } - } - - public string MemberAutomationText + public MemberSymbolViewModel(ISymbol symbol, IGlyphService glyphService) : base(symbol, glyphService) { - get { return MemberSymbol.Kind + " " + MemberName; } } } } diff --git a/src/VisualStudio/Core/Def/Implementation/ExtractInterface/VisualStudioExtractInterfaceOptionsService.cs b/src/VisualStudio/Core/Def/Implementation/ExtractInterface/VisualStudioExtractInterfaceOptionsService.cs index 2c48d5752c6524fce43ec7ed3c187c62367bc432..d2ee2516323c28a2e61b523ada2badc1c0423633 100644 --- a/src/VisualStudio/Core/Def/Implementation/ExtractInterface/VisualStudioExtractInterfaceOptionsService.cs +++ b/src/VisualStudio/Core/Def/Implementation/ExtractInterface/VisualStudioExtractInterfaceOptionsService.cs @@ -57,7 +57,7 @@ public VisualStudioExtractInterfaceOptionsService(IGlyphService glyphService, IT if (result.HasValue && result.Value) { - var includedMembers = viewModel.MemberContainers.Where(c => c.IsChecked).Select(c => c.MemberSymbol); + var includedMembers = viewModel.MemberContainers.Where(c => c.IsChecked).Select(c => c.Symbol); return new ExtractInterfaceOptionsResult( isCancelled: false, diff --git a/src/VisualStudio/Core/Def/Implementation/PickMembers/PickMembersDialog.xaml b/src/VisualStudio/Core/Def/Implementation/PickMembers/PickMembersDialog.xaml index 223fd777b2e8c944070d976b4e0a2639c5a7080d..496a5a5c7b62e2c6dc3eb0fa54c34b758f50cf12 100644 --- a/src/VisualStudio/Core/Def/Implementation/PickMembers/PickMembersDialog.xaml +++ b/src/VisualStudio/Core/Def/Implementation/PickMembers/PickMembersDialog.xaml @@ -74,17 +74,17 @@ + AutomationProperties.AutomationId="{Binding SymbolName}"> + Text="{Binding SymbolName}"/> diff --git a/src/VisualStudio/Core/Def/Implementation/PickMembers/PickMembersDialogViewModel.cs b/src/VisualStudio/Core/Def/Implementation/PickMembers/PickMembersDialogViewModel.cs index cd29dd98c3cfe93805ab8f45feae7f05e743c61e..c01ed44684e287654c0329ad8fdef17d8802b5e7 100644 --- a/src/VisualStudio/Core/Def/Implementation/PickMembers/PickMembersDialogViewModel.cs +++ b/src/VisualStudio/Core/Def/Implementation/PickMembers/PickMembersDialogViewModel.cs @@ -4,15 +4,10 @@ using System.Collections.Immutable; using System.Diagnostics; using System.Linq; -using System.Windows.Media; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.PickMembers; -using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.VisualStudio.Language.Intellisense; using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities; -using Microsoft.VisualStudio.LanguageServices.Utilities; -using Roslyn.Utilities; namespace Microsoft.VisualStudio.LanguageServices.Implementation.PickMembers { @@ -80,7 +75,7 @@ public string MoveUpAutomationText return string.Empty; } - return string.Format(ServicesVSResources.Move_0_above_1, MemberContainers[SelectedIndex.Value].MemberAutomationText, MemberContainers[SelectedIndex.Value - 1].MemberAutomationText); + return string.Format(ServicesVSResources.Move_0_above_1, MemberContainers[SelectedIndex.Value].SymbolAutomationText, MemberContainers[SelectedIndex.Value - 1].SymbolAutomationText); } } @@ -93,12 +88,10 @@ public string MoveDownAutomationText return string.Empty; } - return string.Format(ServicesVSResources.Move_0_below_1, MemberContainers[SelectedIndex.Value].MemberAutomationText, MemberContainers[SelectedIndex.Value + 1].MemberAutomationText); + return string.Format(ServicesVSResources.Move_0_below_1, MemberContainers[SelectedIndex.Value].SymbolAutomationText, MemberContainers[SelectedIndex.Value + 1].SymbolAutomationText); } } - - public bool CanMoveUp { get @@ -152,37 +145,11 @@ private void Move(List list, int index, int delta) SelectedIndex += delta; } - internal class MemberSymbolViewModel : AbstractNotifyPropertyChanged + internal class MemberSymbolViewModel : SymbolViewModel { - private readonly IGlyphService _glyphService; - - public ISymbol MemberSymbol { get; } - - private static SymbolDisplayFormat s_memberDisplayFormat = new SymbolDisplayFormat( - genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, - memberOptions: SymbolDisplayMemberOptions.IncludeParameters, - parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeParamsRefOut | SymbolDisplayParameterOptions.IncludeOptionalBrackets, - miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes); - - public MemberSymbolViewModel(ISymbol symbol, IGlyphService glyphService) + public MemberSymbolViewModel(ISymbol symbol, IGlyphService glyphService) : base(symbol, glyphService) { - MemberSymbol = symbol; - _glyphService = glyphService; - _isChecked = true; } - - private bool _isChecked; - public bool IsChecked - { - get { return _isChecked; } - set { SetProperty(ref _isChecked, value); } - } - - public string MemberName => MemberSymbol.ToDisplayString(s_memberDisplayFormat); - - public ImageSource Glyph => MemberSymbol.GetGlyph().GetImageSource(_glyphService); - - public string MemberAutomationText => MemberSymbol.Kind + " " + MemberName; } internal class OptionViewModel : AbstractNotifyPropertyChanged diff --git a/src/VisualStudio/Core/Def/Implementation/PickMembers/VisualStudioPickMembersService.cs b/src/VisualStudio/Core/Def/Implementation/PickMembers/VisualStudioPickMembersService.cs index 8d45b844004661c23d0dc8be9ef7ebb1d319d132..c96962f9699bff87812c7b95a75944c08f731729 100644 --- a/src/VisualStudio/Core/Def/Implementation/PickMembers/VisualStudioPickMembersService.cs +++ b/src/VisualStudio/Core/Def/Implementation/PickMembers/VisualStudioPickMembersService.cs @@ -34,7 +34,7 @@ public VisualStudioPickMembersService(IGlyphService glyphService) { return new PickMembersResult( viewModel.MemberContainers.Where(c => c.IsChecked) - .Select(c => c.MemberSymbol) + .Select(c => c.Symbol) .ToImmutableArray(), options); } diff --git a/src/VisualStudio/Core/Def/Implementation/Utilities/SymbolViewModel.cs b/src/VisualStudio/Core/Def/Implementation/Utilities/SymbolViewModel.cs index 55004c3796c515b7cd9a835b96779da976db6783..092f7a12899b2ad8af478499613d9e7248092389 100644 --- a/src/VisualStudio/Core/Def/Implementation/Utilities/SymbolViewModel.cs +++ b/src/VisualStudio/Core/Def/Implementation/Utilities/SymbolViewModel.cs @@ -17,14 +17,14 @@ internal class SymbolViewModel : AbstractNotifyPropertyChanged where T : ISym genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, memberOptions: SymbolDisplayMemberOptions.IncludeParameters, parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeParamsRefOut | SymbolDisplayParameterOptions.IncludeOptionalBrackets, - miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes); + miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier); private static readonly SymbolDisplayFormat s_symbolAutomationFormat = new SymbolDisplayFormat( genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, memberOptions: SymbolDisplayMemberOptions.IncludeParameters, parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeParamsRefOut | SymbolDisplayParameterOptions.IncludeOptionalBrackets, kindOptions: SymbolDisplayKindOptions.IncludeTypeKeyword, - miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes); + miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier); public SymbolViewModel(T symbol, IGlyphService glyphService) { diff --git a/src/VisualStudio/Core/Test/ExtractInterface/ExtractInterfaceViewModelTests.vb b/src/VisualStudio/Core/Test/ExtractInterface/ExtractInterfaceViewModelTests.vb index 0941a4c5dbec924fb0629d7b6a425a25af3f4a46..ee7c13a8d4b93e647c6aa4aeb14aee6a2f8edc19 100644 --- a/src/VisualStudio/Core/Test/ExtractInterface/ExtractInterfaceViewModelTests.vb +++ b/src/VisualStudio/Core/Test/ExtractInterface/ExtractInterfaceViewModelTests.vb @@ -394,7 +394,7 @@ class $$MyClass }"]]> Dim viewModel = Await GetViewModelAsync(markup, LanguageNames.CSharp, "IMyClass") - Assert.Equal("Goo(T, CorrelationManager, ref int, [int?], [string], params int[])", viewModel.MemberContainers.Single().MemberName) + Assert.Equal("Goo(T, CorrelationManager, ref int, [int?], [string], params int[])", viewModel.MemberContainers.Single().SymbolName) End Function @@ -411,7 +411,7 @@ class $$MyClass }"]]> Dim viewModel = Await GetViewModelAsync(markup, LanguageNames.CSharp, "IMyClass") - Assert.Equal("Goo", viewModel.MemberContainers.Where(Function(c) c.MemberSymbol.IsKind(SymbolKind.Property)).Single().MemberName) + Assert.Equal("Goo", viewModel.MemberContainers.Where(Function(c) c.Symbol.IsKind(SymbolKind.Property)).Single().SymbolName) End Function @@ -424,7 +424,22 @@ class $$MyClass }"]]> Dim viewModel = Await GetViewModelAsync(markup, LanguageNames.CSharp, "IMyClass") - Assert.Equal("this[int?, [string]]", viewModel.MemberContainers.Where(Function(c) c.MemberSymbol.IsKind(SymbolKind.Property)).Single().MemberName) + Assert.Equal("this[int?, [string]]", viewModel.MemberContainers.Where(Function(c) c.Symbol.IsKind(SymbolKind.Property)).Single().SymbolName) + End Function + + + + Public Async Function TestExtractInterface_MemberDisplay_NullableReferenceType() As Task + Dim markup = e) { } +}"]]> + + Dim viewModel = Await GetViewModelAsync(markup, LanguageNames.CSharp, "IMyClass") + Assert.Equal("M(string?, IEnumerable)", viewModel.MemberContainers.Single(Function(c) c.Symbol.IsKind(SymbolKind.Method)).SymbolName) End Function @@ -441,11 +456,11 @@ public class $$MyClass Dim viewModel = Await GetViewModelAsync(markup, LanguageNames.CSharp, "IMyClass") Assert.Equal(5, viewModel.MemberContainers.Count) - Assert.Equal("Goo()", viewModel.MemberContainers.ElementAt(0).MemberName) - Assert.Equal("Goo(int)", viewModel.MemberContainers.ElementAt(1).MemberName) - Assert.Equal("Goo(int, int)", viewModel.MemberContainers.ElementAt(2).MemberName) - Assert.Equal("Goo(int, string)", viewModel.MemberContainers.ElementAt(3).MemberName) - Assert.Equal("Goo(string)", viewModel.MemberContainers.ElementAt(4).MemberName) + Assert.Equal("Goo()", viewModel.MemberContainers.ElementAt(0).SymbolName) + Assert.Equal("Goo(int)", viewModel.MemberContainers.ElementAt(1).SymbolName) + Assert.Equal("Goo(int, int)", viewModel.MemberContainers.ElementAt(2).SymbolName) + Assert.Equal("Goo(int, string)", viewModel.MemberContainers.ElementAt(3).SymbolName) + Assert.Equal("Goo(string)", viewModel.MemberContainers.ElementAt(4).SymbolName) End Function Private Async Function GetViewModelAsync(markup As XElement, diff --git a/src/VisualStudio/IntegrationTest/TestUtilities/InProcess/ExtractInterfaceDialog_InProc.cs b/src/VisualStudio/IntegrationTest/TestUtilities/InProcess/ExtractInterfaceDialog_InProc.cs index 30839999bbb748f4ffa7a088c0a7aac86ab2e786..6cdfafe9cd66f4ecdfc019114d47c4b650c349eb 100644 --- a/src/VisualStudio/IntegrationTest/TestUtilities/InProcess/ExtractInterfaceDialog_InProc.cs +++ b/src/VisualStudio/IntegrationTest/TestUtilities/InProcess/ExtractInterfaceDialog_InProc.cs @@ -124,7 +124,7 @@ public string[] GetSelectedItems() return listItems.Cast() .Where(viewModel => viewModel.IsChecked) - .Select(viewModel => viewModel.MemberName) + .Select(viewModel => viewModel.SymbolName) .ToArray(); }); } @@ -142,7 +142,7 @@ public void ToggleItem(string item) var memberSelectionList = dialog.GetTestAccessor().Members; var items = memberSelectionList.Items.Cast().ToArray(); - var itemViewModel = items.Single(x => x.MemberName == item); + var itemViewModel = items.Single(x => x.SymbolName == item); itemViewModel.IsChecked = !itemViewModel.IsChecked; // Wait for changes to propagate