Commit 063cc6bf authored by Lorenz Haas's avatar Lorenz Haas Committed by Nikolai Kosjar
Browse files

CppEditor: Handle namespaces when generating method definitions



Consequent use of insertLocationForMethodDefinition respects the
surrounding namespace when moving/inserting definitions.

Task-number: QTCREATORBUG-2676
Task-number: QTCREATORBUG-9332
Change-Id: I6d83cf84d844dd4773900d03563581c88befa7b7
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent 4d5ffd4e
......@@ -136,6 +136,8 @@ private slots:
void test_doxygen_comments_cpp_styleA_corner_case();
void test_quickfix_GenerateGetterSetter_basicGetterWithPrefix();
void test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAndNamespace();
void test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAndNamespaceToCpp();
void test_quickfix_GenerateGetterSetter_basicGetterWithoutPrefix();
void test_quickfix_GenerateGetterSetter_customType();
void test_quickfix_GenerateGetterSetter_constMember();
......@@ -188,6 +190,7 @@ private slots:
void test_quickfix_AddIncludeForUndefinedIdentifier_checkQSomethingInQtIncludePaths();
void test_quickfix_MoveFuncDefOutside_MemberFuncToCpp();
void test_quickfix_MoveFuncDefOutside_MemberFuncToCppInsideNS();
void test_quickfix_MoveFuncDefOutside_MemberFuncOutside1();
void test_quickfix_MoveFuncDefOutside_MemberFuncOutside2();
void test_quickfix_MoveFuncDefOutside_MemberFuncToCppNS();
......
......@@ -408,6 +408,99 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefix()
data.run(&factory);
}
/// Checks: In addition to test_quickfix_GenerateGetterSetter_basicGetterWithPrefix
/// generated definitions should fit in the namespace.
void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAndNamespace()
{
const QByteArray original =
"namespace SomeNamespace {\n"
"class Something\n"
"{\n"
" int @it;\n"
"};\n"
"}\n";
const QByteArray expected =
"namespace SomeNamespace {\n"
"class Something\n"
"{\n"
" int it;\n"
"\n"
"public:\n"
" int getIt() const;\n"
" void setIt(int value);\n"
"};\n"
"int Something::getIt() const\n"
"{\n"
" return it;\n"
"}\n"
"\n"
"void Something::setIt(int value)\n"
"{\n"
" it = value;\n"
"}\n"
"\n"
"}\n\n";
GenerateGetterSetter factory;
TestCase data(original, expected);
data.run(&factory);
}
/// Checks: In addition to test_quickfix_GenerateGetterSetter_basicGetterWithPrefix
/// generated definitions should fit in the namespace.
void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAndNamespaceToCpp()
{
QList<TestDocumentPtr> testFiles;
QByteArray original;
QByteArray expected;
// Header File
original =
"namespace SomeNamespace {\n"
"class Something\n"
"{\n"
" int @it;\n"
"};\n"
"}\n";
expected =
"namespace SomeNamespace {\n"
"class Something\n"
"{\n"
" int it;\n"
"\n"
"public:\n"
" int getIt() const;\n"
" void setIt(int value);\n"
"};\n"
"}\n\n";
testFiles << TestDocument::create(original, expected, QLatin1String("file.h"));
// Source File
original =
"#include \"file.h\"\n"
"namespace SomeNamespace {\n"
"}\n";
expected =
"#include \"file.h\"\n"
"namespace SomeNamespace {\n"
"int Something::getIt() const\n"
"{\n"
" return it;\n"
"}\n"
"\n"
"void Something::setIt(int value)\n"
"{\n"
" it = value;\n"
"}\n\n"
"}\n\n";
testFiles << TestDocument::create(original, expected, QLatin1String("file.cpp"));
GenerateGetterSetter factory;
TestCase data(testFiles);
data.run(&factory);
}
/// Checks:
/// 1. Getter: "get" prefix is not necessary.
/// 2. Setter: Parameter name is base name.
......@@ -1862,6 +1955,53 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCpp()
data.run(&factory);
}
void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppInsideNS()
{
QList<TestDocumentPtr> testFiles;
QByteArray original;
QByteArray expected;
// Header File
original =
"namespace SomeNamespace {\n"
"class Foo {\n"
" int ba@r()\n"
" {\n"
" return 5;\n"
" }\n"
"};\n"
"}\n";
expected =
"namespace SomeNamespace {\n"
"class Foo {\n"
" int ba@r();\n"
"};\n"
"}\n\n";
testFiles << TestDocument::create(original, expected, QLatin1String("file.h"));
// Source File
original =
"#include \"file.h\"\n"
"namespace SomeNamespace {\n"
"\n"
"}\n";
expected =
"#include \"file.h\"\n"
"namespace SomeNamespace {\n"
"\n"
"int Foo::bar()\n"
"{\n"
" return 5;\n"
"}\n"
"\n"
"}\n\n";
testFiles << TestDocument::create(original, expected, QLatin1String("file.cpp"));
MoveFuncDefOutside factory;
TestCase data(testFiles);
data.run(&factory);
}
/// Check: Move definition outside class
void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutside1()
{
......
......@@ -143,7 +143,7 @@ enum DefPos {
DefPosImplementationFile
};
InsertionLocation insertLocationForMethodDefinition(Symbol *symbol,
InsertionLocation insertLocationForMethodDefinition(Symbol *symbol, const bool useSymbolFinder,
CppRefactoringChanges& refactoring,
const QString& fileName)
{
......@@ -151,8 +151,8 @@ InsertionLocation insertLocationForMethodDefinition(Symbol *symbol,
// Try to find optimal location
const InsertionPointLocator locator(refactoring);
const QList<InsertionLocation> list = locator.methodDefinition(symbol, symbol->asDeclaration(),
fileName);
const QList<InsertionLocation> list
= locator.methodDefinition(symbol, useSymbolFinder, fileName);
for (int i = 0; i < list.count(); ++i) {
InsertionLocation location = list.at(i);
if (location.isValid() && location.fileName() == fileName) {
......@@ -2624,7 +2624,7 @@ void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOpe
// Insert Position: Implementation File
if (isHeaderFile && !cppFileName.isEmpty()) {
CppRefactoringChanges refactoring(interface->snapshot());
loc = insertLocationForMethodDefinition(decl, refactoring,
loc = insertLocationForMethodDefinition(decl, true, refactoring,
cppFileName);
if (loc.isValid()) {
op = new InsertDefOperation(interface, decl, loc,
......@@ -2648,7 +2648,7 @@ void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOpe
// Insert Position: Outside Class
CppRefactoringChanges refactoring(interface->snapshot());
loc = insertLocationForMethodDefinition(decl, refactoring,
loc = insertLocationForMethodDefinition(decl, true, refactoring,
interface->fileName());
if (loc.isValid()) {
op = new InsertDefOperation(interface, decl, loc,
......@@ -2914,17 +2914,17 @@ public:
currChanges.insert(declInsertPos, declaration);
if (sameFile) {
const int pos = currentFile->endOf(m_classDecl) + 1;
unsigned line, column;
currentFile->lineAndColumn(pos, &line, &column);
const int insertPos = currentFile->position(line + 1, 1) - 1;
currChanges.insert(insertPos < 0 ? pos : insertPos, implementation);
InsertionLocation loc = insertLocationForMethodDefinition(symbol, false, refactoring,
currentFile->fileName());
currChanges.insert(currentFile->position(loc.line(), loc.column()), implementation);
} else {
CppRefactoringChanges implRefactoring(snapshot());
CppRefactoringFilePtr implFile = implRefactoring.file(implFileName);
CppRefactoringChanges implRef(snapshot());
CppRefactoringFilePtr implFile = implRef.file(implFileName);
ChangeSet implChanges;
const int implInsertPos = implFile->document()->characterCount() - 1;
implChanges.insert(implInsertPos, implementation);
InsertionLocation loc = insertLocationForMethodDefinition(symbol, false,
implRef, implFileName);
const int implInsertPos = implFile->position(loc.line(), loc.column());
implChanges.insert(implFile->position(loc.line(), loc.column()), implementation);
implFile->setChangeSet(implChanges);
implFile->appendIndentRange(
ChangeSet::Range(implInsertPos, implInsertPos + implementation.size()));
......@@ -3778,8 +3778,8 @@ public:
: refactoring.file(m_cppFileName);
// Determine file, insert position and scope
InsertionLocation l = insertLocationForMethodDefinition(m_func, refactoring,
toFile->fileName());
InsertionLocation l
= insertLocationForMethodDefinition(m_func, false, refactoring, toFile->fileName());
const QString prefix = l.prefix();
const QString suffix = l.suffix();
const int insertPos = toFile->position(l.line(), l.column());
......
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