Commit 3f24bd1e authored by Erik Verbruggen's avatar Erik Verbruggen Committed by Orgad Shaneh

C++: fix multi-line continuation handling.

When having doxygen enabled, but leading astriskses disabled, a comment
continuation line did not insert an extra space for where the astrisks
would have been, thus mis-aligning the second line.

Task-number: QTCREATORBUG-12539
Change-Id: I47baa203fd5d9279fa89a06f526f3abed06ce443
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@theqtcompany.com>
parent 601ce9ba
......@@ -182,44 +182,53 @@ bool handleDoxygenContinuation(QTextCursor &cursor,
if (enableDoxygen && !cursor.atEnd() && isCursorAfterCppComment(cursor, doc))
return handleDoxygenCppStyleContinuation(cursor, e);
if (!leadingAsterisks)
return false;
// We continue the comment if the cursor is after a comment's line asterisk and if
// there's no asterisk immediately after the cursor (that would already be considered
// a leading asterisk).
int offset = 0;
const int blockPos = cursor.positionInBlock();
const QString &text = cursor.block().text();
const QString &currentLine = cursor.block().text();
for (; offset < blockPos; ++offset) {
if (!text.at(offset).isSpace())
if (!currentLine.at(offset).isSpace())
break;
}
// In case we don't need to insert leading asteriskses, this code will be run once (right after
// hitting enter on the line containing '/*'). It will insert a continuation without an
// asterisk, but with an extra space. After that, the normal indenting will take over and do the
// Right Thing <TM>.
if (offset < blockPos
&& (text.at(offset) == QLatin1Char('*')
&& (currentLine.at(offset) == QLatin1Char('*')
|| (offset < blockPos - 1
&& text.at(offset) == QLatin1Char('/')
&& text.at(offset + 1) == QLatin1Char('*')))) {
&& currentLine.at(offset) == QLatin1Char('/')
&& currentLine.at(offset + 1) == QLatin1Char('*')))) {
// Ok, so the line started with an '*' or '/*'
int followinPos = blockPos;
for (; followinPos < text.length(); ++followinPos) {
if (!text.at(followinPos).isSpace())
// Now search for the first non-whitespace character to align to:
for (; followinPos < currentLine.length(); ++followinPos) {
if (!currentLine.at(followinPos).isSpace())
break;
}
if (followinPos == text.length()
|| text.at(followinPos) != QLatin1Char('*')) {
if (followinPos == currentLine.length() // a)
|| currentLine.at(followinPos) != QLatin1Char('*')) { // b)
// So either a) the line ended after a '*' and we need to insert a continuation, or
// b) we found the start of some text and we want to align the continuation to that.
QString newLine(QLatin1Char('\n'));
QTextCursor c(cursor);
c.movePosition(QTextCursor::StartOfBlock);
c.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, offset);
newLine.append(c.selectedText());
if (text.at(offset) == QLatin1Char('/')) {
newLine.append(QLatin1String(" * "));
if (currentLine.at(offset) == QLatin1Char('/')) {
if (leadingAsterisks)
newLine.append(QLatin1String(" * "));
else
newLine.append(QLatin1String(" "));
} else {
int start = offset;
while (offset < blockPos && text.at(offset) == QLatin1Char('*'))
while (offset < blockPos && currentLine.at(offset) == QLatin1Char('*'))
++offset;
newLine.append(QString(offset - start, QLatin1Char('*')));
const QChar ch = leadingAsterisks ? QLatin1Char('*') : QLatin1Char(' ');
newLine.append(QString(offset - start, ch));
newLine.append(QLatin1Char(' '));
}
cursor.insertText(newLine);
......
......@@ -32,7 +32,9 @@
#include "cppeditortestcase.h"
#include <coreplugin/editormanager/editormanager.h>
#include <cpptools/commentssettings.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cpptoolssettings.h>
#include <cplusplus/CppDocument.h>
#include <utils/fileutils.h>
......@@ -63,9 +65,11 @@ namespace Tests {
class DoxygenTestCase : public Internal::Tests::TestCase
{
QScopedPointer<CppTools::CommentsSettings> oldSettings;
public:
/// The '|' in the input denotes the cursor position.
DoxygenTestCase(const QByteArray &original, const QByteArray &expected)
DoxygenTestCase(const QByteArray &original, const QByteArray &expected,
CppTools::CommentsSettings *injectedSettings = 0)
{
QVERIFY(succeededSoFar());
......@@ -82,6 +86,12 @@ public:
&testDocument.m_editorWidget));
closeEditorAtEndOfTestCase(testDocument.m_editor);
if (injectedSettings) {
auto *cts = CppTools::CppToolsSettings::instance();
oldSettings.reset(new CppTools::CommentsSettings(cts->commentsSettings()));
injectSettings(injectedSettings);
}
// We want to test documents that start with a comment. By default, the
// editor will fold the very first comment it encounters, assuming
// it is a license header. Currently unfoldAll() does not work as
......@@ -104,6 +114,19 @@ public:
const QString contentsAfterUndo = testDocument.m_editorWidget->document()->toPlainText();
QCOMPARE(contentsAfterUndo, testDocument.m_source);
}
~DoxygenTestCase()
{
if (oldSettings)
injectSettings(oldSettings.data());
}
static void injectSettings(CppTools::CommentsSettings *injection)
{
auto *cts = CppTools::CppToolsSettings::instance();
QVERIFY(QMetaObject::invokeMethod(cts, "commentsSettingsChanged", Qt::DirectConnection,
Q_ARG(CppTools::CommentsSettings, *injection)));
}
};
} // namespace Tests
......@@ -254,5 +277,30 @@ void CppEditorPlugin::test_doxygen_comments()
Tests::DoxygenTestCase(given, expected);
}
void CppEditorPlugin::test_doxygen_comments_no_leading_asterisks_data()
{
QTest::addColumn<QByteArray>("given");
QTest::addColumn<QByteArray>("expected");
QTest::newRow("cpp_style_no_astrix") << _(
"/* asdf asdf|\n"
) << _(
"/* asdf asdf\n"
" \n"
);
}
void CppEditorPlugin::test_doxygen_comments_no_leading_asterisks()
{
QFETCH(QByteArray, given);
QFETCH(QByteArray, expected);
CppTools::CommentsSettings injection;
injection.m_enableDoxygen = true;
injection.m_leadingAsterisks = false;
Tests::DoxygenTestCase(given, expected, &injection);
}
} // namespace Internal
} // namespace CppEditor
......@@ -118,6 +118,8 @@ private slots:
void test_doxygen_comments_data();
void test_doxygen_comments();
void test_doxygen_comments_no_leading_asterisks_data();
void test_doxygen_comments_no_leading_asterisks();
void test_quickfix_data();
void test_quickfix();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment