forked from qt-creator/qt-creator
CppEditor: Quick fix "Insert (Pure) Virtual Methods"
This quick fix inserts (pure) virtual functions of base classes to the current class. For selecting the functions which should be inserted and for choosing the insertion mode (only declarations or with definitions inside, outside or in the implementation file) a dialog is shown. Task-number: QTCREATORBUG-2210 Task-number: QTCREATORBUG-2692 Task-number: QTCREATORBUG-3908 Task-number: QTCREATORBUG-5868 Task-number: QTCREATORBUG-7982 Change-Id: I8e94905afcae4778986f4c3925a494e0c6b3b8ee Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
This commit is contained in:
committed by
Nikolai Kosjar
parent
7ef611047f
commit
d288e3999b
BIN
doc/images/qtcreator-refactoring-virtual-function-dialog.png
Normal file
BIN
doc/images/qtcreator-refactoring-virtual-function-dialog.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
@@ -1957,6 +1957,19 @@
|
|||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
\li Function call or class name
|
\li Function call or class name
|
||||||
|
\row
|
||||||
|
\li Insert (Pure) Virtual Functions
|
||||||
|
\li Select an insertion mode:
|
||||||
|
\list
|
||||||
|
\li Insert only declarations.
|
||||||
|
\li Insert declarations and the corresponding definitions inside the class.
|
||||||
|
\li Insert declarations and the corresponding definitions outside the class.
|
||||||
|
\li Insert declarations and the corresponding definitions in the implementation file
|
||||||
|
(only if an implementation file exists).
|
||||||
|
\endlist
|
||||||
|
\image qtcreator-refactoring-virtual-function-dialog.png
|
||||||
|
|
||||||
|
\li Class or base class name
|
||||||
|
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
|
|||||||
@@ -199,6 +199,18 @@ private slots:
|
|||||||
void test_quickfix_AssignToLocalVariable_noReturnClass();
|
void test_quickfix_AssignToLocalVariable_noReturnClass();
|
||||||
void test_quickfix_AssignToLocalVariable_noReturnFunc();
|
void test_quickfix_AssignToLocalVariable_noReturnFunc();
|
||||||
|
|
||||||
|
void test_quickfix_InsertVirtualMethods_onlyDecl();
|
||||||
|
void test_quickfix_InsertVirtualMethods_onlyDeclWithoutVirtual();
|
||||||
|
void test_quickfix_InsertVirtualMethods_Access();
|
||||||
|
void test_quickfix_InsertVirtualMethods_Superclass();
|
||||||
|
void test_quickfix_InsertVirtualMethods_SuperclassOverride();
|
||||||
|
void test_quickfix_InsertVirtualMethods_PureVirtualOnlyDecl();
|
||||||
|
void test_quickfix_InsertVirtualMethods_PureVirtualInside();
|
||||||
|
void test_quickfix_InsertVirtualMethods_inside();
|
||||||
|
void test_quickfix_InsertVirtualMethods_outside();
|
||||||
|
void test_quickfix_InsertVirtualMethods_implementationFile();
|
||||||
|
void test_quickfix_InsertVirtualMethods_notrigger_allImplemented();
|
||||||
|
|
||||||
// The following tests depend on the projects that are loaded on startup
|
// The following tests depend on the projects that are loaded on startup
|
||||||
// and will be skipped in case no projects are loaded.
|
// and will be skipped in case no projects are loaded.
|
||||||
void test_openEachFile();
|
void test_openEachFile();
|
||||||
|
|||||||
@@ -2014,3 +2014,420 @@ void CppEditorPlugin::test_quickfix_AssignToLocalVariable_noReturnFunc()
|
|||||||
TestCase data(original, expected);
|
TestCase data(original, expected);
|
||||||
data.run(&factory);
|
data.run(&factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test dialog for insert virtual functions
|
||||||
|
class InsertVirtualMethodsDialogTest : public InsertVirtualMethodsDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InsertVirtualMethodsDialogTest(ImplementationMode mode, bool virt, QWidget *parent = 0)
|
||||||
|
: InsertVirtualMethodsDialog(parent)
|
||||||
|
{
|
||||||
|
setImplementationsMode(mode);
|
||||||
|
setInsertKeywordVirtual(virt);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gather()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImplementationMode implementationMode() const
|
||||||
|
{
|
||||||
|
return m_implementationMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool insertKeywordVirtual() const
|
||||||
|
{
|
||||||
|
return m_insertKeywordVirtual;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Check: Insert only declarations
|
||||||
|
void CppEditorPlugin::test_quickfix_InsertVirtualMethods_onlyDecl()
|
||||||
|
{
|
||||||
|
const QByteArray original =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public Bas@eA {\n"
|
||||||
|
"};";
|
||||||
|
const QByteArray expected =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public BaseA {\n"
|
||||||
|
"\n"
|
||||||
|
" // BaseA interface\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
|
||||||
|
InsertVirtualMethodsDialog::ModeOnlyDeclarations, true));
|
||||||
|
TestCase data(original, expected);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check: Insert only declarations vithout virtual keyword
|
||||||
|
void CppEditorPlugin::test_quickfix_InsertVirtualMethods_onlyDeclWithoutVirtual()
|
||||||
|
{
|
||||||
|
const QByteArray original =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public Bas@eA {\n"
|
||||||
|
"};";
|
||||||
|
const QByteArray expected =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public BaseA {\n"
|
||||||
|
"\n"
|
||||||
|
" // BaseA interface\n"
|
||||||
|
"public:\n"
|
||||||
|
" int virtualFuncA();\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
|
||||||
|
InsertVirtualMethodsDialog::ModeOnlyDeclarations, false));
|
||||||
|
TestCase data(original, expected);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check: Are access specifiers considered
|
||||||
|
void CppEditorPlugin::test_quickfix_InsertVirtualMethods_Access()
|
||||||
|
{
|
||||||
|
const QByteArray original =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n"
|
||||||
|
"protected:\n"
|
||||||
|
" virtual int b();\n"
|
||||||
|
"private:\n"
|
||||||
|
" virtual int c();\n"
|
||||||
|
"public slots:\n"
|
||||||
|
" virtual int d();\n"
|
||||||
|
"protected slots:\n"
|
||||||
|
" virtual int e();\n"
|
||||||
|
"private slots:\n"
|
||||||
|
" virtual int f();\n"
|
||||||
|
"signals:\n"
|
||||||
|
" virtual int g();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Der@ived : public BaseA {\n"
|
||||||
|
"};";
|
||||||
|
const QByteArray expected =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n"
|
||||||
|
"protected:\n"
|
||||||
|
" virtual int b();\n"
|
||||||
|
"private:\n"
|
||||||
|
" virtual int c();\n"
|
||||||
|
"public slots:\n"
|
||||||
|
" virtual int d();\n"
|
||||||
|
"protected slots:\n"
|
||||||
|
" virtual int e();\n"
|
||||||
|
"private slots:\n"
|
||||||
|
" virtual int f();\n"
|
||||||
|
"signals:\n"
|
||||||
|
" virtual int g();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public BaseA {\n"
|
||||||
|
"\n"
|
||||||
|
" // BaseA interface\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n\n"
|
||||||
|
"protected:\n"
|
||||||
|
" virtual int b();\n\n"
|
||||||
|
"private:\n"
|
||||||
|
" virtual int c();\n\n"
|
||||||
|
"public slots:\n"
|
||||||
|
" virtual int d();\n\n"
|
||||||
|
"protected slots:\n"
|
||||||
|
" virtual int e();\n\n"
|
||||||
|
"private slots:\n"
|
||||||
|
" virtual int f();\n\n"
|
||||||
|
"signals:\n"
|
||||||
|
" virtual int g();\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
|
||||||
|
InsertVirtualMethodsDialog::ModeOnlyDeclarations, true));
|
||||||
|
TestCase data(original, expected);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check: Is a base class of a base class considered.
|
||||||
|
void CppEditorPlugin::test_quickfix_InsertVirtualMethods_Superclass()
|
||||||
|
{
|
||||||
|
const QByteArray original =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class BaseB : public BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int b();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Der@ived : public BaseB {\n"
|
||||||
|
"};";
|
||||||
|
const QByteArray expected =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class BaseB : public BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int b();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Der@ived : public BaseB {\n"
|
||||||
|
"\n"
|
||||||
|
" // BaseB interface\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int b();\n"
|
||||||
|
"\n"
|
||||||
|
" // BaseA interface\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
|
||||||
|
InsertVirtualMethodsDialog::ModeOnlyDeclarations, true));
|
||||||
|
TestCase data(original, expected);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check: Do not insert reimplemented functions twice.
|
||||||
|
void CppEditorPlugin::test_quickfix_InsertVirtualMethods_SuperclassOverride()
|
||||||
|
{
|
||||||
|
const QByteArray original =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class BaseB : public BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Der@ived : public BaseB {\n"
|
||||||
|
"};";
|
||||||
|
const QByteArray expected =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class BaseB : public BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Der@ived : public BaseB {\n"
|
||||||
|
"\n"
|
||||||
|
" // BaseA interface\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
|
||||||
|
InsertVirtualMethodsDialog::ModeOnlyDeclarations, true));
|
||||||
|
TestCase data(original, expected);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check: Insert only declarations for pure virtual function
|
||||||
|
void CppEditorPlugin::test_quickfix_InsertVirtualMethods_PureVirtualOnlyDecl()
|
||||||
|
{
|
||||||
|
const QByteArray original =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA() = 0;\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public Bas@eA {\n"
|
||||||
|
"};";
|
||||||
|
const QByteArray expected =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA() = 0;\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public BaseA {\n"
|
||||||
|
"\n"
|
||||||
|
" // BaseA interface\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
|
||||||
|
InsertVirtualMethodsDialog::ModeOnlyDeclarations, true));
|
||||||
|
TestCase data(original, expected);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check: Insert pure virtual functions inside class
|
||||||
|
void CppEditorPlugin::test_quickfix_InsertVirtualMethods_PureVirtualInside()
|
||||||
|
{
|
||||||
|
const QByteArray original =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA() = 0;\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public Bas@eA {\n"
|
||||||
|
"};";
|
||||||
|
const QByteArray expected =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA() = 0;\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public BaseA {\n"
|
||||||
|
"\n"
|
||||||
|
" // BaseA interface\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA()\n"
|
||||||
|
" {\n"
|
||||||
|
" }\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
|
||||||
|
InsertVirtualMethodsDialog::ModeInsideClass, true));
|
||||||
|
TestCase data(original, expected);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check: Insert inside class
|
||||||
|
void CppEditorPlugin::test_quickfix_InsertVirtualMethods_inside()
|
||||||
|
{
|
||||||
|
const QByteArray original =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public Bas@eA {\n"
|
||||||
|
"};";
|
||||||
|
const QByteArray expected =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public BaseA {\n"
|
||||||
|
"\n"
|
||||||
|
" // BaseA interface\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA()\n"
|
||||||
|
" {\n"
|
||||||
|
" }\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
|
||||||
|
InsertVirtualMethodsDialog::ModeInsideClass, true));
|
||||||
|
TestCase data(original, expected);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check: Insert outside class
|
||||||
|
void CppEditorPlugin::test_quickfix_InsertVirtualMethods_outside()
|
||||||
|
{
|
||||||
|
const QByteArray original =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public Bas@eA {\n"
|
||||||
|
"};";
|
||||||
|
const QByteArray expected =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public BaseA {\n"
|
||||||
|
"\n"
|
||||||
|
" // BaseA interface\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"int Derived::virtualFuncA()\n"
|
||||||
|
"{\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
|
||||||
|
InsertVirtualMethodsDialog::ModeOutsideClass, true));
|
||||||
|
TestCase data(original, expected);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check: Insert in implementation file
|
||||||
|
void CppEditorPlugin::test_quickfix_InsertVirtualMethods_implementationFile()
|
||||||
|
{
|
||||||
|
QList<TestDocumentPtr> testFiles;
|
||||||
|
QByteArray original;
|
||||||
|
QByteArray expected;
|
||||||
|
|
||||||
|
// Header File
|
||||||
|
original =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public Bas@eA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" Derived();\n"
|
||||||
|
"};";
|
||||||
|
expected =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" Derived();\n"
|
||||||
|
"\n"
|
||||||
|
" // BaseA interface\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int a();\n"
|
||||||
|
"};\n";
|
||||||
|
testFiles << TestDocument::create(original, expected, QLatin1String("file.h"));
|
||||||
|
|
||||||
|
// Source File
|
||||||
|
original = "#include \"file.h\"\n";
|
||||||
|
expected =
|
||||||
|
"#include \"file.h\"\n"
|
||||||
|
"\n\n"
|
||||||
|
"int Derived::a()\n"
|
||||||
|
"{\n}\n";
|
||||||
|
testFiles << TestDocument::create(original, expected, QLatin1String("file.cpp"));
|
||||||
|
|
||||||
|
InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
|
||||||
|
InsertVirtualMethodsDialog::ModeImplementationFile, true));
|
||||||
|
TestCase data(testFiles);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check: No trigger: all implemented
|
||||||
|
void CppEditorPlugin::test_quickfix_InsertVirtualMethods_notrigger_allImplemented()
|
||||||
|
{
|
||||||
|
const QByteArray original =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public Bas@eA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};";
|
||||||
|
const QByteArray expected =
|
||||||
|
"class BaseA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n\n"
|
||||||
|
"class Derived : public Bas@eA {\n"
|
||||||
|
"public:\n"
|
||||||
|
" virtual int virtualFuncA();\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
|
||||||
|
InsertVirtualMethodsDialog::ModeOutsideClass, true));
|
||||||
|
TestCase data(original, expected);
|
||||||
|
data.run(&factory);
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,8 @@
|
|||||||
#include "cppfunctiondecldeflink.h"
|
#include "cppfunctiondecldeflink.h"
|
||||||
#include "cppquickfixassistant.h"
|
#include "cppquickfixassistant.h"
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <cpptools/cppclassesfilter.h>
|
#include <cpptools/cppclassesfilter.h>
|
||||||
#include <cpptools/cppcodestylesettings.h>
|
#include <cpptools/cppcodestylesettings.h>
|
||||||
#include <cpptools/cpppointerdeclarationformatter.h>
|
#include <cpptools/cpppointerdeclarationformatter.h>
|
||||||
@@ -49,16 +51,33 @@
|
|||||||
|
|
||||||
#include <extensionsystem/pluginmanager.h>
|
#include <extensionsystem/pluginmanager.h>
|
||||||
|
|
||||||
|
#include <texteditor/fontsettings.h>
|
||||||
|
#include <texteditor/texteditorsettings.h>
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
|
#include <QItemDelegate>
|
||||||
|
#include <QLabel>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QQueue>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QStandardItemModel>
|
||||||
#include <QTextBlock>
|
#include <QTextBlock>
|
||||||
#include <QTextCursor>
|
#include <QTextCursor>
|
||||||
|
#include <QTreeView>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
|
||||||
@@ -109,6 +128,8 @@ void CppEditor::Internal::registerQuickFixes(ExtensionSystem::IPlugin *plugIn)
|
|||||||
plugIn->addAutoReleasedObject(new MoveFuncDefToDecl);
|
plugIn->addAutoReleasedObject(new MoveFuncDefToDecl);
|
||||||
|
|
||||||
plugIn->addAutoReleasedObject(new AssignToLocalVariable);
|
plugIn->addAutoReleasedObject(new AssignToLocalVariable);
|
||||||
|
|
||||||
|
plugIn->addAutoReleasedObject(new InsertVirtualMethods);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In the following anonymous namespace all functions are collected, which could be of interest for
|
// In the following anonymous namespace all functions are collected, which could be of interest for
|
||||||
@@ -2356,7 +2377,7 @@ public:
|
|||||||
targetFile->apply();
|
targetFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString generateDeclaration(Function *function);
|
static QString generateDeclaration(const Function *function);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_targetFileName;
|
QString m_targetFileName;
|
||||||
@@ -2450,7 +2471,7 @@ void InsertDeclFromDef::match(const CppQuickFixInterface &interface, QuickFixOpe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString InsertDeclOperation::generateDeclaration(Function *function)
|
QString InsertDeclOperation::generateDeclaration(const Function *function)
|
||||||
{
|
{
|
||||||
Overview oo = CppCodeStyleSettings::currentProjectCodeStyleOverview();
|
Overview oo = CppCodeStyleSettings::currentProjectCodeStyleOverview();
|
||||||
oo.showFunctionSignatures = true;
|
oo.showFunctionSignatures = true;
|
||||||
@@ -4284,3 +4305,735 @@ void AssignToLocalVariable::match(const CppQuickFixInterface &interface, QuickFi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class InsertVirtualMethodsOp : public CppQuickFixOperation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InsertVirtualMethodsOp(const QSharedPointer<const CppQuickFixAssistInterface> &interface,
|
||||||
|
InsertVirtualMethodsDialog *factory)
|
||||||
|
: CppQuickFixOperation(interface, 0)
|
||||||
|
, m_factory(factory)
|
||||||
|
, m_classAST(0)
|
||||||
|
, m_valid(false)
|
||||||
|
, m_cppFileName(QString::null)
|
||||||
|
, m_insertPosDecl(0)
|
||||||
|
, m_insertPosOutside(0)
|
||||||
|
, m_functionCount(0)
|
||||||
|
, m_implementedFunctionCount(0)
|
||||||
|
{
|
||||||
|
setDescription(QCoreApplication::translate(
|
||||||
|
"CppEditor::QuickFix", "Insert Virtual Functions of Base Classes"));
|
||||||
|
|
||||||
|
const QList<AST *> &path = interface->path();
|
||||||
|
const int pathSize = path.size();
|
||||||
|
if (pathSize < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Determine if cursor is on a class or a base class
|
||||||
|
if (SimpleNameAST *nameAST = path.at(pathSize - 1)->asSimpleName()) {
|
||||||
|
if (!interface->isCursorOn(nameAST))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!(m_classAST = path.at(pathSize - 2)->asClassSpecifier())) { // normal class
|
||||||
|
int index = pathSize - 2;
|
||||||
|
const BaseSpecifierAST *baseAST = path.at(index)->asBaseSpecifier();// simple bclass
|
||||||
|
if (!baseAST) {
|
||||||
|
if (index > 0 && path.at(index)->asQualifiedName()) // namespaced base class
|
||||||
|
baseAST = path.at(--index)->asBaseSpecifier();
|
||||||
|
}
|
||||||
|
--index;
|
||||||
|
if (baseAST && index >= 0)
|
||||||
|
m_classAST = path.at(index)->asClassSpecifier();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!m_classAST || !m_classAST->base_clause_list)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Determine insert positions
|
||||||
|
const int endOfClassAST = interface->currentFile()->endOf(m_classAST);
|
||||||
|
m_insertPosDecl = endOfClassAST - 1; // Skip last "}"
|
||||||
|
m_insertPosOutside = endOfClassAST + 1; // Step over ";"
|
||||||
|
|
||||||
|
// Determine base classes
|
||||||
|
QList<const Class *> baseClasses;
|
||||||
|
QQueue<ClassOrNamespace *> baseClassQueue;
|
||||||
|
QSet<ClassOrNamespace *> visitedBaseClasses;
|
||||||
|
if (ClassOrNamespace *clazz = interface->context().lookupType(m_classAST->symbol))
|
||||||
|
baseClassQueue.enqueue(clazz);
|
||||||
|
while (!baseClassQueue.isEmpty()) {
|
||||||
|
ClassOrNamespace *clazz = baseClassQueue.dequeue();
|
||||||
|
visitedBaseClasses.insert(clazz);
|
||||||
|
const QList<ClassOrNamespace *> bases = clazz->usings();
|
||||||
|
foreach (ClassOrNamespace *baseClass, bases) {
|
||||||
|
foreach (Symbol *symbol, baseClass->symbols()) {
|
||||||
|
Class *base = symbol->asClass();
|
||||||
|
if (base
|
||||||
|
&& (clazz = interface->context().lookupType(symbol))
|
||||||
|
&& !visitedBaseClasses.contains(clazz)
|
||||||
|
&& !baseClasses.contains(base)) {
|
||||||
|
baseClasses << base;
|
||||||
|
baseClassQueue.enqueue(clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine virtual functions
|
||||||
|
m_factory->classFunctionModel->clear();
|
||||||
|
Overview printer = CppCodeStyleSettings::currentProjectCodeStyleOverview();
|
||||||
|
printer.showFunctionSignatures = true;
|
||||||
|
const TextEditor::FontSettings &fs =
|
||||||
|
TextEditor::TextEditorSettings::instance()->fontSettings();
|
||||||
|
const Format formatReimpFunc = fs.formatFor(C_DISABLED_CODE);
|
||||||
|
foreach (const Class *clazz, baseClasses) {
|
||||||
|
QStandardItem *itemBase = new QStandardItem(printer.prettyName(clazz->name()));
|
||||||
|
itemBase->setData(false, InsertVirtualMethodsDialog::Implemented);
|
||||||
|
itemBase->setData(qVariantFromValue((void *) clazz),
|
||||||
|
InsertVirtualMethodsDialog::ClassOrFunction);
|
||||||
|
const QString baseClassName = printer.prettyName(clazz->name());
|
||||||
|
for (Scope::iterator it = clazz->firstMember(); it != clazz->lastMember(); ++it) {
|
||||||
|
if (const Function *func = (*it)->type()->asFunctionType()) {
|
||||||
|
if (!func->isVirtual())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Filter virtual destructors
|
||||||
|
if (printer.prettyName(func->name()).startsWith(QLatin1Char('~')))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Filter OQbject's
|
||||||
|
// - virtual const QMetaObject *metaObject() const;
|
||||||
|
// - virtual void *qt_metacast(const char *);
|
||||||
|
// - virtual int qt_metacall(QMetaObject::Call, int, void **);
|
||||||
|
if (baseClassName == QLatin1String("QObject")) {
|
||||||
|
if (printer.prettyName(func->name()) == QLatin1String("metaObject"))
|
||||||
|
continue;
|
||||||
|
if (printer.prettyName(func->name()) == QLatin1String("qt_metacast"))
|
||||||
|
continue;
|
||||||
|
if (printer.prettyName(func->name()) == QLatin1String("qt_metacall"))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not implement existing functions inside target class
|
||||||
|
bool funcExistsInClass = false;
|
||||||
|
const Name *funcName = func->name();
|
||||||
|
for (Symbol *symbol = m_classAST->symbol->find(funcName->identifier());
|
||||||
|
symbol; symbol = symbol->next()) {
|
||||||
|
if (!symbol->name()
|
||||||
|
|| !funcName->identifier()->isEqualTo(symbol->identifier())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (symbol->type().isEqualTo(func->type())) {
|
||||||
|
funcExistsInClass = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not show when reimplemented from an other class
|
||||||
|
bool funcReimplemented = false;
|
||||||
|
for (int i = baseClasses.count() - 1; i >= 0; --i) {
|
||||||
|
const Class *prevClass = baseClasses.at(i);
|
||||||
|
if (clazz == prevClass)
|
||||||
|
break; // reached current class
|
||||||
|
|
||||||
|
for (const Symbol *symbol = prevClass->find(funcName->identifier());
|
||||||
|
symbol; symbol = symbol->next()) {
|
||||||
|
if (!symbol->name()
|
||||||
|
|| !funcName->identifier()->isEqualTo(symbol->identifier())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (symbol->type().isEqualTo(func->type())) {
|
||||||
|
funcReimplemented = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (funcReimplemented)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Construct function item
|
||||||
|
const bool isPureVirtual = func->isPureVirtual();
|
||||||
|
QString itemName = printer.prettyType(func->type(), func->name());
|
||||||
|
if (isPureVirtual)
|
||||||
|
itemName += QLatin1String(" = 0");
|
||||||
|
const QString itemReturnTypeString = printer.prettyType(func->returnType());
|
||||||
|
QStandardItem *funcItem = new QStandardItem(
|
||||||
|
itemName + QLatin1String(" : ") + itemReturnTypeString);
|
||||||
|
if (!funcExistsInClass) {
|
||||||
|
funcItem->setCheckable(true);
|
||||||
|
funcItem->setCheckState(Qt::Checked);
|
||||||
|
} else {
|
||||||
|
funcItem->setEnabled(false);
|
||||||
|
funcItem->setData(formatReimpFunc.foreground(), Qt::ForegroundRole);
|
||||||
|
if (formatReimpFunc.background().isValid())
|
||||||
|
funcItem->setData(formatReimpFunc.background(), Qt::BackgroundRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
funcItem->setData(qVariantFromValue((void *) func),
|
||||||
|
InsertVirtualMethodsDialog::ClassOrFunction);
|
||||||
|
funcItem->setData(isPureVirtual, InsertVirtualMethodsDialog::PureVirtual);
|
||||||
|
funcItem->setData(acessSpec(*it), InsertVirtualMethodsDialog::AccessSpec);
|
||||||
|
funcItem->setData(funcExistsInClass, InsertVirtualMethodsDialog::Implemented);
|
||||||
|
|
||||||
|
itemBase->appendRow(funcItem);
|
||||||
|
|
||||||
|
// update internal counters
|
||||||
|
if (funcExistsInClass)
|
||||||
|
++m_implementedFunctionCount;
|
||||||
|
else
|
||||||
|
++m_functionCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (itemBase->hasChildren()) {
|
||||||
|
for (int i = 0; i < itemBase->rowCount(); ++i) {
|
||||||
|
if (itemBase->child(i, 0)->isCheckable()) {
|
||||||
|
itemBase->setCheckable(true);
|
||||||
|
itemBase->setTristate(true);
|
||||||
|
itemBase->setCheckState(Qt::Checked);
|
||||||
|
itemBase->setData(false, InsertVirtualMethodsDialog::Implemented);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_factory->classFunctionModel->invisibleRootItem()->appendRow(itemBase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!m_factory->classFunctionModel->invisibleRootItem()->hasChildren()
|
||||||
|
|| m_functionCount == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isHeaderFile = false;
|
||||||
|
m_cppFileName = correspondingHeaderOrSource(interface->fileName(), &isHeaderFile);
|
||||||
|
m_factory->setHasImplementationFile(isHeaderFile && !m_cppFileName.isEmpty());
|
||||||
|
m_factory->setHasReimplementedFunctions(m_implementedFunctionCount != 0);
|
||||||
|
|
||||||
|
m_valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValid() const
|
||||||
|
{
|
||||||
|
return m_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertionPointLocator::AccessSpec acessSpec(const Symbol *symbol)
|
||||||
|
{
|
||||||
|
const Function *func = symbol->type()->asFunctionType();
|
||||||
|
if (!func)
|
||||||
|
return InsertionPointLocator::Invalid;
|
||||||
|
if (func->isSignal())
|
||||||
|
return InsertionPointLocator::Signals;
|
||||||
|
|
||||||
|
InsertionPointLocator::AccessSpec spec = InsertionPointLocator::Invalid;
|
||||||
|
if (symbol->isPrivate())
|
||||||
|
spec = InsertionPointLocator::Private;
|
||||||
|
else if (symbol->isProtected())
|
||||||
|
spec = InsertionPointLocator::Protected;
|
||||||
|
else if (symbol->isPublic())
|
||||||
|
spec = InsertionPointLocator::Public;
|
||||||
|
else
|
||||||
|
return InsertionPointLocator::Invalid;
|
||||||
|
|
||||||
|
if (func->isSlot()) {
|
||||||
|
switch (spec) {
|
||||||
|
case InsertionPointLocator::Private:
|
||||||
|
return InsertionPointLocator::PrivateSlot;
|
||||||
|
break;
|
||||||
|
case InsertionPointLocator::Protected:
|
||||||
|
return InsertionPointLocator::ProtectedSlot;
|
||||||
|
break;
|
||||||
|
case InsertionPointLocator::Public:
|
||||||
|
return InsertionPointLocator::PublicSlot;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return spec;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void perform()
|
||||||
|
{
|
||||||
|
if (!m_factory->gather())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Core::ICore::settings()->setValue(
|
||||||
|
QLatin1String("QuickFix/InsertVirtualMethods/insertKeywordVirtual"),
|
||||||
|
m_factory->insertKeywordVirtual());
|
||||||
|
Core::ICore::settings()->setValue(
|
||||||
|
QLatin1String("QuickFix/InsertVirtualMethods/implementationMode"),
|
||||||
|
m_factory->implementationMode());
|
||||||
|
Core::ICore::settings()->setValue(
|
||||||
|
QLatin1String("QuickFix/InsertVirtualMethods/hideReimplementedFunctions"),
|
||||||
|
m_factory->hideReimplementedFunctions());
|
||||||
|
|
||||||
|
// Insert declarations (and definition if InsideClass)
|
||||||
|
Overview printer = CppCodeStyleSettings::currentProjectCodeStyleOverview();
|
||||||
|
printer.showFunctionSignatures = true;
|
||||||
|
printer.showReturnTypes = true;
|
||||||
|
printer.showArgumentNames = true;
|
||||||
|
ChangeSet headerChangeSet;
|
||||||
|
for (int i = 0; i < m_factory->classFunctionModel->rowCount(); ++i) {
|
||||||
|
const QStandardItem *parent =
|
||||||
|
m_factory->classFunctionModel->invisibleRootItem()->child(i, 0);
|
||||||
|
if (!parent->isCheckable() || parent->checkState() == Qt::Unchecked)
|
||||||
|
continue;
|
||||||
|
const Class *clazz = (const Class *)
|
||||||
|
parent->data(InsertVirtualMethodsDialog::ClassOrFunction).value<void *>();
|
||||||
|
|
||||||
|
// Add comment
|
||||||
|
const QString comment = QLatin1String("\n// ") + printer.prettyName(clazz->name()) +
|
||||||
|
QLatin1String(" interface\n");
|
||||||
|
headerChangeSet.insert(m_insertPosDecl, comment);
|
||||||
|
|
||||||
|
// Insert Declarations (+ definitions)
|
||||||
|
QString lastAccessSpecString;
|
||||||
|
for (int j = 0; j < parent->rowCount(); ++j) {
|
||||||
|
const QStandardItem *item = parent->child(j, 0);
|
||||||
|
if (!item->isCheckable() || item->checkState() == Qt::Unchecked)
|
||||||
|
continue;
|
||||||
|
const Function *func = (const Function *)
|
||||||
|
item->data(InsertVirtualMethodsDialog::ClassOrFunction).value<void *>();
|
||||||
|
|
||||||
|
// Construct declaration
|
||||||
|
QString declaration = InsertDeclOperation::generateDeclaration(func);
|
||||||
|
if (m_factory->insertKeywordVirtual())
|
||||||
|
declaration = QLatin1String("virtual ") + declaration;
|
||||||
|
if (m_factory->implementationMode() & InsertVirtualMethodsDialog::ModeInsideClass)
|
||||||
|
declaration.replace(declaration.size() - 2, 2, QLatin1String("\n{\n}\n"));
|
||||||
|
const InsertionPointLocator::AccessSpec spec =
|
||||||
|
static_cast<InsertionPointLocator::AccessSpec>(
|
||||||
|
item->data(InsertVirtualMethodsDialog::AccessSpec).toInt());
|
||||||
|
const QString accessSpecString = InsertionPointLocator::accessSpecToString(spec);
|
||||||
|
if (accessSpecString != lastAccessSpecString) {
|
||||||
|
declaration = accessSpecString + declaration;
|
||||||
|
if (!lastAccessSpecString.isEmpty()) // separate if not direct after the comment
|
||||||
|
declaration = QLatin1String("\n") + declaration;
|
||||||
|
lastAccessSpecString = accessSpecString;
|
||||||
|
}
|
||||||
|
headerChangeSet.insert(m_insertPosDecl, declaration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert outside class
|
||||||
|
const QString filename = assistInterface()->currentFile()->fileName();
|
||||||
|
const CppRefactoringChanges refactoring(assistInterface()->snapshot());
|
||||||
|
const CppRefactoringFilePtr headerFile = refactoring.file(filename);
|
||||||
|
const Document::Ptr headerDoc = headerFile->cppDocument();
|
||||||
|
Class *targetClass = m_classAST->symbol;
|
||||||
|
if (m_factory->implementationMode() & InsertVirtualMethodsDialog::ModeOutsideClass) {
|
||||||
|
// make target lookup context
|
||||||
|
unsigned line, column;
|
||||||
|
headerDoc->translationUnit()->getPosition(m_insertPosOutside, &line, &column);
|
||||||
|
Scope *targetScope = headerDoc->scopeAt(line, column);
|
||||||
|
const LookupContext targetContext(headerDoc, assistInterface()->snapshot());
|
||||||
|
ClassOrNamespace *targetCoN = targetContext.lookupType(targetScope);
|
||||||
|
if (!targetCoN)
|
||||||
|
targetCoN = targetContext.globalNamespace();
|
||||||
|
|
||||||
|
// setup rewriting to get minimally qualified names
|
||||||
|
SubstitutionEnvironment env;
|
||||||
|
env.setContext(assistInterface()->context());
|
||||||
|
env.switchScope(targetClass);
|
||||||
|
UseMinimalNames q(targetCoN);
|
||||||
|
env.enter(&q);
|
||||||
|
Control *control = assistInterface()->context().control().data();
|
||||||
|
const QString fullClassName = printer.prettyName(LookupContext::minimalName(
|
||||||
|
targetClass, targetCoN, control));
|
||||||
|
|
||||||
|
for (int i = 0; i < m_factory->classFunctionModel->rowCount(); ++i) {
|
||||||
|
const QStandardItem *parent =
|
||||||
|
m_factory->classFunctionModel->invisibleRootItem()->child(i, 0);
|
||||||
|
if (!parent->isCheckable() || parent->checkState() == Qt::Unchecked)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int j = 0; j < parent->rowCount(); ++j) {
|
||||||
|
const QStandardItem *item = parent->child(j, 0);
|
||||||
|
if (!item->isCheckable() || item->checkState() == Qt::Unchecked)
|
||||||
|
continue;
|
||||||
|
const Function *func = (const Function *)
|
||||||
|
item->data(InsertVirtualMethodsDialog::ClassOrFunction).value<void *>();
|
||||||
|
|
||||||
|
// rewrite the function type and name
|
||||||
|
const FullySpecifiedType tn = rewriteType(func->type(), &env, control);
|
||||||
|
const QString name = fullClassName + QLatin1String("::") +
|
||||||
|
printer.prettyName(func->name());
|
||||||
|
const QString defText = printer.prettyType(tn, name) + QLatin1String("\n{\n}");
|
||||||
|
|
||||||
|
headerChangeSet.insert(m_insertPosOutside, QLatin1String("\n\n") + defText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write header file
|
||||||
|
headerFile->setChangeSet(headerChangeSet);
|
||||||
|
headerFile->appendIndentRange(ChangeSet::Range(m_insertPosDecl, m_insertPosDecl + 1));
|
||||||
|
headerFile->setOpenEditor(true, m_insertPosDecl);
|
||||||
|
headerFile->apply();
|
||||||
|
|
||||||
|
// Insert in implementation file
|
||||||
|
if (m_factory->implementationMode() & InsertVirtualMethodsDialog::ModeImplementationFile) {
|
||||||
|
const Symbol *symbol = headerFile->cppDocument()->lastVisibleSymbolAt(
|
||||||
|
targetClass->line(), targetClass->column());
|
||||||
|
if (!symbol)
|
||||||
|
return;
|
||||||
|
const Class *clazz = symbol->asClass();
|
||||||
|
if (!clazz)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CppRefactoringFilePtr implementationFile = refactoring.file(m_cppFileName);
|
||||||
|
ChangeSet implementationChangeSet;
|
||||||
|
const int insertPos = qMax(0, implementationFile->document()->characterCount() - 1);
|
||||||
|
|
||||||
|
// make target lookup context
|
||||||
|
Document::Ptr implementationDoc = implementationFile->cppDocument();
|
||||||
|
unsigned line, column;
|
||||||
|
implementationDoc->translationUnit()->getPosition(insertPos, &line, &column);
|
||||||
|
Scope *targetScope = implementationDoc->scopeAt(line, column);
|
||||||
|
const LookupContext targetContext(implementationDoc, assistInterface()->snapshot());
|
||||||
|
ClassOrNamespace *targetCoN = targetContext.lookupType(targetScope);
|
||||||
|
if (!targetCoN)
|
||||||
|
targetCoN = targetContext.globalNamespace();
|
||||||
|
|
||||||
|
// Loop through inserted declarations
|
||||||
|
for (unsigned i = targetClass->memberCount(); i < clazz->memberCount(); ++i) {
|
||||||
|
Declaration *decl = clazz->memberAt(i)->asDeclaration();
|
||||||
|
if (!decl)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// setup rewriting to get minimally qualified names
|
||||||
|
SubstitutionEnvironment env;
|
||||||
|
env.setContext(assistInterface()->context());
|
||||||
|
env.switchScope(decl->enclosingScope());
|
||||||
|
UseMinimalNames q(targetCoN);
|
||||||
|
env.enter(&q);
|
||||||
|
Control *control = assistInterface()->context().control().data();
|
||||||
|
|
||||||
|
// rewrite the function type and name + create definition
|
||||||
|
const FullySpecifiedType type = rewriteType(decl->type(), &env, control);
|
||||||
|
const QString name = printer.prettyName(
|
||||||
|
LookupContext::minimalName(decl, targetCoN, control));
|
||||||
|
const QString defText = printer.prettyType(type, name) + QLatin1String("\n{\n}");
|
||||||
|
|
||||||
|
implementationChangeSet.insert(insertPos, QLatin1String("\n\n") + defText);
|
||||||
|
}
|
||||||
|
|
||||||
|
implementationFile->setChangeSet(implementationChangeSet);
|
||||||
|
implementationFile->appendIndentRange(ChangeSet::Range(insertPos, insertPos + 1));
|
||||||
|
implementationFile->apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
InsertVirtualMethodsDialog *m_factory;
|
||||||
|
const ClassSpecifierAST *m_classAST;
|
||||||
|
bool m_valid;
|
||||||
|
QString m_cppFileName;
|
||||||
|
int m_insertPosDecl;
|
||||||
|
int m_insertPosOutside;
|
||||||
|
unsigned m_functionCount;
|
||||||
|
unsigned m_implementedFunctionCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
class InsertVirtualMethodsFilterModel : public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
InsertVirtualMethodsFilterModel(QObject *parent = 0)
|
||||||
|
: QSortFilterProxyModel(parent)
|
||||||
|
, m_hideReimplemented(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||||
|
{
|
||||||
|
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||||
|
|
||||||
|
// Handle base class
|
||||||
|
if (!sourceParent.isValid()) {
|
||||||
|
// check if any child is valid
|
||||||
|
if (!sourceModel()->hasChildren(index))
|
||||||
|
return false;
|
||||||
|
if (!m_hideReimplemented)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (int i = 0; i < sourceModel()->rowCount(index); ++i) {
|
||||||
|
const QModelIndex child = sourceModel()->index(i, 0, index);
|
||||||
|
if (!child.data(InsertVirtualMethodsDialog::Implemented).toBool())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_hideReimplemented)
|
||||||
|
return !index.data(InsertVirtualMethodsDialog::Implemented).toBool();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hideReimplemented() const
|
||||||
|
{
|
||||||
|
return m_hideReimplemented;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHideReimplementedFunctions(bool show)
|
||||||
|
{
|
||||||
|
m_hideReimplemented = show;
|
||||||
|
invalidateFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_hideReimplemented;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
InsertVirtualMethodsDialog::InsertVirtualMethodsDialog(QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
, m_view(0)
|
||||||
|
, m_hideReimplementedFunctions(0)
|
||||||
|
, m_insertMode(0)
|
||||||
|
, m_virtualKeyword(0)
|
||||||
|
, m_buttons(0)
|
||||||
|
, m_hasImplementationFile(false)
|
||||||
|
, m_hasReimplementedFunctions(false)
|
||||||
|
, m_implementationMode(ModeOnlyDeclarations)
|
||||||
|
, m_insertKeywordVirtual(false)
|
||||||
|
, classFunctionModel(new QStandardItemModel(this))
|
||||||
|
, classFunctionFilterModel(new InsertVirtualMethodsFilterModel(this))
|
||||||
|
{
|
||||||
|
classFunctionFilterModel->setSourceModel(classFunctionModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertVirtualMethodsDialog::initGui()
|
||||||
|
{
|
||||||
|
if (m_view)
|
||||||
|
return;
|
||||||
|
|
||||||
|
setWindowTitle(tr("Insert Virtual Functions"));
|
||||||
|
QVBoxLayout *globalVerticalLayout = new QVBoxLayout;
|
||||||
|
|
||||||
|
// View
|
||||||
|
QGroupBox *groupBoxView = new QGroupBox(tr("&Functions to insert:"), this);
|
||||||
|
QVBoxLayout *groupBoxViewLayout = new QVBoxLayout(groupBoxView);
|
||||||
|
m_view = new QTreeView(this);
|
||||||
|
m_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
|
m_view->setHeaderHidden(true);
|
||||||
|
groupBoxViewLayout->addWidget(m_view);
|
||||||
|
m_hideReimplementedFunctions =
|
||||||
|
new QCheckBox(tr("&Hide already implemented functions of current class"), this);
|
||||||
|
groupBoxViewLayout->addWidget(m_hideReimplementedFunctions);
|
||||||
|
|
||||||
|
// Insertion options
|
||||||
|
QGroupBox *groupBoxImplementation = new QGroupBox(tr("&Insertion options:"), this);
|
||||||
|
QVBoxLayout *groupBoxImplementationLayout = new QVBoxLayout(groupBoxImplementation);
|
||||||
|
m_insertMode = new QComboBox(this);
|
||||||
|
m_insertMode->addItem(tr("Insert only declarations"), ModeOnlyDeclarations);
|
||||||
|
m_insertMode->addItem(tr("Insert definitions inside class"), ModeInsideClass);
|
||||||
|
m_insertMode->addItem(tr("Insert definitions outside class"), ModeOutsideClass);
|
||||||
|
m_insertMode->addItem(tr("Insert definitions in implementation file"), ModeImplementationFile);
|
||||||
|
m_virtualKeyword = new QCheckBox(tr("&Add keyword 'virtual' to function declaration"), this);
|
||||||
|
groupBoxImplementationLayout->addWidget(m_insertMode);
|
||||||
|
groupBoxImplementationLayout->addWidget(m_virtualKeyword);
|
||||||
|
groupBoxImplementationLayout->addStretch(99);
|
||||||
|
|
||||||
|
// Bottom button box
|
||||||
|
m_buttons = new QDialogButtonBox(this);
|
||||||
|
m_buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
|
connect(m_buttons, SIGNAL(accepted()), this, SLOT(accept()));
|
||||||
|
connect(m_buttons, SIGNAL(rejected()), this, SLOT(reject()));
|
||||||
|
|
||||||
|
globalVerticalLayout->addWidget(groupBoxView, 9);
|
||||||
|
globalVerticalLayout->addWidget(groupBoxImplementation, 0);
|
||||||
|
globalVerticalLayout->addWidget(m_buttons, 0);
|
||||||
|
setLayout(globalVerticalLayout);
|
||||||
|
|
||||||
|
connect(classFunctionModel, SIGNAL(itemChanged(QStandardItem *)),
|
||||||
|
this, SLOT(updateCheckBoxes(QStandardItem *)));
|
||||||
|
connect(m_hideReimplementedFunctions, SIGNAL(toggled(bool)),
|
||||||
|
this, SLOT(setHideReimplementedFunctions(bool)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertVirtualMethodsDialog::initData()
|
||||||
|
{
|
||||||
|
m_insertKeywordVirtual = Core::ICore::settings()->value(
|
||||||
|
QLatin1String("QuickFix/InsertVirtualMethods/insertKeywordVirtual"),
|
||||||
|
false).toBool();
|
||||||
|
m_implementationMode = static_cast<InsertVirtualMethodsDialog::ImplementationMode>(
|
||||||
|
Core::ICore::settings()->value(
|
||||||
|
QLatin1String("QuickFix/InsertVirtualMethods/implementationMode"), 1).toInt());
|
||||||
|
m_hideReimplementedFunctions->setChecked(
|
||||||
|
Core::ICore::settings()->value(
|
||||||
|
QLatin1String("QuickFix/InsertVirtualMethods/hideReimplementedFunctions"),
|
||||||
|
false).toBool());
|
||||||
|
|
||||||
|
m_view->setModel(classFunctionFilterModel);
|
||||||
|
m_expansionStateNormal.clear();
|
||||||
|
m_expansionStateReimp.clear();
|
||||||
|
m_hideReimplementedFunctions->setVisible(m_hasReimplementedFunctions);
|
||||||
|
m_virtualKeyword->setChecked(m_insertKeywordVirtual);
|
||||||
|
m_insertMode->setCurrentIndex(m_insertMode->findData(m_implementationMode));
|
||||||
|
|
||||||
|
setHideReimplementedFunctions(m_hideReimplementedFunctions->isChecked());
|
||||||
|
|
||||||
|
if (m_hasImplementationFile) {
|
||||||
|
if (m_insertMode->count() == 3) {
|
||||||
|
m_insertMode->addItem(tr("Insert definitions in implementation file"),
|
||||||
|
ModeImplementationFile);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (m_insertMode->count() == 4)
|
||||||
|
m_insertMode->removeItem(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InsertVirtualMethodsDialog::gather()
|
||||||
|
{
|
||||||
|
initGui();
|
||||||
|
initData();
|
||||||
|
|
||||||
|
// Expand the dialog a little bit
|
||||||
|
adjustSize();
|
||||||
|
resize(size() * 1.5);
|
||||||
|
|
||||||
|
QPointer<InsertVirtualMethodsDialog> that(this);
|
||||||
|
const int ret = exec();
|
||||||
|
if (!that)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_implementationMode = implementationMode();
|
||||||
|
m_insertKeywordVirtual = insertKeywordVirtual();
|
||||||
|
return (ret == QDialog::Accepted);
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertVirtualMethodsDialog::ImplementationMode
|
||||||
|
InsertVirtualMethodsDialog::implementationMode() const
|
||||||
|
{
|
||||||
|
return static_cast<InsertVirtualMethodsDialog::ImplementationMode>(
|
||||||
|
m_insertMode->itemData(m_insertMode->currentIndex()).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertVirtualMethodsDialog::setImplementationsMode(InsertVirtualMethodsDialog::ImplementationMode mode)
|
||||||
|
{
|
||||||
|
m_implementationMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InsertVirtualMethodsDialog::insertKeywordVirtual() const
|
||||||
|
{
|
||||||
|
return m_virtualKeyword->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertVirtualMethodsDialog::setInsertKeywordVirtual(bool insert)
|
||||||
|
{
|
||||||
|
m_insertKeywordVirtual = insert;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertVirtualMethodsDialog::setHasImplementationFile(bool file)
|
||||||
|
{
|
||||||
|
m_hasImplementationFile = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertVirtualMethodsDialog::setHasReimplementedFunctions(bool functions)
|
||||||
|
{
|
||||||
|
m_hasReimplementedFunctions = functions;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InsertVirtualMethodsDialog::hideReimplementedFunctions() const
|
||||||
|
{
|
||||||
|
// Safty check necessary because of testing class
|
||||||
|
return (m_hideReimplementedFunctions && m_hideReimplementedFunctions->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertVirtualMethodsDialog::updateCheckBoxes(QStandardItem *item)
|
||||||
|
{
|
||||||
|
if (item->hasChildren()) {
|
||||||
|
const Qt::CheckState state = item->checkState();
|
||||||
|
if (!item->isCheckable() || state == Qt::PartiallyChecked)
|
||||||
|
return;
|
||||||
|
for (int i = 0; i < item->rowCount(); ++i) {
|
||||||
|
if (item->child(i, 0)->isCheckable())
|
||||||
|
item->child(i, 0)->setCheckState(state);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
QStandardItem *parent = item->parent();
|
||||||
|
if (!parent->isCheckable())
|
||||||
|
return;
|
||||||
|
const Qt::CheckState state = item->checkState();
|
||||||
|
for (int i = 0; i < parent->rowCount(); ++i) {
|
||||||
|
if (state != parent->child(i, 0)->checkState()) {
|
||||||
|
parent->setCheckState(Qt::PartiallyChecked);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parent->setCheckState(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertVirtualMethodsDialog::setHideReimplementedFunctions(bool hide)
|
||||||
|
{
|
||||||
|
InsertVirtualMethodsFilterModel *model =
|
||||||
|
qobject_cast<InsertVirtualMethodsFilterModel *>(classFunctionFilterModel);
|
||||||
|
|
||||||
|
if (m_expansionStateNormal.isEmpty() && m_expansionStateReimp.isEmpty()) {
|
||||||
|
model->setHideReimplementedFunctions(hide);
|
||||||
|
m_view->expandAll();
|
||||||
|
saveExpansionState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model->hideReimplemented() == hide)
|
||||||
|
return;
|
||||||
|
|
||||||
|
saveExpansionState();
|
||||||
|
model->setHideReimplementedFunctions(hide);
|
||||||
|
restoreExpansionState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertVirtualMethodsDialog::saveExpansionState()
|
||||||
|
{
|
||||||
|
InsertVirtualMethodsFilterModel *model =
|
||||||
|
qobject_cast<InsertVirtualMethodsFilterModel *>(classFunctionFilterModel);
|
||||||
|
|
||||||
|
QList<bool> &state = model->hideReimplemented() ? m_expansionStateReimp
|
||||||
|
: m_expansionStateNormal;
|
||||||
|
state.clear();
|
||||||
|
for (int i = 0; i < model->rowCount(); ++i)
|
||||||
|
state << m_view->isExpanded(model->index(i, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertVirtualMethodsDialog::restoreExpansionState()
|
||||||
|
{
|
||||||
|
InsertVirtualMethodsFilterModel *model =
|
||||||
|
qobject_cast<InsertVirtualMethodsFilterModel *>(classFunctionFilterModel);
|
||||||
|
|
||||||
|
const QList<bool> &state = model->hideReimplemented() ? m_expansionStateReimp
|
||||||
|
: m_expansionStateNormal;
|
||||||
|
const int stateCount = state.count();
|
||||||
|
for (int i = 0; i < model->rowCount(); ++i) {
|
||||||
|
if (i < stateCount && !state.at(i)) {
|
||||||
|
m_view->collapse(model->index(i, 0));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m_view->expand(model->index(i, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertVirtualMethods::InsertVirtualMethods(InsertVirtualMethodsDialog *dialog)
|
||||||
|
: m_dialog(dialog)
|
||||||
|
{}
|
||||||
|
|
||||||
|
InsertVirtualMethods::~InsertVirtualMethods()
|
||||||
|
{
|
||||||
|
if (m_dialog)
|
||||||
|
m_dialog->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertVirtualMethods::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
|
||||||
|
{
|
||||||
|
InsertVirtualMethodsOp *op = new InsertVirtualMethodsOp(interface, m_dialog);
|
||||||
|
if (op->isValid())
|
||||||
|
result.append(QuickFixOperation::Ptr(op));
|
||||||
|
else
|
||||||
|
delete op;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "cppquickfixes.moc"
|
||||||
|
|||||||
@@ -36,9 +36,18 @@
|
|||||||
|
|
||||||
#include <extensionsystem/iplugin.h>
|
#include <extensionsystem/iplugin.h>
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
|
class QCheckBox;
|
||||||
|
class QComboBox;
|
||||||
|
class QDialogButtonBox;
|
||||||
|
class QStandardItem;
|
||||||
|
class QSortFilterProxyModel;
|
||||||
|
class QStandardItemModel;
|
||||||
class QString;
|
class QString;
|
||||||
|
class QTreeView;
|
||||||
template <class> class QList;
|
template <class> class QList;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
@@ -482,6 +491,78 @@ public:
|
|||||||
void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result);
|
void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Insert (pure) virtual functions of a base class.
|
||||||
|
*/
|
||||||
|
class InsertVirtualMethodsDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum CustomItemRoles {
|
||||||
|
ClassOrFunction = Qt::UserRole + 1,
|
||||||
|
Implemented = Qt::UserRole + 2,
|
||||||
|
PureVirtual = Qt::UserRole + 3,
|
||||||
|
AccessSpec = Qt::UserRole + 4
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ImplementationMode {
|
||||||
|
ModeOnlyDeclarations = 0x00000001,
|
||||||
|
ModeInsideClass = 0x00000002,
|
||||||
|
ModeOutsideClass = 0x00000004,
|
||||||
|
ModeImplementationFile = 0x00000008
|
||||||
|
};
|
||||||
|
|
||||||
|
InsertVirtualMethodsDialog(QWidget *parent = 0);
|
||||||
|
void initGui();
|
||||||
|
void initData();
|
||||||
|
virtual ImplementationMode implementationMode() const;
|
||||||
|
void setImplementationsMode(ImplementationMode mode);
|
||||||
|
virtual bool insertKeywordVirtual() const;
|
||||||
|
void setInsertKeywordVirtual(bool insert);
|
||||||
|
void setHasImplementationFile(bool file);
|
||||||
|
void setHasReimplementedFunctions(bool functions);
|
||||||
|
bool hideReimplementedFunctions() const;
|
||||||
|
virtual bool gather();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateCheckBoxes(QStandardItem *item);
|
||||||
|
void setHideReimplementedFunctions(bool hide);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTreeView *m_view;
|
||||||
|
QCheckBox *m_hideReimplementedFunctions;
|
||||||
|
QComboBox *m_insertMode;
|
||||||
|
QCheckBox *m_virtualKeyword;
|
||||||
|
QDialogButtonBox *m_buttons;
|
||||||
|
QList<bool> m_expansionStateNormal;
|
||||||
|
QList<bool> m_expansionStateReimp;
|
||||||
|
bool m_hasImplementationFile;
|
||||||
|
bool m_hasReimplementedFunctions;
|
||||||
|
|
||||||
|
void saveExpansionState();
|
||||||
|
void restoreExpansionState();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ImplementationMode m_implementationMode;
|
||||||
|
bool m_insertKeywordVirtual;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QStandardItemModel *classFunctionModel;
|
||||||
|
QSortFilterProxyModel *classFunctionFilterModel;
|
||||||
|
};
|
||||||
|
|
||||||
|
class InsertVirtualMethods: public CppQuickFixFactory
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
InsertVirtualMethods(InsertVirtualMethodsDialog *dialog = new InsertVirtualMethodsDialog);
|
||||||
|
~InsertVirtualMethods();
|
||||||
|
void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result);
|
||||||
|
|
||||||
|
private:
|
||||||
|
InsertVirtualMethodsDialog *m_dialog;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace CppEditor
|
} // namespace CppEditor
|
||||||
|
|
||||||
|
|||||||
@@ -42,33 +42,6 @@ using namespace CppTools;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static QString generate(InsertionPointLocator::AccessSpec xsSpec)
|
|
||||||
{
|
|
||||||
switch (xsSpec) {
|
|
||||||
default:
|
|
||||||
case InsertionPointLocator::Public:
|
|
||||||
return QLatin1String("public:\n");
|
|
||||||
|
|
||||||
case InsertionPointLocator::Protected:
|
|
||||||
return QLatin1String("protected:\n");
|
|
||||||
|
|
||||||
case InsertionPointLocator::Private:
|
|
||||||
return QLatin1String("private:\n");
|
|
||||||
|
|
||||||
case InsertionPointLocator::PublicSlot:
|
|
||||||
return QLatin1String("public slots:\n");
|
|
||||||
|
|
||||||
case InsertionPointLocator::ProtectedSlot:
|
|
||||||
return QLatin1String("protected slots:\n");
|
|
||||||
|
|
||||||
case InsertionPointLocator::PrivateSlot:
|
|
||||||
return QLatin1String("private slots:\n");
|
|
||||||
|
|
||||||
case InsertionPointLocator::Signals:
|
|
||||||
return QLatin1String("signals:\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ordering(InsertionPointLocator::AccessSpec xsSpec)
|
static int ordering(InsertionPointLocator::AccessSpec xsSpec)
|
||||||
{
|
{
|
||||||
static QList<InsertionPointLocator::AccessSpec> order = QList<InsertionPointLocator::AccessSpec>()
|
static QList<InsertionPointLocator::AccessSpec> order = QList<InsertionPointLocator::AccessSpec>()
|
||||||
@@ -161,7 +134,7 @@ protected:
|
|||||||
if (needsLeadingEmptyLine)
|
if (needsLeadingEmptyLine)
|
||||||
prefix += QLatin1String("\n");
|
prefix += QLatin1String("\n");
|
||||||
if (needsPrefix)
|
if (needsPrefix)
|
||||||
prefix += generate(_xsSpec);
|
prefix += InsertionPointLocator::accessSpecToString(_xsSpec);
|
||||||
|
|
||||||
QString suffix;
|
QString suffix;
|
||||||
if (needsSuffix)
|
if (needsSuffix)
|
||||||
@@ -299,6 +272,33 @@ InsertionLocation::InsertionLocation(const QString &fileName,
|
|||||||
, m_column(column)
|
, m_column(column)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
QString InsertionPointLocator::accessSpecToString(InsertionPointLocator::AccessSpec xsSpec)
|
||||||
|
{
|
||||||
|
switch (xsSpec) {
|
||||||
|
default:
|
||||||
|
case InsertionPointLocator::Public:
|
||||||
|
return QLatin1String("public:\n");
|
||||||
|
|
||||||
|
case InsertionPointLocator::Protected:
|
||||||
|
return QLatin1String("protected:\n");
|
||||||
|
|
||||||
|
case InsertionPointLocator::Private:
|
||||||
|
return QLatin1String("private:\n");
|
||||||
|
|
||||||
|
case InsertionPointLocator::PublicSlot:
|
||||||
|
return QLatin1String("public slots:\n");
|
||||||
|
|
||||||
|
case InsertionPointLocator::ProtectedSlot:
|
||||||
|
return QLatin1String("protected slots:\n");
|
||||||
|
|
||||||
|
case InsertionPointLocator::PrivateSlot:
|
||||||
|
return QLatin1String("private slots:\n");
|
||||||
|
|
||||||
|
case InsertionPointLocator::Signals:
|
||||||
|
return QLatin1String("signals:\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
InsertionPointLocator::InsertionPointLocator(const CppRefactoringChanges &refactoringChanges)
|
InsertionPointLocator::InsertionPointLocator(const CppRefactoringChanges &refactoringChanges)
|
||||||
: m_refactoringChanges(refactoringChanges)
|
: m_refactoringChanges(refactoringChanges)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ public:
|
|||||||
ProtectedSlot = Protected | SlotBit,
|
ProtectedSlot = Protected | SlotBit,
|
||||||
PrivateSlot = Private | SlotBit
|
PrivateSlot = Private | SlotBit
|
||||||
};
|
};
|
||||||
|
static QString accessSpecToString(InsertionPointLocator::AccessSpec xsSpec);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InsertionPointLocator(const CppRefactoringChanges &refactoringChanges);
|
InsertionPointLocator(const CppRefactoringChanges &refactoringChanges);
|
||||||
|
|||||||
Reference in New Issue
Block a user