示例#1
0
            private static void AddIndentBlockOperations(List <IndentBlockOperation> list, SyntaxNode node)
            {
                // only add indent block operation if the base token is the first token on line
                var text      = node.SyntaxTree.GetText();
                var baseToken = node.Parent.GetFirstToken(includeZeroWidth: true);

                list.Add(FormattingOperations.CreateRelativeIndentBlockOperation(
                             baseToken,
                             node.GetFirstToken(includeZeroWidth: true).GetNextToken(includeZeroWidth: true),
                             node.GetLastToken(includeZeroWidth: true).GetPreviousToken(includeZeroWidth: true),
                             indentationDelta: 1,
                             option: IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine));
            }
        protected void AddIndentBlockOperation(
            List <IndentBlockOperation> list,
            SyntaxToken startToken,
            SyntaxToken endToken,
            IndentBlockOption option = IndentBlockOption.RelativePosition)
        {
            if (startToken.Kind() == SyntaxKind.None || endToken.Kind() == SyntaxKind.None)
            {
                return;
            }

            list.Add(FormattingOperations.CreateIndentBlockOperation(startToken, endToken, indentationDelta: 1, option: option));
        }
示例#3
0
        private void AddChangeSignatureIndentOperation(List <IndentBlockOperation> list, SyntaxNode node)
        {
            if (node.Parent != null)
            {
                var baseToken  = node.Parent.GetFirstToken();
                var startToken = node.GetFirstToken();
                var endToken   = node.GetLastToken();
                var span       = CommonFormattingHelpers.GetSpanIncludingTrailingAndLeadingTriviaOfAdjacentTokens(startToken, endToken);
                span = TextSpan.FromBounds(Math.Max(baseToken.Span.End, span.Start), span.End);

                list.Add(FormattingOperations.CreateRelativeIndentBlockOperation(baseToken, startToken, endToken, span, indentationDelta: 1, option: IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine));
            }
        }
示例#4
0
            public override AdjustSpacesOperation GetAdjustSpacesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustSpacesOperation> nextOperation)
            {
                var spaceOperation = base.GetAdjustSpacesOperation(previousToken, currentToken, optionSet, nextOperation);

                // if there is force space operation, convert it to ForceSpaceIfSingleLine operation.
                // (force space basically means remove all line breaks)
                if (spaceOperation != null && spaceOperation.Option == AdjustSpacesOption.ForceSpaces)
                {
                    return(FormattingOperations.CreateAdjustSpacesOperation(spaceOperation.Space, AdjustSpacesOption.ForceSpacesIfOnSingleLine));
                }

                return(spaceOperation);
            }
        protected void AddAbsoluteZeroIndentBlockOperation(
            List <IndentBlockOperation> list,
            SyntaxToken startToken,
            SyntaxToken endToken,
            IndentBlockOption option = IndentBlockOption.AbsolutePosition)
        {
            if (startToken.CSharpKind() == SyntaxKind.None || endToken.CSharpKind() == SyntaxKind.None)
            {
                return;
            }

            list.Add(FormattingOperations.CreateIndentBlockOperation(startToken, endToken, indentationDelta: 0, option: option));
        }
        private static void AddPropertyDeclarationSuppressOperations(List <SuppressOperation> list, SyntaxNode node)
        {
            var basePropertyDeclaration = node as BasePropertyDeclarationSyntax;

            if (basePropertyDeclaration != null && basePropertyDeclaration.AccessorList != null &&
                basePropertyDeclaration.AccessorList.Accessors.All(a => a.Body == null) &&
                basePropertyDeclaration.GetAnnotatedTrivia(SyntaxAnnotation.ElasticAnnotation).Any())
            {
                var tokens = basePropertyDeclaration.GetFirstAndLastMemberDeclarationTokensAfterAttributes();

                list.Add(FormattingOperations.CreateSuppressOperation(tokens.Item1, tokens.Item2, SuppressOption.NoWrapping | SuppressOption.IgnoreElastic));
            }
        }
