private bool ApplyDynamicSpacesOperation(AdjustSpacesOperation operation, int pairIndex) { var triviaInfo = _tokenStream.GetTriviaData(pairIndex); if (triviaInfo.SecondTokenIsFirstTokenOnLine) { return(false); } Contract.ThrowIfFalse(triviaInfo.LineBreaks == 0); var indentation = _context.GetBaseIndentation(_tokenStream.GetToken(pairIndex + 1)); var previousToken = _tokenStream.GetToken(pairIndex); bool multipleLines; int tokenLength; _tokenStream.GetTokenLength(previousToken, out tokenLength, out multipleLines); // get end column of previous token var endColumnOfPreviousToken = multipleLines ? tokenLength : _tokenStream.GetCurrentColumn(previousToken) + tokenLength; // check whether current position is less than indentation if (endColumnOfPreviousToken < indentation) { _tokenStream.ApplyChange(pairIndex, triviaInfo.WithSpace(indentation - endColumnOfPreviousToken, _context, _formattingRules)); return(true); } // delegate to normal single-line space applier return(ApplySpaceIfSingleLine(operation, pairIndex)); }
public static bool ContainsElasticTrivia( this SuppressOperation operation, TokenStream tokenStream ) { var startToken = tokenStream.GetTokenData(operation.StartToken); var nextToken = startToken.GetNextTokenData(); var endToken = tokenStream.GetTokenData(operation.EndToken); var previousToken = endToken.GetPreviousTokenData(); return(tokenStream.GetTriviaData(startToken, nextToken).TreatAsElastic || tokenStream.GetTriviaData(previousToken, endToken).TreatAsElastic); }
private AnchorData FindAnchorSpanOnSameLineAfterToken(TokenData tokenData) { // every token after given token on same line is implicitly dependent to the token. // check whether one of them is an anchor token. AnchorData lastBaseAnchorData = null; while (tokenData.IndexInStream >= 0) { AnchorData tempAnchorData; if (_anchorBaseTokenMap.TryGetValue(tokenData.Token, out tempAnchorData)) { lastBaseAnchorData = tempAnchorData; } // tokenPairIndex is always 0 <= ... < TokenCount - 1 var tokenPairIndex = tokenData.IndexInStream; if (_tokenStream.TokenCount - 1 <= tokenPairIndex || _tokenStream.GetTriviaData(tokenPairIndex).SecondTokenIsFirstTokenOnLine) { return(lastBaseAnchorData); } tokenData = tokenData.GetNextTokenData(); } return(lastBaseAnchorData); }
private void ApplyAnchorOperations( FormattingContext context, TokenStream tokenStream, TokenPairWithOperations[] tokenOperations, OperationApplier applier, CancellationToken cancellationToken) { using (Logger.LogBlock(FeatureId.Formatting, FunctionId.Formatting_ApplyAnchorOperation, cancellationToken)) { var tokenPairsToApplyAnchorOperations = this.TaskExecutor.Filter( tokenOperations, p => p.LineOperation == null && tokenStream.GetTriviaData(p.PairIndex).SecondTokenIsFirstTokenOnLine, p => p.PairIndex, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); // TODO: find out a way to apply anchor operation concurrently if possible var previousChangesMap = new Dictionary <SyntaxToken, int>(); tokenPairsToApplyAnchorOperations.Do(pairIndex => { cancellationToken.ThrowIfCancellationRequested(); applier.ApplyAnchorIndentation(pairIndex, previousChangesMap, cancellationToken); }); // go through all relative indent block operation, and see whether it is affected by the anchor operation context.GetAllRelativeIndentBlockOperations().Do(o => { cancellationToken.ThrowIfCancellationRequested(); applier.ApplyBaseTokenIndentationChangesFromTo(FindCorrectBaseTokenOfRelativeIndentBlockOperation(o, tokenStream), o.StartToken, o.EndToken, previousChangesMap, cancellationToken); }); } }
private bool ApplyBaseTokenIndentationChangesFromTo( TokenData baseToken, TokenData startToken, TokenData endToken, Dictionary <SyntaxToken, int> previousChangesMap, CancellationToken cancellationToken) { // if baseToken is not in the stream, then it is guaranteeded to be not moved. var tokenWithIndex = baseToken; if (tokenWithIndex.IndexInStream < 0) { return(false); } // now, check whether tokens on that the base token depends have been moved. // any token before the base token on the same line has implicit dependency over the base token. while (tokenWithIndex.IndexInStream >= 0) { // check whether given token have moved if (previousChangesMap.ContainsKey(tokenWithIndex.Token)) { break; } // 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) { return(false); } tokenWithIndex = tokenWithIndex.GetPreviousTokenData(); } // didn't find anything moved if (tokenWithIndex.IndexInStream < 0) { return(false); } // we are not moved var indentationDelta = this.context.GetDeltaFromPreviousChangesMap(tokenWithIndex.Token, previousChangesMap); if (indentationDelta == 0) { return(false); } startToken = startToken.IndexInStream < 0 ? tokenStream.FirstTokenInStream : startToken; endToken = endToken.IndexInStream < 0 ? tokenStream.LastTokenInStream : endToken; ApplyIndentationDeltaFromTo(startToken, endToken, indentationDelta, previousChangesMap, cancellationToken); return(true); }
private void ApplyTriviaOperations(FormattingContext context, TokenStream tokenStream, CancellationToken cancellationToken) { // trivia formatting result appliers Action <int, TriviaData> regularApplier = (tokenPairIndex, info) => { tokenStream.ApplyChange(tokenPairIndex, info); }; // trivia formatting applier Action <int> triviaFormatter = tokenPairIndex => { var triviaInfo = tokenStream.GetTriviaData(tokenPairIndex); triviaInfo.Format(context, this.formattingRules, regularApplier, cancellationToken, tokenPairIndex); }; this.TaskExecutor.For(0, tokenStream.TokenCount - 1, triviaFormatter, cancellationToken); }
private void ApplyTriviaOperations(FormattingContext context, TokenStream tokenStream, CancellationToken cancellationToken) { // trivia formatting result appliers void regularApplier(int tokenPairIndex, TriviaData info) { tokenStream.ApplyChange(tokenPairIndex, info); } // trivia formatting applier void triviaFormatter(int tokenPairIndex) { var triviaInfo = tokenStream.GetTriviaData(tokenPairIndex); triviaInfo.Format(context, _formattingRules, regularApplier, cancellationToken, tokenPairIndex); } this.TaskExecutor.For(0, tokenStream.TokenCount - 1, triviaFormatter, cancellationToken); }
private static void ApplySpaceAndWrappingOperationsBody( FormattingContext context, TokenStream tokenStream, TokenPairWithOperations operation, OperationApplier applier, CancellationToken cancellationToken) { var token1 = operation.Token1; var token2 = operation.Token2; // check whether one of tokens is missing (which means syntax error exist around two tokens) // in error case, we leave code as user wrote if (token1.IsMissing || token2.IsMissing) { return; } var triviaInfo = tokenStream.GetTriviaData(operation.PairIndex); var spanBetweenTokens = TextSpan.FromBounds(token1.Span.End, token2.SpanStart); if (operation.LineOperation != null) { if (!context.IsWrappingSuppressed(spanBetweenTokens)) { // TODO : need to revisit later for the case where line and space operations // are conflicting each other by forcing new lines and removing new lines. // // if wrapping operation applied, no need to run any other operation if (applier.Apply(operation.LineOperation, operation.PairIndex, cancellationToken)) { return; } } } if (operation.SpaceOperation != null) { if (!context.IsSpacingSuppressed(spanBetweenTokens)) { applier.Apply(operation.SpaceOperation, operation.PairIndex); } } }
private void ApplyTriviaOperations(FormattingContext context, TokenStream tokenStream, CancellationToken cancellationToken) { // trivia formatting result appliers void regularApplier(int tokenPairIndex, TriviaData info) { tokenStream.ApplyChange(tokenPairIndex, info); } // trivia formatting applier void triviaFormatter(int tokenPairIndex) { var triviaInfo = tokenStream.GetTriviaData(tokenPairIndex); triviaInfo.Format(context, _formattingRules, regularApplier, cancellationToken, tokenPairIndex); } for (var i = 0; i < tokenStream.TokenCount - 1; i++) { cancellationToken.ThrowIfCancellationRequested(); triviaFormatter(i); } }