protected IndentationResult GetIndentationOfLine(TextLine lineToMatch, int addedSpaces)
            {
                var firstNonWhitespace = lineToMatch.GetFirstNonWhitespacePosition();
                firstNonWhitespace = firstNonWhitespace ?? lineToMatch.End;

                return GetIndentationOfPosition(firstNonWhitespace.Value, addedSpaces);
            }
        public static bool ShouldUseSmartTokenFormatterInsteadOfIndenter(
            IEnumerable<AbstractFormattingRule> formattingRules,
            CompilationUnitSyntax root,
            TextLine line,
            IOptionService optionService,
            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.AsAnalyzerConfigOptions(optionService, LanguageNames.CSharp));
            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;
        }
Esempio n. 3
0
            protected IndentationResult GetIndentationOfLine(TextLine lineToMatch, int addedSpaces)
            {
                var firstNonWhitespace = lineToMatch.GetFirstNonWhitespacePosition();

                firstNonWhitespace = firstNonWhitespace ?? lineToMatch.End;

                return(GetIndentationOfPosition(firstNonWhitespace.Value, addedSpaces));
            }
        public static bool ShouldUseSmartTokenFormatterInsteadOfIndenter(
            IEnumerable<IFormattingRule> formattingRules,
            CompilationUnitSyntax root,
            TextLine line,
            OptionSet optionSet,
            CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(formattingRules);
            Contract.ThrowIfNull(root);

            if (!optionSet.GetOption(FeatureOnOffOptions.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;
            }

            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)
            {
                // 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;
        }
Esempio n. 5
0
        public static bool ShouldUseSmartTokenFormatterInsteadOfIndenter(
            IEnumerable <IFormattingRule> formattingRules,
            CompilationUnitSyntax root,
            TextLine line,
            OptionSet optionSet,
            CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(formattingRules);
            Contract.ThrowIfNull(root);

            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);
        }
            protected override IndentationResult?GetDesiredIndentationWorker(
                SyntaxToken token, TextLine previousLine, int lastNonWhitespacePosition)
            {
                // okay, now check whether the text we found is trivia or actual token.
                if (token.Span.Contains(lastNonWhitespacePosition))
                {
                    // okay, it is a token case, do special work based on type of last token on previous line
                    return(GetIndentationBasedOnToken(token));
                }
                else
                {
                    // there must be trivia that contains or touch this position
                    Contract.Assert(token.FullSpan.Contains(lastNonWhitespacePosition));

                    // okay, now check whether the trivia is at the beginning of the line
                    var firstNonWhitespacePosition = previousLine.GetFirstNonWhitespacePosition();
                    if (!firstNonWhitespacePosition.HasValue)
                    {
                        return(IndentFromStartOfLine(0));
                    }

                    var trivia = Tree.GetRoot(CancellationToken).FindTrivia(firstNonWhitespacePosition.Value, findInsideTrivia: true);
                    if (trivia.Kind() == SyntaxKind.None || this.LineToBeIndented.LineNumber > previousLine.LineNumber + 1)
                    {
                        // If the token belongs to the next statement and is also the first token of the statement, then it means the user wants
                        // to start type a new statement. So get indentation from the start of the line but not based on the token.
                        // Case:
                        // static void Main(string[] args)
                        // {
                        //     // A
                        //     // B
                        //
                        //     $$
                        //     return;
                        // }

                        var containingStatement = token.GetAncestor <StatementSyntax>();
                        if (containingStatement != null && containingStatement.GetFirstToken() == token)
                        {
                            var position = GetCurrentPositionNotBelongToEndOfFileToken(LineToBeIndented.Start);
                            return(IndentFromStartOfLine(Finder.GetIndentationOfCurrentPosition(Tree, token, position, CancellationToken)));
                        }

                        // If the token previous of the base token happens to be a Comma from a separation list then we need to handle it different
                        // Case:
                        // var s = new List<string>
                        //                 {
                        //                     """",
                        //                             """",/*sdfsdfsdfsdf*/
                        //                                  // dfsdfsdfsdfsdf
                        //
                        //                             $$
                        //                 };
                        var previousToken = token.GetPreviousToken();
                        if (previousToken.IsKind(SyntaxKind.CommaToken))
                        {
                            return(GetIndentationFromCommaSeparatedList(previousToken));
                        }
                        else if (!previousToken.IsKind(SyntaxKind.None))
                        {
                            // okay, beginning of the line is not trivia, use the last token on the line as base token
                            return(GetIndentationBasedOnToken(token));
                        }
                    }

                    // this case we will keep the indentation of this trivia line
                    // this trivia can't be preprocessor by the way.
                    return(GetIndentationOfLine(previousLine));
                }
            }