示例#7
0
        protected static void AddSuppressOperation(
            List <SuppressOperation> list,
            SyntaxToken startToken,
            SyntaxToken endToken,
            SuppressOption option
            )
        {
            if (startToken.Kind() == SyntaxKind.None || endToken.Kind() == SyntaxKind.None)
            {
                return;
            }

            list.Add(FormattingOperations.CreateSuppressOperation(startToken, endToken, option));
        }
示例#8
0
        public static bool ShouldUseSmartTokenFormatterInsteadOfIndenter(
            IEnumerable <IFormattingRule> formattingRules,
            CompilationUnitSyntax root,
            ITextSnapshotLine line,
            OptionSet optionSet,
            CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(formattingRules);
            Contract.ThrowIfNull(root);
            Contract.ThrowIfNull(line);

            if (optionSet.GetOption(FormattingOptions.SmartIndent, LanguageNames.CSharp) != FormattingOptions.IndentStyle.Smart)
            {
                return(false);
            }

            var firstNonWhitespacePosition = line.GetFirstNonWhitespacePosition();

            if (!firstNonWhitespacePosition.HasValue)
            {
                return(false);
            }

            var token = root.FindToken(firstNonWhitespacePosition.Value);

            if (token.IsKind(SyntaxKind.None) ||
                token.SpanStart != firstNonWhitespacePosition)
            {
                return(false);
            }

            // first see whether there is a line operation for current token
            var previousToken = token.GetPreviousToken(includeZeroWidth: true);

            // only use smart token formatter when we have two visible tokens.
            if (previousToken.Kind() == SyntaxKind.None || previousToken.IsMissing)
            {
                return(false);
            }

            var lineOperation = FormattingOperations.GetAdjustNewLinesOperation(formattingRules, previousToken, token, optionSet);

            if (lineOperation != null && lineOperation.Option != AdjustNewLinesOption.ForceLinesIfOnSingleLine)
            {
                return(true);
            }

            // no indentation operation, nothing to do for smart token formatter
            return(false);
        }
示例#9
0
        private void SuppressVariableDeclaration(List <SuppressOperation> list, SyntaxNode node, OptionSet optionSet)
        {
            if (node.IsKind(SyntaxKind.FieldDeclaration) || node.IsKind(SyntaxKind.EventDeclaration) ||
                node.IsKind(SyntaxKind.EventFieldDeclaration) || node.IsKind(SyntaxKind.LocalDeclarationStatement))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.SpacesIgnoreAroundVariableDeclaration))
                {
                    var firstToken = node.GetFirstToken(includeZeroWidth: true);
                    var lastToken  = node.GetLastToken(includeZeroWidth: true);

                    list.Add(FormattingOperations.CreateSuppressOperation(firstToken, lastToken, SuppressOption.NoSpacing));
                }
            }
        }
示例#10
0
            public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustNewLinesOperation> nextOperation)
            {
                // Since we know the general shape of these new import statements, we simply look for where
                // tokens are not on the same line and force them to only be separated by a single newline.

                _text.GetLineAndOffset(previousToken.Span.Start, out int previousLine, out _);
                _text.GetLineAndOffset(currentToken.Span.Start, out int currentLine, out _);

                if (previousLine != currentLine)
                {
                    return(FormattingOperations.CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.ForceLines));
                }

                return(null);
            }
        public AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustNewLinesOperation> nextOperation)
        {
            // case: insert blank line in empty method body.
            if (previousToken.Kind() == SyntaxKind.OpenBraceToken &&
                currentToken.Kind() == SyntaxKind.CloseBraceToken)
            {
                if (currentToken.Parent.Kind() == SyntaxKind.Block &&
                    currentToken.Parent.Parent.Kind() == SyntaxKind.MethodDeclaration)
                {
                    return(FormattingOperations.CreateAdjustNewLinesOperation(2, AdjustNewLinesOption.ForceLines));
                }
            }

            return(nextOperation.Invoke());
        }
