|
// 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.Composition;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeRefactorings.PullMemberUp.Dialog;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.PullMemberUp;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.LanguageServices.Implementation.PullMemberUp.MainDialog;
using Microsoft.VisualStudio.LanguageServices.Utilities;
using Microsoft.VisualStudio.Utilities;
using Roslyn.Utilities;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.PullMemberUp;
[ExportWorkspaceService(typeof(IPullMemberUpOptionsService), ServiceLayer.Host), Shared]
internal class VisualStudioPullMemberUpService : IPullMemberUpOptionsService
{
private readonly IGlyphService _glyphService;
private readonly IUIThreadOperationExecutor _uiThreadOperationExecutor;
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public VisualStudioPullMemberUpService(IGlyphService glyphService, IUIThreadOperationExecutor uiThreadOperationExecutor)
{
_glyphService = glyphService;
_uiThreadOperationExecutor = uiThreadOperationExecutor;
}
public PullMembersUpOptions GetPullMemberUpOptions(Document document, ImmutableArray<ISymbol> selectedMembers)
{
// all selected members must have the same containing type
var containingType = selectedMembers[0].ContainingType;
var membersInType = containingType.GetMembers().
WhereAsArray(MemberAndDestinationValidator.IsMemberValid);
var memberViewModels = membersInType
.SelectAsArray(member =>
new MemberSymbolViewModel(member, _glyphService)
{
// The member user selected will be checked at the beginning.
IsChecked = selectedMembers.Any(SymbolEquivalenceComparer.Instance.Equals, member),
MakeAbstract = false,
IsMakeAbstractCheckable = !member.IsKind(SymbolKind.Field) && !member.IsAbstract,
IsCheckable = true
});
using var cancellationTokenSource = new CancellationTokenSource();
var baseTypeRootViewModel = BaseTypeTreeNodeViewModel.CreateBaseTypeTree(
_glyphService,
document.Project.Solution,
containingType,
cancellationTokenSource.Token);
var memberToDependentsMap = SymbolDependentsBuilder.FindMemberToDependentsMap(membersInType, document.Project, cancellationTokenSource.Token);
var viewModel = new PullMemberUpDialogViewModel(_uiThreadOperationExecutor, memberViewModels, baseTypeRootViewModel, memberToDependentsMap);
var dialog = new PullMemberUpDialog(viewModel);
var result = dialog.ShowModal();
// Dialog has finshed its work, cancel finding dependents task.
cancellationTokenSource.Cancel();
if (result.GetValueOrDefault())
{
return dialog.ViewModel.CreatePullMemberUpOptions();
}
else
{
return null;
}
}
}
|