示例#1
0
            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));
            }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
                });
            }
        }
示例#5
0
            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);
            }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        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);
                }
            }
        }
示例#9
0
        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);
            }
        }