示例#12
0
        protected static void AddAlignIndentationOfTokensToBaseTokenOperation(
            List <AlignTokensOperation> list,
            SyntaxNode containingNode,
            SyntaxToken baseNode,
            IEnumerable <SyntaxToken> tokens,
            AlignTokensOption option = AlignTokensOption.AlignIndentationOfTokensToBaseToken
            )
        {
            if (containingNode == null || tokens == null)
            {
                return;
            }

            list.Add(FormattingOperations.CreateAlignTokensOperation(baseNode, tokens, option));
        }
示例#13
0
            public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustNewLinesOperation> nextOperation)
            {
                if (currentToken.Parent != null)
                {
                    var currentTokenParentParent = currentToken.Parent.Parent;
                    if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentTokenParentParent != null &&
                        (currentTokenParentParent.Kind() == SyntaxKind.SimpleLambdaExpression ||
                         currentTokenParentParent.Kind() == SyntaxKind.ParenthesizedLambdaExpression ||
                         currentTokenParentParent.Kind() == SyntaxKind.AnonymousMethodExpression))
                    {
                        return(FormattingOperations.CreateAdjustNewLinesOperation(0, AdjustNewLinesOption.PreserveLines));
                    }
                }

                return(nextOperation.Invoke());
            }
示例#14
0
 protected static void SetAlignmentBlockOperation(
     List <IndentBlockOperation> list,
     SyntaxToken baseToken,
     SyntaxToken startToken,
     SyntaxToken endToken,
     IndentBlockOption option = IndentBlockOption.RelativePosition
     )
 {
     list.Add(
         FormattingOperations.CreateRelativeIndentBlockOperation(
             baseToken,
             startToken,
             endToken,
             indentationDelta: 0,
             option: option
             )
         );
 }
示例#15
0
            public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustNewLinesOperation> nextOperation)
            {
                // no line operation. no line changes what so ever
                var lineOperation = base.GetAdjustNewLinesOperation(previousToken, currentToken, optionSet, nextOperation);

                if (lineOperation != null)
                {
                    // ignore force if same line option
                    if (lineOperation.Option == AdjustNewLinesOption.ForceLinesIfOnSingleLine)
                    {
                        return(null);
                    }

                    // basically means don't ever put new line if there isn't already one, but do
                    // indentation.
                    return(FormattingOperations.CreateAdjustNewLinesOperation(line: 0, option: AdjustNewLinesOption.PreserveLines));
                }

                return(null);
            }
                /// <summary>
                /// Align all the wrapped parts of the expression with the token after 'return'.
                /// That way we get:
                ///
                /// return a == obj.a &amp;&amp;
                ///        b == obj.b &amp;&amp;
                ///        ...
                /// </summary>
                public override void AddIndentBlockOperations(
                    List <IndentBlockOperation> list, SyntaxNode node, OptionSet optionSet, NextAction <IndentBlockOperation> nextOperation)
                {
                    if (_syntaxFacts.IsReturnStatement(node))
                    {
                        var expr = _syntaxFacts.GetExpressionOfReturnStatement(node);
                        if (expr?.ChildNodesAndTokens().Count > 1)
                        {
                            list.Add(FormattingOperations.CreateRelativeIndentBlockOperation(
                                         expr.GetFirstToken(),
                                         expr.GetFirstToken().GetNextToken(),
                                         node.GetLastToken(),
                                         indentationDelta: 0,
                                         option: IndentBlockOption.RelativePosition));

                            return;
                        }
                    }

                    nextOperation.Invoke(list);
                }
