aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSemih Yavuz <[email protected]>2024-11-11 15:38:38 +0100
committerSemih Yavuz <[email protected]>2024-12-05 23:24:29 +0100
commit9f1fca90e7b760f54e5fb5689e662defb669c64b (patch)
tree7b4929c7496806c0933f85b803f696bc19ee8ca0
parent7736fdc9940878ce6bd9fb2f8b053f0b1258156e (diff)
qmlformat: separate reindentAndSplit's concerns
This also changes the behavior of linebreak by combining the split sequence in a single set. Prior to this commit, linebreak position was attempted to be detected for a set of tokens. Then, if there is a left paranthesis in the same line, that would take the split location. Now change this logic so that break the line after the last token that lays on column smaller than the allowed maximum width. Task-number: QTBUG-113590 Change-Id: Ib0e7291a139265ab9bc09be0c574704da25fd722 Reviewed-by: Sami Shalayel <[email protected]>
-rw-r--r--src/qmldom/qqmldomindentinglinewriter.cpp171
-rw-r--r--src/qmldom/qqmldomindentinglinewriter_p.h3
-rw-r--r--src/qmldom/qqmldomlinewriter_p.h2
3 files changed, 92 insertions, 84 deletions
diff --git a/src/qmldom/qqmldomindentinglinewriter.cpp b/src/qmldom/qqmldomindentinglinewriter.cpp
index 99f81c1717..65dcdfade8 100644
--- a/src/qmldom/qqmldomindentinglinewriter.cpp
+++ b/src/qmldom/qqmldomindentinglinewriter.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qqmldomindentinglinewriter_p.h"
+#include "qqmldomlinewriter_p.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QRegularExpression>
@@ -10,6 +11,9 @@ QT_BEGIN_NAMESPACE
namespace QQmlJS {
namespace Dom {
+static QSet<int> splitSequence = { QQmlJSGrammar::T_COMMA, QQmlJSGrammar::T_AND_AND,
+ QQmlJSGrammar::T_OR_OR, QQmlJSGrammar::T_LPAREN };
+
FormatPartialStatus &IndentingLineWriter::fStatus()
{
if (!m_fStatusValid) {
@@ -26,99 +30,100 @@ void IndentingLineWriter::willCommit()
void IndentingLineWriter::reindentAndSplit(const QString &eol, bool eof)
{
- bool shouldReindent = m_reindent;
-indentAgain:
// maybe re-indent
- if (shouldReindent && m_columnNr == 0) {
+ if (m_reindent && m_columnNr == 0)
setLineIndent(fStatus().indentLine());
- }
- if (!eol.isEmpty() || eof) {
- LineWriterOptions::TrailingSpace trailingSpace;
- if (!m_currentLine.isEmpty() && m_currentLine.trimmed().isEmpty()) {
- // space only line
- const Scanner::State &oldState = m_preCachedStatus.lexerState;
- if (oldState.isMultilineComment())
- trailingSpace = m_options.commentTrailingSpace;
- else if (oldState.isMultiline())
- trailingSpace = m_options.stringTrailingSpace;
- else
- trailingSpace = m_options.codeTrailingSpace;
- // in the LSP we will probably want to treat is specially if it is the line with the
- // cursor, of if indentation of it is requested
+
+ if (!eol.isEmpty() || eof)
+ handleTrailingSpace();
+
+ // maybe split long line
+ if (m_options.maxLineLength > 0 && m_currentLine.size() > m_options.maxLineLength)
+ splitOnMaxLength(eol, eof);
+
+ // maybe write out
+ if (!eol.isEmpty() || eof)
+ commitLine(eol);
+}
+
+void IndentingLineWriter::handleTrailingSpace()
+{
+ LineWriterOptions::TrailingSpace trailingSpace;
+ if (!m_currentLine.isEmpty() && m_currentLine.trimmed().isEmpty()) {
+ // space only line
+ const Scanner::State &oldState = m_preCachedStatus.lexerState;
+ if (oldState.isMultilineComment())
+ trailingSpace = m_options.commentTrailingSpace;
+ else if (oldState.isMultiline())
+ trailingSpace = m_options.stringTrailingSpace;
+ else
+ trailingSpace = m_options.codeTrailingSpace;
+ // in the LSP we will probably want to treat is specially if it is the line with the
+ // cursor, of if indentation of it is requested
+ } else {
+ const Scanner::State &currentState = fStatus().currentStatus.lexerState;
+ if (currentState.isMultilineComment()) {
+ trailingSpace = m_options.commentTrailingSpace;
+ } else if (currentState.isMultiline()) {
+ trailingSpace = m_options.stringTrailingSpace;
} else {
- const Scanner::State &currentState = fStatus().currentStatus.lexerState;
- if (currentState.isMultilineComment()) {
+ const int kind =
+ (fStatus().lineTokens.isEmpty() ? Lexer::T_EOL
+ : fStatus().lineTokens.last().lexKind);
+ if (Token::lexKindIsComment(kind)) {
+ // a // comment...
trailingSpace = m_options.commentTrailingSpace;
- } else if (currentState.isMultiline()) {
- trailingSpace = m_options.stringTrailingSpace;
+ Q_ASSERT(fStatus().currentStatus.state().type
+ != FormatTextStatus::StateType::MultilineCommentCont
+ && fStatus().currentStatus.state().type
+ != FormatTextStatus::StateType::
+ MultilineCommentStart); // these should have been
+ // handled above
} else {
- const int kind =
- (fStatus().lineTokens.isEmpty() ? Lexer::T_EOL
- : fStatus().lineTokens.last().lexKind);
- if (Token::lexKindIsComment(kind)) {
- // a // comment...
- trailingSpace = m_options.commentTrailingSpace;
- Q_ASSERT(fStatus().currentStatus.state().type
- != FormatTextStatus::StateType::MultilineCommentCont
- && fStatus().currentStatus.state().type
- != FormatTextStatus::StateType::
- MultilineCommentStart); // these should have been
- // handled above
- } else {
- trailingSpace = m_options.codeTrailingSpace;
- }
+ trailingSpace = m_options.codeTrailingSpace;
}
}
- handleTrailingSpace(trailingSpace);
}
- // maybe split long line
- if (m_options.maxLineLength > 0 && m_currentLine.size() > m_options.maxLineLength) {
- int possibleSplit = -1;
- if (fStatus().lineTokens.size() > 1) {
- // {}[] should already be handled (handle also here?)
- int minLen = 0;
- while (minLen < m_currentLine.size() && m_currentLine.at(minLen).isSpace())
- ++minLen;
- minLen = column(minLen) + m_options.minContentLength;
- int maxLen = qMax(minLen + m_options.strongMaxLineExtra, m_options.maxLineLength);
- std::array<QSet<int>, 2> splitSequence(
- { QSet<int>({ // try split after ',','||','&&'
- QQmlJSGrammar::T_COMMA, QQmlJSGrammar::T_AND_AND,
- QQmlJSGrammar::T_OR_OR }),
- QSet<int>({ // try split after '('
- QQmlJSGrammar::T_LPAREN }) });
- // try split after other binary operators?
- int minSplit = m_currentLine.size();
- for (const QSet<int> &splitOnToken : splitSequence) {
- for (int iToken = 0; iToken < fStatus().tokenCount(); ++iToken) {
- const Token t = fStatus().tokenAt(iToken);
- int tCol = column(t.end());
- if (splitOnToken.contains(t.lexKind) && tCol > minLen) {
- if (tCol <= maxLen && possibleSplit < t.end())
- possibleSplit = t.end();
- if (t.end() < minSplit)
- minSplit = t.end();
- }
- }
- if (possibleSplit > 0)
- break;
- }
- if (possibleSplit == -1 && minSplit + 4 < m_currentLine.size())
- possibleSplit = minSplit;
- if (possibleSplit > 0) {
- lineChanged();
- quint32 oChange = eolToWrite().size();
- changeAtOffset(m_utf16Offset + possibleSplit, oChange, 0,
- 0); // line & col change updated in commitLine
- commitLine(eolToWrite(), TextAddType::NewlineSplit, possibleSplit);
- shouldReindent = true;
- goto indentAgain;
- }
+ LineWriter::handleTrailingSpace(trailingSpace);
+}
+
+void IndentingLineWriter::splitOnMaxLength(const QString &eol, bool eof)
+{
+ int possibleSplit = -1;
+ if (fStatus().lineTokens.size() <= 1)
+ return;
+ // {}[] should already be handled (handle also here?)
+ int minLen = 0;
+ while (minLen < m_currentLine.size() && m_currentLine.at(minLen).isSpace())
+ ++minLen;
+ minLen = column(minLen) + m_options.minContentLength;
+ int maxLen = qMax(minLen + m_options.strongMaxLineExtra, m_options.maxLineLength);
+
+ // try split after other binary operators?
+ int minSplit = m_currentLine.size();
+
+ for (int iToken = 0; iToken < fStatus().tokenCount(); ++iToken) {
+ const Token t = fStatus().tokenAt(iToken);
+ int tCol = column(t.end());
+ if (splitSequence.contains(t.lexKind) && tCol > minLen) {
+ if (tCol <= maxLen && possibleSplit < t.end())
+ possibleSplit = t.end();
+ if (t.end() < minSplit)
+ minSplit = t.end();
}
}
- // maybe write out
- if (!eol.isEmpty() || eof)
- commitLine(eol);
+
+ if (possibleSplit == -1 && minSplit + 4 < m_currentLine.size())
+ possibleSplit = minSplit;
+ if (possibleSplit > 0) {
+ lineChanged();
+ quint32 oChange = eolToWrite().size();
+ changeAtOffset(m_utf16Offset + possibleSplit, oChange, 0,
+ 0); // line & col change updated in commitLine
+ commitLine(eolToWrite(), TextAddType::NewlineSplit, possibleSplit);
+ setReindent(true);
+ reindentAndSplit(eol, eof);
+ }
}
} // namespace Dom
diff --git a/src/qmldom/qqmldomindentinglinewriter_p.h b/src/qmldom/qqmldomindentinglinewriter_p.h
index 63ec3fc432..21197e277a 100644
--- a/src/qmldom/qqmldomindentinglinewriter_p.h
+++ b/src/qmldom/qqmldomindentinglinewriter_p.h
@@ -41,6 +41,7 @@ public:
{
}
void reindentAndSplit(const QString &eol, bool eof = false) override;
+ void handleTrailingSpace();
FormatPartialStatus &fStatus();
void lineChanged() override { m_fStatusValid = false; }
@@ -48,6 +49,8 @@ public:
bool reindent() const { return m_reindent; }
void setReindent(bool v) { m_reindent = v; }
+ void splitOnMaxLength(const QString &eol, bool eof);
+
private:
Q_DISABLE_COPY_MOVE(IndentingLineWriter)
protected:
diff --git a/src/qmldom/qqmldomlinewriter_p.h b/src/qmldom/qqmldomlinewriter_p.h
index 0046e3e31a..05fa3a4399 100644
--- a/src/qmldom/qqmldomlinewriter_p.h
+++ b/src/qmldom/qqmldomlinewriter_p.h
@@ -82,7 +82,7 @@ public:
enum class AttributesSequence { Normalize, Preserve };
Q_ENUM(AttributesSequence)
- int maxLineLength = -1;
+ int maxLineLength = -1; // -1 means no limit
int strongMaxLineExtra = 20;
int minContentLength = 10;
#if defined (Q_OS_WIN)