forked from qt-creator/qt-creator
CppEditor: Fix insert position of AddIncludeForUndefinedIdentifier
If there are no includes, add new include at the top of file but skip possible comments at the beginning. Task-number: QTCREATORBUG-8799 Change-Id: Ie2be644f6ad0a948cf3d8700efa00087753d9863 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
This commit is contained in:
committed by
Nikolai Kosjar
parent
a6ee961bc3
commit
2e8d471c3b
@@ -125,6 +125,11 @@ private slots:
|
|||||||
void test_quickfix_InsertDefFromDecl_headerSource_namespace1();
|
void test_quickfix_InsertDefFromDecl_headerSource_namespace1();
|
||||||
void test_quickfix_InsertDefFromDecl_headerSource_namespace2();
|
void test_quickfix_InsertDefFromDecl_headerSource_namespace2();
|
||||||
void test_quickfix_InsertDefFromDecl_freeFunction();
|
void test_quickfix_InsertDefFromDecl_freeFunction();
|
||||||
|
|
||||||
|
void test_quickfix_AddIncludeForUndefinedIdentifier_normal();
|
||||||
|
void test_quickfix_AddIncludeForUndefinedIdentifier_noinclude();
|
||||||
|
void test_quickfix_AddIncludeForUndefinedIdentifier_noincludeComment01();
|
||||||
|
void test_quickfix_AddIncludeForUndefinedIdentifier_noincludeComment02();
|
||||||
#endif // WITH_TESTS
|
#endif // WITH_TESTS
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -881,3 +881,165 @@ void CppPlugin::test_quickfix_InsertDefFromDecl_freeFunction()
|
|||||||
TestCase data(original, expected);
|
TestCase data(original, expected);
|
||||||
data.run(&factory);
|
data.run(&factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check normal add include if there is already a include
|
||||||
|
void CppPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_normal()
|
||||||
|
{
|
||||||
|
QList<TestDocumentPtr> testFiles;
|
||||||
|
|
||||||
|
QByteArray original;
|
||||||
|
QByteArray expected;
|
||||||
|
|
||||||
|
// Header File
|
||||||
|
original = "class Foo {};\n";
|
||||||
|
expected = original + "\n";
|
||||||
|
testFiles << TestDocument::create(original, expected, QLatin1String("file.h"));
|
||||||
|
|
||||||
|
// Source File
|
||||||
|
original =
|
||||||
|
"#include \"someheader.h\"\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" Fo@o foo;\n"
|
||||||
|
"}\n"
|
||||||
|
;
|
||||||
|
expected =
|
||||||
|
"#include \"someheader.h\"\n"
|
||||||
|
"#include \"file.h\"\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" Foo foo;\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
;
|
||||||
|
testFiles << TestDocument::create(original, expected, QLatin1String("file.cpp"));
|
||||||
|
|
||||||
|
AddIncludeForUndefinedIdentifier factory;
|
||||||
|
TestCase data(testFiles);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check add include if no include is present
|
||||||
|
void CppPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_noinclude()
|
||||||
|
{
|
||||||
|
QList<TestDocumentPtr> testFiles;
|
||||||
|
|
||||||
|
QByteArray original;
|
||||||
|
QByteArray expected;
|
||||||
|
|
||||||
|
// Header File
|
||||||
|
original = "class Foo {};\n";
|
||||||
|
expected = original + "\n";
|
||||||
|
testFiles << TestDocument::create(original, expected, QLatin1String("file.h"));
|
||||||
|
|
||||||
|
// Source File
|
||||||
|
original =
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" Fo@o foo;\n"
|
||||||
|
"}\n"
|
||||||
|
;
|
||||||
|
expected =
|
||||||
|
"#include \"file.h\"\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" Foo foo;\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
;
|
||||||
|
testFiles << TestDocument::create(original, expected, QLatin1String("file.cpp"));
|
||||||
|
|
||||||
|
AddIncludeForUndefinedIdentifier factory;
|
||||||
|
TestCase data(testFiles);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check add include if no include is present with comment on top
|
||||||
|
void CppPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_noincludeComment01()
|
||||||
|
{
|
||||||
|
QList<TestDocumentPtr> testFiles;
|
||||||
|
|
||||||
|
QByteArray original;
|
||||||
|
QByteArray expected;
|
||||||
|
|
||||||
|
// Header File
|
||||||
|
original = "class Foo {};\n";
|
||||||
|
expected = original + "\n";
|
||||||
|
testFiles << TestDocument::create(original, expected, QLatin1String("file.h"));
|
||||||
|
|
||||||
|
// Source File
|
||||||
|
original =
|
||||||
|
"\n"
|
||||||
|
"// comment\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" Fo@o foo;\n"
|
||||||
|
"}\n"
|
||||||
|
;
|
||||||
|
expected =
|
||||||
|
"\n"
|
||||||
|
"// comment\n"
|
||||||
|
"\n"
|
||||||
|
"#include \"file.h\"\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" Foo foo;\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
;
|
||||||
|
testFiles << TestDocument::create(original, expected, QLatin1String("file.cpp"));
|
||||||
|
|
||||||
|
AddIncludeForUndefinedIdentifier factory;
|
||||||
|
TestCase data(testFiles);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
/// Check add include if no include is present with comment on top
|
||||||
|
void CppPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_noincludeComment02()
|
||||||
|
{
|
||||||
|
QList<TestDocumentPtr> testFiles;
|
||||||
|
|
||||||
|
QByteArray original;
|
||||||
|
QByteArray expected;
|
||||||
|
|
||||||
|
// Header File
|
||||||
|
original = "class Foo {};\n";
|
||||||
|
expected = original + "\n";
|
||||||
|
testFiles << TestDocument::create(original, expected, QLatin1String("file.h"));
|
||||||
|
|
||||||
|
// Source File
|
||||||
|
original =
|
||||||
|
"\n"
|
||||||
|
"/*\n"
|
||||||
|
" comment\n"
|
||||||
|
" */\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" Fo@o foo;\n"
|
||||||
|
"}\n"
|
||||||
|
;
|
||||||
|
expected =
|
||||||
|
"\n"
|
||||||
|
"/*\n"
|
||||||
|
" comment\n"
|
||||||
|
" */\n"
|
||||||
|
"\n"
|
||||||
|
"#include \"file.h\"\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" Foo foo;\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
;
|
||||||
|
testFiles << TestDocument::create(original, expected, QLatin1String("file.cpp"));
|
||||||
|
|
||||||
|
AddIncludeForUndefinedIdentifier factory;
|
||||||
|
TestCase data(testFiles);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
@@ -1606,21 +1606,64 @@ public:
|
|||||||
CppRefactoringChanges refactoring(snapshot());
|
CppRefactoringChanges refactoring(snapshot());
|
||||||
CppRefactoringFilePtr file = refactoring.file(fileName());
|
CppRefactoringFilePtr file = refactoring.file(fileName());
|
||||||
|
|
||||||
// find location of last include in file
|
|
||||||
QList<Document::Include> includes = file->cppDocument()->includes();
|
QList<Document::Include> includes = file->cppDocument()->includes();
|
||||||
|
if (includes.isEmpty()) {
|
||||||
|
// No includes, find possible first/multi line comment
|
||||||
|
int insertPos = 0;
|
||||||
|
QTextBlock block = file->document()->firstBlock();
|
||||||
|
while (block.isValid()) {
|
||||||
|
const QString trimmedText = block.text().trimmed();
|
||||||
|
|
||||||
|
// Only skip the first comment!
|
||||||
|
if (trimmedText.startsWith(QLatin1String("/*"))) {
|
||||||
|
do {
|
||||||
|
const int pos = block.text().indexOf(QLatin1String("*/"));
|
||||||
|
if (pos > -1) {
|
||||||
|
insertPos = block.position() + pos + 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
block = block.next();
|
||||||
|
} while (block.isValid());
|
||||||
|
break;
|
||||||
|
} else if (trimmedText.startsWith(QLatin1String("//"))) {
|
||||||
|
block = block.next();
|
||||||
|
while (block.isValid()) {
|
||||||
|
if (!block.text().trimmed().startsWith(QLatin1String("//"))) {
|
||||||
|
insertPos = block.position() - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
block = block.next();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!trimmedText.isEmpty())
|
||||||
|
break;
|
||||||
|
block = block.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeSet changes;
|
||||||
|
if (insertPos != 0)
|
||||||
|
changes.insert(insertPos, QLatin1String("\n\n#include ") + m_include);
|
||||||
|
else
|
||||||
|
changes.insert(insertPos, QString::fromLatin1("#include %1\n\n").arg(m_include));
|
||||||
|
file->setChangeSet(changes);
|
||||||
|
file->apply();
|
||||||
|
} else {
|
||||||
|
// find location of last include in file
|
||||||
unsigned lastIncludeLine = 0;
|
unsigned lastIncludeLine = 0;
|
||||||
foreach (const Document::Include &include, includes) {
|
foreach (const Document::Include &include, includes) {
|
||||||
if (include.line() > lastIncludeLine)
|
if (include.line() > lastIncludeLine)
|
||||||
lastIncludeLine = include.line();
|
lastIncludeLine = include.line();
|
||||||
}
|
}
|
||||||
|
|
||||||
// add include
|
const int insertPos = qMax(0, file->position(lastIncludeLine + 1, 1) - 1);
|
||||||
const int insertPos = file->position(lastIncludeLine + 1, 1) - 1;
|
|
||||||
ChangeSet changes;
|
ChangeSet changes;
|
||||||
changes.insert(insertPos, QLatin1String("\n#include ") + m_include);
|
changes.insert(insertPos, QLatin1String("\n#include ") + m_include);
|
||||||
file->setChangeSet(changes);
|
file->setChangeSet(changes);
|
||||||
file->apply();
|
file->apply();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_include;
|
QString m_include;
|
||||||
|
Reference in New Issue
Block a user