示例#17
0
        protected static void AddUnindentBlockOperation(
            List <IndentBlockOperation> list,
            SyntaxToken startToken,
            SyntaxToken endToken,
            bool includeTriviaAtEnd  = false,
            IndentBlockOption option = IndentBlockOption.RelativePosition
            )
        {
            if (startToken.Kind() == SyntaxKind.None || endToken.Kind() == SyntaxKind.None)
            {
                return;
            }

            if (includeTriviaAtEnd)
            {
                list.Add(
                    FormattingOperations.CreateIndentBlockOperation(
                        startToken,
                        endToken,
                        indentationDelta: -1,
                        option: option
                        )
                    );
            }
            else
            {
                var startPosition = CommonFormattingHelpers.GetStartPositionOfSpan(startToken);
                var endPosition   = endToken.Span.End;

                list.Add(
                    FormattingOperations.CreateIndentBlockOperation(
                        startToken,
                        endToken,
                        TextSpan.FromBounds(startPosition, endPosition),
                        indentationDelta: -1,
                        option: option
                        )
                    );
            }
        }
示例#18
0
            protected override AdjustNewLinesOperation GetAdjustNewLinesOperationBetweenMembersAndUsings(SyntaxToken token1, SyntaxToken token2)
            {
                var previousToken = (SyntaxToken)token1;
                var currentToken  = (SyntaxToken)token2;

                // We are not between members or usings if the last token wasn't the end of a statement or if the current token
                // is the end of a scope.
                if ((previousToken.Kind() != SyntaxKind.SemicolonToken && previousToken.Kind() != SyntaxKind.CloseBraceToken) ||
                    currentToken.Kind() == SyntaxKind.CloseBraceToken)
                {
                    return(null);
                }

                SyntaxNode previousMember = FormattingRangeHelper.GetEnclosingMember(previousToken);
                SyntaxNode nextMember     = FormattingRangeHelper.GetEnclosingMember(currentToken);

                // Is the previous statement an using directive? If so, treat it like a member to add
                // the right number of lines.
                if (previousToken.Kind() == SyntaxKind.SemicolonToken && previousToken.Parent.Kind() == SyntaxKind.UsingDirective)
                {
                    previousMember = previousToken.Parent;
                }

                if (previousMember == null || nextMember == null || previousMember == nextMember)
                {
                    return(null);
                }

                // If we have two members of the same kind, we won't insert a blank line
                if (previousMember.Kind() == nextMember.Kind())
                {
                    return(FormattingOperations.CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.ForceLines));
                }

                // Force a blank line between the two nodes by counting the number of lines of
                // trivia and adding one to it.
                var triviaList = token1.TrailingTrivia.Concat(token2.LeadingTrivia);

                return(FormattingOperations.CreateAdjustNewLinesOperation(GetNumberOfLines(triviaList) + 1, AdjustNewLinesOption.ForceLines));
            }
示例#19
0
            private void ReplaceCaseIndentationRules(List <IndentBlockOperation> list, SyntaxNode node)
            {
                var section = node as SwitchSectionSyntax;

                if (section == null || section.Statements.Count == 0)
                {
                    return;
                }

                var startToken = section.Statements.First().GetFirstToken(includeZeroWidth: true);
                var endToken   = section.Statements.Last().GetLastToken(includeZeroWidth: true);

                for (int i = 0; i < list.Count; i++)
                {
                    var operation = list[i];
                    if (operation.StartToken == startToken && operation.EndToken == endToken)
                    {
                        // replace operation
                        list[i] = FormattingOperations.CreateIndentBlockOperation(startToken, endToken, indentationDelta: 1, option: IndentBlockOption.RelativePosition);
                    }
                }
            }
