提交 651452ee 编写于 作者: J Jason Malinowski

Add nullable annotations to the "extract interface" dialog

Fixes https://github.com/dotnet/roslyn/issues/37176
上级 0a6d482a
......@@ -136,17 +136,17 @@
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox x:Uid="SelectableMemberCheckBox"
AutomationProperties.Name="{Binding MemberAutomationText}"
AutomationProperties.Name="{Binding SymbolAutomationText}"
IsChecked="{Binding IsChecked, Mode=TwoWay}"
Width="Auto"
Focusable="False"
AutomationProperties.AutomationId="{Binding MemberName}">
AutomationProperties.AutomationId="{Binding SymbolName}">
</CheckBox>
<Image x:Uid="SelectableMemberGlyph"
Margin="8,0,0,0"
Source="{Binding Glyph}"/>
<TextBlock x:Uid="SelectableMemberName"
Text="{Binding MemberName}"/>
Text="{Binding SymbolName}"/>
</StackPanel>
</DataTemplate>
</u:AutomationDelegatingListView.ItemTemplate>
......
......@@ -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<ISymbol>
{
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; }
}
}
}
......
......@@ -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,
......
......@@ -394,7 +394,7 @@ class $$MyClass
}"]]></Text>
Dim viewModel = Await GetViewModelAsync(markup, LanguageNames.CSharp, "IMyClass")
Assert.Equal("Goo<T>(T, CorrelationManager, ref int, [int?], [string], params int[])", viewModel.MemberContainers.Single().MemberName)
Assert.Equal("Goo<T>(T, CorrelationManager, ref int, [int?], [string], params int[])", viewModel.MemberContainers.Single().SymbolName)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.ExtractInterface)>
......@@ -411,7 +411,7 @@ class $$MyClass
}"]]></Text>
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
<Fact, Trait(Traits.Feature, Traits.Features.ExtractInterface)>
......@@ -424,7 +424,22 @@ class $$MyClass
}"]]></Text>
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
<Fact, Trait(Traits.Feature, Traits.Features.ExtractInterface)>
<WorkItem(37176, "https://github.com/dotnet/roslyn/issues/37176")>
Public Async Function TestExtractInterface_MemberDisplay_NullableReferenceType() As Task
Dim markup = <Text><![CDATA[
#nullable enable
using System.Collections.Generic;
class $$MyClass
{
public void M(string? s, IEnumerable<string?> e) { }
}"]]></Text>
Dim viewModel = Await GetViewModelAsync(markup, LanguageNames.CSharp, "IMyClass")
Assert.Equal("M(string?, IEnumerable<string?>)", viewModel.MemberContainers.Single(Function(c) c.Symbol.IsKind(SymbolKind.Method)).SymbolName)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.ExtractInterface)>
......@@ -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,
......
......@@ -124,7 +124,7 @@ public string[] GetSelectedItems()
return listItems.Cast<ExtractInterfaceDialogViewModel.MemberSymbolViewModel>()
.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<ExtractInterfaceDialogViewModel.MemberSymbolViewModel>().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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册