private List <SuppressOperation> GetInitialSuppressOperations(SyntaxToken token, SuppressOption mask)
            {
                var startNode     = token.Parent;
                var startPosition = token.SpanStart;

                // starting from given token, move up to root until the first meaningful
                // operation has found
                var list = new List <SuppressOperation>();

                bool predicate(SuppressOperation o)
                {
                    if (o == null)
                    {
                        return(true);
                    }

                    if (!o.TextSpan.Contains(startPosition))
                    {
                        return(true);
                    }

                    if (o.ContainsElasticTrivia(_tokenStream) && !o.Option.IsOn(SuppressOption.IgnoreElasticWrapping))
                    {
                        return(true);
                    }

                    if (!o.Option.IsMaskOn(mask))
                    {
                        return(true);
                    }

                    return(false);
                }

                var currentIndentationNode = startNode;

                while (currentIndentationNode != null)
                {
                    _formattingRules.AddSuppressOperations(list, currentIndentationNode);

                    list.RemoveAll(predicate);
                    if (list.Count > 0)
                    {
                        return(list);
                    }

                    currentIndentationNode = currentIndentationNode.Parent;
                }

                return(null);
            }
Exemple #2
0
        protected virtual NodeOperations CreateNodeOperations(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            // iterating tree is very expensive. do it once and cache it to list
            List <SyntaxNode> nodeIterator;

            using (Logger.LogBlock(FunctionId.Formatting_IterateNodes, cancellationToken))
            {
                const int magicLengthToNodesRatio = 5;
                var       result = new List <SyntaxNode>(Math.Max(this.SpanToFormat.Length / magicLengthToNodesRatio, 4));

                foreach (var node in _commonRoot.DescendantNodesAndSelf(this.SpanToFormat))
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    result.Add(node);
                }

                nodeIterator = result;
            }

            // iterate through each operation using index to not create any unnecessary object
            cancellationToken.ThrowIfCancellationRequested();
            List <IndentBlockOperation> indentBlockOperation;

            using (Logger.LogBlock(FunctionId.Formatting_CollectIndentBlock, cancellationToken))
            {
                indentBlockOperation = AddOperations <IndentBlockOperation>(nodeIterator, (l, n) => _formattingRules.AddIndentBlockOperations(l, n), cancellationToken);
            }

            cancellationToken.ThrowIfCancellationRequested();
            List <SuppressOperation> suppressOperation;

            using (Logger.LogBlock(FunctionId.Formatting_CollectSuppressOperation, cancellationToken))
            {
                suppressOperation = AddOperations <SuppressOperation>(nodeIterator, (l, n) => _formattingRules.AddSuppressOperations(l, n), cancellationToken);
            }

            cancellationToken.ThrowIfCancellationRequested();
            List <AlignTokensOperation> alignmentOperation;

            using (Logger.LogBlock(FunctionId.Formatting_CollectAlignOperation, cancellationToken))
            {
                var operations = AddOperations <AlignTokensOperation>(nodeIterator, (l, n) => _formattingRules.AddAlignTokensOperations(l, n), cancellationToken);

                // make sure we order align operation from left to right
                operations.Sort((o1, o2) => o1.BaseToken.Span.CompareTo(o2.BaseToken.Span));

                alignmentOperation = operations;
            }

            cancellationToken.ThrowIfCancellationRequested();
            List <AnchorIndentationOperation> anchorIndentationOperations;

            using (Logger.LogBlock(FunctionId.Formatting_CollectAnchorOperation, cancellationToken))
            {
                anchorIndentationOperations = AddOperations <AnchorIndentationOperation>(nodeIterator, (l, n) => _formattingRules.AddAnchorIndentationOperations(l, n), cancellationToken);
            }

            return(new NodeOperations(indentBlockOperation, suppressOperation, anchorIndentationOperations, alignmentOperation));
        }