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); }
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)); }
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)); }