示例#20
0
            public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustNewLinesOperation> nextOperation)
            {
                // for extract method case, for a hybrid case, don't force rule, but preserve user style
                var operation = base.GetAdjustNewLinesOperation(previousToken, currentToken, optionSet, nextOperation);

                if (operation == null)
                {
                    return(null);
                }

                if (operation.Option == AdjustNewLinesOption.ForceLinesIfOnSingleLine)
                {
                    return(FormattingOperations.CreateAdjustNewLinesOperation(operation.Line, AdjustNewLinesOption.PreserveLines));
                }

                if (operation.Option != AdjustNewLinesOption.ForceLines)
                {
                    return(operation);
                }

                if (previousToken.RawKind == (int)SyntaxKind.OpenBraceToken)
                {
                    return(operation);
                }

                if (previousToken.BetweenFieldAndNonFieldMember(currentToken))
                {
                    // make sure to have at least 2 line breaks between field and other members except field
                    return(FormattingOperations.CreateAdjustNewLinesOperation(2, AdjustNewLinesOption.PreserveLines));
                }

                if (previousToken.HasHybridTriviaBetween(currentToken))
                {
                    return(FormattingOperations.CreateAdjustNewLinesOperation(operation.Line, AdjustNewLinesOption.PreserveLines));
                }

                return(operation);
            }
示例#21
0
        public override void AddIndentBlockOperations(
            List <IndentBlockOperation> list, SyntaxNode node, OptionSet optionSet, NextAction <IndentBlockOperation> nextOperation)
        {
            if (node.HasAnnotation(SpecializedFormattingAnnotation) &&
                node is ConditionalExpressionSyntax conditional)
            {
                var statement = conditional.FirstAncestorOrSelf <StatementSyntax>();
                if (statement != null)
                {
                    var baseToken = statement.GetFirstToken();

                    // we want to indent the ? and : in one level from the containing statement.
                    list.Add(FormattingOperations.CreateRelativeIndentBlockOperation(
                                 baseToken, conditional.QuestionToken, conditional.WhenTrue.GetLastToken(),
                                 indentationDelta: 1, IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine));
                    list.Add(FormattingOperations.CreateRelativeIndentBlockOperation(
                                 baseToken, conditional.ColonToken, conditional.WhenFalse.GetLastToken(),
                                 indentationDelta: 1, IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine));
                    return;
                }
            }

            nextOperation.Invoke(list);
        }
示例#22
0
 protected static AdjustNewLinesOperation CreateAdjustNewLinesOperation(
     int line,
     AdjustNewLinesOption option
     ) => FormattingOperations.CreateAdjustNewLinesOperation(line, option);
示例#23
0
 protected AdjustSpacesOperation CreateAdjustSpacesOperation(int space, AdjustSpacesOption option)
 => FormattingOperations.CreateAdjustSpacesOperation(space, option);
示例#24
0
 protected AdjustSpacesOperation CreateAdjustSpacesOperation(int space, AdjustSpacesOption option)
 {
     return(FormattingOperations.CreateAdjustSpacesOperation(space, option));
 }
