Beispiel #1
0
        private void CloseFormattingScope()
        {
            Debug.Assert(_tokens.CurrentToken.TokenType == RTokenType.CloseCurlyBrace);

            _tb.SoftLineBreak();
            _tb.CloseIndentLevel();
            _tb.SoftIndent();

            if (_formattingScopes.Count > 1)
            {
                if (_formattingScopes.Peek().CloseBracePosition == _tokens.Position)
                {
                    FormattingScope scope = _formattingScopes.Pop();
                    scope.Close();
                }
            }

            AppendToken(leadingSpace: false, trailingSpace: false);

            if (SuppressLineBreakCount == 0 && !_tokens.IsEndOfStream())
            {
                // We insert line break after } unless next token is comma
                // (scope is in the argument list) or a closing brace
                // (last parameter in a function or indexer) or it is followed by 'else'
                // so 'else' does not get separated from 'if'.
                if (!KeepCurlyAndElseTogether())
                {
                    if (!IsClosingToken(_tokens.CurrentToken) && !IsInArguments())
                    {
                        _tb.SoftLineBreak();
                    }
                }
            }
        }
Beispiel #2
0
        private void CloseFormattingScope()
        {
            Debug.Assert(_tokens.CurrentToken.TokenType == RTokenType.CloseCurlyBrace);

            if (!SingleLineScope)
            {
                _tb.SoftLineBreak();
                _tb.CloseIndentLevel();
                _tb.SoftIndent();
            }

            var leadingSpace = SingleLineScope && _tokens.PreviousToken.TokenType != RTokenType.CloseCurlyBrace;

            if (_formattingScopes.Count > 1)
            {
                if (_formattingScopes.Peek().CloseBracePosition == _tokens.Position)
                {
                    FormattingScope scope = _formattingScopes.Pop();
                    scope.Dispose();
                }
            }

            AppendToken(leadingSpace: leadingSpace, trailingSpace: false);

            bool singleLineScopeJustClosed = false;

            if (_tokens.CurrentToken.Start >= _singleLineScopeEnd)
            {
                _singleLineScopeEnd       = -1;
                singleLineScopeJustClosed = true;
            }

            if (SuppressLineBreakCount == 0 && !_tokens.IsEndOfStream())
            {
                // We insert line break after } unless
                //  a) Next token is comma (scope is in the argument list) or
                //  b) Next token is a closing brace (last parameter in a function or indexer) or
                //  c) Next token is by 'else' (so 'else' does not get separated from 'if') or
                //  d) We are in a single-line scope sequence like if() {{ }}
                if (!KeepCurlyAndElseTogether())
                {
                    if (singleLineScopeJustClosed &&
                        !IsClosingToken(_tokens.CurrentToken) &&
                        !IsInArguments())
                    {
                        SoftLineBreak();
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Appends statements inside scope that follows control block
        /// such as if() { } or a single statement that follows
        /// scope-less as in 'if() stmt' conditional.
        /// </summary>
        private void AppendStatementsInScope(string keyword)
        {
            // May or may not have curly braces
            if (_tokens.CurrentToken.TokenType == RTokenType.OpenCurlyBrace)
            {
                // Regular { } scope so just handle it normally
                AppendScopeContent(stopAtLineBreak: false);

                if (keyword == "if" &&
                    _tokens.CurrentToken.IsKeywordText(_textProvider, "else") &&
                    !_tokens.IsLineBreakAfter(_textProvider, _tokens.Position - 1))
                {
                    // if (FALSE) {
                    //   x <- 1
                    // } else
                    // i.e. keep 'else' at the same line except when user did add line break as in
                    // if (...) { 1 }
                    // else { 2 }

                    if (!_options.BracesOnNewLine && _tokens.PreviousToken.TokenType == RTokenType.CloseCurlyBrace)
                    {
                        while (_tb.LastCharacter.IsLineBreak())
                        {
                            // Undo line break
                            _tb.Remove(_tb.Length - 1, 1);
                        }

                        _tb.AppendPreformattedText(" ");
                    }
                    AppendKeyword();
                }
                return;
            }

            // No curly braces: single statement block
            bool foundSameLineElse = false;

            if (keyword == "if")
            {
                // Per R language spec:
                // <quote>
                //   The 'else' clause is optional. The statement if(any(x <= 0)) x <- x[x <= 0]
                //   is valid. When the if statement is not in a block the else, if present, must
                //   appear on the same line as the end of statement after if. Otherwise the new line
                //   at the end of statement completes the if and yields a syntactically
                //   complete statement that is evaluated.
                // </quote>
                //
                // So we have to be very careful here. If 'if' is not scoped then we need
                // to check if 'else' is on the same line and then keep the line as is
                // i.e. format but not break into multiple lines. On the other hand,
                // if there is no 'else' then we can insert break after the 'if(...)'

                foundSameLineElse = HasSameLineElse();
                if (foundSameLineElse)
                {
                    _formattingScopes.SuppressLineBreakCount++;
                    AppendScopeContent(stopAtLineBreak: true);
                    _formattingScopes.SuppressLineBreakCount--;

                    return;
                }
            }

            if (_formattingScopes.SuppressLineBreakCount > 0)
            {
                AppendScopeContent(stopAtLineBreak: true);
                return;
            }

            bool addLineBreak = true;

            // Special case: preserve like break between 'else' and 'if'
            // if user put it there  'else if' remains on one line
            // if user didn't then add line break between them.

            if (_braceHandler.IsInArguments())
            {
                addLineBreak = false;
            }
            else if (!_tokens.IsLineBreakAfter(_textProvider, _tokens.Position - 1))
            {
                if (keyword.EqualsOrdinal("else") && _tokens.CurrentToken.IsKeywordText(_textProvider, "if"))
                {
                    addLineBreak = false;
                }
                else if ((keyword.EqualsOrdinal("if") || keyword.EqualsOrdinal("else") || keyword.EqualsOrdinal("repeat")) &&
                         _tokens.CurrentToken.TokenType != RTokenType.OpenCurlyBrace)
                {
                    // Preserve single-line conditionals like 'if (true) x <- 1'
                    addLineBreak = false;
                }
            }

            if (addLineBreak)
            {
                _tb.SoftLineBreak();
                _tb.NewIndentLevel();

                // This scope-less 'if' so we have to stop at the end
                // of the line as in
                //  if (TRUE)
                //      x <- 1
                //  else {
                //  }

                AppendScopeContent(stopAtLineBreak: true, stopAtElse: true);

                //  if (TRUE)
                //      repeat {
                //      }
                //  else
                //
                _tb.CloseIndentLevel();
            }
            else
            {
                _tb.AppendSpace();
            }
        }