protected virtual NodeOperations CreateNodeOperations(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

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

            using (Logger.LogBlock(FunctionId.Formatting_IterateNodes, cancellationToken))
            {
                const int magicLengthToNodesRatio = 5;
                var       result = new SegmentedList <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));
        }
Esempio n. 2
0
        protected virtual NodeOperations CreateNodeOperationTasks(CancellationToken cancellationToken)
        {
            // iterating tree is very expensive. do it once and cache it to list
            var nodeIteratorTask = this.TaskExecutor.StartNew(() =>
            {
                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);
                    }

                    return(result);
                }
            },
                                                              cancellationToken);

            // iterate through each operation using index to not create any unnecessary object
            var indentBlockOperationTask = this.TaskExecutor.ContinueWith(nodeIteratorTask, task =>
            {
                using (Logger.LogBlock(FunctionId.Formatting_CollectIndentBlock, cancellationToken))
                {
                    return(AddOperations <IndentBlockOperation>(task.Result, (l, n) => _formattingRules.AddIndentBlockOperations(l, n), cancellationToken));
                }
            },
                                                                          cancellationToken);

            var suppressOperationTask = this.TaskExecutor.ContinueWith(nodeIteratorTask, task =>
            {
                using (Logger.LogBlock(FunctionId.Formatting_CollectSuppressOperation, cancellationToken))
                {
                    return(AddOperations <SuppressOperation>(task.Result, (l, n) => _formattingRules.AddSuppressOperations(l, n), cancellationToken));
                }
            },
                                                                       cancellationToken);

            var alignmentOperationTask = this.TaskExecutor.ContinueWith(nodeIteratorTask, task =>
            {
                using (Logger.LogBlock(FunctionId.Formatting_CollectAlignOperation, cancellationToken))
                {
                    var operations = AddOperations <AlignTokensOperation>(task.Result, (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));

                    return(operations);
                }
            },
                                                                        cancellationToken);

            var anchorIndentationOperationsTask = this.TaskExecutor.ContinueWith(nodeIteratorTask, task =>
            {
                using (Logger.LogBlock(FunctionId.Formatting_CollectAnchorOperation, cancellationToken))
                {
                    return(AddOperations <AnchorIndentationOperation>(task.Result, (l, n) => _formattingRules.AddAnchorIndentationOperations(l, n), cancellationToken));
                }
            },
                                                                                 cancellationToken);

            return(new NodeOperations(indentBlockOperationTask, suppressOperationTask, anchorIndentationOperationsTask, alignmentOperationTask));
        }