示例#25
0
 protected AdjustNewLinesOperation CreateAdjustNewLinesOperation(int line, AdjustNewLinesOption option)
 {
     return(FormattingOperations.CreateAdjustNewLinesOperation(line, option));
 }
        private AdjustNewLinesOperation GetAdjustNewLinesOperationBetweenMembers(SyntaxToken previousToken, SyntaxToken currentToken)
        {
            if (!FormattingRangeHelper.InBetweenTwoMembers(previousToken, currentToken))
            {
                return(null);
            }

            var previousMember = FormattingRangeHelper.GetEnclosingMember(previousToken);
            var nextMember     = FormattingRangeHelper.GetEnclosingMember(currentToken);

            if (previousMember == null || nextMember == null)
            {
                return(null);
            }

            // see whether first non whitespace trivia after before the current member is a comment or not
            var triviaList = currentToken.LeadingTrivia;
            var firstNonWhitespaceTrivia = triviaList.FirstOrDefault(trivia => !IsWhitespace(trivia));

            if (firstNonWhitespaceTrivia.IsRegularOrDocComment())
            {
                // the first one is a comment, add two more lines than existing number of lines
                var numberOfLines = GetNumberOfLines(triviaList);
                var numberOfLinesBeforeComment = GetNumberOfLines(triviaList.Take(triviaList.IndexOf(firstNonWhitespaceTrivia)));
                var addedLines = (numberOfLinesBeforeComment < 1) ? 2 : 1;
                return(CreateAdjustNewLinesOperation(numberOfLines + addedLines, AdjustNewLinesOption.ForceLines));
            }

            // If we have two members of the same kind, we won't insert a blank line if both members
            // have any content (e.g. accessors bodies, non-empty method bodies, etc.).
            if (previousMember.Kind() == nextMember.Kind())
            {
                // Easy cases:
                if (previousMember.Kind() == SyntaxKind.FieldDeclaration ||
                    previousMember.Kind() == SyntaxKind.EventFieldDeclaration)
                {
                    // Ensure that fields and events are each declared on a separate line.
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.ForceLines));
                }

                // Don't insert a blank line between properties, indexers or events with no accessors
                if (previousMember is BasePropertyDeclarationSyntax previousProperty)
                {
                    var nextProperty = (BasePropertyDeclarationSyntax)nextMember;

                    if (previousProperty?.AccessorList?.Accessors.All(a => a.Body == null) == true &&
                        nextProperty?.AccessorList?.Accessors.All(a => a.Body == null) == true)
                    {
                        return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                    }
                }

                // Don't insert a blank line between methods with no bodies
                if (previousMember is BaseMethodDeclarationSyntax previousMethod)
                {
                    var nextMethod = (BaseMethodDeclarationSyntax)nextMember;

                    if (previousMethod.Body == null &&
                        nextMethod.Body == null)
                    {
                        return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                    }
                }
            }

            return(FormattingOperations.CreateAdjustNewLinesOperation(2 /* +1 for member itself and +1 for a blank line*/, AdjustNewLinesOption.ForceLines));
        }
示例#27
0
        public static bool ShouldUseSmartTokenFormatterInsteadOfIndenter(
            IEnumerable <AbstractFormattingRule> formattingRules,
            CompilationUnitSyntax root,
            TextLine line,
            OptionSet optionSet,
            out SyntaxToken token)
        {
            Contract.ThrowIfNull(formattingRules);
            Contract.ThrowIfNull(root);

            token = default;
            if (!optionSet.GetOption(FormattingOptions.AutoFormattingOnReturn, LanguageNames.CSharp))
            {
                return(false);
            }

            if (optionSet.GetOption(FormattingOptions.SmartIndent, LanguageNames.CSharp) != FormattingOptions.IndentStyle.Smart)
            {
                return(false);
            }

            var firstNonWhitespacePosition = line.GetFirstNonWhitespacePosition();

            if (!firstNonWhitespacePosition.HasValue)
            {
                return(false);
            }

            token = root.FindToken(firstNonWhitespacePosition.Value);
            if (IsInvalidToken(token))
            {
                return(false);
            }

            if (token.IsKind(SyntaxKind.None) ||
                token.SpanStart != firstNonWhitespacePosition)
            {
                return(false);
            }

            // first see whether there is a line operation for current token
            var previousToken = token.GetPreviousToken(includeZeroWidth: true);

            // only use smart token formatter when we have two visible tokens.
            if (previousToken.Kind() == SyntaxKind.None || previousToken.IsMissing)
            {
                return(false);
            }

            var lineOperation = FormattingOperations.GetAdjustNewLinesOperation(formattingRules, previousToken, token, optionSet);

            if (lineOperation == null || lineOperation.Option == AdjustNewLinesOption.ForceLinesIfOnSingleLine)
            {
                // no indentation operation, nothing to do for smart token formatter
                return(false);
            }

            // We're pressing enter between two tokens, have the formatter figure out hte appropriate
            // indentation.
            return(true);
        }
        // return 1 space for every token pairs as a default operation
        public AdjustSpacesOperation GetAdjustSpacesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustSpacesOperation> nextOperation)
        {
            int space = currentToken.Kind() == SyntaxKind.EndOfFileToken ? 0 : 1;

            return(FormattingOperations.CreateAdjustSpacesOperation(space, AdjustSpacesOption.DefaultSpacesIfOnSingleLine));
        }