Пример #1
0
        private void ApplySpaceAndWrappingOperations(
            FormattingContext context,
            TokenStream tokenStream,
            TokenPairWithOperations[] tokenOperations,
            OperationApplier applier,
            CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.Formatting_ApplySpaceAndLine, cancellationToken))
            {
                // go through each token pairs and apply operations. operations don't need to be applied in order
                var partitioner = new Partitioner(context, tokenStream, tokenOperations);

                // always create task 1 more than current processor count
                var partitions = partitioner.GetPartitions(this.TaskExecutor == TaskExecutor.Synchronous ? 1 : Environment.ProcessorCount + 1);

                var tasks = new List <Task>(
                    partitions.Select(
                        partition =>
                        this.TaskExecutor.StartNew(
                            () =>
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    partition.Do(operationPair => ApplySpaceAndWrappingOperationsBody(context, tokenStream, operationPair, applier, cancellationToken));
                },
                            cancellationToken)));

                Task.WaitAll(tasks.ToArray(), cancellationToken);
            }
        }
Пример #2
0
        private void ApplySpecialOperations(
            FormattingContext context, NodeOperations nodeOperationsCollector, OperationApplier applier, CancellationToken cancellationToken)
        {
            // apply alignment operation
            using (Logger.LogBlock(FunctionId.Formatting_CollectAlignOperation, cancellationToken))
            {
                cancellationToken.ThrowIfCancellationRequested();

                // TODO : figure out a way to run alignment operations in parallel. probably find
                // unions and run each chunk in separate tasks
                var previousChangesMap  = new Dictionary <SyntaxToken, int>();
                var alignmentOperations = nodeOperationsCollector.AlignmentOperation;

                alignmentOperations.Do(operation =>
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    applier.ApplyAlignment(operation, previousChangesMap, cancellationToken);
                });

                // go through all relative indent block operation, and see whether it is affected by previous operations
                context.GetAllRelativeIndentBlockOperations().Do(o =>
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    applier.ApplyBaseTokenIndentationChangesFromTo(FindCorrectBaseTokenOfRelativeIndentBlockOperation(o, context.TokenStream), o.StartToken, o.EndToken, previousChangesMap, cancellationToken);
                });
            }
        }
Пример #3
0
        private void ApplyAnchorOperations(
            FormattingContext context,
            TokenStream tokenStream,
            TokenPairWithOperations[] tokenOperations,
            OperationApplier applier,
            CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.Formatting_ApplyAnchorOperation, cancellationToken))
            {
                var tokenPairsToApplyAnchorOperations = this.TaskExecutor.Filter(
                    tokenOperations,
                    p => AnchorOperationCandidate(p),
                    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 void ApplyTokenOperations(
            FormattingContext context,
            NodeOperations nodeOperations,
            SegmentedArray <TokenPairWithOperations> tokenOperations,
            CancellationToken cancellationToken)
        {
            var applier = new OperationApplier(context, _formattingRules);

            ApplySpaceAndWrappingOperations(context, tokenOperations, applier, cancellationToken);

            ApplyAnchorOperations(context, tokenOperations, applier, cancellationToken);

            ApplySpecialOperations(context, nodeOperations, applier, cancellationToken);
        }
Пример #5
0
        private void ApplyTokenOperations(
            FormattingContext context,
            TokenStream tokenStream,
            NodeOperations nodeOperations,
            TokenPairWithOperations[] tokenOperations,
            CancellationToken cancellationToken)
        {
            var applier = new OperationApplier(context, tokenStream, _formattingRules);

            ApplySpaceAndWrappingOperations(context, tokenStream, tokenOperations, applier, cancellationToken);

            ApplyAnchorOperations(context, tokenStream, tokenOperations, applier, cancellationToken);

            ApplySpecialOperations(context, tokenStream, nodeOperations, applier, cancellationToken);
        }
Пример #6
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);
                }
            }
        }
Пример #7
0
        private void ApplyTokenOperations(
            FormattingContext context,
            TokenStream tokenStream,
            Task anchorContextTask,
            NodeOperations nodeOperations,
            TokenPairWithOperations[] tokenOperations,
            CancellationToken cancellationToken)
        {
            var applier = new OperationApplier(context, tokenStream, this.formattingRules);

            ApplySpaceAndWrappingOperations(context, tokenStream, tokenOperations, applier, cancellationToken);

            // wait until anchor task to finish adding its information to context
            anchorContextTask.Wait(cancellationToken);

            ApplyAnchorOperations(context, tokenStream, tokenOperations, applier, cancellationToken);

            ApplySpecialOperations(context, tokenStream, nodeOperations, applier, cancellationToken);
        }
Пример #8
0
        private async Task ApplyTokenOperationsAsync(
            FormattingContext context,
            TokenStream tokenStream,
            Task anchorContextTask,
            NodeOperations nodeOperations,
            TokenPairWithOperations[] tokenOperations,
            CancellationToken cancellationToken)
        {
            var applier = new OperationApplier(context, tokenStream, _formattingRules);

            ApplySpaceAndWrappingOperations(context, tokenStream, tokenOperations, applier, cancellationToken);

            // wait until anchor task to finish adding its information to context
            await anchorContextTask.ConfigureAwait(false);

            ApplyAnchorOperations(context, tokenStream, tokenOperations, applier, cancellationToken);

            await ApplySpecialOperationsAsync(context, tokenStream, nodeOperations, applier, cancellationToken).ConfigureAwait(false);
        }
Пример #9
0
        private void ApplySpaceAndWrappingOperations(
            FormattingContext context,
            TokenPairWithOperations[] tokenOperations,
            OperationApplier applier,
            CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.Formatting_ApplySpaceAndLine, cancellationToken))
            {
                // go through each token pairs and apply operations. operations don't need to be applied in order
                var partitioner = new Partitioner(context, tokenOperations);

                // always create task 1 more than current processor count
                var partitions = partitioner.GetPartitions(partitionCount: 1, cancellationToken);

                foreach (var partition in partitions)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    partition.Do(operationPair => ApplySpaceAndWrappingOperationsBody(context, operationPair, applier, cancellationToken));
                }
            }
        }
        /// <summary>
        /// Retrieves, applies, and acknowledges each operation from the provided <paramref name="queue"/>.
        /// </summary>
        /// <param name="queue">The queue.</param>
        /// <param name="apply">The method used to apply each operation.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <param name="initiated">
        /// Optional completion to signify that the queue draining has begun.
        /// </param>
        /// <returns>A <see cref="Task"/> representing the work performed.</returns>
        private static async Task PumpOperations(
            IOperationStream queue,
            OperationApplier apply,
            CancellationToken cancellationToken,
            TaskCompletionSource <int> initiated = null)
        {
            var firstOperation = true;

            do
            {
                cancellationToken.ThrowIfCancellationRequested();

                // Start retrieving the next operation.
                var nextOperation = queue.GetOperationAsync(cancellationToken);

                // If this is the first operation and the caller has requested to be notified that draining has begun,
                // notify the caller.
                if (firstOperation)
                {
                    initiated?.TrySetResult(0);
                    firstOperation = false;
                }

                // Wait for the operation to be retrieved.
                var operation = await nextOperation.ConfigureAwait(false);

                // A null operation signifies that the queue has been completely drained.
                if (operation == null)
                {
                    return;
                }

                // Apply and acknowledge the operation.
                await apply(operation, cancellationToken).ConfigureAwait(false);

                operation.Acknowledge();
            }while (true);
        }
        /// <summary>
        /// Retrieves, applies, and acknowledges each operation from the provided <paramref name="queue"/>.
        /// </summary>
        /// <param name="queue">The queue.</param>
        /// <param name="apply">The method used to apply each operation.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <param name="initiated">
        /// Optional completion to signify that the queue draining has begun.
        /// </param>
        /// <returns>A <see cref="Task"/> representing the work performed.</returns>
        private static async Task PumpOperations(
            IOperationStream queue,
            OperationApplier apply,
            CancellationToken cancellationToken,
            TaskCompletionSource<int> initiated = null)
        {
            var firstOperation = true;
            do
            {
                cancellationToken.ThrowIfCancellationRequested();

                // Start retrieving the next operation.
                var nextOperation = queue.GetOperationAsync(cancellationToken);

                // If this is the first operation and the caller has requested to be notified that draining has begun,
                // notify the caller.
                if (firstOperation)
                {
                    initiated?.TrySetResult(0);
                    firstOperation = false;
                }

                // Wait for the operation to be retrieved.
                var operation = await nextOperation.ConfigureAwait(false);

                // A null operation signifies that the queue has been completely drained.
                if (operation == null)
                {
                    return;
                }
                
                // Apply and acknowledge the operation.
                await apply(operation, cancellationToken).ConfigureAwait(false);
                operation.Acknowledge();
            }
            while (true);
        }