未验证 提交 0fd9904c 编写于 作者: S Sam Harwell 提交者: GitHub

Merge pull request #33291 from sharwell/fewer-allocs

Reduce allocations in the formatter
......@@ -11,6 +11,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.CodingConventions" Version="$(MicrosoftVisualStudioCodingConventionsVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="$(MicrosoftCodeAnalysisCommonFixedVersion)" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="$(SystemThreadingTasksExtensionsVersion)" />
</ItemGroup>
<ItemGroup>
<!--
......@@ -30,6 +31,7 @@
<Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\ExceptionUtilities.cs" Link="InternalUtilities\ExceptionUtilities.cs" />
<Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\IReadOnlySet.cs" Link="InternalUtilities\IReadOnlySet.cs" />
<Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\KeyValuePairUtil.cs" Link="InternalUtilities\KeyValuePairUtil.cs" />
<Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\PerformanceSensitiveAttribute.cs" Link="PerformanceSensitiveAttribute.cs" />
<Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\SpecializedCollections.cs" Link="InternalUtilities\SpecializedCollections.cs" />
<Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\SpecializedCollections.Empty.Collection.cs" Link="InternalUtilities\SpecializedCollections.Empty.Collection.cs" />
<Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\SpecializedCollections.Empty.cs" Link="InternalUtilities\SpecializedCollections.Empty.cs" />
......@@ -158,6 +160,7 @@
<Compile Include="..\..\..\Workspaces\Core\Portable\Shared\Extensions\SyntaxTokenExtensions.cs" Link="Formatting\SyntaxTokenExtensions.cs" />
<Compile Include="..\..\..\Workspaces\Core\Portable\Shared\Extensions\SyntaxTreeExtensions_SharedWithCodeStyle.cs" Link="Formatting\SyntaxTreeExtensions_SharedWithCodeStyle.cs" />
<Compile Include="..\..\..\Workspaces\Core\Portable\Shared\Extensions\SyntaxTriviaExtensions.cs" Link="Formatting\SyntaxTriviaExtensions.cs" />
<Compile Include="..\..\..\Workspaces\Core\Portable\Shared\Extensions\SyntaxTriviaListExtensions.cs" Link="Formatting\SyntaxTriviaListExtensions.cs" />
<Compile Include="..\..\..\Workspaces\Core\Portable\Shared\Extensions\TextLineExtensions.cs" Link="Formatting\TextLineExtensions.cs" />
<Compile Include="..\..\..\Workspaces\Core\Portable\Shared\NormalizedTextSpanCollection.cs" Link="Formatting\NormalizedTextSpanCollection.cs" />
<Compile Include="..\..\..\Workspaces\Core\Portable\Shared\Utilities\AliasSymbolCache.cs" Link="AliasSymbolCache.cs" />
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using Microsoft.CodeAnalysis.Options;
namespace Microsoft.CodeAnalysis
......@@ -41,13 +40,8 @@ private static bool TryGetEditorConfigOption<T>(this OptionSet analyzerConfigOpt
continue;
}
if (editorConfigStorageLocation.TryGetOption(
underlyingOption: null,
allRawConventions: new Dictionary<string, object> { { editorConfigStorageLocation.KeyName, stringValue } },
typeof(T),
out var rawValue))
if (editorConfigStorageLocation.TryGetOption(stringValue, typeof(T), out value))
{
value = (T)rawValue;
return true;
}
}
......
......@@ -55,6 +55,15 @@ public bool AllowCaptures
set;
}
/// <summary>
/// Gets or sets a value indicating whether implicit boxing of value types is allowed.
/// </summary>
public bool AllowImplicitBoxing
{
get;
set;
}
/// <summary>
/// Gets or sets a value indicating whether enumeration of a generic <see cref="IEnumerable{T}"/> is allowed.
/// </summary>
......
......@@ -100,7 +100,7 @@ private bool ShouldFormat(FormattingContext context)
public override void Format(
FormattingContext context,
ChainedFormattingRules formattingRules,
Action<int, TriviaData> formattingResultApplier,
Action<int, TokenStream, TriviaData> formattingResultApplier,
CancellationToken cancellationToken,
int tokenPairIndex = TokenPairIndexNotNeeded)
{
......@@ -109,7 +109,7 @@ private bool ShouldFormat(FormattingContext context)
return;
}
formattingResultApplier(tokenPairIndex, Format(context, formattingRules, this.LineBreaks, this.Spaces, cancellationToken));
formattingResultApplier(tokenPairIndex, context.TokenStream, Format(context, formattingRules, this.LineBreaks, this.Spaces, cancellationToken));
}
public override List<SyntaxTrivia> GetTriviaList(CancellationToken cancellationToken)
......
......@@ -78,7 +78,7 @@ public override TriviaData WithIndentation(int indentation, FormattingContext co
throw new NotImplementedException();
}
public override void Format(FormattingContext context, ChainedFormattingRules formattingRules, Action<int, TriviaData> formattingResultApplier, CancellationToken cancellationToken, int tokenPairIndex = TokenPairIndexNotNeeded)
public override void Format(FormattingContext context, ChainedFormattingRules formattingRules, Action<int, TokenStream, TriviaData> formattingResultApplier, CancellationToken cancellationToken, int tokenPairIndex = TokenPairIndexNotNeeded)
{
throw new NotImplementedException();
}
......
......@@ -71,7 +71,7 @@ public override TriviaData WithSpace(int space, FormattingContext context, Chain
public override void Format(
FormattingContext context,
ChainedFormattingRules formattingRules,
Action<int, TriviaData> formattingResultApplier,
Action<int, TokenStream, TriviaData> formattingResultApplier,
CancellationToken cancellationToken,
int tokenPairIndex = TokenPairIndexNotNeeded)
{
......@@ -90,6 +90,7 @@ public override TriviaData WithSpace(int space, FormattingContext context, Chain
}
formattingResultApplier(tokenPairIndex,
context.TokenStream,
new FormattedComplexTrivia(
context,
formattingRules,
......
......@@ -18,13 +18,11 @@ internal abstract partial class AbstractFormatEngine
private class OperationApplier
{
private readonly FormattingContext _context;
private readonly TokenStream _tokenStream;
private readonly ChainedFormattingRules _formattingRules;
public OperationApplier(FormattingContext context, TokenStream tokenStream, ChainedFormattingRules formattingRules)
public OperationApplier(FormattingContext context, ChainedFormattingRules formattingRules)
{
_context = context;
_tokenStream = tokenStream;
_formattingRules = formattingRules;
}
......@@ -50,7 +48,7 @@ public bool Apply(AdjustSpacesOperation operation, int pairIndex)
private bool ApplyDynamicSpacesOperation(AdjustSpacesOperation operation, int pairIndex)
{
var triviaInfo = _tokenStream.GetTriviaData(pairIndex);
var triviaInfo = _context.TokenStream.GetTriviaData(pairIndex);
if (triviaInfo.SecondTokenIsFirstTokenOnLine)
{
......@@ -59,18 +57,18 @@ private bool ApplyDynamicSpacesOperation(AdjustSpacesOperation operation, int pa
Contract.ThrowIfFalse(triviaInfo.LineBreaks == 0);
var indentation = _context.GetBaseIndentation(_tokenStream.GetToken(pairIndex + 1));
var indentation = _context.GetBaseIndentation(_context.TokenStream.GetToken(pairIndex + 1));
var previousToken = _tokenStream.GetToken(pairIndex);
_tokenStream.GetTokenLength(previousToken, out var tokenLength, out var multipleLines);
var previousToken = _context.TokenStream.GetToken(pairIndex);
_context.TokenStream.GetTokenLength(previousToken, out var tokenLength, out var multipleLines);
// get end column of previous token
var endColumnOfPreviousToken = multipleLines ? tokenLength : _tokenStream.GetCurrentColumn(previousToken) + tokenLength;
var endColumnOfPreviousToken = multipleLines ? tokenLength : _context.TokenStream.GetCurrentColumn(previousToken) + tokenLength;
// check whether current position is less than indentation
if (endColumnOfPreviousToken < indentation)
{
_tokenStream.ApplyChange(pairIndex, triviaInfo.WithSpace(indentation - endColumnOfPreviousToken, _context, _formattingRules));
_context.TokenStream.ApplyChange(pairIndex, triviaInfo.WithSpace(indentation - endColumnOfPreviousToken, _context, _formattingRules));
return true;
}
......@@ -80,7 +78,7 @@ private bool ApplyDynamicSpacesOperation(AdjustSpacesOperation operation, int pa
private bool ApplyPreserveSpacesOperation(AdjustSpacesOperation operation, int pairIndex)
{
var triviaInfo = _tokenStream.GetTriviaData(pairIndex);
var triviaInfo = _context.TokenStream.GetTriviaData(pairIndex);
var space = operation.Space;
if (triviaInfo.SecondTokenIsFirstTokenOnLine)
......@@ -95,26 +93,26 @@ private bool ApplyPreserveSpacesOperation(AdjustSpacesOperation operation, int p
return false;
}
_tokenStream.ApplyChange(pairIndex, triviaInfo.WithSpace(space, _context, _formattingRules));
_context.TokenStream.ApplyChange(pairIndex, triviaInfo.WithSpace(space, _context, _formattingRules));
return true;
}
public bool ApplyForceSpacesOperation(AdjustSpacesOperation operation, int pairIndex)
{
var triviaInfo = _tokenStream.GetTriviaData(pairIndex);
var triviaInfo = _context.TokenStream.GetTriviaData(pairIndex);
if (triviaInfo.LineBreaks == 0 && triviaInfo.Spaces == operation.Space)
{
return false;
}
_tokenStream.ApplyChange(pairIndex, triviaInfo.WithSpace(operation.Space, _context, _formattingRules));
_context.TokenStream.ApplyChange(pairIndex, triviaInfo.WithSpace(operation.Space, _context, _formattingRules));
return true;
}
private bool ApplySpaceIfSingleLine(AdjustSpacesOperation operation, int pairIndex)
{
var triviaInfo = _tokenStream.GetTriviaData(pairIndex);
var triviaInfo = _context.TokenStream.GetTriviaData(pairIndex);
var space = operation.Space;
if (triviaInfo.SecondTokenIsFirstTokenOnLine)
......@@ -129,7 +127,7 @@ private bool ApplySpaceIfSingleLine(AdjustSpacesOperation operation, int pairInd
return false;
}
_tokenStream.ApplyChange(pairIndex, triviaInfo.WithSpace(space, _context, _formattingRules));
_context.TokenStream.ApplyChange(pairIndex, triviaInfo.WithSpace(space, _context, _formattingRules));
return true;
}
......@@ -151,8 +149,8 @@ public bool Apply(AdjustNewLinesOperation operation, int pairIndex, Cancellation
// else we leave the tokens as it is (Note: We should not preserve too. If we
// we do, then that will be counted as a line operation and the indentation of
// the second token will be modified)
if (_tokenStream.TwoTokensOnSameLine(_tokenStream.GetToken(pairIndex),
_tokenStream.GetToken(pairIndex + 1)))
if (_context.TokenStream.TwoTokensOnSameLine(_context.TokenStream.GetToken(pairIndex),
_context.TokenStream.GetToken(pairIndex + 1)))
{
return ApplyForceLinesOperation(operation, pairIndex, cancellationToken);
}
......@@ -165,9 +163,9 @@ public bool Apply(AdjustNewLinesOperation operation, int pairIndex, Cancellation
private bool ApplyForceLinesOperation(AdjustNewLinesOperation operation, int pairIndex, CancellationToken cancellationToken)
{
var triviaInfo = _tokenStream.GetTriviaData(pairIndex);
var triviaInfo = _context.TokenStream.GetTriviaData(pairIndex);
var indentation = _context.GetBaseIndentation(_tokenStream.GetToken(pairIndex + 1));
var indentation = _context.GetBaseIndentation(_context.TokenStream.GetToken(pairIndex + 1));
if (triviaInfo.LineBreaks == operation.Line && triviaInfo.Spaces == indentation && !triviaInfo.TreatAsElastic)
{
// things are already in the shape we want, so we don't actually need to do
......@@ -176,22 +174,22 @@ private bool ApplyForceLinesOperation(AdjustNewLinesOperation operation, int pai
}
// well, force it regardless original content
_tokenStream.ApplyChange(pairIndex, triviaInfo.WithLine(operation.Line, indentation, _context, _formattingRules, cancellationToken));
_context.TokenStream.ApplyChange(pairIndex, triviaInfo.WithLine(operation.Line, indentation, _context, _formattingRules, cancellationToken));
return true;
}
public bool ApplyPreserveLinesOperation(
AdjustNewLinesOperation operation, int pairIndex, CancellationToken cancellationToken)
{
var triviaInfo = _tokenStream.GetTriviaData(pairIndex);
var triviaInfo = _context.TokenStream.GetTriviaData(pairIndex);
// okay, check whether there is line between token more than we want
// check whether we should force it if it is less than given number
var indentation = _context.GetBaseIndentation(_tokenStream.GetToken(pairIndex + 1));
var indentation = _context.GetBaseIndentation(_context.TokenStream.GetToken(pairIndex + 1));
if (operation.Line > triviaInfo.LineBreaks)
{
// alright force them
_tokenStream.ApplyChange(pairIndex, triviaInfo.WithLine(operation.Line, indentation, _context, _formattingRules, cancellationToken));
_context.TokenStream.ApplyChange(pairIndex, triviaInfo.WithLine(operation.Line, indentation, _context, _formattingRules, cancellationToken));
return true;
}
......@@ -199,7 +197,7 @@ private bool ApplyForceLinesOperation(AdjustNewLinesOperation operation, int pai
if (triviaInfo.SecondTokenIsFirstTokenOnLine &&
indentation != triviaInfo.Spaces)
{
_tokenStream.ApplyChange(pairIndex, triviaInfo.WithIndentation(indentation, _context, _formattingRules, cancellationToken));
_context.TokenStream.ApplyChange(pairIndex, triviaInfo.WithIndentation(indentation, _context, _formattingRules, cancellationToken));
return true;
}
......@@ -268,7 +266,7 @@ private bool ApplyForceLinesOperation(AdjustNewLinesOperation operation, int pai
case AlignTokensOption.AlignIndentationOfTokensToFirstTokenOfBaseTokenLine:
{
if (!ApplyAlignment(_tokenStream.FirstTokenOfBaseTokenLine(operation.BaseToken), operation.Tokens, previousChangesMap, out tokenData, cancellationToken))
if (!ApplyAlignment(_context.TokenStream.FirstTokenOfBaseTokenLine(operation.BaseToken), operation.Tokens, previousChangesMap, out tokenData, cancellationToken))
{
return false;
}
......@@ -295,14 +293,14 @@ private bool ApplyForceLinesOperation(AdjustNewLinesOperation operation, int pai
{
// rather than having external new changes map, having snapshot concept
// in token stream might be easier to understand.
int baseSpaceOrIndentation = _tokenStream.GetCurrentColumn(token);
int baseSpaceOrIndentation = _context.TokenStream.GetCurrentColumn(token);
for (int i = 0; i < list.Count; i++)
{
var currentToken = list[i];
var previousToken = _tokenStream.GetPreviousTokenData(currentToken);
var previousToken = _context.TokenStream.GetPreviousTokenData(currentToken);
var triviaInfo = _tokenStream.GetTriviaData(previousToken, currentToken);
var triviaInfo = _context.TokenStream.GetTriviaData(previousToken, currentToken);
if (!triviaInfo.SecondTokenIsFirstTokenOnLine)
{
continue;
......@@ -338,7 +336,7 @@ private bool ApplyForceLinesOperation(AdjustNewLinesOperation operation, int pai
}
// okay, update indentation
_tokenStream.ApplyChange(
_context.TokenStream.ApplyChange(
previousToken.IndexInStream,
triviaInfo.WithIndentation(baseSpaceOrIndentation, _context, _formattingRules, cancellationToken));
}
......@@ -354,7 +352,7 @@ private IList<TokenData> GetTokenWithIndices(IEnumerable<SyntaxToken> tokens)
continue;
}
var tokenWithIndex = _tokenStream.GetTokenData(token);
var tokenWithIndex = _context.TokenStream.GetTokenData(token);
if (tokenWithIndex.IndexInStream < 0)
{
// this token is not inside of the formatting span, ignore
......@@ -385,10 +383,10 @@ private IList<TokenData> GetTokenWithIndices(IEnumerable<SyntaxToken> tokens)
}
// first token was anchor token, now find last token with index
var lastToken = _tokenStream.GetTokenData(endAnchorToken);
var lastToken = _context.TokenStream.GetTokenData(endAnchorToken);
if (lastToken.IndexInStream < 0)
{
lastToken = _tokenStream.LastTokenInStream;
lastToken = _context.TokenStream.LastTokenInStream;
}
ApplyBaseTokenIndentationChangesFromTo(firstToken, firstToken, lastToken, newChangesMap, cancellationToken);
......@@ -407,7 +405,7 @@ private IList<TokenData> GetTokenWithIndices(IEnumerable<SyntaxToken> tokens)
// can this run parallel? at least finding out all first token on line.
for (var pairIndex = firstToken.IndexInStream; pairIndex < lastToken.IndexInStream; pairIndex++)
{
var triviaInfo = _tokenStream.GetTriviaData(pairIndex);
var triviaInfo = _context.TokenStream.GetTriviaData(pairIndex);
if (!triviaInfo.SecondTokenIsFirstTokenOnLine)
{
continue;
......@@ -422,7 +420,7 @@ private IList<TokenData> GetTokenWithIndices(IEnumerable<SyntaxToken> tokens)
// bail fast here.
// if an entity is in the map, then it means indentation has been applied to the token pair already.
// no reason to do same work again.
var currentToken = _tokenStream.GetToken(pairIndex + 1);
var currentToken = _context.TokenStream.GetToken(pairIndex + 1);
if (previousChangesMap.ContainsKey(currentToken))
{
continue;
......@@ -455,7 +453,7 @@ private IList<TokenData> GetTokenWithIndices(IEnumerable<SyntaxToken> tokens)
previousChangesMap.Add(currentToken, triviaInfo.Spaces);
// okay, update indentation
_tokenStream.ApplyChange(pairIndex, triviaInfo.WithIndentation(indentation, _context, _formattingRules, cancellationToken));
_context.TokenStream.ApplyChange(pairIndex, triviaInfo.WithIndentation(indentation, _context, _formattingRules, cancellationToken));
}
public bool ApplyBaseTokenIndentationChangesFromTo(
......@@ -467,9 +465,9 @@ private IList<TokenData> GetTokenWithIndices(IEnumerable<SyntaxToken> tokens)
{
Contract.ThrowIfFalse(baseToken.RawKind != 0 && startToken.RawKind != 0 && endToken.RawKind != 0);
var baseTokenWithIndex = _tokenStream.GetTokenData(baseToken);
var firstTokenWithIndex = _tokenStream.GetTokenData(startToken).GetPreviousTokenData();
var lastTokenWithIndex = _tokenStream.GetTokenData(endToken);
var baseTokenWithIndex = _context.TokenStream.GetTokenData(baseToken);
var firstTokenWithIndex = _context.TokenStream.GetTokenData(startToken).GetPreviousTokenData();
var lastTokenWithIndex = _context.TokenStream.GetTokenData(endToken);
return ApplyBaseTokenIndentationChangesFromTo(
baseTokenWithIndex, firstTokenWithIndex, lastTokenWithIndex, previousChangesMap, cancellationToken);
......@@ -502,7 +500,7 @@ private IList<TokenData> GetTokenWithIndices(IEnumerable<SyntaxToken> tokens)
// okay, this token is not moved, check one before me as long as it is on the same line
var tokenPairIndex = tokenWithIndex.IndexInStream - 1;
if (tokenPairIndex < 0 ||
_tokenStream.GetTriviaData(tokenPairIndex).SecondTokenIsFirstTokenOnLine)
_context.TokenStream.GetTriviaData(tokenPairIndex).SecondTokenIsFirstTokenOnLine)
{
return false;
}
......@@ -523,8 +521,8 @@ private IList<TokenData> GetTokenWithIndices(IEnumerable<SyntaxToken> tokens)
return false;
}
startToken = startToken.IndexInStream < 0 ? _tokenStream.FirstTokenInStream : startToken;
endToken = endToken.IndexInStream < 0 ? _tokenStream.LastTokenInStream : endToken;
startToken = startToken.IndexInStream < 0 ? _context.TokenStream.FirstTokenInStream : startToken;
endToken = endToken.IndexInStream < 0 ? _context.TokenStream.LastTokenInStream : endToken;
ApplyIndentationDeltaFromTo(startToken, endToken, indentationDelta, previousChangesMap, cancellationToken);
return true;
......@@ -533,7 +531,7 @@ private IList<TokenData> GetTokenWithIndices(IEnumerable<SyntaxToken> tokens)
public bool ApplyAnchorIndentation(
int pairIndex, Dictionary<SyntaxToken, int> previousChangesMap, CancellationToken cancellationToken)
{
var triviaInfo = _tokenStream.GetTriviaData(pairIndex);
var triviaInfo = _context.TokenStream.GetTriviaData(pairIndex);
if (!triviaInfo.SecondTokenIsFirstTokenOnLine)
{
......@@ -546,7 +544,7 @@ private IList<TokenData> GetTokenWithIndices(IEnumerable<SyntaxToken> tokens)
return false;
}
var firstTokenOnLine = _tokenStream.GetToken(pairIndex + 1);
var firstTokenOnLine = _context.TokenStream.GetToken(pairIndex + 1);
var indentation = triviaInfo.Spaces + _context.GetAnchorDeltaFromOriginalColumn(firstTokenOnLine);
if (triviaInfo.Spaces != indentation)
......@@ -555,7 +553,7 @@ private IList<TokenData> GetTokenWithIndices(IEnumerable<SyntaxToken> tokens)
previousChangesMap.Add(firstTokenOnLine, triviaInfo.Spaces);
// okay, update indentation
_tokenStream.ApplyChange(pairIndex, triviaInfo.WithIndentation(indentation, _context, _formattingRules, cancellationToken));
_context.TokenStream.ApplyChange(pairIndex, triviaInfo.WithIndentation(indentation, _context, _formattingRules, cancellationToken));
return true;
}
......
......@@ -15,17 +15,14 @@ private class Partitioner
private const int MinimumItemsPerPartition = 30000;
private readonly FormattingContext _context;
private readonly TokenStream _tokenStream;
private readonly TokenPairWithOperations[] _operationPairs;
public Partitioner(FormattingContext context, TokenStream tokenStream, TokenPairWithOperations[] operationPairs)
public Partitioner(FormattingContext context, TokenPairWithOperations[] operationPairs)
{
Contract.ThrowIfNull(context);
Contract.ThrowIfNull(tokenStream);
Contract.ThrowIfNull(operationPairs);
_context = context;
_tokenStream = tokenStream;
_operationPairs = operationPairs;
}
......@@ -68,7 +65,7 @@ public List<IEnumerable<TokenPairWithOperations>> GetPartitions(int partitionCou
break;
}
var nextTokenWithIndex = _tokenStream.GetTokenData(nextToken);
var nextTokenWithIndex = _context.TokenStream.GetTokenData(nextToken);
if (nextTokenWithIndex.IndexInStream < 0)
{
// first token for next partition is out side of valid token stream
......
......@@ -105,16 +105,16 @@ public AbstractFormattingResult Format(CancellationToken cancellationToken)
cancellationToken.ThrowIfCancellationRequested();
var anchorContext = nodeOperations.AnchorIndentationOperations.Do(context.AddAnchorIndentationOperation);
BuildContext(context, tokenStream, nodeOperations, cancellationToken);
BuildContext(context, nodeOperations, cancellationToken);
ApplyBeginningOfTreeTriviaOperation(context, tokenStream, cancellationToken);
ApplyBeginningOfTreeTriviaOperation(context, cancellationToken);
ApplyTokenOperations(context, tokenStream, nodeOperations,
ApplyTokenOperations(context, nodeOperations,
tokenOperation, cancellationToken);
ApplyTriviaOperations(context, tokenStream, cancellationToken);
ApplyTriviaOperations(context, cancellationToken);
ApplyEndOfTreeTriviaOperation(context, tokenStream, cancellationToken);
ApplyEndOfTreeTriviaOperation(context, cancellationToken);
return CreateFormattingResult(tokenStream);
}
......@@ -231,76 +231,79 @@ private List<T> AddOperations<T>(List<SyntaxNode> nodes, Action<List<T>, SyntaxN
private void ApplyTokenOperations(
FormattingContext context,
TokenStream tokenStream,
NodeOperations nodeOperations,
TokenPairWithOperations[] tokenOperations,
CancellationToken cancellationToken)
{
var applier = new OperationApplier(context, tokenStream, _formattingRules);
ApplySpaceAndWrappingOperations(context, tokenStream, tokenOperations, applier, cancellationToken);
var applier = new OperationApplier(context, _formattingRules);
ApplySpaceAndWrappingOperations(context, tokenOperations, applier, cancellationToken);
ApplyAnchorOperations(context, tokenStream, tokenOperations, applier, cancellationToken);
ApplyAnchorOperations(context, tokenOperations, applier, cancellationToken);
ApplySpecialOperations(context, tokenStream, nodeOperations, applier, cancellationToken);
ApplySpecialOperations(context, nodeOperations, applier, cancellationToken);
}
private void ApplyBeginningOfTreeTriviaOperation(
FormattingContext context, TokenStream tokenStream, CancellationToken cancellationToken)
FormattingContext context, CancellationToken cancellationToken)
{
if (!tokenStream.FormatBeginningOfTree)
if (!context.TokenStream.FormatBeginningOfTree)
{
return;
}
void beginningOfTreeTriviaInfoApplier(int i, TriviaData info)
void beginningOfTreeTriviaInfoApplier(int i, TokenStream ts, TriviaData info)
{
tokenStream.ApplyBeginningOfTreeChange(info);
ts.ApplyBeginningOfTreeChange(info);
}
// remove all leading indentation
var triviaInfo = tokenStream.GetTriviaDataAtBeginningOfTree().WithIndentation(0, context, _formattingRules, cancellationToken);
var triviaInfo = context.TokenStream.GetTriviaDataAtBeginningOfTree().WithIndentation(0, context, _formattingRules, cancellationToken);
triviaInfo.Format(context, _formattingRules, beginningOfTreeTriviaInfoApplier, cancellationToken);
}
private void ApplyEndOfTreeTriviaOperation(
FormattingContext context, TokenStream tokenStream, CancellationToken cancellationToken)
FormattingContext context, CancellationToken cancellationToken)
{
if (!tokenStream.FormatEndOfTree)
if (!context.TokenStream.FormatEndOfTree)
{
return;
}
void endOfTreeTriviaInfoApplier(int i, TriviaData info)
void endOfTreeTriviaInfoApplier(int i, TokenStream ts, TriviaData info)
{
tokenStream.ApplyEndOfTreeChange(info);
ts.ApplyEndOfTreeChange(info);
}
// remove all trailing indentation
var triviaInfo = tokenStream.GetTriviaDataAtEndOfTree().WithIndentation(0, context, _formattingRules, cancellationToken);
var triviaInfo = context.TokenStream.GetTriviaDataAtEndOfTree().WithIndentation(0, context, _formattingRules, cancellationToken);
triviaInfo.Format(context, _formattingRules, endOfTreeTriviaInfoApplier, cancellationToken);
}
private void ApplyTriviaOperations(FormattingContext context, TokenStream tokenStream, CancellationToken cancellationToken)
[PerformanceSensitive("https://github.com/dotnet/roslyn/issues/30819", AllowCaptures = false)]
private void ApplyTriviaOperations(FormattingContext context, CancellationToken cancellationToken)
{
// trivia formatting result appliers
void regularApplier(int tokenPairIndex, TriviaData info)
void regularApplier(int tokenPairIndex, TokenStream ts, TriviaData info)
{
tokenStream.ApplyChange(tokenPairIndex, info);
ts.ApplyChange(tokenPairIndex, info);
}
// trivia formatting applier
void triviaFormatter(int tokenPairIndex)
void triviaFormatter(int tokenPairIndex, FormattingContext ctx, ChainedFormattingRules formattingRules, CancellationToken ct)
{
var triviaInfo = tokenStream.GetTriviaData(tokenPairIndex);
triviaInfo.Format(context, _formattingRules, regularApplier, cancellationToken, tokenPairIndex);
var triviaInfo = ctx.TokenStream.GetTriviaData(tokenPairIndex);
triviaInfo.Format(
ctx,
formattingRules,
(int tokenPairIndex1, TokenStream ts, TriviaData info) => regularApplier(tokenPairIndex1, ts, info),
ct,
tokenPairIndex);
}
for (var i = 0; i < tokenStream.TokenCount - 1; i++)
for (var i = 0; i < context.TokenStream.TokenCount - 1; i++)
{
cancellationToken.ThrowIfCancellationRequested();
triviaFormatter(i);
triviaFormatter(i, context, _formattingRules, cancellationToken);
}
}
......@@ -313,7 +316,7 @@ private TextSpan GetSpanToFormat()
}
private void ApplySpecialOperations(
FormattingContext context, TokenStream tokenStream, NodeOperations nodeOperationsCollector, OperationApplier applier, CancellationToken cancellationToken)
FormattingContext context, NodeOperations nodeOperationsCollector, OperationApplier applier, CancellationToken cancellationToken)
{
// apply alignment operation
using (Logger.LogBlock(FunctionId.Formatting_CollectAlignOperation, cancellationToken))
......@@ -335,14 +338,13 @@ private TextSpan GetSpanToFormat()
context.GetAllRelativeIndentBlockOperations().Do(o =>
{
cancellationToken.ThrowIfCancellationRequested();
applier.ApplyBaseTokenIndentationChangesFromTo(FindCorrectBaseTokenOfRelativeIndentBlockOperation(o, tokenStream), o.StartToken, o.EndToken, previousChangesMap, cancellationToken);
applier.ApplyBaseTokenIndentationChangesFromTo(FindCorrectBaseTokenOfRelativeIndentBlockOperation(o, context.TokenStream), o.StartToken, o.EndToken, previousChangesMap, cancellationToken);
});
}
}
private void ApplyAnchorOperations(
FormattingContext context,
TokenStream tokenStream,
TokenPairWithOperations[] tokenOperations,
OperationApplier applier,
CancellationToken cancellationToken)
......@@ -367,7 +369,7 @@ private TextSpan GetSpanToFormat()
context.GetAllRelativeIndentBlockOperations().Do(o =>
{
cancellationToken.ThrowIfCancellationRequested();
applier.ApplyBaseTokenIndentationChangesFromTo(FindCorrectBaseTokenOfRelativeIndentBlockOperation(o, tokenStream), o.StartToken, o.EndToken, previousChangesMap, cancellationToken);
applier.ApplyBaseTokenIndentationChangesFromTo(FindCorrectBaseTokenOfRelativeIndentBlockOperation(o, context.TokenStream), o.StartToken, o.EndToken, previousChangesMap, cancellationToken);
});
}
}
......@@ -400,7 +402,6 @@ private SyntaxToken FindCorrectBaseTokenOfRelativeIndentBlockOperation(IndentBlo
private void ApplySpaceAndWrappingOperations(
FormattingContext context,
TokenStream tokenStream,
TokenPairWithOperations[] tokenOperations,
OperationApplier applier,
CancellationToken cancellationToken)
......@@ -408,7 +409,7 @@ private SyntaxToken FindCorrectBaseTokenOfRelativeIndentBlockOperation(IndentBlo
using (Logger.LogBlock(FunctionId.Formatting_ApplySpaceAndLine, cancellationToken))
{
// go through each token pairs and apply operations. operations don't need to be applied in order
var partitioner = new Partitioner(context, tokenStream, tokenOperations);
var partitioner = new Partitioner(context, tokenOperations);
// always create task 1 more than current processor count
var partitions = partitioner.GetPartitions(partitionCount: 1, cancellationToken);
......@@ -416,14 +417,13 @@ private SyntaxToken FindCorrectBaseTokenOfRelativeIndentBlockOperation(IndentBlo
foreach (var partition in partitions)
{
cancellationToken.ThrowIfCancellationRequested();
partition.Do(operationPair => ApplySpaceAndWrappingOperationsBody(context, tokenStream, operationPair, applier, cancellationToken));
partition.Do(operationPair => ApplySpaceAndWrappingOperationsBody(context, operationPair, applier, cancellationToken));
}
}
}
private static void ApplySpaceAndWrappingOperationsBody(
FormattingContext context,
TokenStream tokenStream,
TokenPairWithOperations operation,
OperationApplier applier,
CancellationToken cancellationToken)
......@@ -438,7 +438,7 @@ private SyntaxToken FindCorrectBaseTokenOfRelativeIndentBlockOperation(IndentBlo
return;
}
var triviaInfo = tokenStream.GetTriviaData(operation.PairIndex);
var triviaInfo = context.TokenStream.GetTriviaData(operation.PairIndex);
var spanBetweenTokens = TextSpan.FromBounds(token1.Span.End, token2.SpanStart);
if (operation.LineOperation != null)
......@@ -467,7 +467,6 @@ private SyntaxToken FindCorrectBaseTokenOfRelativeIndentBlockOperation(IndentBlo
private void BuildContext(
FormattingContext context,
TokenStream tokenStream,
NodeOperations nodeOperations,
CancellationToken cancellationToken)
{
......
......@@ -69,7 +69,7 @@ public override TriviaData WithIndentation(int indentation, FormattingContext co
}
public override void Format(
FormattingContext context, ChainedFormattingRules formattingRules, Action<int, TriviaData> formattingResultApplier, CancellationToken cancellationToken, int tokenPairIndex = TokenPairIndexNotNeeded)
FormattingContext context, ChainedFormattingRules formattingRules, Action<int, TokenStream, TriviaData> formattingResultApplier, CancellationToken cancellationToken, int tokenPairIndex = TokenPairIndexNotNeeded)
{
throw new NotImplementedException();
}
......
......@@ -77,11 +77,11 @@ public override TriviaData WithLine(int line, int indentation, FormattingContext
public override void Format(
FormattingContext context,
ChainedFormattingRules formattingRules,
Action<int, TriviaData> formattingResultApplier,
Action<int, TokenStream, TriviaData> formattingResultApplier,
CancellationToken cancellationToken,
int tokenPairIndex = TokenPairIndexNotNeeded)
{
formattingResultApplier(tokenPairIndex, new FormattedWhitespace(this.OptionSet, this.LineBreaks, this.Spaces, this.Language));
formattingResultApplier(tokenPairIndex, context.TokenStream, new FormattedWhitespace(this.OptionSet, this.LineBreaks, this.Spaces, this.Language));
}
}
}
......
......@@ -78,7 +78,7 @@ public override TriviaData WithLine(int line, int indentation, FormattingContext
public override void Format(
FormattingContext context,
ChainedFormattingRules formattingRules,
Action<int, TriviaData> formattingResultApplier,
Action<int, TokenStream, TriviaData> formattingResultApplier,
CancellationToken cancellationToken,
int tokenPairIndex = TokenPairIndexNotNeeded)
{
......
......@@ -49,7 +49,7 @@ protected TriviaData(OptionSet optionSet, string language)
public abstract void Format(
FormattingContext context,
ChainedFormattingRules formattingRules,
Action<int, TriviaData> formattingResultApplier,
Action<int, TokenStream, TriviaData> formattingResultApplier,
CancellationToken cancellationToken,
int tokenPairIndex = TokenPairIndexNotNeeded);
}
......
......@@ -54,23 +54,30 @@ public bool TryGetOption(object underlyingOption, IReadOnlyDictionary<string, ob
{
if (allRawConventions.TryGetValue(KeyName, out object value))
{
var optionalValue = _parseValue(value.ToString(), type);
if (optionalValue.HasValue)
{
result = optionalValue.Value;
}
else
{
result = null;
}
return result != null;
var ret = TryGetOption(value.ToString(), type, out var typedResult);
result = typedResult;
return ret;
}
result = null;
return false;
}
internal bool TryGetOption(string value, Type type, out T result)
{
var optionalValue = _parseValue(value, type);
if (optionalValue.HasValue)
{
result = optionalValue.Value;
return result != null;
}
else
{
result = default;
return false;
}
}
/// <summary>
/// Gets the editorconfig string representation for this storage location.
/// </summary>
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.CodeAnalysis.Shared.Extensions
{
internal static class SyntaxTriviaListExtensions
{
public static SyntaxTrivia? FirstOrNullable(this SyntaxTriviaList triviaList, Func<SyntaxTrivia, bool> predicate)
{
foreach (var trivia in triviaList)
{
if (predicate(trivia))
{
return trivia;
}
}
return null;
}
public static SyntaxTrivia LastOrDefault(this SyntaxTriviaList triviaList)
=> triviaList.Any() ? triviaList.Last() : default;
}
......
......@@ -68,6 +68,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
Return False
End Function
<PerformanceSensitive("https://github.com/dotnet/roslyn/issues/30819", AllowImplicitBoxing:=False)>
Private Function GetTrailingColonTrivia(statement As StatementSyntax) As SyntaxTrivia?
If Not statement.HasTrailingTrivia Then
Return Nothing
......@@ -87,11 +88,20 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
Return False
End Function
<PerformanceSensitive("https://github.com/dotnet/roslyn/issues/30819", AllowCaptures:=False)>
Private Function PartOfMultilineLambdaFooter(node As SyntaxNode) As Boolean
Return node.AncestorsAndSelf.
Where(Function(n) TypeOf n Is MultiLineLambdaExpressionSyntax).
OfType(Of MultiLineLambdaExpressionSyntax).
Any(Function(n) n.EndSubOrFunctionStatement Is node)
For Each n In node.AncestorsAndSelf
Dim multiLine = TryCast(n, MultiLineLambdaExpressionSyntax)
If multiLine Is Nothing Then
Continue For
End If
If (multiLine.EndSubOrFunctionStatement Is node) Then
Return True
End If
Next
Return False
End Function
End Module
End Namespace
......@@ -31,16 +31,21 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting
Public Overrides Sub AddAlignTokensOperationsSlow(operations As List(Of AlignTokensOperation), node As SyntaxNode, optionSet As OptionSet, ByRef nextAction As NextAlignTokensOperationAction)
End Sub
<PerformanceSensitive("https://github.com/dotnet/roslyn/issues/30819", AllowCaptures:=False, AllowImplicitBoxing:=False)>
Public Overrides Function GetAdjustNewLinesOperationSlow(previousToken As SyntaxToken, currentToken As SyntaxToken, optionSet As OptionSet, ByRef nextOperation As NextGetAdjustNewLinesOperation) As AdjustNewLinesOperation
If previousToken.Parent Is Nothing Then
Return Nothing
End If
Dim combinedTrivia = previousToken.TrailingTrivia.Concat(currentToken.LeadingTrivia)
Dim lastTrivia = combinedTrivia.LastOrDefault(AddressOf ColonOrLineContinuationTrivia)
Dim combinedTrivia = (previousToken.TrailingTrivia, currentToken.LeadingTrivia)
Dim lastTrivia = LastOrDefaultTrivia(
combinedTrivia,
Function(trivia As SyntaxTrivia) ColonOrLineContinuationTrivia(trivia))
If lastTrivia.RawKind = SyntaxKind.ColonTrivia Then
Return FormattingOperations.CreateAdjustNewLinesOperation(0, AdjustNewLinesOption.PreserveLines)
ElseIf lastTrivia.RawKind = SyntaxKind.LineContinuationTrivia AndAlso previousToken.Parent.GetAncestorsOrThis(Of SyntaxNode)().Any(AddressOf IsSingleLineIfOrElseClauseSyntax) Then
ElseIf lastTrivia.RawKind = SyntaxKind.LineContinuationTrivia AndAlso previousToken.Parent.GetAncestorsOrThis(Of SyntaxNode)().Any(Function(node As SyntaxNode) IsSingleLineIfOrElseClauseSyntax(node)) Then
Return Nothing
End If
......@@ -89,14 +94,31 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting
Return Nothing
End Function
Private Function IsSingleLineIfOrElseClauseSyntax(node As SyntaxNode) As Boolean
Private Shared Function IsSingleLineIfOrElseClauseSyntax(node As SyntaxNode) As Boolean
Return TypeOf node Is SingleLineIfStatementSyntax OrElse TypeOf node Is SingleLineElseClauseSyntax
End Function
Private Function ColonOrLineContinuationTrivia(trivia As SyntaxTrivia) As Boolean
Private Shared Function ColonOrLineContinuationTrivia(trivia As SyntaxTrivia) As Boolean
Return trivia.RawKind = SyntaxKind.ColonTrivia OrElse trivia.RawKind = SyntaxKind.LineContinuationTrivia
End Function
<PerformanceSensitive("https://github.com/dotnet/roslyn/issues/30819", AllowCaptures:=False, AllowImplicitBoxing:=False)>
Private Shared Function LastOrDefaultTrivia(triviaListPair As (SyntaxTriviaList, SyntaxTriviaList), predicate As Func(Of SyntaxTrivia, Boolean)) As SyntaxTrivia
For Each trivia In triviaListPair.Item2.Reverse()
If predicate(trivia) Then
Return trivia
End If
Next
For Each trivia In triviaListPair.Item1.Reverse()
If predicate(trivia) Then
Return trivia
End If
Next
Return Nothing
End Function
Private Function ContainEndOfLine(previousToken As SyntaxToken, nextToken As SyntaxToken) As Boolean
Return previousToken.TrailingTrivia.Any(SyntaxKind.EndOfLineTrivia) OrElse nextToken.LeadingTrivia.Any(SyntaxKind.EndOfLineTrivia)
End Function
......
......@@ -57,11 +57,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting
Public Overrides Sub Format(context As FormattingContext,
formattingRules As ChainedFormattingRules,
formattingResultApplier As Action(Of Integer, TriviaData),
formattingResultApplier As Action(Of Integer, TokenStream, TriviaData),
cancellationToken As CancellationToken,
Optional tokenPairIndex As Integer = TokenPairIndexNotNeeded)
If Me.ContainsChanges Then
formattingResultApplier(tokenPairIndex, Me)
formattingResultApplier(tokenPairIndex, context.TokenStream, Me)
End If
End Sub
End Class
......
......@@ -90,14 +90,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting
Public Overrides Sub Format(context As FormattingContext,
formattingRules As ChainedFormattingRules,
formattingResultApplier As Action(Of Integer, TriviaData),
formattingResultApplier As Action(Of Integer, TokenStream, TriviaData),
cancellationToken As CancellationToken,
Optional tokenPairIndex As Integer = TokenPairIndexNotNeeded)
If Not ShouldFormat(context) Then
Return
End If
formattingResultApplier(tokenPairIndex, Format(context, formattingRules, Me.LineBreaks, Me.Spaces, cancellationToken))
formattingResultApplier(tokenPairIndex, context.TokenStream, Format(context, formattingRules, Me.LineBreaks, Me.Spaces, cancellationToken))
End Sub
Public Overrides Function GetTextChanges(span As TextSpan) As IEnumerable(Of TextChange)
......
......@@ -63,7 +63,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting
Public Overrides Sub Format(context As FormattingContext,
formattingRules As ChainedFormattingRules,
formattingResultApplier As Action(Of Integer, TriviaData),
formattingResultApplier As Action(Of Integer, TokenStream, TriviaData),
cancellationToken As CancellationToken,
Optional tokenPairIndex As Integer = TokenPairIndexNotNeeded)
Throw New NotImplementedException()
......
......@@ -69,7 +69,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting
Public Overrides Sub Format(context As FormattingContext,
formattingRules As ChainedFormattingRules,
formattingResultApplier As Action(Of Integer, TriviaData),
formattingResultApplier As Action(Of Integer, TokenStream, TriviaData),
cancellationToken As CancellationToken,
Optional tokenPairIndex As Integer = TokenPairIndexNotNeeded)
Contract.ThrowIfFalse(Me.SecondTokenIsFirstTokenOnLine)
......@@ -87,6 +87,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting
formattingResultApplier(
tokenPairIndex,
context.TokenStream,
New FormattedComplexTrivia(context, formattingRules, Me._original.Token1, Me._original.Token2, Me.LineBreaks, Me.Spaces, Me._original.OriginalString, cancellationToken))
End Sub
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册