未验证 提交 a58c2cce 编写于 作者: D David Poeschl 提交者: GitHub

Merge pull request #32858 from CyrusNajmabadi/indentation

Add helpers to make it easy to compute smart-indenting in wrapping refactoring.
......@@ -23,8 +23,10 @@
namespace Microsoft.CodeAnalysis.Editor.CSharp.Formatting.Indentation
{
[ExportLanguageService(typeof(ISynchronousIndentationService), LanguageNames.CSharp), Shared]
internal partial class CSharpIndentationService : AbstractIndentationService<CompilationUnitSyntax>
internal sealed partial class CSharpIndentationService : AbstractIndentationService<CompilationUnitSyntax>
{
public static readonly CSharpIndentationService Instance = new CSharpIndentationService();
private static readonly AbstractFormattingRule s_instance = new FormattingRule();
protected override AbstractFormattingRule GetSpecializedIndentationFormattingRule()
......
......@@ -2,6 +2,7 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Editor.CSharp.Formatting.Indentation;
using Microsoft.CodeAnalysis.Editor.Wrapping.BinaryExpression;
namespace Microsoft.CodeAnalysis.Editor.CSharp.Wrapping.BinaryExpression
......@@ -9,7 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.Wrapping.BinaryExpression
internal class CSharpBinaryExpressionWrapper : AbstractBinaryExpressionWrapper<BinaryExpressionSyntax>
{
public CSharpBinaryExpressionWrapper()
: base(CSharpSyntaxFactsService.Instance, CSharpPrecedenceService.Instance)
: base(CSharpIndentationService.Instance, CSharpSyntaxFactsService.Instance, CSharpPrecedenceService.Instance)
{
}
......
......@@ -11,10 +11,9 @@ internal abstract class AbstractCSharpSeparatedSyntaxListWrapper<TListSyntax, TL
where TListSyntax : SyntaxNode
where TListItemSyntax : SyntaxNode
{
// In our scenario we want to control all formatting ourselves. So tell the indenter to not
// depend on a formatter being available so it does all the work to figure out indentation
// itself.
protected override IBlankLineIndentationService GetIndentationService()
=> new CSharpIndentationService();
protected AbstractCSharpSeparatedSyntaxListWrapper()
: base(CSharpIndentationService.Instance)
{
}
}
}
......@@ -86,6 +86,29 @@ protected abstract class AbstractCodeActionComputer<TWrapper> : ICodeActionCompu
protected abstract Task<ImmutableArray<WrappingGroup>> ComputeWrappingGroupsAsync();
protected string GetSmartIndentationAfter(SyntaxNodeOrToken nodeOrToken)
{
var newSourceText = OriginalSourceText.WithChanges(new TextChange(new TextSpan(nodeOrToken.Span.End, 0), NewLine));
newSourceText = newSourceText.WithChanges(
new TextChange(TextSpan.FromBounds(nodeOrToken.Span.End + NewLine.Length, newSourceText.Length), ""));
var newDocument = OriginalDocument.WithText(newSourceText);
var indentationService = Wrapper.IndentationService;
var originalLineNumber = newSourceText.Lines.GetLineFromPosition(nodeOrToken.Span.End).LineNumber;
var desiredIndentation = indentationService.GetBlankLineIndentation(
newDocument, originalLineNumber + 1,
FormattingOptions.IndentStyle.Smart,
CancellationToken);
var baseLine = newSourceText.Lines.GetLineFromPosition(desiredIndentation.BasePosition);
var baseOffsetInLine = desiredIndentation.BasePosition - baseLine.Start;
var indent = baseOffsetInLine + desiredIndentation.Offset;
var indentString = indent.CreateIndentationString(UseTabs, TabSize);
return indentString;
}
/// <summary>
/// Try to create a CodeAction representing these edits. Can return <see langword="null"/> in several
/// cases, including:
......
......@@ -21,6 +21,13 @@ namespace Microsoft.CodeAnalysis.Editor.Wrapping
/// </summary>
internal abstract partial class AbstractSyntaxWrapper : ISyntaxWrapper
{
protected IBlankLineIndentationService IndentationService { get; }
protected AbstractSyntaxWrapper(IBlankLineIndentationService indentationService)
{
this.IndentationService = indentationService;
}
public abstract Task<ICodeActionComputer> TryCreateComputerAsync(Document document, int position, SyntaxNode node, CancellationToken cancellationToken);
protected static async Task<bool> ContainsUnformattableContentAsync(
......
......@@ -17,8 +17,9 @@ internal abstract partial class AbstractBinaryExpressionWrapper<TBinaryExpressio
private readonly IPrecedenceService _precedenceService;
protected AbstractBinaryExpressionWrapper(
IBlankLineIndentationService indentationService,
ISyntaxFactsService syntaxFacts,
IPrecedenceService precedenceService)
IPrecedenceService precedenceService) : base(indentationService)
{
_syntaxFacts = syntaxFacts;
_precedenceService = precedenceService;
......
......@@ -30,7 +30,10 @@ internal abstract partial class AbstractSeparatedSyntaxListWrapper<
protected abstract string Wrap_every_item { get; }
protected abstract IBlankLineIndentationService GetIndentationService();
protected AbstractSeparatedSyntaxListWrapper(IBlankLineIndentationService indentationService)
: base(indentationService)
{
}
protected abstract TListSyntax TryGetApplicableList(SyntaxNode node);
protected abstract SeparatedSyntaxList<TListItemSyntax> GetListItems(TListSyntax listSyntax);
......
......@@ -23,8 +23,6 @@ private class SeparatedSyntaxListCodeActionComputer : AbstractCodeActionComputer
private readonly TListSyntax _listSyntax;
private readonly SeparatedSyntaxList<TListItemSyntax> _listItems;
private readonly IBlankLineIndentationService _indentationService;
/// <summary>
/// The indentation string necessary to indent an item in a list such that the start of
/// that item will exact start at the end of the open-token for the containing list. i.e.
......@@ -58,8 +56,6 @@ private class SeparatedSyntaxListCodeActionComputer : AbstractCodeActionComputer
_listSyntax = listSyntax;
_listItems = listItems;
_indentationService = service.GetIndentationService();
var generator = SyntaxGenerator.GetGenerator(this.OriginalDocument);
_afterOpenTokenIndentationTrivia = generator.Whitespace(GetAfterOpenTokenIdentation());
......@@ -90,24 +86,7 @@ private string GetSingleIdentation()
// indented.
var openToken = _listSyntax.GetFirstToken();
var newSourceText = OriginalSourceText.WithChanges(new TextChange(new TextSpan(openToken.Span.End, 0), NewLine));
newSourceText = newSourceText.WithChanges(
new TextChange(TextSpan.FromBounds(openToken.Span.End + NewLine.Length, newSourceText.Length), ""));
var newDocument = OriginalDocument.WithText(newSourceText);
var originalLineNumber = newSourceText.Lines.GetLineFromPosition(openToken.Span.Start).LineNumber;
var desiredIndentation = _indentationService.GetBlankLineIndentation(
newDocument, originalLineNumber + 1,
FormattingOptions.IndentStyle.Smart,
CancellationToken);
var baseLine = newSourceText.Lines.GetLineFromPosition(desiredIndentation.BasePosition);
var baseOffsetInLine = desiredIndentation.BasePosition - baseLine.Start;
var indent = baseOffsetInLine + desiredIndentation.Offset;
var indentString = indent.CreateIndentationString(UseTabs, TabSize);
return indentString;
return GetSmartIndentationAfter(openToken);
}
private SyntaxTrivia GetIndentationTrivia(WrappingStyle wrappingStyle)
......
......@@ -13,13 +13,24 @@ Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Formatting.Indentation
<ExportLanguageService(GetType(ISynchronousIndentationService), LanguageNames.VisualBasic), [Shared]>
Partial Friend Class VisualBasicIndentationService
Partial Friend NotInheritable Class VisualBasicIndentationService
Inherits AbstractIndentationService(Of CompilationUnitSyntax)
Private Shared ReadOnly s_instance As AbstractFormattingRule = New SpecialFormattingRule()
Public Shared ReadOnly DefaultInstance As New VisualBasicIndentationService()
Public Shared ReadOnly WithoutParameterAlignmentInstance As New VisualBasicIndentationService(NoOpFormattingRule.Instance)
Private ReadOnly _specializedIndentationRule As AbstractFormattingRule
Public Sub New()
Me.New(New SpecialFormattingRule())
End Sub
Private Sub New(specializedIndentationRule As AbstractFormattingRule)
_specializedIndentationRule = specializedIndentationRule
End Sub
Protected Overrides Function GetSpecializedIndentationFormattingRule() As AbstractFormattingRule
Return s_instance
Return _specializedIndentationRule
End Function
Protected Overrides Function GetIndenter(syntaxFacts As ISyntaxFactsService,
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.Formatting.Indentation
Imports Microsoft.CodeAnalysis.Editor.Wrapping.BinaryExpression
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
......@@ -8,7 +9,12 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Wrapping.BinaryExpression
Inherits AbstractBinaryExpressionWrapper(Of BinaryExpressionSyntax)
Public Sub New()
MyBase.New(VisualBasicSyntaxFactsService.Instance, VisualBasicPrecedenceService.Instance)
' Override default indentation behavior. The special indentation rule tries to
' align parameters. But that's what we're actually trying to control, so we need
' to remove this.
MyBase.New(VisualBasicIndentationService.WithoutParameterAlignmentInstance,
VisualBasicSyntaxFactsService.Instance,
VisualBasicPrecedenceService.Instance)
End Sub
Protected Overrides Function GetNewLineBeforeOperatorTrivia(newLine As SyntaxTriviaList) As SyntaxTriviaList
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.Editor
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.Formatting.Indentation
Imports Microsoft.CodeAnalysis.Editor.Wrapping.SeparatedSyntaxList
Imports Microsoft.CodeAnalysis.Formatting.Rules
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Wrapping.SeparatedSyntaxList
Friend MustInherit Class AbstractVisualBasicSeparatedSyntaxListWrapper(
Partial Friend MustInherit Class AbstractVisualBasicSeparatedSyntaxListWrapper(
Of TListSyntax As SyntaxNode, TListItemSyntax As SyntaxNode)
Inherits AbstractSeparatedSyntaxListWrapper(Of TListSyntax, TListItemSyntax)
Protected Overrides Function GetIndentationService() As IBlankLineIndentationService
Return New IndentationService()
End Function
Private Class IndentationService
Inherits VisualBasicIndentationService
Protected Overrides Function GetSpecializedIndentationFormattingRule() As AbstractFormattingRule
' Override default indentation behavior. The special indentation rule tries to
' align parameters. But that's what we're actually trying to control, so we need
' to remove this.
Return NoOpFormattingRule.Instance
End Function
End Class
Protected Sub New()
MyBase.New(VisualBasicIndentationService.WithoutParameterAlignmentInstance)
End Sub
End Class
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册