Commit c6a7fb8c authored by Nikolai Kosjar's avatar Nikolai Kosjar
Browse files

C++: Refactor quick fixes



 - Put declarations into quickfixes.h to simplify testing
 - Give the factories more meaningful names

Change-Id: If74c29a8c17819d5369ffa3df94d146b14e53af9
Reviewed-by: default avatarErik Verbruggen <erik.verbruggen@digia.com>
parent 986fc8bf
...@@ -22,6 +22,7 @@ HEADERS += cppplugin.h \ ...@@ -22,6 +22,7 @@ HEADERS += cppplugin.h \
cppinsertqtpropertymembers.h \ cppinsertqtpropertymembers.h \
cppquickfixassistant.h \ cppquickfixassistant.h \
cppquickfix.h \ cppquickfix.h \
cppquickfixes.h \
cppfunctiondecldeflink.h cppfunctiondecldeflink.h
SOURCES += cppplugin.cpp \ SOURCES += cppplugin.cpp \
......
...@@ -54,6 +54,7 @@ QtcPlugin { ...@@ -54,6 +54,7 @@ QtcPlugin {
"cppquickfixassistant.cpp", "cppquickfixassistant.cpp",
"cppquickfixassistant.h", "cppquickfixassistant.h",
"cppquickfixes.cpp", "cppquickfixes.cpp",
"cppquickfixes.h",
"cppsnippetprovider.cpp", "cppsnippetprovider.cpp",
"cppsnippetprovider.h", "cppsnippetprovider.h",
"cpptypehierarchy.cpp", "cpptypehierarchy.cpp",
......
...@@ -151,7 +151,7 @@ Class *isMemberFunction(const LookupContext &context, Function *function) ...@@ -151,7 +151,7 @@ Class *isMemberFunction(const LookupContext &context, Function *function)
} // anonymous namespace } // anonymous namespace
void DeclFromDef::match(const CppQuickFixInterface &interface, QuickFixOperations &result) void InsertDeclFromDef::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{ {
const QList<AST *> &path = interface->path(); const QList<AST *> &path = interface->path();
CppRefactoringFilePtr file = interface->currentFile(); CppRefactoringFilePtr file = interface->currentFile();
...@@ -287,7 +287,7 @@ private: ...@@ -287,7 +287,7 @@ private:
} // anonymous namespace } // anonymous namespace
void DefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOperations &result) void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{ {
const QList<AST *> &path = interface->path(); const QList<AST *> &path = interface->path();
...@@ -319,11 +319,11 @@ void DefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOperation ...@@ -319,11 +319,11 @@ void DefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOperation
namespace { namespace {
class GetterSetterOperation : public CppQuickFixOperation class GenerateGetterSetterOperation : public CppQuickFixOperation
{ {
public: public:
GetterSetterOperation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, GenerateGetterSetterOperation(const QSharedPointer<const CppQuickFixAssistInterface> &interface,
bool testMode = false) bool testMode = false)
: CppQuickFixOperation(interface) : CppQuickFixOperation(interface)
, m_variableName(0) , m_variableName(0)
, m_declaratorId(0) , m_declaratorId(0)
...@@ -602,9 +602,9 @@ public: ...@@ -602,9 +602,9 @@ public:
} // namespace } // namespace
void GetterSetter::match(const CppQuickFixInterface &interface, QuickFixOperations &result) void GenerateGetterSetter::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{ {
GetterSetterOperation *op = new GetterSetterOperation(interface, m_testMode); GenerateGetterSetterOperation *op = new GenerateGetterSetterOperation(interface, m_testMode);
if (op->isValid()) if (op->isValid())
result.append(CppQuickFixOperation::Ptr(op)); result.append(CppQuickFixOperation::Ptr(op));
else else
......
...@@ -35,13 +35,13 @@ ...@@ -35,13 +35,13 @@
namespace CppEditor { namespace CppEditor {
namespace Internal { namespace Internal {
class DeclFromDef: public CppQuickFixFactory class InsertDeclFromDef: public CppQuickFixFactory
{ {
public: public:
void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result); void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result);
}; };
class DefFromDecl: public CppQuickFixFactory class InsertDefFromDecl: public CppQuickFixFactory
{ {
public: public:
void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result); void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result);
...@@ -53,10 +53,10 @@ public: ...@@ -53,10 +53,10 @@ public:
void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result); void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result);
}; };
class GetterSetter : public CppQuickFixFactory class GenerateGetterSetter : public CppQuickFixFactory
{ {
public: public:
GetterSetter(const bool testMode = false) : m_testMode(testMode) {} GenerateGetterSetter(const bool testMode = false) : m_testMode(testMode) {}
void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result); void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result);
private: private:
const bool m_testMode; const bool m_testMode;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "cpptypehierarchy.h" #include "cpptypehierarchy.h"
#include "cppsnippetprovider.h" #include "cppsnippetprovider.h"
#include "cppquickfixassistant.h" #include "cppquickfixassistant.h"
#include "cppquickfixes.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
...@@ -187,7 +188,7 @@ bool CppPlugin::initialize(const QStringList & /*arguments*/, QString *errorMess ...@@ -187,7 +188,7 @@ bool CppPlugin::initialize(const QStringList & /*arguments*/, QString *errorMess
m_quickFixProvider = new CppQuickFixAssistProvider; m_quickFixProvider = new CppQuickFixAssistProvider;
addAutoReleasedObject(m_quickFixProvider); addAutoReleasedObject(m_quickFixProvider);
registerQuickFixes(this); CppEditor::Internal::registerQuickFixes(this);
QObject *core = Core::ICore::instance(); QObject *core = Core::ICore::instance();
CppFileWizard::BaseFileWizardParameters wizardParameters(Core::IWizard::FileWizard); CppFileWizard::BaseFileWizardParameters wizardParameters(Core::IWizard::FileWizard);
......
...@@ -90,18 +90,18 @@ private slots: ...@@ -90,18 +90,18 @@ private slots:
#ifdef WITH_TESTS #ifdef WITH_TESTS
private slots: // quickfix tests private slots: // quickfix tests
void test_quickfix_GetterSetter_basicGetterWithPrefix(); void test_quickfix_GenerateGetterSetter_basicGetterWithPrefix();
void test_quickfix_GetterSetter_basicGetterWithoutPrefix(); void test_quickfix_GenerateGetterSetter_basicGetterWithoutPrefix();
void test_quickfix_GetterSetter_customType(); void test_quickfix_GenerateGetterSetter_customType();
void test_quickfix_GetterSetter_constMember(); void test_quickfix_GenerateGetterSetter_constMember();
void test_quickfix_GetterSetter_pointerToNonConst(); void test_quickfix_GenerateGetterSetter_pointerToNonConst();
void test_quickfix_GetterSetter_pointerToConst(); void test_quickfix_GenerateGetterSetter_pointerToConst();
void test_quickfix_GetterSetter_staticMember(); void test_quickfix_GenerateGetterSetter_staticMember();
void test_quickfix_GetterSetter_secondDeclarator(); void test_quickfix_GenerateGetterSetter_secondDeclarator();
void test_quickfix_GetterSetter_triggeringRightAfterPointerSign(); void test_quickfix_GenerateGetterSetter_triggeringRightAfterPointerSign();
void test_quickfix_GetterSetter_notTriggeringOnMemberFunction(); void test_quickfix_GenerateGetterSetter_notTriggeringOnMemberFunction();
void test_quickfix_GetterSetter_notTriggeringOnMemberArray(); void test_quickfix_GenerateGetterSetter_notTriggeringOnMemberArray();
void test_quickfix_GetterSetter_notTriggeringWhenGetterOrSetterExist(); void test_quickfix_GenerateGetterSetter_notTriggeringWhenGetterOrSetterExist();
#endif // WITH_TESTS #endif // WITH_TESTS
private: private:
......
...@@ -194,7 +194,7 @@ void TestCase::run(CppQuickFixFactory *factory, const QByteArray &expected, ...@@ -194,7 +194,7 @@ void TestCase::run(CppQuickFixFactory *factory, const QByteArray &expected,
/// 1. If the name does not start with ("m_" or "_") and does not /// 1. If the name does not start with ("m_" or "_") and does not
/// end with "_", we are forced to prefix the getter with "get". /// end with "_", we are forced to prefix the getter with "get".
/// 2. Setter: Use pass by value on integer/float and pointer types. /// 2. Setter: Use pass by value on integer/float and pointer types.
void CppPlugin::test_quickfix_GetterSetter_basicGetterWithPrefix() void CppPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefix()
{ {
TestCase data("\n" TestCase data("\n"
"class Something\n" "class Something\n"
...@@ -224,14 +224,14 @@ void CppPlugin::test_quickfix_GetterSetter_basicGetterWithPrefix() ...@@ -224,14 +224,14 @@ void CppPlugin::test_quickfix_GetterSetter_basicGetterWithPrefix()
"\n" "\n"
; ;
GetterSetter factory(/*testMode=*/ true); GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected); data.run(&factory, expected);
} }
/// Checks: /// Checks:
/// 1. Getter: "get" prefix is not necessary. /// 1. Getter: "get" prefix is not necessary.
/// 2. Setter: Parameter name is base name. /// 2. Setter: Parameter name is base name.
void CppPlugin::test_quickfix_GetterSetter_basicGetterWithoutPrefix() void CppPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithoutPrefix()
{ {
TestCase data("\n" TestCase data("\n"
"class Something\n" "class Something\n"
...@@ -261,13 +261,13 @@ void CppPlugin::test_quickfix_GetterSetter_basicGetterWithoutPrefix() ...@@ -261,13 +261,13 @@ void CppPlugin::test_quickfix_GetterSetter_basicGetterWithoutPrefix()
"\n" "\n"
; ;
GetterSetter factory(/*testMode=*/ true); GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected); data.run(&factory, expected);
} }
/// Check: Setter: Use pass by reference for parameters which /// Check: Setter: Use pass by reference for parameters which
/// are not integer, float or pointers. /// are not integer, float or pointers.
void CppPlugin::test_quickfix_GetterSetter_customType() void CppPlugin::test_quickfix_GenerateGetterSetter_customType()
{ {
TestCase data("\n" TestCase data("\n"
"class Something\n" "class Something\n"
...@@ -297,14 +297,14 @@ void CppPlugin::test_quickfix_GetterSetter_customType() ...@@ -297,14 +297,14 @@ void CppPlugin::test_quickfix_GetterSetter_customType()
"\n" "\n"
; ;
GetterSetter factory(/*testMode=*/ true); GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected); data.run(&factory, expected);
} }
/// Checks: /// Checks:
/// 1. Setter: No setter is generated for const members. /// 1. Setter: No setter is generated for const members.
/// 2. Getter: Return a non-const type since it pass by value anyway. /// 2. Getter: Return a non-const type since it pass by value anyway.
void CppPlugin::test_quickfix_GetterSetter_constMember() void CppPlugin::test_quickfix_GenerateGetterSetter_constMember()
{ {
TestCase data("\n" TestCase data("\n"
"class Something\n" "class Something\n"
...@@ -328,12 +328,12 @@ void CppPlugin::test_quickfix_GetterSetter_constMember() ...@@ -328,12 +328,12 @@ void CppPlugin::test_quickfix_GetterSetter_constMember()
"\n" "\n"
; ;
GetterSetter factory(/*testMode=*/ true); GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected); data.run(&factory, expected);
} }
/// Checks: No special treatment for pointer to non const. /// Checks: No special treatment for pointer to non const.
void CppPlugin::test_quickfix_GetterSetter_pointerToNonConst() void CppPlugin::test_quickfix_GenerateGetterSetter_pointerToNonConst()
{ {
TestCase data("\n" TestCase data("\n"
"class Something\n" "class Something\n"
...@@ -363,12 +363,12 @@ void CppPlugin::test_quickfix_GetterSetter_pointerToNonConst() ...@@ -363,12 +363,12 @@ void CppPlugin::test_quickfix_GetterSetter_pointerToNonConst()
"\n" "\n"
; ;
GetterSetter factory(/*testMode=*/ true); GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected); data.run(&factory, expected);
} }
/// Checks: No special treatment for pointer to const. /// Checks: No special treatment for pointer to const.
void CppPlugin::test_quickfix_GetterSetter_pointerToConst() void CppPlugin::test_quickfix_GenerateGetterSetter_pointerToConst()
{ {
TestCase data("\n" TestCase data("\n"
"class Something\n" "class Something\n"
...@@ -398,14 +398,14 @@ void CppPlugin::test_quickfix_GetterSetter_pointerToConst() ...@@ -398,14 +398,14 @@ void CppPlugin::test_quickfix_GetterSetter_pointerToConst()
"\n" "\n"
; ;
GetterSetter factory(/*testMode=*/ true); GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected); data.run(&factory, expected);
} }
/// Checks: /// Checks:
/// 1. Setter: Setter is a static function. /// 1. Setter: Setter is a static function.
/// 2. Getter: Getter is a static, non const function. /// 2. Getter: Getter is a static, non const function.
void CppPlugin::test_quickfix_GetterSetter_staticMember() void CppPlugin::test_quickfix_GenerateGetterSetter_staticMember()
{ {
TestCase data("\n" TestCase data("\n"
"class Something\n" "class Something\n"
...@@ -435,12 +435,12 @@ void CppPlugin::test_quickfix_GetterSetter_staticMember() ...@@ -435,12 +435,12 @@ void CppPlugin::test_quickfix_GetterSetter_staticMember()
"\n" "\n"
; ;
GetterSetter factory(/*testMode=*/ true); GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected); data.run(&factory, expected);
} }
/// Check: Check if it works on the second declarator /// Check: Check if it works on the second declarator
void CppPlugin::test_quickfix_GetterSetter_secondDeclarator() void CppPlugin::test_quickfix_GenerateGetterSetter_secondDeclarator()
{ {
TestCase data("\n" TestCase data("\n"
"class Something\n" "class Something\n"
...@@ -470,12 +470,12 @@ void CppPlugin::test_quickfix_GetterSetter_secondDeclarator() ...@@ -470,12 +470,12 @@ void CppPlugin::test_quickfix_GetterSetter_secondDeclarator()
"\n" "\n"
; ;
GetterSetter factory(/*testMode=*/ true); GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected); data.run(&factory, expected);
} }
/// Check: Quick fix is offered for "int *@it;" ('@' denotes the text cursor position) /// Check: Quick fix is offered for "int *@it;" ('@' denotes the text cursor position)
void CppPlugin::test_quickfix_GetterSetter_triggeringRightAfterPointerSign() void CppPlugin::test_quickfix_GenerateGetterSetter_triggeringRightAfterPointerSign()
{ {
TestCase data("\n" TestCase data("\n"
"class Something\n" "class Something\n"
...@@ -505,33 +505,33 @@ void CppPlugin::test_quickfix_GetterSetter_triggeringRightAfterPointerSign() ...@@ -505,33 +505,33 @@ void CppPlugin::test_quickfix_GetterSetter_triggeringRightAfterPointerSign()
"\n" "\n"
; ;
GetterSetter factory(/*testMode=*/ true); GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected); data.run(&factory, expected);
} }
/// Check: Quick fix is not triggered on a member function. /// Check: Quick fix is not triggered on a member function.
void CppPlugin::test_quickfix_GetterSetter_notTriggeringOnMemberFunction() void CppPlugin::test_quickfix_GenerateGetterSetter_notTriggeringOnMemberFunction()
{ {
TestCase data("class Something { void @f(); };"); TestCase data("class Something { void @f(); };");
QByteArray expected = data.originalText; QByteArray expected = data.originalText;
GetterSetter factory(/*testMode=*/ true); GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected, /*changesExpected=*/ false); data.run(&factory, expected, /*changesExpected=*/ false);
} }
/// Check: Quick fix is not triggered on an member array; /// Check: Quick fix is not triggered on an member array;
void CppPlugin::test_quickfix_GetterSetter_notTriggeringOnMemberArray() void CppPlugin::test_quickfix_GenerateGetterSetter_notTriggeringOnMemberArray()
{ {
TestCase data("class Something { void @a[10]; };"); TestCase data("class Something { void @a[10]; };");
QByteArray expected = data.originalText; QByteArray expected = data.originalText;
GetterSetter factory(/*testMode=*/ true); GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected, /*changesExpected=*/ false); data.run(&factory, expected, /*changesExpected=*/ false);
} }
/// Check: Do not offer the quick fix if there is already a member with the /// Check: Do not offer the quick fix if there is already a member with the
/// getter or setter name we would generate. /// getter or setter name we would generate.
void CppPlugin::test_quickfix_GetterSetter_notTriggeringWhenGetterOrSetterExist() void CppPlugin::test_quickfix_GenerateGetterSetter_notTriggeringWhenGetterOrSetterExist()
{ {
TestCase data("\n" TestCase data("\n"
"class Something {\n" "class Something {\n"
...@@ -540,6 +540,6 @@ void CppPlugin::test_quickfix_GetterSetter_notTriggeringWhenGetterOrSetterExist( ...@@ -540,6 +540,6 @@ void CppPlugin::test_quickfix_GetterSetter_notTriggeringWhenGetterOrSetterExist(
"};\n"); "};\n");
QByteArray expected = data.originalText; QByteArray expected = data.originalText;
GetterSetter factory(/*testMode=*/ true); GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected, /*changesExpected=*/ false); data.run(&factory, expected, /*changesExpected=*/ false);
} }
This diff is collapsed.
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef CPPQUICKFIXES_H
#define CPPQUICKFIXES_H
#include "cppquickfix.h"
#include <cpptools/cpprefactoringchanges.h>
#include <extensionsystem/iplugin.h>
#include <AST.h>
#include <ASTMatcher.h>
QT_BEGIN_NAMESPACE
class QByteArray;
class QString;
template <class> class QList;
QT_END_NAMESPACE
using namespace CppTools;
using namespace CPlusPlus;
using namespace TextEditor;
namespace CppEditor {
namespace Internal {
void registerQuickFixes(ExtensionSystem::IPlugin *plugIn);
/*!
Adds an include for an undefined identifier.
Activates on: the undefined identifier
*/
class AddIncludeForUndefinedIdentifier : public CppQuickFixFactory
{
public:
void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
};
/*!
Can be triggered on a class forward declaration to add the matching #include.
Activates on: the name of a forward-declared class or struct
*/
class AddIncludeForForwardDeclaration: public CppQuickFixFactory
{
public:
void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
};
/*!
Rewrite
a op b
As
b flipop a
Activates on: <= < > >= == != && ||
*/
class FlipLogicalOperands: public CppQuickFixFactory
{
public:
void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
};
/*!
Rewrite
a op b -> !(a invop b)
(a op b) -> !(a invop b)
!(a op b) -> (a invob b)
Activates on: <= < > >= == !=
*/
class InverseLogicalComparison: public CppQuickFixFactory
{
public:
void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
};
/*!
Rewrite
!a && !b
As
!(a || b)
Activates on: &&
*/
class RewriteLogicalAnd: public CppQuickFixFactory
{
public:
void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
private:
ASTMatcher matcher;
};
/*!
Replace
"abcd"
QLatin1String("abcd")
QLatin1Literal("abcd")
With
@"abcd"
Activates on: the string literal, if the file type is a Objective-C(++) file.
*/
class ConvertCStringToNSString: public CppQuickFixFactory
{
public: