public CallExpressionCodeActionComputer(
                AbstractChainedExpressionWrapper <TNameSyntax, TBaseArgumentListSyntax> service,
                Document document,
                SourceText originalSourceText,
                SyntaxWrappingOptions options,
                ImmutableArray <ImmutableArray <SyntaxNodeOrToken> > chunks,
                CancellationToken cancellationToken)
                : base(service, document, originalSourceText, options, cancellationToken)
            {
                _chunks = chunks;

                var generator = SyntaxGenerator.GetGenerator(document);

                // Both [0][0] indices are safe here.  We can only get here if we had more than
                // two chunks to wrap.  And each chunk is required to have at least three elements
                // (i.e. <c>. name (arglist)</c>).
                var firstPeriod = chunks[0][0];

                _firstPeriodIndentationTrivia = new SyntaxTriviaList(generator.Whitespace(
                                                                         OriginalSourceText.GetOffset(firstPeriod.SpanStart).CreateIndentationString(options.UseTabs, options.TabSize)));

                _smartIndentTrivia = new SyntaxTriviaList(generator.Whitespace(
                                                              GetSmartIndentationAfter(firstPeriod)));

                _newlineBeforeOperatorTrivia = service.GetNewLineBeforeOperatorTrivia(NewLineTrivia);
            }
Exemplo n.º 2
0
        public sealed override async Task <ICodeActionComputer?> TryCreateComputerAsync(
            Document document, int position, SyntaxNode node, SyntaxWrappingOptions options, bool containsSyntaxError, CancellationToken cancellationToken)
        {
            if (containsSyntaxError)
            {
                return(null);
            }

            // We have to be on a chain part.  If not, there's nothing to do here at all.
            if (!IsDecomposableChainPart(node))
            {
                return(null);
            }

            // Has to be the topmost chain part.  If we're not on the topmost, then just
            // bail out here.  Our caller will continue walking upwards until it hits the
            // topmost node.
            if (IsDecomposableChainPart(node.Parent))
            {
                return(null);
            }

            // We're at the top of something that looks like it could be part of a chained
            // expression.  Break it into the individual chunks.  We need to have at least
            // two chunks or this to be worth wrapping.
            //
            // i.e. if we only have <c>this.Goo(...)</c> there's nothing to wrap.  However, we can
            // wrap when we have <c>this.Goo(...).Bar(...)</c>.
            var chunks = GetChainChunks(node);

            if (chunks.Length <= 1)
            {
                return(null);
            }

            // If any of these chunk parts are unformattable, then we don't want to offer anything
            // here as we may make formatting worse for this construct.
            foreach (var chunk in chunks)
            {
                var unformattable = await ContainsUnformattableContentAsync(
                    document, chunk, cancellationToken).ConfigureAwait(false);

                if (unformattable)
                {
                    return(null);
                }
            }

            // Looks good.  Create the action computer which will actually determine
            // the set of wrapping options to provide.
            var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            return(new CallExpressionCodeActionComputer(
                       this, document, sourceText, options, chunks, cancellationToken));
        }
        public override async Task <ICodeActionComputer?> TryCreateComputerAsync(
            Document document, int position, SyntaxNode declaration, SyntaxWrappingOptions options, bool containsSyntaxError, CancellationToken cancellationToken)
        {
            var listSyntax = TryGetApplicableList(declaration);

            if (listSyntax == null || listSyntax.Span.IsEmpty)
            {
                return(null);
            }

            var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            if (!PositionIsApplicable(root, position, declaration, containsSyntaxError, listSyntax))
            {
                return(null);
            }

            var listItems = GetListItems(listSyntax);

            if (listItems.Count <= 1)
            {
                // nothing to do with 0-1 items.  Simple enough for users to just edit
                // themselves, and this prevents constant clutter with formatting that isn't
                // really that useful.
                return(null);
            }

            var containsUnformattableContent = await ContainsUnformattableContentAsync(
                document, listItems.GetWithSeparators(), cancellationToken).ConfigureAwait(false);

            if (containsUnformattableContent)
            {
                return(null);
            }

            var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            return(new SeparatedSyntaxListCodeActionComputer(
                       this, document, sourceText, options, listSyntax, listItems, cancellationToken));
        }
            public SeparatedSyntaxListCodeActionComputer(
                AbstractSeparatedSyntaxListWrapper <TListSyntax, TListItemSyntax> service,
                Document document,
                SourceText sourceText,
                SyntaxWrappingOptions options,
                TListSyntax listSyntax,
                SeparatedSyntaxList <TListItemSyntax> listItems,
                CancellationToken cancellationToken)
                : base(service, document, sourceText, options, cancellationToken)
            {
                _listSyntax = listSyntax;
                _listItems  = listItems;

                _shouldMoveOpenBraceToNewLine  = service.ShouldMoveOpenBraceToNewLine(options);
                _shouldMoveCloseBraceToNewLine = service.ShouldMoveCloseBraceToNewLine;

                var generator = SyntaxGenerator.GetGenerator(OriginalDocument);

                _afterOpenTokenIndentationTrivia = generator.Whitespace(GetAfterOpenTokenIdentation());
                _singleIndentationTrivia         = generator.Whitespace(GetSingleIdentation());
                _braceIndentationTrivia          = generator.Whitespace(GetBraceTokenIndentation());
            }
            public BinaryExpressionCodeActionComputer(
                AbstractBinaryExpressionWrapper <TBinaryExpressionSyntax> service,
                Document document,
                SourceText originalSourceText,
                SyntaxWrappingOptions options,
                TBinaryExpressionSyntax binaryExpression,
                ImmutableArray <SyntaxNodeOrToken> exprsAndOperators,
                CancellationToken cancellationToken)
                : base(service, document, originalSourceText, options, cancellationToken)
            {
                _exprsAndOperators = exprsAndOperators;

                var generator = SyntaxGenerator.GetGenerator(document);

                _newlineBeforeOperatorTrivia = service.GetNewLineBeforeOperatorTrivia(NewLineTrivia);

                _indentAndAlignTrivia = new SyntaxTriviaList(generator.Whitespace(
                                                                 OriginalSourceText.GetOffset(binaryExpression.Span.Start)
                                                                 .CreateIndentationString(options.FormattingOptions.UseTabs, options.FormattingOptions.TabSize)));

                _smartIndentTrivia = new SyntaxTriviaList(generator.Whitespace(
                                                              GetSmartIndentationAfter(_exprsAndOperators[1])));
            }
 protected abstract bool ShouldMoveOpenBraceToNewLine(SyntaxWrappingOptions options);
 protected override bool ShouldMoveOpenBraceToNewLine(SyntaxWrappingOptions options)
 => false;
Exemplo n.º 8
0
        public sealed override async Task <ICodeActionComputer?> TryCreateComputerAsync(
            Document document, int position, SyntaxNode node, SyntaxWrappingOptions options, bool containsSyntaxError, CancellationToken cancellationToken)
        {
            if (containsSyntaxError)
            {
                return(null);
            }

            if (node is not TBinaryExpressionSyntax binaryExpr)
            {
                return(null);
            }

            var precedence = _precedenceService.GetPrecedenceKind(binaryExpr);

            if (precedence == PrecedenceKind.Other)
            {
                return(null);
            }

            // Don't process this binary expression if it's in a parent binary expr of the same or
            // lower precedence.  We'll just allow our caller to walk up to that and call back into
            // us to handle.  This way, we're always starting at the topmost binary expr of this
            // precedence.
            //
            // for example, if we have `if (a + b == c + d)` expectation is to wrap on the lower
            // precedence `==` op, not either of the `+` ops
            //
            // Note: we use `<=` when comparing precedence because lower precedence has a higher
            // value.
            if (binaryExpr.Parent is TBinaryExpressionSyntax parentBinary &&
                precedence <= _precedenceService.GetPrecedenceKind(parentBinary))
            {
                return(null);
            }

            var exprsAndOperators = GetExpressionsAndOperators(precedence, binaryExpr);

#if DEBUG
            Debug.Assert(exprsAndOperators.Length >= 3);
            Debug.Assert(exprsAndOperators.Length % 2 == 1, "Should have odd number of exprs and operators");
            for (var i = 0; i < exprsAndOperators.Length; i++)
            {
                var item = exprsAndOperators[i];
                Debug.Assert(((i % 2) == 0 && item.IsNode) ||
                             ((i % 2) == 1 && item.IsToken));
            }
#endif

            var containsUnformattableContent = await ContainsUnformattableContentAsync(
                document, exprsAndOperators, cancellationToken).ConfigureAwait(false);

            if (containsUnformattableContent)
            {
                return(null);
            }

            var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            return(new BinaryExpressionCodeActionComputer(
                       this, document, sourceText, options, binaryExpr,
                       exprsAndOperators, cancellationToken));
        }
 protected override bool ShouldMoveOpenBraceToNewLine(SyntaxWrappingOptions options)
 => ((CSharpSyntaxWrappingOptions)options).NewLinesForBracesInObjectCollectionArrayInitializers;