|
// 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.
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Indentation;
using Microsoft.CodeAnalysis.Shared.Extensions;
namespace Microsoft.CodeAnalysis.Wrapping.SeparatedSyntaxList;
/// <summary>
/// Base type for all wrappers that involve wrapping a comma-separated list of items.
/// </summary>
internal abstract partial class AbstractSeparatedSyntaxListWrapper<
TListSyntax,
TListItemSyntax>
: AbstractSyntaxWrapper
where TListSyntax : SyntaxNode
where TListItemSyntax : SyntaxNode
{
protected abstract string Unwrap_list { get; }
protected abstract string Wrap_long_list { get; }
protected abstract string Unwrap_and_indent_all_items { get; }
protected abstract string Unwrap_all_items { get; }
protected abstract string Indent_all_items { get; }
protected abstract string Align_wrapped_items { get; }
protected abstract string Indent_wrapped_items { get; }
protected abstract string Wrap_every_item { get; }
public abstract bool Supports_WrapEveryGroup_UnwrapFirst { get; }
public abstract bool Supports_UnwrapGroup_WrapFirst_IndentRest { get; }
public abstract bool Supports_WrapLongGroup_UnwrapFirst { get; }
protected AbstractSeparatedSyntaxListWrapper(IIndentationService indentationService)
: base(indentationService)
{
}
protected abstract bool ShouldMoveCloseBraceToNewLine { get; }
protected abstract bool ShouldMoveOpenBraceToNewLine(SyntaxWrappingOptions options);
protected abstract SyntaxToken FirstToken(TListSyntax listSyntax);
protected abstract SyntaxToken LastToken(TListSyntax listSyntax);
protected abstract TListSyntax? TryGetApplicableList(SyntaxNode node);
protected abstract SeparatedSyntaxList<TListItemSyntax> GetListItems(TListSyntax listSyntax);
protected abstract bool PositionIsApplicable(
SyntaxNode root, int position, SyntaxNode declaration, bool containsSyntaxError, TListSyntax listSyntax);
public override async Task<ICodeActionComputer?> TryCreateComputerAsync(
Document document, int position, SyntaxNode declaration, SyntaxWrappingOptions options, bool containsSyntaxError, CancellationToken cancellationToken)
{
var listSyntax = TryGetApplicableList(declaration);
if (listSyntax == null || listSyntax.Span.IsEmpty)
return null;
var firstToken = FirstToken(listSyntax);
var lastToken = LastToken(listSyntax);
if (firstToken.IsMissing || lastToken.IsMissing || firstToken.Span.IsEmpty || lastToken.Span.IsEmpty)
return null;
var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
if (!PositionIsApplicable(root, position, declaration, containsSyntaxError, listSyntax))
return null;
var listItems = GetListItems(listSyntax);
if (listItems.Count <= 1)
{
// nothing to do with 0-1 items. Simple enough for users to just edit
// themselves, and this prevents constant clutter with formatting that isn't
// really that useful.
return null;
}
var containsUnformattableContent = await ContainsUnformattableContentAsync(
document, listItems.GetWithSeparators(), cancellationToken).ConfigureAwait(false);
if (containsUnformattableContent)
return null;
var sourceText = await document.GetValueTextAsync(cancellationToken).ConfigureAwait(false);
return new SeparatedSyntaxListCodeActionComputer(
this, document, sourceText, options, listSyntax, listItems);
}
}
|