summaryrefslogtreecommitdiff
path: root/src/plugins/cppeditor
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@digia.com>2013-02-07 12:16:41 +0100
committerNikolai Kosjar <nikolai.kosjar@digia.com>2013-02-14 12:25:20 +0100
commitc6a7fb8ccf82ae69be615c4672a790229dff995c (patch)
tree5bfa9c05e573730450c519e670a95ab13288e4e8 /src/plugins/cppeditor
parent986fc8bfc93c87451c6532f61c407e3459feccc1 (diff)
downloadqt-creator-c6a7fb8ccf82ae69be615c4672a790229dff995c.tar.gz
C++: Refactor quick fixes
- Put declarations into quickfixes.h to simplify testing - Give the factories more meaningful names Change-Id: If74c29a8c17819d5369ffa3df94d146b14e53af9 Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
Diffstat (limited to 'src/plugins/cppeditor')
-rw-r--r--src/plugins/cppeditor/cppeditor.pro1
-rw-r--r--src/plugins/cppeditor/cppeditor.qbs1
-rw-r--r--src/plugins/cppeditor/cppinsertdecldef.cpp14
-rw-r--r--src/plugins/cppeditor/cppinsertdecldef.h8
-rw-r--r--src/plugins/cppeditor/cppplugin.cpp3
-rw-r--r--src/plugins/cppeditor/cppplugin.h24
-rw-r--r--src/plugins/cppeditor/cppquickfix_test.cpp48
-rw-r--r--src/plugins/cppeditor/cppquickfixes.cpp2981
-rw-r--r--src/plugins/cppeditor/cppquickfixes.h393
9 files changed, 1794 insertions, 1679 deletions
diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro
index 604246173b..b7fa70a6f7 100644
--- a/src/plugins/cppeditor/cppeditor.pro
+++ b/src/plugins/cppeditor/cppeditor.pro
@@ -22,6 +22,7 @@ HEADERS += cppplugin.h \
cppinsertqtpropertymembers.h \
cppquickfixassistant.h \
cppquickfix.h \
+ cppquickfixes.h \
cppfunctiondecldeflink.h
SOURCES += cppplugin.cpp \
diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs
index 7f92612944..96540ea650 100644
--- a/src/plugins/cppeditor/cppeditor.qbs
+++ b/src/plugins/cppeditor/cppeditor.qbs
@@ -54,6 +54,7 @@ QtcPlugin {
"cppquickfixassistant.cpp",
"cppquickfixassistant.h",
"cppquickfixes.cpp",
+ "cppquickfixes.h",
"cppsnippetprovider.cpp",
"cppsnippetprovider.h",
"cpptypehierarchy.cpp",
diff --git a/src/plugins/cppeditor/cppinsertdecldef.cpp b/src/plugins/cppeditor/cppinsertdecldef.cpp
index 2e8a788cad..cf534e9d21 100644
--- a/src/plugins/cppeditor/cppinsertdecldef.cpp
+++ b/src/plugins/cppeditor/cppinsertdecldef.cpp
@@ -151,7 +151,7 @@ Class *isMemberFunction(const LookupContext &context, Function *function)
} // anonymous namespace
-void DeclFromDef::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+void InsertDeclFromDef::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{
const QList<AST *> &path = interface->path();
CppRefactoringFilePtr file = interface->currentFile();
@@ -287,7 +287,7 @@ private:
} // anonymous namespace
-void DefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{
const QList<AST *> &path = interface->path();
@@ -319,11 +319,11 @@ void DefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOperation
namespace {
-class GetterSetterOperation : public CppQuickFixOperation
+class GenerateGetterSetterOperation : public CppQuickFixOperation
{
public:
- GetterSetterOperation(const QSharedPointer<const CppQuickFixAssistInterface> &interface,
- bool testMode = false)
+ GenerateGetterSetterOperation(const QSharedPointer<const CppQuickFixAssistInterface> &interface,
+ bool testMode = false)
: CppQuickFixOperation(interface)
, m_variableName(0)
, m_declaratorId(0)
@@ -602,9 +602,9 @@ public:
} // 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())
result.append(CppQuickFixOperation::Ptr(op));
else
diff --git a/src/plugins/cppeditor/cppinsertdecldef.h b/src/plugins/cppeditor/cppinsertdecldef.h
index 75d4488d69..d73dd67cd7 100644
--- a/src/plugins/cppeditor/cppinsertdecldef.h
+++ b/src/plugins/cppeditor/cppinsertdecldef.h
@@ -35,13 +35,13 @@
namespace CppEditor {
namespace Internal {
-class DeclFromDef: public CppQuickFixFactory
+class InsertDeclFromDef: public CppQuickFixFactory
{
public:
void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result);
};
-class DefFromDecl: public CppQuickFixFactory
+class InsertDefFromDecl: public CppQuickFixFactory
{
public:
void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result);
@@ -53,10 +53,10 @@ public:
void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result);
};
-class GetterSetter : public CppQuickFixFactory
+class GenerateGetterSetter : public CppQuickFixFactory
{
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);
private:
const bool m_testMode;
diff --git a/src/plugins/cppeditor/cppplugin.cpp b/src/plugins/cppeditor/cppplugin.cpp
index 0210d8a8df..eac6390c0b 100644
--- a/src/plugins/cppeditor/cppplugin.cpp
+++ b/src/plugins/cppeditor/cppplugin.cpp
@@ -38,6 +38,7 @@
#include "cpptypehierarchy.h"
#include "cppsnippetprovider.h"
#include "cppquickfixassistant.h"
+#include "cppquickfixes.h"
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
@@ -187,7 +188,7 @@ bool CppPlugin::initialize(const QStringList & /*arguments*/, QString *errorMess
m_quickFixProvider = new CppQuickFixAssistProvider;
addAutoReleasedObject(m_quickFixProvider);
- registerQuickFixes(this);
+ CppEditor::Internal::registerQuickFixes(this);
QObject *core = Core::ICore::instance();
CppFileWizard::BaseFileWizardParameters wizardParameters(Core::IWizard::FileWizard);
diff --git a/src/plugins/cppeditor/cppplugin.h b/src/plugins/cppeditor/cppplugin.h
index fca9c54de8..5f3b2f70c4 100644
--- a/src/plugins/cppeditor/cppplugin.h
+++ b/src/plugins/cppeditor/cppplugin.h
@@ -90,18 +90,18 @@ private slots:
#ifdef WITH_TESTS
private slots: // quickfix tests
- void test_quickfix_GetterSetter_basicGetterWithPrefix();
- void test_quickfix_GetterSetter_basicGetterWithoutPrefix();
- void test_quickfix_GetterSetter_customType();
- void test_quickfix_GetterSetter_constMember();
- void test_quickfix_GetterSetter_pointerToNonConst();
- void test_quickfix_GetterSetter_pointerToConst();
- void test_quickfix_GetterSetter_staticMember();
- void test_quickfix_GetterSetter_secondDeclarator();
- void test_quickfix_GetterSetter_triggeringRightAfterPointerSign();
- void test_quickfix_GetterSetter_notTriggeringOnMemberFunction();
- void test_quickfix_GetterSetter_notTriggeringOnMemberArray();
- void test_quickfix_GetterSetter_notTriggeringWhenGetterOrSetterExist();
+ void test_quickfix_GenerateGetterSetter_basicGetterWithPrefix();
+ void test_quickfix_GenerateGetterSetter_basicGetterWithoutPrefix();
+ void test_quickfix_GenerateGetterSetter_customType();
+ void test_quickfix_GenerateGetterSetter_constMember();
+ void test_quickfix_GenerateGetterSetter_pointerToNonConst();
+ void test_quickfix_GenerateGetterSetter_pointerToConst();
+ void test_quickfix_GenerateGetterSetter_staticMember();
+ void test_quickfix_GenerateGetterSetter_secondDeclarator();
+ void test_quickfix_GenerateGetterSetter_triggeringRightAfterPointerSign();
+ void test_quickfix_GenerateGetterSetter_notTriggeringOnMemberFunction();
+ void test_quickfix_GenerateGetterSetter_notTriggeringOnMemberArray();
+ void test_quickfix_GenerateGetterSetter_notTriggeringWhenGetterOrSetterExist();
#endif // WITH_TESTS
private:
diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp
index 45f49f66c0..f134043a8c 100644
--- a/src/plugins/cppeditor/cppquickfix_test.cpp
+++ b/src/plugins/cppeditor/cppquickfix_test.cpp
@@ -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
/// end with "_", we are forced to prefix the getter with "get".
/// 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"
"class Something\n"
@@ -224,14 +224,14 @@ void CppPlugin::test_quickfix_GetterSetter_basicGetterWithPrefix()
"\n"
;
- GetterSetter factory(/*testMode=*/ true);
+ GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected);
}
/// Checks:
/// 1. Getter: "get" prefix is not necessary.
/// 2. Setter: Parameter name is base name.
-void CppPlugin::test_quickfix_GetterSetter_basicGetterWithoutPrefix()
+void CppPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithoutPrefix()
{
TestCase data("\n"
"class Something\n"
@@ -261,13 +261,13 @@ void CppPlugin::test_quickfix_GetterSetter_basicGetterWithoutPrefix()
"\n"
;
- GetterSetter factory(/*testMode=*/ true);
+ GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected);
}
/// Check: Setter: Use pass by reference for parameters which
/// are not integer, float or pointers.
-void CppPlugin::test_quickfix_GetterSetter_customType()
+void CppPlugin::test_quickfix_GenerateGetterSetter_customType()
{
TestCase data("\n"
"class Something\n"
@@ -297,14 +297,14 @@ void CppPlugin::test_quickfix_GetterSetter_customType()
"\n"
;
- GetterSetter factory(/*testMode=*/ true);
+ GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected);
}
/// Checks:
/// 1. Setter: No setter is generated for const members.
/// 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"
"class Something\n"
@@ -328,12 +328,12 @@ void CppPlugin::test_quickfix_GetterSetter_constMember()
"\n"
;
- GetterSetter factory(/*testMode=*/ true);
+ GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected);
}
/// Checks: No special treatment for pointer to non const.
-void CppPlugin::test_quickfix_GetterSetter_pointerToNonConst()
+void CppPlugin::test_quickfix_GenerateGetterSetter_pointerToNonConst()
{
TestCase data("\n"
"class Something\n"
@@ -363,12 +363,12 @@ void CppPlugin::test_quickfix_GetterSetter_pointerToNonConst()
"\n"
;
- GetterSetter factory(/*testMode=*/ true);
+ GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected);
}
/// Checks: No special treatment for pointer to const.
-void CppPlugin::test_quickfix_GetterSetter_pointerToConst()
+void CppPlugin::test_quickfix_GenerateGetterSetter_pointerToConst()
{
TestCase data("\n"
"class Something\n"
@@ -398,14 +398,14 @@ void CppPlugin::test_quickfix_GetterSetter_pointerToConst()
"\n"
;
- GetterSetter factory(/*testMode=*/ true);
+ GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected);
}
/// Checks:
/// 1. Setter: Setter is a static 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"
"class Something\n"
@@ -435,12 +435,12 @@ void CppPlugin::test_quickfix_GetterSetter_staticMember()
"\n"
;
- GetterSetter factory(/*testMode=*/ true);
+ GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected);
}
/// Check: Check if it works on the second declarator
-void CppPlugin::test_quickfix_GetterSetter_secondDeclarator()
+void CppPlugin::test_quickfix_GenerateGetterSetter_secondDeclarator()
{
TestCase data("\n"
"class Something\n"
@@ -470,12 +470,12 @@ void CppPlugin::test_quickfix_GetterSetter_secondDeclarator()
"\n"
;
- GetterSetter factory(/*testMode=*/ true);
+ GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected);
}
/// 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"
"class Something\n"
@@ -505,33 +505,33 @@ void CppPlugin::test_quickfix_GetterSetter_triggeringRightAfterPointerSign()
"\n"
;
- GetterSetter factory(/*testMode=*/ true);
+ GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected);
}
/// 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(); };");
QByteArray expected = data.originalText;
- GetterSetter factory(/*testMode=*/ true);
+ GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected, /*changesExpected=*/ false);
}
/// 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]; };");
QByteArray expected = data.originalText;
- GetterSetter factory(/*testMode=*/ true);
+ GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected, /*changesExpected=*/ false);
}
/// Check: Do not offer the quick fix if there is already a member with the
/// getter or setter name we would generate.
-void CppPlugin::test_quickfix_GetterSetter_notTriggeringWhenGetterOrSetterExist()
+void CppPlugin::test_quickfix_GenerateGetterSetter_notTriggeringWhenGetterOrSetterExist()
{
TestCase data("\n"
"class Something {\n"
@@ -540,6 +540,6 @@ void CppPlugin::test_quickfix_GetterSetter_notTriggeringWhenGetterOrSetterExist(
"};\n");
QByteArray expected = data.originalText;
- GetterSetter factory(/*testMode=*/ true);
+ GenerateGetterSetter factory(/*testMode=*/ true);
data.run(&factory, expected, /*changesExpected=*/ false);
}
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index 288cbd87da..9967ef84fe 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -27,20 +27,14 @@
**
****************************************************************************/
-#include "cppcompleteswitch.h"
+#include "cppquickfixes.h"
+
#include "cppcompleteswitch.h"
#include "cppeditor.h"
-#include "cppfunctiondecldeflink.h"
#include "cppinsertdecldef.h"
#include "cppinsertqtpropertymembers.h"
#include "cppquickfixassistant.h"
-#include "cppquickfix.h"
-#include <AST.h>
-#include <ASTMatcher.h>
-#include <ASTPatternBuilder.h>
-#include <ASTVisitor.h>
-#include <CoreTypes.h>
#include <Literals.h>
#include <Name.h>
#include <Names.h>
@@ -48,7 +42,6 @@
#include <Symbols.h>
#include <Token.h>
#include <TranslationUnit.h>
-#include <Type.h>
#include <cplusplus/CppRewriter.h>
#include <cplusplus/DependencyTable.h>
@@ -57,29 +50,58 @@
#include <cpptools/cppclassesfilter.h>
#include <cpptools/cppcodestylesettings.h>
#include <cpptools/cpppointerdeclarationformatter.h>
-#include <cpptools/cpprefactoringchanges.h>
#include <cpptools/cpptoolsconstants.h>
-#include <cpptools/cpptoolsreuse.h>
-#include <cpptools/insertionpointlocator.h>
#include <cpptools/ModelManagerInterface.h>
-#include <cpptools/searchsymbols.h>
#include <cpptools/symbolfinder.h>
-#include <extensionsystem/iplugin.h>
#include <extensionsystem/pluginmanager.h>
+#include <utils/changeset.h>
#include <utils/qtcassert.h>
-#include <cctype>
#include <QApplication>
#include <QFileInfo>
+#include <QSharedPointer>
#include <QTextBlock>
#include <QTextCursor>
using namespace CppEditor;
using namespace CppEditor::Internal;
-using namespace CppTools;
-using namespace CPlusPlus;
-using namespace TextEditor;
-using namespace Utils;
+
+void CppEditor::Internal::registerQuickFixes(ExtensionSystem::IPlugin *plugIn)
+{
+ plugIn->addAutoReleasedObject(new AddIncludeForUndefinedIdentifier);
+ plugIn->addAutoReleasedObject(new AddIncludeForForwardDeclaration);
+
+ plugIn->addAutoReleasedObject(new FlipLogicalOperands);
+ plugIn->addAutoReleasedObject(new InverseLogicalComparison);
+ plugIn->addAutoReleasedObject(new RewriteLogicalAnd);
+
+ plugIn->addAutoReleasedObject(new ConvertToCamelCase);
+
+ plugIn->addAutoReleasedObject(new ConvertCStringToNSString);
+ plugIn->addAutoReleasedObject(new ConvertNumericLiteral);
+ plugIn->addAutoReleasedObject(new TranslateStringLiteral);
+ plugIn->addAutoReleasedObject(new WrapStringLiteral);
+
+ plugIn->addAutoReleasedObject(new MoveDeclarationOutOfIf);
+ plugIn->addAutoReleasedObject(new MoveDeclarationOutOfWhile);
+
+ plugIn->addAutoReleasedObject(new SplitIfStatement);
+ plugIn->addAutoReleasedObject(new SplitSimpleDeclaration);
+
+ plugIn->addAutoReleasedObject(new AddLocalDeclaration);
+ plugIn->addAutoReleasedObject(new AddBracesToIf);
+ plugIn->addAutoReleasedObject(new RearrangeParamDeclarationList);
+ plugIn->addAutoReleasedObject(new ReformatPointerDeclaration);
+
+ plugIn->addAutoReleasedObject(new CompleteSwitchCaseStatement);
+ plugIn->addAutoReleasedObject(new InsertQtPropertyMembers);
+
+ plugIn->addAutoReleasedObject(new ApplyDeclDefLinkChanges);
+ plugIn->addAutoReleasedObject(new ExtractFunction);
+ plugIn->addAutoReleasedObject(new GenerateGetterSetter);
+ plugIn->addAutoReleasedObject(new InsertDeclFromDef);
+ plugIn->addAutoReleasedObject(new InsertDefFromDecl);
+}
static inline bool isQtStringLiteral(const QByteArray &id)
{
@@ -91,838 +113,702 @@ static inline bool isQtStringTranslation(const QByteArray &id)
return id == "tr" || id == "trUtf8" || id == "translate" || id == "QT_TRANSLATE_NOOP";
}
-namespace {
-
-/*
- Rewrite
- a op b -> !(a invop b)
- (a op b) -> !(a invop b)
- !(a op b) -> (a invob b)
-
- Activates on: <= < > >= == !=
-*/
-class UseInverseOp: public CppQuickFixFactory
+class InverseLogicalComparisonOp: public CppQuickFixOperation
{
public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+ InverseLogicalComparisonOp(const CppQuickFixInterface &interface, int priority,
+ BinaryExpressionAST *binary, Kind invertToken)
+ : CppQuickFixOperation(interface, priority)
+ , binary(binary), nested(0), negation(0)
{
- CppRefactoringFilePtr file = interface->currentFile();
+ Token tok;
+ tok.f.kind = invertToken;
+ replacement = QLatin1String(tok.spell());
- const QList<AST *> &path = interface->path();
- int index = path.size() - 1;
- BinaryExpressionAST *binary = path.at(index)->asBinaryExpression();
- if (! binary)
- return;
- if (! interface->isCursorOn(binary->binary_op_token))
- return;
+ // check for enclosing nested expression
+ if (priority - 1 >= 0)
+ nested = interface->path()[priority - 1]->asNestedExpression();
- Kind invertToken;
- switch (file->tokenAt(binary->binary_op_token).kind()) {
- case T_LESS_EQUAL:
- invertToken = T_GREATER;
- break;
- case T_LESS:
- invertToken = T_GREATER_EQUAL;
- break;
- case T_GREATER:
- invertToken = T_LESS_EQUAL;
- break;
- case T_GREATER_EQUAL:
- invertToken = T_LESS;
- break;
- case T_EQUAL_EQUAL:
- invertToken = T_EXCLAIM_EQUAL;
- break;
- case T_EXCLAIM_EQUAL:
- invertToken = T_EQUAL_EQUAL;
- break;
- default:
- return;
+ // check for ! before parentheses
+ if (nested && priority - 2 >= 0) {
+ negation = interface->path()[priority - 2]->asUnaryExpression();
+ if (negation && ! interface->currentFile()->tokenAt(negation->unary_op_token).is(T_EXCLAIM))
+ negation = 0;
}
-
- result.append(CppQuickFixOperation::Ptr(new Operation(interface, index, binary, invertToken)));
}
-private:
- class Operation: public CppQuickFixOperation
+ QString description() const
{
- BinaryExpressionAST *binary;
- NestedExpressionAST *nested;
- UnaryExpressionAST *negation;
-
- QString replacement;
+ return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement);
+ }
- public:
- Operation(const CppQuickFixInterface &interface,
- int priority, BinaryExpressionAST *binary, Kind invertToken)
- : CppQuickFixOperation(interface, priority)
- , binary(binary), nested(0), negation(0)
- {
- Token tok;
- tok.f.kind = invertToken;
- replacement = QLatin1String(tok.spell());
-
- // check for enclosing nested expression
- if (priority - 1 >= 0)
- nested = interface->path()[priority - 1]->asNestedExpression();
-
- // check for ! before parentheses
- if (nested && priority - 2 >= 0) {
- negation = interface->path()[priority - 2]->asUnaryExpression();
- if (negation && ! interface->currentFile()->tokenAt(negation->unary_op_token).is(T_EXCLAIM))
- negation = 0;
- }
+ void perform()
+ {
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+
+ ChangeSet changes;
+ if (negation) {
+ // can't remove parentheses since that might break precedence
+ changes.remove(currentFile->range(negation->unary_op_token));
+ } else if (nested) {
+ changes.insert(currentFile->startOf(nested), QLatin1String("!"));
+ } else {
+ changes.insert(currentFile->startOf(binary), QLatin1String("!("));
+ changes.insert(currentFile->endOf(binary), QLatin1String(")"));
}
+ changes.replace(currentFile->range(binary->binary_op_token), replacement);
+ currentFile->setChangeSet(changes);
+ currentFile->apply();
+ }
- virtual QString description() const
- {
- return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement);
- }
+private:
+ BinaryExpressionAST *binary;
+ NestedExpressionAST *nested;
+ UnaryExpressionAST *negation;
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
-
- ChangeSet changes;
- if (negation) {
- // can't remove parentheses since that might break precedence
- changes.remove(currentFile->range(negation->unary_op_token));
- } else if (nested) {
- changes.insert(currentFile->startOf(nested), QLatin1String("!"));
- } else {
- changes.insert(currentFile->startOf(binary), QLatin1String("!("));
- changes.insert(currentFile->endOf(binary), QLatin1String(")"));
- }
- changes.replace(currentFile->range(binary->binary_op_token), replacement);
- currentFile->setChangeSet(changes);
- currentFile->apply();
- }
- };
+ QString replacement;
};
-/*
- Rewrite
- a op b
+void InverseLogicalComparison::match(const CppQuickFixInterface &interface,
+ QuickFixOperations &result)
+{
+ CppRefactoringFilePtr file = interface->currentFile();
+
+ const QList<AST *> &path = interface->path();
+ int index = path.size() - 1;
+ BinaryExpressionAST *binary = path.at(index)->asBinaryExpression();
+ if (! binary)
+ return;
+ if (! interface->isCursorOn(binary->binary_op_token))
+ return;
+
+ Kind invertToken;
+ switch (file->tokenAt(binary->binary_op_token).kind()) {
+ case T_LESS_EQUAL:
+ invertToken = T_GREATER;
+ break;
+ case T_LESS:
+ invertToken = T_GREATER_EQUAL;
+ break;
+ case T_GREATER:
+ invertToken = T_LESS_EQUAL;
+ break;
+ case T_GREATER_EQUAL:
+ invertToken = T_LESS;
+ break;
+ case T_EQUAL_EQUAL:
+ invertToken = T_EXCLAIM_EQUAL;
+ break;
+ case T_EXCLAIM_EQUAL:
+ invertToken = T_EQUAL_EQUAL;
+ break;
+ default:
+ return;
+ }
- As
- b flipop a
+ result.append(CppQuickFixOperation::Ptr(
+ new InverseLogicalComparisonOp(interface, index, binary, invertToken)));
+}
- Activates on: <= < > >= == != && ||
-*/
-class FlipBinaryOp: public CppQuickFixFactory
+class FlipLogicalOperandsOp: public CppQuickFixOperation
{
public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+ FlipLogicalOperandsOp(const CppQuickFixInterface &interface, int priority,
+ BinaryExpressionAST *binary, QString replacement)
+ : CppQuickFixOperation(interface)
+ , binary(binary)
+ , replacement(replacement)
{
- const QList<AST *> &path = interface->path();
- CppRefactoringFilePtr file = interface->currentFile();
+ setPriority(priority);
+ }
- int index = path.size() - 1;
- BinaryExpressionAST *binary = path.at(index)->asBinaryExpression();
- if (! binary)
- return;
- if (! interface->isCursorOn(binary->binary_op_token))
- return;
+ QString description() const
+ {
+ if (replacement.isEmpty())
+ return QApplication::translate("CppTools::QuickFix", "Swap Operands");
+ else
+ return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement);
+ }
- Kind flipToken;
- switch (file->tokenAt(binary->binary_op_token).kind()) {
- case T_LESS_EQUAL:
- flipToken = T_GREATER_EQUAL;
- break;
- case T_LESS:
- flipToken = T_GREATER;
- break;
- case T_GREATER:
- flipToken = T_LESS;
- break;
- case T_GREATER_EQUAL:
- flipToken = T_LESS_EQUAL;
- break;
- case T_EQUAL_EQUAL:
- case T_EXCLAIM_EQUAL:
- case T_AMPER_AMPER:
- case T_PIPE_PIPE:
- flipToken = T_EOF_SYMBOL;
- break;
- default:
- return;
- }
+ void perform()
+ {
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
- QString replacement;
- if (flipToken != T_EOF_SYMBOL) {
- Token tok;
- tok.f.kind = flipToken;
- replacement = QLatin1String(tok.spell());
- }
+ ChangeSet changes;
+ changes.flip(currentFile->range(binary->left_expression), currentFile->range(binary->right_expression));
+ if (! replacement.isEmpty())
+ changes.replace(currentFile->range(binary->binary_op_token), replacement);
- result.append(QuickFixOperation::Ptr(new Operation(interface, index, binary, replacement)));
+ currentFile->setChangeSet(changes);
+ currentFile->apply();
}
private:
- class Operation: public CppQuickFixOperation
- {
- public:
- Operation(const CppQuickFixInterface &interface,
- int priority, BinaryExpressionAST *binary, QString replacement)
- : CppQuickFixOperation(interface)
- , binary(binary)
- , replacement(replacement)
- {
- setPriority(priority);
- }
-
- virtual QString description() const
- {
- if (replacement.isEmpty())
- return QApplication::translate("CppTools::QuickFix", "Swap Operands");
- else
- return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement);
- }
-
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+ BinaryExpressionAST *binary;
+ QString replacement;
+};
- ChangeSet changes;
- changes.flip(currentFile->range(binary->left_expression), currentFile->range(binary->right_expression));
- if (! replacement.isEmpty())
- changes.replace(currentFile->range(binary->binary_op_token), replacement);
+void FlipLogicalOperands::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+{
+ const QList<AST *> &path = interface->path();
+ CppRefactoringFilePtr file = interface->currentFile();
- currentFile->setChangeSet(changes);
- currentFile->apply();
- }
+ int index = path.size() - 1;
+ BinaryExpressionAST *binary = path.at(index)->asBinaryExpression();
+ if (! binary)
+ return;
+ if (! interface->isCursorOn(binary->binary_op_token))
+ return;
- private:
- BinaryExpressionAST *binary;
- QString replacement;
- };
-};
+ Kind flipToken;
+ switch (file->tokenAt(binary->binary_op_token).kind()) {
+ case T_LESS_EQUAL:
+ flipToken = T_GREATER_EQUAL;
+ break;
+ case T_LESS:
+ flipToken = T_GREATER;
+ break;
+ case T_GREATER:
+ flipToken = T_LESS;
+ break;
+ case T_GREATER_EQUAL:
+ flipToken = T_LESS_EQUAL;
+ break;
+ case T_EQUAL_EQUAL:
+ case T_EXCLAIM_EQUAL:
+ case T_AMPER_AMPER:
+ case T_PIPE_PIPE:
+ flipToken = T_EOF_SYMBOL;
+ break;
+ default:
+ return;
+ }
-/*
- Rewrite
- !a && !b
+ QString replacement;
+ if (flipToken != T_EOF_SYMBOL) {
+ Token tok;
+ tok.f.kind = flipToken;
+ replacement = QLatin1String(tok.spell());
+ }
- As
- !(a || b)
+ result.append(QuickFixOperation::Ptr(
+ new FlipLogicalOperandsOp(interface, index, binary, replacement)));
+}
- Activates on: &&
-*/
-class RewriteLogicalAndOp: public CppQuickFixFactory
+class RewriteLogicalAndOp: public CppQuickFixOperation
{
public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+ QSharedPointer<ASTPatternBuilder> mk;
+ UnaryExpressionAST *left;
+ UnaryExpressionAST *right;
+ BinaryExpressionAST *pattern;
+
+ RewriteLogicalAndOp(const CppQuickFixInterface &interface)
+ : CppQuickFixOperation(interface)
+ , mk(new ASTPatternBuilder)
{
- BinaryExpressionAST *expression = 0;
- const QList<AST *> &path = interface->path();
- CppRefactoringFilePtr file = interface->currentFile();
-
- int index = path.size() - 1;
- for (; index != -1; --index) {
- expression = path.at(index)->asBinaryExpression();
- if (expression)
- break;
- }
-
- if (! expression)
- return;
+ left = mk->UnaryExpression();
+ right = mk->UnaryExpression();
+ pattern = mk->BinaryExpression(left, right);
+ }
- if (! interface->isCursorOn(expression->binary_op_token))
- return;
+ void perform()
+ {
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+
+ ChangeSet changes;
+ changes.replace(currentFile->range(pattern->binary_op_token), QLatin1String("||"));
+ changes.remove(currentFile->range(left->unary_op_token));
+ changes.remove(currentFile->range(right->unary_op_token));
+ const int start = currentFile->startOf(pattern);
+ const int end = currentFile->endOf(pattern);
+ changes.insert(start, QLatin1String("!("));
+ changes.insert(end, QLatin1String(")"));
+
+ currentFile->setChangeSet(changes);
+ currentFile->appendIndentRange(currentFile->range(pattern));
+ currentFile->apply();
+ }
+};
- QSharedPointer<Operation> op(new Operation(interface));
+void RewriteLogicalAnd::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+{
+ BinaryExpressionAST *expression = 0;
+ const QList<AST *> &path = interface->path();
+ CppRefactoringFilePtr file = interface->currentFile();
- if (expression->match(op->pattern, &matcher) &&
- file->tokenAt(op->pattern->binary_op_token).is(T_AMPER_AMPER) &&
- file->tokenAt(op->left->unary_op_token).is(T_EXCLAIM) &&
- file->tokenAt(op->right->unary_op_token).is(T_EXCLAIM)) {
- op->setDescription(QApplication::translate("CppTools::QuickFix", "Rewrite Condition Using ||"));
- op->setPriority(index);
- result.append(op);
- }
+ int index = path.size() - 1;
+ for (; index != -1; --index) {
+ expression = path.at(index)->asBinaryExpression();
+ if (expression)
+ break;
}
-private:
- class Operation: public CppQuickFixOperation
- {
- public:
- QSharedPointer<ASTPatternBuilder> mk;
- UnaryExpressionAST *left;
- UnaryExpressionAST *right;
- BinaryExpressionAST *pattern;
-
- Operation(const CppQuickFixInterface &interface)
- : CppQuickFixOperation(interface)
- , mk(new ASTPatternBuilder)
- {
- left = mk->UnaryExpression();
- right = mk->UnaryExpression();
- pattern = mk->BinaryExpression(left, right);
- }
+ if (! expression)
+ return;
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+ if (! interface->isCursorOn(expression->binary_op_token))
+ return;
- ChangeSet changes;
- changes.replace(currentFile->range(pattern->binary_op_token), QLatin1String("||"));
- changes.remove(currentFile->range(left->unary_op_token));
- changes.remove(currentFile->range(right->unary_op_token));
- const int start = currentFile->startOf(pattern);
- const int end = currentFile->endOf(pattern);
- changes.insert(start, QLatin1String("!("));
- changes.insert(end, QLatin1String(")"));
+ QSharedPointer<RewriteLogicalAndOp> op(new RewriteLogicalAndOp(interface));
- currentFile->setChangeSet(changes);
- currentFile->appendIndentRange(currentFile->range(pattern));
- currentFile->apply();
- }
- };
+ if (expression->match(op->pattern, &matcher) &&
+ file->tokenAt(op->pattern->binary_op_token).is(T_AMPER_AMPER) &&
+ file->tokenAt(op->left->unary_op_token).is(T_EXCLAIM) &&
+ file->tokenAt(op->right->unary_op_token).is(T_EXCLAIM)) {
+ op->setDescription(QApplication::translate("CppTools::QuickFix", "Rewrite Condition Using ||"));
+ op->setPriority(index);
+ result.append(op);
+ }
+}
-private:
- ASTMatcher matcher;
-};
+bool SplitSimpleDeclaration::checkDeclaration(SimpleDeclarationAST *declaration)
+{
+ if (! declaration->semicolon_token)
+ return false;
-/*
- Rewrite
- int *a, b;
+ if (! declaration->decl_specifier_list)
+ return false;
- As
- int *a;
- int b;
+ for (SpecifierListAST *it = declaration->decl_specifier_list; it; it = it->next) {
+ SpecifierAST *specifier = it->value;
- Activates on: the type or the variable names.
-*/
-class SplitSimpleDeclarationOp: public CppQuickFixFactory
-{
- static bool checkDeclaration(SimpleDeclarationAST *declaration)
- {
- if (! declaration->semicolon_token)
+ if (specifier->asEnumSpecifier() != 0)
return false;
- if (! declaration->decl_specifier_list)
+ else if (specifier->asClassSpecifier() != 0)
return false;
+ }
- for (SpecifierListAST *it = declaration->decl_specifier_list; it; it = it->next) {
- SpecifierAST *specifier = it->value;
-
- if (specifier->asEnumSpecifier() != 0)
- return false;
-
- else if (specifier->asClassSpecifier() != 0)
- return false;
- }
+ if (! declaration->declarator_list)
+ return false;
- if (! declaration->declarator_list)
- return false;
+ else if (! declaration->declarator_list->next)
+ return false;
- else if (! declaration->declarator_list->next)
- return false;
+ return true;
+}
- return true;
+class SplitSimpleDeclarationOp: public CppQuickFixOperation
+{
+public:
+ SplitSimpleDeclarationOp(const CppQuickFixInterface &interface, int priority,
+ SimpleDeclarationAST *decl)
+ : CppQuickFixOperation(interface, priority)
+ , declaration(decl)
+ {
+ setDescription(QApplication::translate("CppTools::QuickFix",
+ "Split Declaration"));
}
-public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+ void perform()
{
- CoreDeclaratorAST *core_declarator = 0;
- const QList<AST *> &path = interface->path();
- CppRefactoringFilePtr file = interface->currentFile();
- const int cursorPosition = file->cursor().selectionStart();
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
- for (int index = path.size() - 1; index != -1; --index) {
- AST *node = path.at(index);
+ ChangeSet changes;
- if (CoreDeclaratorAST *coreDecl = node->asCoreDeclarator())
- core_declarator = coreDecl;
+ SpecifierListAST *specifiers = declaration->decl_specifier_list;
+ int declSpecifiersStart = currentFile->startOf(specifiers->firstToken());
+ int declSpecifiersEnd = currentFile->endOf(specifiers->lastToken() - 1);
+ int insertPos = currentFile->endOf(declaration->semicolon_token);
- else if (SimpleDeclarationAST *simpleDecl = node->asSimpleDeclaration()) {
- if (checkDeclaration(simpleDecl)) {
- SimpleDeclarationAST *declaration = simpleDecl;
+ DeclaratorAST *prevDeclarator = declaration->declarator_list->value;
- const int startOfDeclSpecifier = file->startOf(declaration->decl_specifier_list->firstToken());
- const int endOfDeclSpecifier = file->endOf(declaration->decl_specifier_list->lastToken() - 1);
+ for (DeclaratorListAST *it = declaration->declarator_list->next; it; it = it->next) {
+ DeclaratorAST *declarator = it->value;
- if (cursorPosition >= startOfDeclSpecifier && cursorPosition <= endOfDeclSpecifier) {
- // the AST node under cursor is a specifier.
- result.append(QuickFixOperation::Ptr(new Operation(interface, index, declaration)));
- return;
- }
+ changes.insert(insertPos, QLatin1String("\n"));
+ changes.copy(declSpecifiersStart, declSpecifiersEnd, insertPos);
+ changes.insert(insertPos, QLatin1String(" "));
+ changes.move(currentFile->range(declarator), insertPos);
+ changes.insert(insertPos, QLatin1String(";"));
- if (core_declarator && interface->isCursorOn(core_declarator)) {
- // got a core-declarator under the text cursor.
- result.append(QuickFixOperation::Ptr(new Operation(interface, index, declaration)));
- return;
- }
- }
+ const int prevDeclEnd = currentFile->endOf(prevDeclarator);
+ changes.remove(prevDeclEnd, currentFile->startOf(declarator));
- return;
- }
+ prevDeclarator = declarator;
}
+
+ currentFile->setChangeSet(changes);
+ currentFile->appendIndentRange(currentFile->range(declaration));
+ currentFile->apply();
}
private:
- class Operation: public CppQuickFixOperation
- {
- public:
- Operation(const CppQuickFixInterface &interface, int priority, SimpleDeclarationAST *decl)
- : CppQuickFixOperation(interface, priority)
- , declaration(decl)
- {
- setDescription(QApplication::translate("CppTools::QuickFix",
- "Split Declaration"));
- }
-
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+ SimpleDeclarationAST *declaration;
+};
- ChangeSet changes;
+void SplitSimpleDeclaration::match(const CppQuickFixInterface &interface,
+ QuickFixOperations &result)
+{
+ CoreDeclaratorAST *core_declarator = 0;
+ const QList<AST *> &path = interface->path();
+ CppRefactoringFilePtr file = interface->currentFile();
+ const int cursorPosition = file->cursor().selectionStart();
- SpecifierListAST *specifiers = declaration->decl_specifier_list;
- int declSpecifiersStart = currentFile->startOf(specifiers->firstToken());
- int declSpecifiersEnd = currentFile->endOf(specifiers->lastToken() - 1);
- int insertPos = currentFile->endOf(declaration->semicolon_token);
+ for (int index = path.size() - 1; index != -1; --index) {
+ AST *node = path.at(index);
- DeclaratorAST *prevDeclarator = declaration->declarator_list->value;
+ if (CoreDeclaratorAST *coreDecl = node->asCoreDeclarator())
+ core_declarator = coreDecl;
- for (DeclaratorListAST *it = declaration->declarator_list->next; it; it = it->next) {
- DeclaratorAST *declarator = it->value;
+ else if (SimpleDeclarationAST *simpleDecl = node->asSimpleDeclaration()) {
+ if (checkDeclaration(simpleDecl)) {
+ SimpleDeclarationAST *declaration = simpleDecl;
- changes.insert(insertPos, QLatin1String("\n"));
- changes.copy(declSpecifiersStart, declSpecifiersEnd, insertPos);
- changes.insert(insertPos, QLatin1String(" "));
- changes.move(currentFile->range(declarator), insertPos);
- changes.insert(insertPos, QLatin1String(";"));
+ const int startOfDeclSpecifier = file->startOf(declaration->decl_specifier_list->firstToken());
+ const int endOfDeclSpecifier = file->endOf(declaration->decl_specifier_list->lastToken() - 1);
- const int prevDeclEnd = currentFile->endOf(prevDeclarator);
- changes.remove(prevDeclEnd, currentFile->startOf(declarator));
+ if (cursorPosition >= startOfDeclSpecifier && cursorPosition <= endOfDeclSpecifier) {
+ // the AST node under cursor is a specifier.
+ result.append(QuickFixOperation::Ptr(
+ new SplitSimpleDeclarationOp(interface, index, declaration)));
+ return;
+ }
- prevDeclarator = declarator;
+ if (core_declarator && interface->isCursorOn(core_declarator)) {
+ // got a core-declarator under the text cursor.
+ result.append(QuickFixOperation::Ptr(
+ new SplitSimpleDeclarationOp(interface, index, declaration)));
+ return;
+ }
}
- currentFile->setChangeSet(changes);
- currentFile->appendIndentRange(currentFile->range(declaration));
- currentFile->apply();
+ return;
}
+ }
+}
- private:
- SimpleDeclarationAST *declaration;
- };
-};
+class AddBracesToIfOp: public CppQuickFixOperation
+{
+public:
+ AddBracesToIfOp(const CppQuickFixInterface &interface, int priority, StatementAST *statement)
+ : CppQuickFixOperation(interface, priority)
+ , _statement(statement)
+ {
+ setDescription(QApplication::translate("CppTools::QuickFix",
+ "Add Curly Braces"));
+ }
-/*
- Add curly braces to a if statement that doesn't already contain a
- compound statement. I.e.
+ void perform()
+ {
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+
+ ChangeSet changes;
+
+ const int start = currentFile->endOf(_statement->firstToken() - 1);
+ changes.insert(start, QLatin1String(" {"));
+
+ const int end = currentFile->endOf(_statement->lastToken() - 1);
+ changes.insert(end, QLatin1String("\n}"));
+
+ currentFile->setChangeSet(changes);
+ currentFile->appendIndentRange(Utils::ChangeSet::Range(start, end));
+ currentFile->apply();
+ }
- if (a)
- b;
- becomes
- if (a)
- b;
+private:
+ StatementAST *_statement;
+};
- Activates on: the if
-*/
-class AddBracesToIfOp: public CppQuickFixFactory
+void AddBracesToIf::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{
-public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
- {
- const QList<AST *> &path = interface->path();
+ const QList<AST *> &path = interface->path();
- // show when we're on the 'if' of an if statement
- int index = path.size() - 1;
+ // show when we're on the 'if' of an if statement
+ int index = path.size() - 1;
+ IfStatementAST *ifStatement = path.at(index)->asIfStatement();
+ if (ifStatement && interface->isCursorOn(ifStatement->if_token) && ifStatement->statement
+ && ! ifStatement->statement->asCompoundStatement()) {
+ result.append(QuickFixOperation::Ptr(
+ new AddBracesToIfOp(interface, index, ifStatement->statement)));
+ return;
+ }
+
+ // or if we're on the statement contained in the if
+ // ### This may not be such a good idea, consider nested ifs...
+ for (; index != -1; --index) {
IfStatementAST *ifStatement = path.at(index)->asIfStatement();
- if (ifStatement && interface->isCursorOn(ifStatement->if_token) && ifStatement->statement
+ if (ifStatement && ifStatement->statement
+ && interface->isCursorOn(ifStatement->statement)
&& ! ifStatement->statement->asCompoundStatement()) {
- result.append(QuickFixOperation::Ptr(new Operation(interface, index, ifStatement->statement)));
+ result.append(QuickFixOperation::Ptr(
+ new AddBracesToIfOp(interface, index, ifStatement->statement)));
return;
}
+ }
- // or if we're on the statement contained in the if
- // ### This may not be such a good idea, consider nested ifs...
- for (; index != -1; --index) {
- IfStatementAST *ifStatement = path.at(index)->asIfStatement();
- if (ifStatement && ifStatement->statement
- && interface->isCursorOn(ifStatement->statement)
- && ! ifStatement->statement->asCompoundStatement()) {
- result.append(QuickFixOperation::Ptr(new Operation(interface, index, ifStatement->statement)));
- return;
- }
- }
+ // ### This could very well be extended to the else branch
+ // and other nodes entirely.
+}
- // ### This could very well be extended to the else branch
- // and other nodes entirely.
+class MoveDeclarationOutOfIfOp: public CppQuickFixOperation
+{
+public:
+ MoveDeclarationOutOfIfOp(const CppQuickFixInterface &interface)
+ : CppQuickFixOperation(interface)
+ {
+ setDescription(QApplication::translate("CppTools::QuickFix",
+ "Move Declaration out of Condition"));
+
+ condition = mk.Condition();
+ pattern = mk.IfStatement(condition);
}
-private:
- class Operation: public CppQuickFixOperation
+ void perform()
{
- public:
- Operation(const CppQuickFixInterface &interface, int priority, StatementAST *statement)
- : CppQuickFixOperation(interface, priority)
- , _statement(statement)
- {
- setDescription(QApplication::translate("CppTools::QuickFix",
- "Add Curly Braces"));
- }
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+ ChangeSet changes;
- ChangeSet changes;
+ changes.copy(currentFile->range(core), currentFile->startOf(condition));
- const int start = currentFile->endOf(_statement->firstToken() - 1);
- changes.insert(start, QLatin1String(" {"));
+ int insertPos = currentFile->startOf(pattern);
+ changes.move(currentFile->range(condition), insertPos);
+ changes.insert(insertPos, QLatin1String(";\n"));
- const int end = currentFile->endOf(_statement->lastToken() - 1);
- changes.insert(end, QLatin1String("\n}"));
-
- currentFile->setChangeSet(changes);
- currentFile->appendIndentRange(Utils::ChangeSet::Range(start, end));
- currentFile->apply();
- }
+ currentFile->setChangeSet(changes);
+ currentFile->appendIndentRange(currentFile->range(pattern));
+ currentFile->apply();
+ }
- private:
- StatementAST *_statement;
- };
+ ASTMatcher matcher;
+ ASTPatternBuilder mk;
+ CPPEditorWidget *editor;
+ ConditionAST *condition;
+ IfStatementAST *pattern;
+ CoreDeclaratorAST *core;
};
-/*
- Replace
- if (Type name = foo()) {...}
-
- With
- Type name = foo;
- if (name) {...}
-
- Activates on: the name of the introduced variable
-*/
-class MoveDeclarationOutOfIfOp: public CppQuickFixFactory
+void MoveDeclarationOutOfIf::match(const CppQuickFixInterface &interface,
+ QuickFixOperations &result)
{
-public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
- {
- const QList<AST *> &path = interface->path();
- QSharedPointer<Operation> op(new Operation(interface));
-
- int index = path.size() - 1;
- for (; index != -1; --index) {
- if (IfStatementAST *statement = path.at(index)->asIfStatement()) {
- if (statement->match(op->pattern, &op->matcher) && op->condition->declarator) {
- DeclaratorAST *declarator = op->condition->declarator;
- op->core = declarator->core_declarator;
- if (! op->core)
- return;
+ const QList<AST *> &path = interface->path();
+ typedef QSharedPointer<MoveDeclarationOutOfIfOp> Ptr;
+ Ptr op(new MoveDeclarationOutOfIfOp(interface));
+
+ int index = path.size() - 1;
+ for (; index != -1; --index) {
+ if (IfStatementAST *statement = path.at(index)->asIfStatement()) {
+ if (statement->match(op->pattern, &op->matcher) && op->condition->declarator) {
+ DeclaratorAST *declarator = op->condition->declarator;
+ op->core = declarator->core_declarator;
+ if (! op->core)
+ return;
- if (interface->isCursorOn(op->core)) {
- op->setPriority(index);
- result.append(op);
- return;
- }
+ if (interface->isCursorOn(op->core)) {
+ op->setPriority(index);
+ result.append(op);
+ return;
}
}
}
}
+}
-private:
- class Operation: public CppQuickFixOperation
+class MoveDeclarationOutOfWhileOp: public CppQuickFixOperation
+{
+public:
+ MoveDeclarationOutOfWhileOp(const CppQuickFixInterface &interface)
+ : CppQuickFixOperation(interface)
{
- public:
- Operation(const CppQuickFixInterface &interface)
- : CppQuickFixOperation(interface)
- {
- setDescription(QApplication::translate("CppTools::QuickFix",
- "Move Declaration out of Condition"));
-
- condition = mk.Condition();
- pattern = mk.IfStatement(condition);
- }
+ setDescription(QApplication::translate("CppTools::QuickFix",
+ "Move Declaration out of Condition"));
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+ condition = mk.Condition();
+ pattern = mk.WhileStatement(condition);
+ }
- ChangeSet changes;
+ void perform()
+ {
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
- changes.copy(currentFile->range(core), currentFile->startOf(condition));
+ ChangeSet changes;
- int insertPos = currentFile->startOf(pattern);
- changes.move(currentFile->range(condition), insertPos);
- changes.insert(insertPos, QLatin1String(";\n"));
+ changes.insert(currentFile->startOf(condition), QLatin1String("("));
+ changes.insert(currentFile->endOf(condition), QLatin1String(") != 0"));
- currentFile->setChangeSet(changes);
- currentFile->appendIndentRange(currentFile->range(pattern));
- currentFile->apply();
- }
+ int insertPos = currentFile->startOf(pattern);
+ const int conditionStart = currentFile->startOf(condition);
+ changes.move(conditionStart, currentFile->startOf(core), insertPos);
+ changes.copy(currentFile->range(core), insertPos);
+ changes.insert(insertPos, QLatin1String(";\n"));
- ASTMatcher matcher;
- ASTPatternBuilder mk;
- CPPEditorWidget *editor;
- ConditionAST *condition;
- IfStatementAST *pattern;
- CoreDeclaratorAST *core;
- };
-};
-
-/*
- Replace
- while (Type name = foo()) {...}
+ currentFile->setChangeSet(changes);
+ currentFile->appendIndentRange(currentFile->range(pattern));
+ currentFile->apply();
+ }
- With
- Type name;
- while ((name = foo()) != 0) {...}
+ ASTMatcher matcher;
+ ASTPatternBuilder mk;
+ CPPEditorWidget *editor;
+ ConditionAST *condition;
+ WhileStatementAST *pattern;
+ CoreDeclaratorAST *core;
+};
- Activates on: the name of the introduced variable
-*/
-class MoveDeclarationOutOfWhileOp: public CppQuickFixFactory
+void MoveDeclarationOutOfWhile::match(const CppQuickFixInterface &interface,
+ QuickFixOperations &result)
{
-public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
- {
- const QList<AST *> &path = interface->path();
- QSharedPointer<Operation> op(new Operation(interface));
+ const QList<AST *> &path = interface->path();
+ QSharedPointer<MoveDeclarationOutOfWhileOp> op(new MoveDeclarationOutOfWhileOp(interface));
- int index = path.size() - 1;
- for (; index != -1; --index) {
- if (WhileStatementAST *statement = path.at(index)->asWhileStatement()) {
- if (statement->match(op->pattern, &op->matcher) && op->condition->declarator) {
- DeclaratorAST *declarator = op->condition->declarator;
- op->core = declarator->core_declarator;
+ int index = path.size() - 1;
+ for (; index != -1; --index) {
+ if (WhileStatementAST *statement = path.at(index)->asWhileStatement()) {
+ if (statement->match(op->pattern, &op->matcher) && op->condition->declarator) {
+ DeclaratorAST *declarator = op->condition->declarator;
+ op->core = declarator->core_declarator;
- if (! op->core)
- return;
+ if (! op->core)
+ return;
- if (! declarator->equal_token)
- return;
+ if (! declarator->equal_token)
+ return;
- if (! declarator->initializer)
- return;
+ if (! declarator->initializer)
+ return;
- if (interface->isCursorOn(op->core)) {
- op->setPriority(index);
- result.append(op);
- return;
- }
+ if (interface->isCursorOn(op->core)) {
+ op->setPriority(index);
+ result.append(op);
+ return;
}
}
}
}
+}
-private:
- class Operation: public CppQuickFixOperation
+class SplitIfStatementOp: public CppQuickFixOperation
+{
+public:
+ SplitIfStatementOp(const CppQuickFixInterface &interface, int priority,
+ IfStatementAST *pattern, BinaryExpressionAST *condition)
+ : CppQuickFixOperation(interface, priority)
+ , pattern(pattern)
+ , condition(condition)
{
- public:
- Operation(const CppQuickFixInterface &interface)
- : CppQuickFixOperation(interface)
- {
- setDescription(QApplication::translate("CppTools::QuickFix",
- "Move Declaration out of Condition"));
-
- condition = mk.Condition();
- pattern = mk.WhileStatement(condition);
- }
-
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
-
- ChangeSet changes;
-
- changes.insert(currentFile->startOf(condition), QLatin1String("("));
- changes.insert(currentFile->endOf(condition), QLatin1String(") != 0"));
+ setDescription(QApplication::translate("CppTools::QuickFix",
+ "Split if Statement"));
+ }
- int insertPos = currentFile->startOf(pattern);
- const int conditionStart = currentFile->startOf(condition);
- changes.move(conditionStart, currentFile->startOf(core), insertPos);
- changes.copy(currentFile->range(core), insertPos);
- changes.insert(insertPos, QLatin1String(";\n"));
+ void perform()
+ {
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
- currentFile->setChangeSet(changes);
- currentFile->appendIndentRange(currentFile->range(pattern));
- currentFile->apply();
- }
+ const Token binaryToken = currentFile->tokenAt(condition->binary_op_token);
- ASTMatcher matcher;
- ASTPatternBuilder mk;
- CPPEditorWidget *editor;
- ConditionAST *condition;
- WhileStatementAST *pattern;
- CoreDeclaratorAST *core;
- };
-};
+ if (binaryToken.is(T_AMPER_AMPER))
+ splitAndCondition(currentFile);
+ else
+ splitOrCondition(currentFile);
+ }
-/*
- Replace
- if (something && something_else) {
- }
-
- with
- if (something)
- if (something_else)
- }
-
- and
- if (something || something_else)
- x;
-
- with
- if (something)
- x;
- else if (something_else)
- x;
-
- Activates on: && or ||
-*/
-class SplitIfStatementOp: public CppQuickFixFactory
-{
-public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+ void splitAndCondition(CppRefactoringFilePtr currentFile) const
{
- IfStatementAST *pattern = 0;
- const QList<AST *> &path = interface->path();
-
- int index = path.size() - 1;
- for (; index != -1; --index) {
- AST *node = path.at(index);
- if (IfStatementAST *stmt = node->asIfStatement()) {
- pattern = stmt;
- break;
- }
- }
+ ChangeSet changes;
- if (! pattern || ! pattern->statement)
- return;
+ int startPos = currentFile->startOf(pattern);
+ changes.insert(startPos, QLatin1String("if ("));
+ changes.move(currentFile->range(condition->left_expression), startPos);
+ changes.insert(startPos, QLatin1String(") {\n"));
- unsigned splitKind = 0;
- for (++index; index < path.size(); ++index) {
- AST *node = path.at(index);
- BinaryExpressionAST *condition = node->asBinaryExpression();
- if (! condition)
- return;
-
- Token binaryToken = interface->currentFile()->tokenAt(condition->binary_op_token);
-
- // only accept a chain of ||s or &&s - no mixing
- if (! splitKind) {
- splitKind = binaryToken.kind();
- if (splitKind != T_AMPER_AMPER && splitKind != T_PIPE_PIPE)
- return;
- // we can't reliably split &&s in ifs with an else branch
- if (splitKind == T_AMPER_AMPER && pattern->else_statement)
- return;
- } else if (splitKind != binaryToken.kind()) {
- return;
- }
+ const int lExprEnd = currentFile->endOf(condition->left_expression);
+ changes.remove(lExprEnd, currentFile->startOf(condition->right_expression));
+ changes.insert(currentFile->endOf(pattern), QLatin1String("\n}"));
- if (interface->isCursorOn(condition->binary_op_token)) {
- result.append(QuickFixOperation::Ptr(new Operation(interface, index, pattern, condition)));
- return;
- }
- }
+ currentFile->setChangeSet(changes);
+ currentFile->appendIndentRange(currentFile->range(pattern));
+ currentFile->apply();
}
-private:
- class Operation: public CppQuickFixOperation
+ void splitOrCondition(CppRefactoringFilePtr currentFile) const
{
- public:
- Operation(const CppQuickFixInterface &interface, int priority,
- IfStatementAST *pattern, BinaryExpressionAST *condition)
- : CppQuickFixOperation(interface, priority)
- , pattern(pattern)
- , condition(condition)
- {
- setDescription(QApplication::translate("CppTools::QuickFix",
- "Split if Statement"));
- }
+ ChangeSet changes;
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+ StatementAST *ifTrueStatement = pattern->statement;
+ CompoundStatementAST *compoundStatement = ifTrueStatement->asCompoundStatement();
- const Token binaryToken = currentFile->tokenAt(condition->binary_op_token);
+ int insertPos = currentFile->endOf(ifTrueStatement);
+ if (compoundStatement)
+ changes.insert(insertPos, QLatin1String(" "));
+ else
+ changes.insert(insertPos, QLatin1String("\n"));
+ changes.insert(insertPos, QLatin1String("else if ("));
- if (binaryToken.is(T_AMPER_AMPER))
- splitAndCondition(currentFile);
- else
- splitOrCondition(currentFile);
- }
+ const int rExprStart = currentFile->startOf(condition->right_expression);
+ changes.move(rExprStart, currentFile->startOf(pattern->rparen_token), insertPos);
+ changes.insert(insertPos, QLatin1String(")"));
- void splitAndCondition(CppRefactoringFilePtr currentFile)
- {
- ChangeSet changes;
+ const int rParenEnd = currentFile->endOf(pattern->rparen_token);
+ changes.copy(rParenEnd, currentFile->endOf(pattern->statement), insertPos);
- int startPos = currentFile->startOf(pattern);
- changes.insert(startPos, QLatin1String("if ("));
- changes.move(currentFile->range(condition->left_expression), startPos);
- changes.insert(startPos, QLatin1String(") {\n"));
+ const int lExprEnd = currentFile->endOf(condition->left_expression);
+ changes.remove(lExprEnd, currentFile->startOf(condition->right_expression));
- const int lExprEnd = currentFile->endOf(condition->left_expression);
- changes.remove(lExprEnd, currentFile->startOf(condition->right_expression));
- changes.insert(currentFile->endOf(pattern), QLatin1String("\n}"));
-
- currentFile->setChangeSet(changes);
- currentFile->appendIndentRange(currentFile->range(pattern));
- currentFile->apply();
- }
+ currentFile->setChangeSet(changes);
+ currentFile->appendIndentRange(currentFile->range(pattern));
+ currentFile->apply();
+ }
- void splitOrCondition(CppRefactoringFilePtr currentFile)
- {
- ChangeSet changes;
+private:
+ IfStatementAST *pattern;
+ BinaryExpressionAST *condition;
+};
- StatementAST *ifTrueStatement = pattern->statement;
- CompoundStatementAST *compoundStatement = ifTrueStatement->asCompoundStatement();
+void SplitIfStatement::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+{
+ IfStatementAST *pattern = 0;
+ const QList<AST *> &path = interface->path();
- int insertPos = currentFile->endOf(ifTrueStatement);
- if (compoundStatement)
- changes.insert(insertPos, QLatin1String(" "));
- else
- changes.insert(insertPos, QLatin1String("\n"));
- changes.insert(insertPos, QLatin1String("else if ("));
+ int index = path.size() - 1;
+ for (; index != -1; --index) {
+ AST *node = path.at(index);
+ if (IfStatementAST *stmt = node->asIfStatement()) {
+ pattern = stmt;
+ break;
+ }
+ }
- const int rExprStart = currentFile->startOf(condition->right_expression);
- changes.move(rExprStart, currentFile->startOf(pattern->rparen_token), insertPos);
- changes.insert(insertPos, QLatin1String(")"));
+ if (! pattern || ! pattern->statement)
+ return;
- const int rParenEnd = currentFile->endOf(pattern->rparen_token);
- changes.copy(rParenEnd, currentFile->endOf(pattern->statement), insertPos);
+ unsigned splitKind = 0;
+ for (++index; index < path.size(); ++index) {
+ AST *node = path.at(index);
+ BinaryExpressionAST *condition = node->asBinaryExpression();
+ if (! condition)
+ return;
- const int lExprEnd = currentFile->endOf(condition->left_expression);
- changes.remove(lExprEnd, currentFile->startOf(condition->right_expression));
+ Token binaryToken = interface->currentFile()->tokenAt(condition->binary_op_token);
- currentFile->setChangeSet(changes);
- currentFile->appendIndentRange(currentFile->range(pattern));
- currentFile->apply();
+ // only accept a chain of ||s or &&s - no mixing
+ if (! splitKind) {
+ splitKind = binaryToken.kind();
+ if (splitKind != T_AMPER_AMPER && splitKind != T_PIPE_PIPE)
+ return;
+ // we can't reliably split &&s in ifs with an else branch
+ if (splitKind == T_AMPER_AMPER && pattern->else_statement)
+ return;
+ } else if (splitKind != binaryToken.kind()) {
+ return;
}
- private:
- IfStatementAST *pattern;
- BinaryExpressionAST *condition;
- };
-};
-
-/*
- Replace
- "abcd" -> QLatin1String("abcd")
- @"abcd" -> QLatin1String("abcd") (Objective C)
- 'a' -> QLatin1Char('a')
- 'a' -> "a"
- "a" -> 'a' or QLatin1Char('a') (Single character string constants)
- "\n" -> '\n', QLatin1Char('\n')
- Except if they are already enclosed in
- QLatin1Char, QT_TRANSLATE_NOOP, tr,
- trUtf8, QLatin1Literal, QLatin1String
-
- Activates on: the string or character literal
-*/
+ if (interface->isCursorOn(condition->binary_op_token)) {
+ result.append(QuickFixOperation::Ptr(
+ new SplitIfStatementOp(interface, index, pattern, condition)));
+ return;
+ }
+ }
+}
static inline QString msgQtStringLiteralDescription(const QString &replacement, int qtVersion)
{
@@ -935,56 +821,9 @@ static inline QString msgQtStringLiteralDescription(const QString &replacement)
return QApplication::translate("CppTools::QuickFix", "Enclose in %1(...)").arg(replacement);
}
-class WrapStringLiteral: public CppQuickFixFactory
-{
-public:
- typedef const CppQuickFixInterface AssistInterfacePtr;
-
- enum ActionFlags
- {
- EncloseInQLatin1CharAction = 0x1, EncloseInQLatin1StringAction = 0x2, EncloseInQStringLiteralAction = 0x4,
- EncloseActionMask = EncloseInQLatin1CharAction | EncloseInQLatin1StringAction | EncloseInQStringLiteralAction,
- TranslateTrAction = 0x8, TranslateQCoreApplicationAction = 0x10, TranslateNoopAction = 0x20,
- TranslationMask = TranslateTrAction | TranslateQCoreApplicationAction | TranslateNoopAction,
- RemoveObjectiveCAction = 0x40,
- ConvertEscapeSequencesToCharAction = 0x100, ConvertEscapeSequencesToStringAction = 0x200,
- SingleQuoteAction = 0x400, DoubleQuoteAction = 0x800
- };
-
- enum Type { TypeString, TypeObjCString, TypeChar, TypeNone };
-
- //void match(const AssistInterfacePtr &interface, QuickFixOperations &result);
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
- static QString replacement(unsigned actions);
- static QByteArray stringToCharEscapeSequences(const QByteArray &content);
- static QByteArray charToStringEscapeSequences(const QByteArray &content);
-
- static ExpressionAST *analyze(const QList<AST *> &path, const CppRefactoringFilePtr &file,
- Type *type,
- QByteArray *enclosingFunction = 0,
- CallAST **enclosingFunctionCall = 0);
-
- // Operations performs the operations of type ActionFlags passed in as actions.
- class Operation : public CppQuickFixOperation
- {
- public:
- Operation(const AssistInterfacePtr &interface, int priority,
- unsigned actions, const QString &description, ExpressionAST *literal,
- const QString &translationContext = QString());
-
- void perform();
-
- private:
- const unsigned m_actions;
- ExpressionAST *m_literal;
- const QString m_translationContext;
- };
-};
-
/* Analze a string/character literal like "x", QLatin1String("x") and return the literal
* (StringLiteral or NumericLiteral for characters) and its type
* and the enclosing function (QLatin1String, tr...) */
-
ExpressionAST *WrapStringLiteral::analyze(const QList<AST *> &path,
const CppRefactoringFilePtr &file,
Type *type,
@@ -1029,6 +868,87 @@ ExpressionAST *WrapStringLiteral::analyze(const QList<AST *> &path,
return literal;
}
+/// Operation performs the operations of type ActionFlags passed in as actions.
+class WrapStringLiteralOp : public CppQuickFixOperation
+{
+public:
+ typedef WrapStringLiteral Factory;
+
+ WrapStringLiteralOp(const CppQuickFixInterface &interface, int priority,
+ unsigned actions, const QString &description, ExpressionAST *literal,
+ const QString &translationContext = QString())
+ : CppQuickFixOperation(interface, priority), m_actions(actions), m_literal(literal),
+ m_translationContext(translationContext)
+ {
+ setDescription(description);
+ }
+
+ void perform()
+ {
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+
+ ChangeSet changes;
+
+ const int startPos = currentFile->startOf(m_literal);
+ const int endPos = currentFile->endOf(m_literal);
+
+ // kill leading '@'. No need to adapt endPos, that is done by ChangeSet
+ if (m_actions & Factory::RemoveObjectiveCAction)
+ changes.remove(startPos, startPos + 1);
+
+ // Fix quotes
+ if (m_actions & (Factory::SingleQuoteAction | Factory::DoubleQuoteAction)) {
+ const QString newQuote((m_actions & Factory::SingleQuoteAction) ? QLatin1Char('\'') : QLatin1Char('"'));
+ changes.replace(startPos, startPos + 1, newQuote);
+ changes.replace(endPos - 1, endPos, newQuote);
+ }
+
+ // Convert single character strings into character constants
+ if (m_actions & Factory::ConvertEscapeSequencesToCharAction) {
+ StringLiteralAST *stringLiteral = m_literal->asStringLiteral();
+ QTC_ASSERT(stringLiteral, return ;);
+ const QByteArray oldContents(currentFile->tokenAt(stringLiteral->literal_token).identifier->chars());
+ const QByteArray newContents = Factory::stringToCharEscapeSequences(oldContents);
+ QTC_ASSERT(!newContents.isEmpty(), return ;);
+ if (oldContents != newContents)
+ changes.replace(startPos + 1, endPos -1, QString::fromLatin1(newContents));
+ }
+
+ // Convert character constants into strings constants
+ if (m_actions & Factory::ConvertEscapeSequencesToStringAction) {
+ NumericLiteralAST *charLiteral = m_literal->asNumericLiteral(); // char 'c' constants are numerical.
+ QTC_ASSERT(charLiteral, return ;);
+ const QByteArray oldContents(currentFile->tokenAt(charLiteral->literal_token).identifier->chars());
+ const QByteArray newContents = Factory::charToStringEscapeSequences(oldContents);
+ QTC_ASSERT(!newContents.isEmpty(), return ;);
+ if (oldContents != newContents)
+ changes.replace(startPos + 1, endPos -1, QString::fromLatin1(newContents));
+ }
+
+ // Enclose in literal or translation function, macro.
+ if (m_actions & (Factory::EncloseActionMask | Factory::TranslationMask)) {
+ changes.insert(endPos, QString(QLatin1Char(')')));
+ QString leading = Factory::replacement(m_actions);
+ leading += QLatin1Char('(');
+ if (m_actions & (Factory::TranslateQCoreApplicationAction | Factory::TranslateNoopAction)) {
+ leading += QLatin1Char('"');
+ leading += m_translationContext;
+ leading += QLatin1String("\", ");
+ }
+ changes.insert(startPos, leading);
+ }
+
+ currentFile->setChangeSet(changes);
+ currentFile->apply();
+ }
+
+private:
+ const unsigned m_actions;
+ ExpressionAST *m_literal;
+ const QString m_translationContext;
+};
+
void WrapStringLiteral::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{
typedef CppQuickFixOperation::Ptr OperationPtr;
@@ -1037,7 +957,7 @@ void WrapStringLiteral::match(const CppQuickFixInterface &interface, QuickFixOpe
QByteArray enclosingFunction;
const QList<AST *> &path = interface->path();
CppRefactoringFilePtr file = interface->currentFile();
- ExpressionAST *literal = WrapStringLiteral::analyze(path, file, &type, &enclosingFunction);
+ ExpressionAST *literal = analyze(path, file, &type, &enclosingFunction);
if (!literal || type == TypeNone)
return;
if ((type == TypeChar && enclosingFunction == "QLatin1Char")
@@ -1048,17 +968,17 @@ void WrapStringLiteral::match(const CppQuickFixInterface &interface, QuickFixOpe
const int priority = path.size() - 1; // very high priority
if (type == TypeChar) {
unsigned actions = EncloseInQLatin1CharAction;
- QString description = msgQtStringLiteralDescription(WrapStringLiteral::replacement(actions));
- result << OperationPtr(new Operation(interface, priority, actions,
- description, literal));
+ QString description = msgQtStringLiteralDescription(replacement(actions));
+ result << OperationPtr(new WrapStringLiteralOp(interface, priority, actions,
+ description, literal));
if (NumericLiteralAST *charLiteral = literal->asNumericLiteral()) {
const QByteArray contents(file->tokenAt(charLiteral->literal_token).identifier->chars());
if (!charToStringEscapeSequences(contents).isEmpty()) {
actions = DoubleQuoteAction | ConvertEscapeSequencesToStringAction;
description = QApplication::translate("CppTools::QuickFix",
"Convert to String Literal");
- result << OperationPtr(new Operation(interface, priority, actions,
- description, literal));
+ result << OperationPtr(new WrapStringLiteralOp(interface, priority, actions,
+ description, literal));
}
}
} else {
@@ -1072,23 +992,24 @@ void WrapStringLiteral::match(const CppQuickFixInterface &interface, QuickFixOpe
| ConvertEscapeSequencesToCharAction | objectiveCActions;
QString description = QApplication::translate("CppTools::QuickFix",
"Convert to Character Literal and Enclose in QLatin1Char(...)");
- result << OperationPtr(new Operation(interface, priority,
- actions, description, literal));
+ result << OperationPtr(new WrapStringLiteralOp(interface, priority,
+ actions, description, literal));
actions &= ~EncloseInQLatin1CharAction;
description = QApplication::translate("CppTools::QuickFix",
"Convert to Character Literal");
- result << OperationPtr(new Operation(interface, priority,
- actions, description, literal));
+ result << OperationPtr(new WrapStringLiteralOp(interface, priority,
+ actions, description, literal));
}
}
actions = EncloseInQLatin1StringAction | objectiveCActions;
- result << OperationPtr(new Operation(interface, priority, actions,
- msgQtStringLiteralDescription(WrapStringLiteral::replacement(actions), 4),
- literal));
+ result << OperationPtr(
+ new WrapStringLiteralOp(interface, priority, actions,
+ msgQtStringLiteralDescription(replacement(actions), 4),
+ literal));
actions = EncloseInQStringLiteralAction | objectiveCActions;
- result << OperationPtr(new Operation(interface, priority, actions,
- msgQtStringLiteralDescription(WrapStringLiteral::replacement(actions), 5),
- literal));
+ result << OperationPtr(
+ new WrapStringLiteralOp(interface, priority, actions,
+ msgQtStringLiteralDescription(replacement(actions), 5), literal));
}
}
@@ -1131,394 +1052,331 @@ QByteArray WrapStringLiteral::charToStringEscapeSequences(const QByteArray &cont
return QByteArray();
}
-WrapStringLiteral::Operation::Operation(const AssistInterfacePtr &interface, int priority,
- unsigned actions, const QString &description, ExpressionAST *literal,
- const QString &translationContext)
- : CppQuickFixOperation(interface, priority), m_actions(actions), m_literal(literal),
- m_translationContext(translationContext)
+void TranslateStringLiteral::match(const CppQuickFixInterface &interface,
+ QuickFixOperations &result)
{
- setDescription(description);
-}
+ // Initialize
+ WrapStringLiteral::Type type = WrapStringLiteral::TypeNone;
+ QByteArray enclosingFunction;
+ const QList<AST *> &path = interface->path();
+ CppRefactoringFilePtr file = interface->currentFile();
+ ExpressionAST *literal = WrapStringLiteral::analyze(path, file, &type, &enclosingFunction);
+ if (!literal || type != WrapStringLiteral::TypeString
+ || isQtStringLiteral(enclosingFunction) || isQtStringTranslation(enclosingFunction))
+ return;
-void WrapStringLiteral::Operation::perform()
-{
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
-
- ChangeSet changes;
-
- const int startPos = currentFile->startOf(m_literal);
- const int endPos = currentFile->endOf(m_literal);
-
- // kill leading '@'. No need to adapt endPos, that is done by ChangeSet
- if (m_actions & RemoveObjectiveCAction)
- changes.remove(startPos, startPos + 1);
-
- // Fix quotes
- if (m_actions & (SingleQuoteAction | DoubleQuoteAction)) {
- const QString newQuote((m_actions & SingleQuoteAction) ? QLatin1Char('\'') : QLatin1Char('"'));
- changes.replace(startPos, startPos + 1, newQuote);
- changes.replace(endPos - 1, endPos, newQuote);
- }
-
- // Convert single character strings into character constants
- if (m_actions & ConvertEscapeSequencesToCharAction) {
- StringLiteralAST *stringLiteral = m_literal->asStringLiteral();
- QTC_ASSERT(stringLiteral, return ;);
- const QByteArray oldContents(currentFile->tokenAt(stringLiteral->literal_token).identifier->chars());
- const QByteArray newContents = stringToCharEscapeSequences(oldContents);
- QTC_ASSERT(!newContents.isEmpty(), return ;);
- if (oldContents != newContents)
- changes.replace(startPos + 1, endPos -1, QString::fromLatin1(newContents));
- }
-
- // Convert character constants into strings constants
- if (m_actions & ConvertEscapeSequencesToStringAction) {
- NumericLiteralAST *charLiteral = m_literal->asNumericLiteral(); // char 'c' constants are numerical.
- QTC_ASSERT(charLiteral, return ;);
- const QByteArray oldContents(currentFile->tokenAt(charLiteral->literal_token).identifier->chars());
- const QByteArray newContents = charToStringEscapeSequences(oldContents);
- QTC_ASSERT(!newContents.isEmpty(), return ;);
- if (oldContents != newContents)
- changes.replace(startPos + 1, endPos -1, QString::fromLatin1(newContents));
- }
-
- // Enclose in literal or translation function, macro.
- if (m_actions & (EncloseActionMask | TranslationMask)) {
- changes.insert(endPos, QString(QLatin1Char(')')));
- QString leading = WrapStringLiteral::replacement(m_actions);
- leading += QLatin1Char('(');
- if (m_actions & (TranslateQCoreApplicationAction | TranslateNoopAction)) {
- leading += QLatin1Char('"');
- leading += m_translationContext;
- leading += QLatin1String("\", ");
+ QString trContext;
+
+ QSharedPointer<Control> control = interface->context().control();
+ const Name *trName = control->identifier("tr");
+
+ // Check whether we are in a method:
+ const QString description = QApplication::translate("CppTools::QuickFix", "Mark as Translatable");
+ for (int i = path.size() - 1; i >= 0; --i) {
+ if (FunctionDefinitionAST *definition = path.at(i)->asFunctionDefinition()) {
+ Function *function = definition->symbol;
+ ClassOrNamespace *b = interface->context().lookupType(function);
+ if (b) {
+ // Do we have a tr method?
+ foreach (const LookupItem &r, b->find(trName)) {
+ Symbol *s = r.declaration();
+ if (s->type()->isFunctionType()) {
+ // no context required for tr
+ result.append(QuickFixOperation::Ptr(
+ new WrapStringLiteralOp(interface, path.size() - 1,
+ WrapStringLiteral::TranslateTrAction,
+ description, literal)));
+ return;
+ }
+ }
+ }
+ // We need to do a QCA::translate, so we need a context.
+ // Use fully qualified class name:
+ Overview oo;
+ foreach (const Name *n, LookupContext::path(function)) {
+ if (!trContext.isEmpty())
+ trContext.append(QLatin1String("::"));
+ trContext.append(oo.prettyName(n));
+ }
+ // ... or global if none available!
+ if (trContext.isEmpty())
+ trContext = QLatin1String("GLOBAL");
+ result.append(QuickFixOperation::Ptr(
+ new WrapStringLiteralOp(interface, path.size() - 1,
+ WrapStringLiteral::TranslateQCoreApplicationAction,
+ description, literal, trContext)));
+ return;
}
- changes.insert(startPos, leading);
}
- currentFile->setChangeSet(changes);
- currentFile->apply();
+ // We need to use Q_TRANSLATE_NOOP
+ result.append(QuickFixOperation::Ptr(
+ new WrapStringLiteralOp(interface, path.size() - 1,
+ WrapStringLiteral::TranslateNoopAction,
+ description, literal, trContext)));
}
-/*
- Replace
- "abcd"
- With
- tr("abcd") or
- QCoreApplication::translate("CONTEXT", "abcd") or
- QT_TRANSLATE_NOOP("GLOBAL", "abcd")
- depending on what is available.
-
- Activates on: the string literal
-*/
-class TranslateStringLiteral: public CppQuickFixFactory
+class ConvertCStringToNSStringOp: public CppQuickFixOperation
{
public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+ ConvertCStringToNSStringOp(const CppQuickFixInterface &interface, int priority,
+ StringLiteralAST *stringLiteral, CallAST *qlatin1Call)
+ : CppQuickFixOperation(interface, priority)
+ , stringLiteral(stringLiteral)
+ , qlatin1Call(qlatin1Call)
{
- // Initialize
- WrapStringLiteral::Type type = WrapStringLiteral::TypeNone;
- QByteArray enclosingFunction;
- const QList<AST *> &path = interface->path();
- CppRefactoringFilePtr file = interface->currentFile();
- ExpressionAST *literal = WrapStringLiteral::analyze(path, file, &type, &enclosingFunction);
- if (!literal || type != WrapStringLiteral::TypeString
- || isQtStringLiteral(enclosingFunction) || isQtStringTranslation(enclosingFunction))
- return;
-
- QString trContext;
-
- QSharedPointer<Control> control = interface->context().control();
- const Name *trName = control->identifier("tr");
-
- // Check whether we are in a method:
- const QString description = QApplication::translate("CppTools::QuickFix", "Mark as Translatable");
- for (int i = path.size() - 1; i >= 0; --i) {
- if (FunctionDefinitionAST *definition = path.at(i)->asFunctionDefinition()) {
- Function *function = definition->symbol;
- ClassOrNamespace *b = interface->context().lookupType(function);
- if (b) {
- // Do we have a tr method?
- foreach (const LookupItem &r, b->find(trName)) {
- Symbol *s = r.declaration();
- if (s->type()->isFunctionType()) {
- // no context required for tr
- result.append(QuickFixOperation::Ptr(new WrapStringLiteral::Operation(interface, path.size() - 1,
- WrapStringLiteral::TranslateTrAction,
- description, literal)));
- return;
- }
- }
- }
- // We need to do a QCA::translate, so we need a context.
- // Use fully qualified class name:
- Overview oo;
- foreach (const Name *n, LookupContext::path(function)) {
- if (!trContext.isEmpty())
- trContext.append(QLatin1String("::"));
- trContext.append(oo.prettyName(n));
- }
- // ... or global if none available!
- if (trContext.isEmpty())
- trContext = QLatin1String("GLOBAL");
- result.append(QuickFixOperation::Ptr(new WrapStringLiteral::Operation(interface, path.size() - 1,
- WrapStringLiteral::TranslateQCoreApplicationAction,
- description, literal, trContext)));
- return;
- }
- }
-
- // We need to use Q_TRANSLATE_NOOP
- result.append(QuickFixOperation::Ptr(new WrapStringLiteral::Operation(interface, path.size() - 1,
- WrapStringLiteral::TranslateNoopAction,
- description, literal, trContext)));
+ setDescription(QApplication::translate("CppTools::QuickFix",
+ "Convert to Objective-C String Literal"));
}
-};
-/**
- * Replace
- * "abcd"
- * QLatin1String("abcd")
- * QLatin1Literal("abcd")
- * With
- * @"abcd"
- *
- * Activates on: the string literal, if the file type is a Objective-C(++) file.
- */
-class CStringToNSString: public CppQuickFixFactory
-{
-public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+ void perform()
{
- CppRefactoringFilePtr file = interface->currentFile();
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
- if (interface->editor()->mimeType() != QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE))
- return;
+ ChangeSet changes;
- WrapStringLiteral::Type type = WrapStringLiteral::TypeNone;
- QByteArray enclosingFunction;
- CallAST *qlatin1Call;
- const QList<AST *> &path = interface->path();
- ExpressionAST *literal = WrapStringLiteral::analyze(path, file, &type, &enclosingFunction, &qlatin1Call);
- if (!literal || type != WrapStringLiteral::TypeString)
- return;
- if (!isQtStringLiteral(enclosingFunction))
- qlatin1Call = 0;
+ if (qlatin1Call) {
+ changes.replace(currentFile->startOf(qlatin1Call), currentFile->startOf(stringLiteral), QLatin1String("@"));
+ changes.remove(currentFile->endOf(stringLiteral), currentFile->endOf(qlatin1Call));
+ } else {
+ changes.insert(currentFile->startOf(stringLiteral), QLatin1String("@"));
+ }
- result.append(QuickFixOperation::Ptr(new Operation(interface, path.size() - 1, literal->asStringLiteral(), qlatin1Call)));
+ currentFile->setChangeSet(changes);
+ currentFile->apply();
}
private:
- class Operation: public CppQuickFixOperation
- {
- public:
- Operation(const CppQuickFixInterface &interface, int priority, StringLiteralAST *stringLiteral, CallAST *qlatin1Call)
- : CppQuickFixOperation(interface, priority)
- , stringLiteral(stringLiteral)
- , qlatin1Call(qlatin1Call)
- {
- setDescription(QApplication::translate("CppTools::QuickFix",
- "Convert to Objective-C String Literal"));
- }
-
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+ StringLiteralAST *stringLiteral;
+ CallAST *qlatin1Call;
+};
- ChangeSet changes;
+void ConvertCStringToNSString::match(const CppQuickFixInterface &interface,
+ QuickFixOperations &result)
+{
+ CppRefactoringFilePtr file = interface->currentFile();
- if (qlatin1Call) {
- changes.replace(currentFile->startOf(qlatin1Call), currentFile->startOf(stringLiteral), QLatin1String("@"));
- changes.remove(currentFile->endOf(stringLiteral), currentFile->endOf(qlatin1Call));
- } else {
- changes.insert(currentFile->startOf(stringLiteral), QLatin1String("@"));
- }
+ if (interface->editor()->mimeType() != QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE))
+ return;
- currentFile->setChangeSet(changes);
- currentFile->apply();
- }
+ WrapStringLiteral::Type type = WrapStringLiteral::TypeNone;
+ QByteArray enclosingFunction;
+ CallAST *qlatin1Call;
+ const QList<AST *> &path = interface->path();
+ ExpressionAST *literal = WrapStringLiteral::analyze(path, file, &type, &enclosingFunction, &qlatin1Call);
+ if (!literal || type != WrapStringLiteral::TypeString)
+ return;
+ if (!isQtStringLiteral(enclosingFunction))
+ qlatin1Call = 0;
- private:
- StringLiteralAST *stringLiteral;
- CallAST *qlatin1Call;
- };
-};
+ result.append(QuickFixOperation::Ptr(
+ new ConvertCStringToNSStringOp(interface, path.size() - 1, literal->asStringLiteral(),
+ qlatin1Call)));
+}
-/*
- Base class for converting numeric literals between decimal, octal and hex.
- Does the base check for the specific ones and parses the number.
- Test cases:
- 0xFA0Bu;
- 0X856A;
- 298.3;
- 199;
- 074;
- 199L;
- 074L;
- -199;
- -017;
- 0783; // invalid octal
- 0; // border case, allow only hex<->decimal
-
- Activates on: numeric literals
-*/
-class ConvertNumericLiteral: public CppQuickFixFactory
+class ConvertNumericLiteralOp: public CppQuickFixOperation
{
public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+ ConvertNumericLiteralOp(const CppQuickFixInterface &interface, int start, int end,
+ const QString &replacement)
+ : CppQuickFixOperation(interface)
+ , start(start)
+ , end(end)
+ , replacement(replacement)
+ {}
+
+ void perform()
{
- const QList<AST *> &path = interface->path();
- CppRefactoringFilePtr file = interface->currentFile();
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
- if (path.isEmpty())
- return;
+ ChangeSet changes;
+ changes.replace(start, end, replacement);
+ currentFile->setChangeSet(changes);
+ currentFile->apply();
+ }
- NumericLiteralAST *literal = path.last()->asNumericLiteral();
+private:
+ int start, end;
+ QString replacement;
+};
- if (! literal)
- return;
+void ConvertNumericLiteral::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+{
+ const QList<AST *> &path = interface->path();
+ CppRefactoringFilePtr file = interface->currentFile();
- Token token = file->tokenAt(literal->asNumericLiteral()->literal_token);
- if (!token.is(T_NUMERIC_LITERAL))
- return;
- const NumericLiteral *numeric = token.number;
- if (numeric->isDouble() || numeric->isFloat())
- return;
+ if (path.isEmpty())
+ return;
- // remove trailing L or U and stuff
- const char * const spell = numeric->chars();
- int numberLength = numeric->size();
- while (numberLength > 0 && !std::isxdigit(spell[numberLength - 1]))
- --numberLength;
- if (numberLength < 1)
- return;
+ NumericLiteralAST *literal = path.last()->asNumericLiteral();
- // convert to number
- bool valid;
- ulong value = QString::fromUtf8(spell).left(numberLength).toULong(&valid, 0);
- if (!valid) // e.g. octal with digit > 7
- return;
+ if (! literal)
+ return;
- const int priority = path.size() - 1; // very high priority
- const int start = file->startOf(literal);
- const char * const str = numeric->chars();
+ Token token = file->tokenAt(literal->asNumericLiteral()->literal_token);
+ if (!token.is(T_NUMERIC_LITERAL))
+ return;
+ const NumericLiteral *numeric = token.number;
+ if (numeric->isDouble() || numeric->isFloat())
+ return;
- if (!numeric->isHex()) {
+ // remove trailing L or U and stuff
+ const char * const spell = numeric->chars();
+ int numberLength = numeric->size();
+ while (numberLength > 0 && !std::isxdigit(spell[numberLength - 1]))
+ --numberLength;
+ if (numberLength < 1)
+ return;
+
+ // convert to number
+ bool valid;
+ ulong value = QString::fromUtf8(spell).left(numberLength).toULong(&valid, 0);
+ if (!valid) // e.g. octal with digit > 7
+ return;
+
+ const int priority = path.size() - 1; // very high priority
+ const int start = file->startOf(literal);
+ const char * const str = numeric->chars();
+
+ if (!numeric->isHex()) {
+ /*
+ Convert integer literal to hex representation.
+ Replace
+ 32
+ 040
+ With
+ 0x20
+
+ */
+ QString replacement;
+ replacement.sprintf("0x%lX", value);
+ QuickFixOperation::Ptr op(
+ new ConvertNumericLiteralOp(interface, start, start + numberLength, replacement));
+ op->setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Hexadecimal"));
+ op->setPriority(priority);
+ result.append(op);
+ }
+
+ if (value != 0) {
+ if (!(numberLength > 1 && str[0] == '0' && str[1] != 'x' && str[1] != 'X')) {
/*
- Convert integer literal to hex representation.
+ Convert integer literal to octal representation.
Replace
32
- 040
- With
0x20
-
+ With
+ 040
*/
QString replacement;
- replacement.sprintf("0x%lX", value);
- QuickFixOperation::Ptr op(new ConvertNumeric(interface, start, start + numberLength, replacement));
- op->setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Hexadecimal"));
+ replacement.sprintf("0%lo", value);
+ QuickFixOperation::Ptr op(
+ new ConvertNumericLiteralOp(interface, start, start + numberLength, replacement));
+ op->setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Octal"));
op->setPriority(priority);
result.append(op);
}
+ }
- if (value != 0) {
- if (!(numberLength > 1 && str[0] == '0' && str[1] != 'x' && str[1] != 'X')) {
- /*
- Convert integer literal to octal representation.
- Replace
- 32
- 0x20
- With
- 040
- */
- QString replacement;
- replacement.sprintf("0%lo", value);
- QuickFixOperation::Ptr op(new ConvertNumeric(interface, start, start + numberLength, replacement));
- op->setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Octal"));
- op->setPriority(priority);
- result.append(op);
- }
+ if (value != 0 || numeric->isHex()) {
+ if (!(numberLength > 1 && str[0] != '0')) {
+ /*
+ Convert integer literal to decimal representation.
+ Replace
+ 0x20
+ 040
+ With
+ 32
+ */
+ QString replacement;
+ replacement.sprintf("%lu", value);
+ QuickFixOperation::Ptr op(
+ new ConvertNumericLiteralOp(interface, start, start + numberLength, replacement));
+ op->setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Decimal"));
+ op->setPriority(priority);
+ result.append(op);
}
+ }
+}
- if (value != 0 || numeric->isHex()) {
- if (!(numberLength > 1 && str[0] != '0')) {
- /*
- Convert integer literal to decimal representation.
- Replace
- 0x20
- 040
- With
- 32
- */
- QString replacement;
- replacement.sprintf("%lu", value);
- QuickFixOperation::Ptr op(new ConvertNumeric(interface, start, start + numberLength, replacement));
- op->setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Decimal"));
- op->setPriority(priority);
- result.append(op);
- }
- }
+class AddIncludeForForwardDeclarationOp: public CppQuickFixOperation
+{
+public:
+ AddIncludeForForwardDeclarationOp(const CppQuickFixInterface &interface, int priority,
+ Symbol *fwdClass)
+ : CppQuickFixOperation(interface, priority)
+ , fwdClass(fwdClass)
+ {
+ setDescription(QApplication::translate("CppTools::QuickFix",
+ "#include Header File"));
}
-private:
- class ConvertNumeric: public CppQuickFixOperation
+ void perform()
{
- public:
- ConvertNumeric(const CppQuickFixInterface &interface,
- int start, int end, const QString &replacement)
- : CppQuickFixOperation(interface)
- , start(start)
- , end(end)
- , replacement(replacement)
- {}
-
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
-
- ChangeSet changes;
- changes.replace(start, end, replacement);
- currentFile->setChangeSet(changes);
- currentFile->apply();
- }
+ QTC_ASSERT(fwdClass != 0, return);
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+
+ CppTools::SymbolFinder symbolFinder;
+ if (Class *k = symbolFinder.findMatchingClassDeclaration(fwdClass, snapshot())) {
+ const QString headerFile = QString::fromUtf8(k->fileName(), k->fileNameLength());
+
+ // collect the fwd headers
+ Snapshot fwdHeaders;
+ fwdHeaders.insert(snapshot().document(headerFile));
+ foreach (Document::Ptr doc, snapshot()) {
+ QFileInfo headerFileInfo(doc->fileName());
+ if (doc->globalSymbolCount() == 0 && doc->includes().size() == 1)
+ fwdHeaders.insert(doc);
+ else if (headerFileInfo.suffix().isEmpty())
+ fwdHeaders.insert(doc);
+ }
- protected:
- int start, end;
- QString replacement;
- };
-};
+ DependencyTable dep;
+ dep.build(fwdHeaders);
+ QStringList candidates = dep.dependencyTable().value(headerFile);
+
+ const QString className = QString::fromUtf8(k->identifier()->chars());
+
+ QString best;
+ foreach (const QString &c, candidates) {
+ QFileInfo headerFileInfo(c);
+ if (headerFileInfo.fileName() == className) {
+ best = c;
+ break;
+ } else if (headerFileInfo.fileName().at(0).isUpper()) {
+ best = c;
+ // and continue
+ } else if (! best.isEmpty()) {
+ if (c.count(QLatin1Char('/')) < best.count(QLatin1Char('/')))
+ best = c;
+ }
+ }
-/*
- Can be triggered on a class forward declaration to add the matching #include.
+ if (best.isEmpty())
+ best = headerFile;
- Activates on: the name of a forward-declared class or struct
-*/
-class FixForwardDeclarationOp: public CppQuickFixFactory
-{
-public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
- {
- const QList<AST *> &path = interface->path();
+ int pos = currentFile->startOf(1);
- for (int index = path.size() - 1; index != -1; --index) {
- AST *ast = path.at(index);
- if (NamedTypeSpecifierAST *namedTy = ast->asNamedTypeSpecifier()) {
- if (Symbol *fwdClass = checkName(interface, namedTy->name)) {
- result.append(QuickFixOperation::Ptr(new Operation(interface, index, fwdClass)));
- return;
- }
- } else if (ElaboratedTypeSpecifierAST *eTy = ast->asElaboratedTypeSpecifier()) {
- if (Symbol *fwdClass = checkName(interface, eTy->name)) {
- result.append(QuickFixOperation::Ptr(new Operation(interface, index, fwdClass)));
- return;
- }
+ unsigned currentLine = currentFile->cursor().blockNumber() + 1;
+ unsigned bestLine = 0;
+ foreach (const Document::Include &incl, assistInterface()->semanticInfo().doc->includes()) {
+ if (incl.line() < currentLine)
+ bestLine = incl.line();
}
+
+ if (bestLine)
+ pos = currentFile->document()->findBlockByNumber(bestLine).position();
+
+ Utils::ChangeSet changes;
+ changes.insert(pos, QLatin1String("#include <")
+ + QFileInfo(best).fileName() + QLatin1String(">\n"));
+ currentFile->setChangeSet(changes);
+ currentFile->apply();
}
}
-protected:
static Symbol *checkName(const CppQuickFixInterface &interface, NameAST *ast)
{
if (ast && interface->isCursorOn(ast)) {
@@ -1547,634 +1405,495 @@ protected:
}
private:
- class Operation: public CppQuickFixOperation
- {
- public:
- Operation(const CppQuickFixInterface &interface, int priority, Symbol *fwdClass)
- : CppQuickFixOperation(interface, priority)
- , fwdClass(fwdClass)
- {
- setDescription(QApplication::translate("CppTools::QuickFix",
- "#include Header File"));
- }
-
- void perform()
- {
- QTC_ASSERT(fwdClass != 0, return);
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
-
- CppTools::SymbolFinder symbolFinder;
- if (Class *k = symbolFinder.findMatchingClassDeclaration(fwdClass, snapshot())) {
- const QString headerFile = QString::fromUtf8(k->fileName(), k->fileNameLength());
-
- // collect the fwd headers
- Snapshot fwdHeaders;
- fwdHeaders.insert(snapshot().document(headerFile));
- foreach (Document::Ptr doc, snapshot()) {
- QFileInfo headerFileInfo(doc->fileName());
- if (doc->globalSymbolCount() == 0 && doc->includes().size() == 1)
- fwdHeaders.insert(doc);
- else if (headerFileInfo.suffix().isEmpty())
- fwdHeaders.insert(doc);
- }
-
-
- DependencyTable dep;
- dep.build(fwdHeaders);
- QStringList candidates = dep.dependencyTable().value(headerFile);
-
- const QString className = QString::fromUtf8(k->identifier()->chars());
-
- QString best;
- foreach (const QString &c, candidates) {
- QFileInfo headerFileInfo(c);
- if (headerFileInfo.fileName() == className) {
- best = c;
- break;
- } else if (headerFileInfo.fileName().at(0).isUpper()) {
- best = c;
- // and continue
- } else if (! best.isEmpty()) {
- if (c.count(QLatin1Char('/')) < best.count(QLatin1Char('/')))
- best = c;
- }
- }
-
- if (best.isEmpty())
- best = headerFile;
+ Symbol *fwdClass;
+};
- int pos = currentFile->startOf(1);
+void AddIncludeForForwardDeclaration::match(const CppQuickFixInterface &interface,
+ QuickFixOperations &result)
+{
+ const QList<AST *> &path = interface->path();
- unsigned currentLine = currentFile->cursor().blockNumber() + 1;
- unsigned bestLine = 0;
- foreach (const Document::Include &incl, assistInterface()->semanticInfo().doc->includes()) {
- if (incl.line() < currentLine)
- bestLine = incl.line();
- }
+ for (int index = path.size() - 1; index != -1; --index) {
+ AST *ast = path.at(index);
+ if (NamedTypeSpecifierAST *namedTy = ast->asNamedTypeSpecifier()) {
+ if (Symbol *fwdClass = AddIncludeForForwardDeclarationOp::checkName(interface, namedTy->name)) {
+ result.append(QuickFixOperation::Ptr(
+ new AddIncludeForForwardDeclarationOp(interface, index, fwdClass)));
+ return;
+ }
+ } else if (ElaboratedTypeSpecifierAST *eTy = ast->asElaboratedTypeSpecifier()) {
+ if (Symbol *fwdClass = AddIncludeForForwardDeclarationOp::checkName(interface, eTy->name)) {
+ result.append(QuickFixOperation::Ptr(
+ new AddIncludeForForwardDeclarationOp(interface, index, fwdClass)));
+ return;
+ }
+ }
+ }
+}
- if (bestLine)
- pos = currentFile->document()->findBlockByNumber(bestLine).position();
+class AddLocalDeclarationOp: public CppQuickFixOperation
+{
+public:
+ AddLocalDeclarationOp(const CppQuickFixInterface &interface,
+ int priority,
+ const BinaryExpressionAST *binaryAST,
+ const SimpleNameAST *simpleNameAST)
+ : CppQuickFixOperation(interface, priority)
+ , binaryAST(binaryAST)
+ , simpleNameAST(simpleNameAST)
+ {
+ setDescription(QApplication::translate("CppTools::QuickFix", "Add Local Declaration"));
+ }
+ void perform()
+ {
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+
+ TypeOfExpression typeOfExpression;
+ typeOfExpression.init(assistInterface()->semanticInfo().doc,
+ snapshot(), assistInterface()->context().bindings());
+ Scope *scope = currentFile->scopeAt(binaryAST->firstToken());
+ const QList<LookupItem> result =
+ typeOfExpression(currentFile->textOf(binaryAST->right_expression).toUtf8(),
+ scope,
+ TypeOfExpression::Preprocess);
+
+ if (! result.isEmpty()) {
+ SubstitutionEnvironment env;
+ env.setContext(assistInterface()->context());
+ env.switchScope(result.first().scope());
+ ClassOrNamespace *con = typeOfExpression.context().lookupType(scope);
+ if (!con)
+ con = typeOfExpression.context().globalNamespace();
+ UseMinimalNames q(con);
+ env.enter(&q);
+
+ Control *control = assistInterface()->context().control().data();
+ FullySpecifiedType tn = rewriteType(result.first().type(), &env, control);
+
+ Overview oo = CppCodeStyleSettings::currentProjectCodeStyleOverview();
+ QString ty = oo.prettyType(tn, simpleNameAST->name);
+ if (! ty.isEmpty()) {
Utils::ChangeSet changes;
- changes.insert(pos, QLatin1String("#include <")
- + QFileInfo(best).fileName() + QLatin1String(">\n"));
+ changes.replace(currentFile->startOf(binaryAST),
+ currentFile->endOf(simpleNameAST),
+ ty);
currentFile->setChangeSet(changes);
currentFile->apply();
}
}
+ }
- private:
- Symbol *fwdClass;
- };
+private:
+ const BinaryExpressionAST *binaryAST;
+ const SimpleNameAST *simpleNameAST;
};
-/*
- Rewrites
- a = foo();
- As
- Type a = foo();
- Where Type is the return type of foo()
-
- Activates on: the assignee, if the type of the right-hand side of the assignment is known.
-*/
-class AddLocalDeclarationOp: public CppQuickFixFactory
+void AddLocalDeclaration::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{
-public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
- {
- const QList<AST *> &path = interface->path();
- CppRefactoringFilePtr file = interface->currentFile();
-
- for (int index = path.size() - 1; index != -1; --index) {
- if (BinaryExpressionAST *binary = path.at(index)->asBinaryExpression()) {
- if (binary->left_expression && binary->right_expression && file->tokenAt(binary->binary_op_token).is(T_EQUAL)) {
- IdExpressionAST *idExpr = binary->left_expression->asIdExpression();
- if (interface->isCursorOn(binary->left_expression) && idExpr && idExpr->name->asSimpleName() != 0) {
- SimpleNameAST *nameAST = idExpr->name->asSimpleName();
- const QList<LookupItem> results = interface->context().lookup(nameAST->name, file->scopeAt(nameAST->firstToken()));
- Declaration *decl = 0;
- foreach (const LookupItem &r, results) {
- if (! r.declaration())
- continue;
- else if (Declaration *d = r.declaration()->asDeclaration()) {
- if (! d->type()->isFunctionType()) {
- decl = d;
- break;
- }
+ const QList<AST *> &path = interface->path();
+ CppRefactoringFilePtr file = interface->currentFile();
+
+ for (int index = path.size() - 1; index != -1; --index) {
+ if (BinaryExpressionAST *binary = path.at(index)->asBinaryExpression()) {
+ if (binary->left_expression && binary->right_expression && file->tokenAt(binary->binary_op_token).is(T_EQUAL)) {
+ IdExpressionAST *idExpr = binary->left_expression->asIdExpression();
+ if (interface->isCursorOn(binary->left_expression) && idExpr && idExpr->name->asSimpleName() != 0) {
+ SimpleNameAST *nameAST = idExpr->name->asSimpleName();
+ const QList<LookupItem> results = interface->context().lookup(nameAST->name, file->scopeAt(nameAST->firstToken()));
+ Declaration *decl = 0;
+ foreach (const LookupItem &r, results) {
+ if (! r.declaration())
+ continue;
+ else if (Declaration *d = r.declaration()->asDeclaration()) {
+ if (! d->type()->isFunctionType()) {
+ decl = d;
+ break;
}
}
+ }
- if (! decl) {
- result.append(QuickFixOperation::Ptr(
- new Operation(interface, index, binary, nameAST)));
- return;
- }
+ if (! decl) {
+ result.append(QuickFixOperation::Ptr(
+ new AddLocalDeclarationOp(interface, index, binary, nameAST)));
+ return;
}
}
}
}
}
+}
-private:
- class Operation: public CppQuickFixOperation
+class ConvertToCamelCaseOp: public CppQuickFixOperation
+{
+public:
+ ConvertToCamelCaseOp(const CppQuickFixInterface &interface, int priority,
+ const QString &newName)
+ : CppQuickFixOperation(interface, priority)
+ , m_name(newName)
{
- public:
- Operation(const CppQuickFixInterface &interface,
- int priority,
- const BinaryExpressionAST *binaryAST,
- const SimpleNameAST *simpleNameAST)
- : CppQuickFixOperation(interface, priority)
- , binaryAST(binaryAST)
- , simpleNameAST(simpleNameAST)
- {
- setDescription(QApplication::translate("CppTools::QuickFix", "Add Local Declaration"));
- }
+ setDescription(QApplication::translate("CppTools::QuickFix",
+ "Convert to Camel Case"));
+ }
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
-
- TypeOfExpression typeOfExpression;
- typeOfExpression.init(assistInterface()->semanticInfo().doc,
- snapshot(), assistInterface()->context().bindings());
- Scope *scope = currentFile->scopeAt(binaryAST->firstToken());
- const QList<LookupItem> result =
- typeOfExpression(currentFile->textOf(binaryAST->right_expression).toUtf8(),
- scope,
- TypeOfExpression::Preprocess);
-
- if (! result.isEmpty()) {
- SubstitutionEnvironment env;
- env.setContext(assistInterface()->context());
- env.switchScope(result.first().scope());
- ClassOrNamespace *con = typeOfExpression.context().lookupType(scope);
- if (!con)
- con = typeOfExpression.context().globalNamespace();
- UseMinimalNames q(con);
- env.enter(&q);
-
- Control *control = assistInterface()->context().control().data();
- FullySpecifiedType tn = rewriteType(result.first().type(), &env, control);
-
- Overview oo = CppCodeStyleSettings::currentProjectCodeStyleOverview();
- QString ty = oo.prettyType(tn, simpleNameAST->name);
- if (! ty.isEmpty()) {
- Utils::ChangeSet changes;
- changes.replace(currentFile->startOf(binaryAST),
- currentFile->endOf(simpleNameAST),
- ty);
- currentFile->setChangeSet(changes);
- currentFile->apply();
- }
+ void perform()
+ {
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+
+ for (int i = 1; i < m_name.length(); ++i) {
+ QCharRef c = m_name[i];
+ if (c.isUpper()) {
+ c = c.toLower();
+ } else if (i < m_name.length() - 1
+ && isConvertibleUnderscore(m_name, i)) {
+ m_name.remove(i, 1);
+ m_name[i] = m_name.at(i).toUpper();
}
}
+ static_cast<CppEditor::Internal::CPPEditorWidget*>(assistInterface()->editor())->renameUsagesNow(m_name);
+ }
- private:
- const BinaryExpressionAST *binaryAST;
- const SimpleNameAST *simpleNameAST;
- };
+ static bool isConvertibleUnderscore(const QString &name, int pos)
+ {
+ return name.at(pos) == QLatin1Char('_') && name.at(pos+1).isLetter()
+ && !(pos == 1 && name.at(0) == QLatin1Char('m'));
+ }
+
+private:
+ QString m_name;
};
-/**
- * Turns "an_example_symbol" into "anExampleSymbol" and
- * "AN_EXAMPLE_SYMBOL" into "AnExampleSymbol".
- *
- * Activates on: identifiers
- */
-class ToCamelCaseConverter : public CppQuickFixFactory
+void ConvertToCamelCase::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{
-public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
- {
- const QList<AST *> &path = interface->path();
+ const QList<AST *> &path = interface->path();
- if (path.isEmpty())
- return;
+ if (path.isEmpty())
+ return;
- AST * const ast = path.last();
- const Name *name = 0;
- if (const NameAST * const nameAst = ast->asName()) {
- if (nameAst->name && nameAst->name->asNameId())
- name = nameAst->name;
- } else if (const NamespaceAST * const namespaceAst = ast->asNamespace()) {
- name = namespaceAst->symbol->name();
- }
+ AST * const ast = path.last();
+ const Name *name = 0;
+ if (const NameAST * const nameAst = ast->asName()) {
+ if (nameAst->name && nameAst->name->asNameId())
+ name = nameAst->name;
+ } else if (const NamespaceAST * const namespaceAst = ast->asNamespace()) {
+ name = namespaceAst->symbol->name();
+ }
- if (!name)
- return;
+ if (!name)
+ return;
- QString newName = QString::fromUtf8(name->identifier()->chars());
- if (newName.length() < 3)
+ QString newName = QString::fromUtf8(name->identifier()->chars());
+ if (newName.length() < 3)
+ return;
+ for (int i = 1; i < newName.length() - 1; ++i) {
+ if (ConvertToCamelCaseOp::isConvertibleUnderscore(newName, i)) {
+ result.append(QuickFixOperation::Ptr(
+ new ConvertToCamelCaseOp(interface, path.size() - 1, newName)));
return;
- for (int i = 1; i < newName.length() - 1; ++i) {
- if (Operation::isConvertibleUnderscore(newName, i)) {
- result.append(QuickFixOperation::Ptr(new Operation(interface, path.size() - 1, newName)));
- return;
- }
}
}
+}
-private:
- class Operation: public CppQuickFixOperation
+class AddIncludeForUndefinedIdentifierOp: public CppQuickFixOperation
+{
+public:
+ AddIncludeForUndefinedIdentifierOp(const CppQuickFixInterface &interface, int priority,
+ const QString &include)
+ : CppQuickFixOperation(interface, priority)
+ , m_include(include)
{
- public:
- Operation(const CppQuickFixInterface &interface, int priority, const QString &newName)
- : CppQuickFixOperation(interface, priority)
- , m_name(newName)
- {
- setDescription(QApplication::translate("CppTools::QuickFix",
- "Convert to Camel Case"));
- }
-
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
-
- for (int i = 1; i < m_name.length(); ++i) {
- QCharRef c = m_name[i];
- if (c.isUpper()) {
- c = c.toLower();
- } else if (i < m_name.length() - 1
- && isConvertibleUnderscore(m_name, i)) {
- m_name.remove(i, 1);
- m_name[i] = m_name.at(i).toUpper();
- }
- }
- static_cast<CppEditor::Internal::CPPEditorWidget*>(assistInterface()->editor())->renameUsagesNow(m_name);
- }
+ setDescription(QApplication::translate("CppTools::QuickFix",
+ "Add #include %1").arg(m_include));
+ }
- static bool isConvertibleUnderscore(const QString &name, int pos)
- {
- return name.at(pos) == QLatin1Char('_') && name.at(pos+1).isLetter()
- && !(pos == 1 && name.at(0) == QLatin1Char('m'));
- }
+ void perform()
+ {
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr file = refactoring.file(fileName());
+
+ // find location of last include in file
+ QList<Document::Include> includes = file->cppDocument()->includes();
+ unsigned lastIncludeLine = 0;
+ foreach (const Document::Include &include, includes) {
+ if (include.line() > lastIncludeLine)
+ lastIncludeLine = include.line();
+ }
+
+ // add include
+ const int insertPos = file->position(lastIncludeLine + 1, 1) - 1;
+ ChangeSet changes;
+ changes.insert(insertPos, QLatin1String("\n#include ") + m_include);
+ file->setChangeSet(changes);
+ file->apply();
+ }
- private:
- QString m_name;
- };
+private:
+ QString m_include;
};
-/**
- * Adds an include for an undefined identifier.
- */
-class IncludeAdder : public CppQuickFixFactory
+void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interface,
+ QuickFixOperations &result)
{
-public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
- {
- CppClassesFilter *classesFilter = ExtensionSystem::PluginManager::getObject<CppClassesFilter>();
- if (!classesFilter)
- return;
+ CppClassesFilter *classesFilter = ExtensionSystem::PluginManager::getObject<CppClassesFilter>();
+ if (!classesFilter)
+ return;
- const QList<AST *> &path = interface->path();
+ const QList<AST *> &path = interface->path();
- if (path.isEmpty())
- return;
+ if (path.isEmpty())
+ return;
- // find the largest enclosing Name
- const NameAST *enclosingName = 0;
- const SimpleNameAST *innermostName = 0;
- for (int i = path.size() - 1; i >= 0; --i) {
- if (NameAST *nameAst = path.at(i)->asName()) {
- enclosingName = nameAst;
- if (!innermostName) {
- innermostName = nameAst->asSimpleName();
- if (!innermostName)
- return;
- }
- } else {
- break;
+ // find the largest enclosing Name
+ const NameAST *enclosingName = 0;
+ const SimpleNameAST *innermostName = 0;
+ for (int i = path.size() - 1; i >= 0; --i) {
+ if (NameAST *nameAst = path.at(i)->asName()) {
+ enclosingName = nameAst;
+ if (!innermostName) {
+ innermostName = nameAst->asSimpleName();
+ if (!innermostName)
+ return;
}
+ } else {
+ break;
}
- if (!enclosingName || !enclosingName->name)
- return;
+ }
+ if (!enclosingName || !enclosingName->name)
+ return;
- // find the enclosing scope
- unsigned line, column;
- const Document::Ptr &doc = interface->semanticInfo().doc;
- doc->translationUnit()->getTokenStartPosition(enclosingName->firstToken(), &line, &column);
- Scope *scope = doc->scopeAt(line, column);
- if (!scope)
- return;
+ // find the enclosing scope
+ unsigned line, column;
+ const Document::Ptr &doc = interface->semanticInfo().doc;
+ doc->translationUnit()->getTokenStartPosition(enclosingName->firstToken(), &line, &column);
+ Scope *scope = doc->scopeAt(line, column);
+ if (!scope)
+ return;
- // check if the name resolves to something
- QList<LookupItem> existingResults = interface->context().lookup(enclosingName->name, scope);
- if (!existingResults.isEmpty())
- return;
+ // check if the name resolves to something
+ QList<LookupItem> existingResults = interface->context().lookup(enclosingName->name, scope);
+ if (!existingResults.isEmpty())
+ return;
- const QString &className = Overview().prettyName(innermostName->name);
- if (className.isEmpty())
- return;
+ const QString &className = Overview().prettyName(innermostName->name);
+ if (className.isEmpty())
+ return;
- // find the include paths
- QStringList includePaths;
- CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
- QList<CppModelManagerInterface::ProjectInfo> projectInfos = modelManager->projectInfos();
- bool inProject = false;
- foreach (const CppModelManagerInterface::ProjectInfo &info, projectInfos) {
- foreach (CppModelManagerInterface::ProjectPart::Ptr part, info.projectParts()) {
- if (part->sourceFiles.contains(doc->fileName()) || part->objcSourceFiles.contains(doc->fileName()) || part->headerFiles.contains(doc->fileName())) {
- inProject = true;
- includePaths += part->includePaths;
- }
+ // find the include paths
+ QStringList includePaths;
+ CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
+ QList<CppModelManagerInterface::ProjectInfo> projectInfos = modelManager->projectInfos();
+ bool inProject = false;
+ foreach (const CppModelManagerInterface::ProjectInfo &info, projectInfos) {
+ foreach (CppModelManagerInterface::ProjectPart::Ptr part, info.projectParts()) {
+ if (part->sourceFiles.contains(doc->fileName()) || part->objcSourceFiles.contains(doc->fileName()) || part->headerFiles.contains(doc->fileName())) {
+ inProject = true;
+ includePaths += part->includePaths;
}
}
- if (!inProject) {
- // better use all include paths than none
- foreach (const CppModelManagerInterface::ProjectInfo &info, projectInfos) {
- foreach (CppModelManagerInterface::ProjectPart::Ptr part, info.projectParts())
- includePaths += part->includePaths;
- }
+ }
+ if (!inProject) {
+ // better use all include paths than none
+ foreach (const CppModelManagerInterface::ProjectInfo &info, projectInfos) {
+ foreach (CppModelManagerInterface::ProjectPart::Ptr part, info.projectParts())
+ includePaths += part->includePaths;
}
+ }
- // find a include file through the locator
- QFutureInterface<Locator::FilterEntry> dummyInterface;
- QList<Locator::FilterEntry> matches = classesFilter->matchesFor(dummyInterface, className);
- bool classExists = false;
- foreach (const Locator::FilterEntry &entry, matches) {
- const ModelItemInfo info = entry.internalData.value<ModelItemInfo>();
- if (info.symbolName != className)
- continue;
- classExists = true;
- const QString &fileName = info.fileName;
- const QFileInfo fileInfo(fileName);
-
- // find the shortest way to include fileName given the includePaths
- QString shortestInclude;
-
- if (fileInfo.path() == QFileInfo(doc->fileName()).path()) {
- shortestInclude = QLatin1Char('"') + fileInfo.fileName() + QLatin1Char('"');
- } else {
- foreach (const QString &includePath, includePaths) {
- if (!fileName.startsWith(includePath))
- continue;
- QString relativePath = fileName.mid(includePath.size());
- if (!relativePath.isEmpty() && relativePath.at(0) == QLatin1Char('/'))
- relativePath = relativePath.mid(1);
- if (shortestInclude.isEmpty() || relativePath.size() + 2 < shortestInclude.size())
- shortestInclude = QLatin1Char('<') + relativePath + QLatin1Char('>');
- }
+ // find a include file through the locator
+ QFutureInterface<Locator::FilterEntry> dummyInterface;
+ QList<Locator::FilterEntry> matches = classesFilter->matchesFor(dummyInterface, className);
+ bool classExists = false;
+ foreach (const Locator::FilterEntry &entry, matches) {
+ const ModelItemInfo info = entry.internalData.value<ModelItemInfo>();
+ if (info.symbolName != className)
+ continue;
+ classExists = true;
+ const QString &fileName = info.fileName;
+ const QFileInfo fileInfo(fileName);
+
+ // find the shortest way to include fileName given the includePaths
+ QString shortestInclude;
+
+ if (fileInfo.path() == QFileInfo(doc->fileName()).path()) {
+ shortestInclude = QLatin1Char('"') + fileInfo.fileName() + QLatin1Char('"');
+ } else {
+ foreach (const QString &includePath, includePaths) {
+ if (!fileName.startsWith(includePath))
+ continue;
+ QString relativePath = fileName.mid(includePath.size());
+ if (!relativePath.isEmpty() && relativePath.at(0) == QLatin1Char('/'))
+ relativePath = relativePath.mid(1);
+ if (shortestInclude.isEmpty() || relativePath.size() + 2 < shortestInclude.size())
+ shortestInclude = QLatin1Char('<') + relativePath + QLatin1Char('>');
}
-
- if (!shortestInclude.isEmpty())
- result += CppQuickFixOperation::Ptr(new Operation(interface, 0, shortestInclude));
}
- // for QSomething, propose a <QSomething> include -- if such a class was in the locator
- if (classExists
- && className.size() > 2
- && className.at(0) == QLatin1Char('Q')
- && className.at(1).isUpper()) {
- const QString include = QLatin1Char('<') + className + QLatin1Char('>');
- result += CppQuickFixOperation::Ptr(new Operation(interface, 1, include));
+ if (!shortestInclude.isEmpty()) {
+ result += CppQuickFixOperation::Ptr(
+ new AddIncludeForUndefinedIdentifierOp(interface, 0, shortestInclude));
}
}
-private:
- class Operation: public CppQuickFixOperation
- {
- public:
- Operation(const CppQuickFixInterface &interface, int priority, const QString &include)
- : CppQuickFixOperation(interface, priority)
- , m_include(include)
- {
- setDescription(QApplication::translate("CppTools::QuickFix",
- "Add #include %1").arg(m_include));
- }
-
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr file = refactoring.file(fileName());
-
- // find location of last include in file
- QList<Document::Include> includes = file->cppDocument()->includes();
- unsigned lastIncludeLine = 0;
- foreach (const Document::Include &include, includes) {
- if (include.line() > lastIncludeLine)
- lastIncludeLine = include.line();
- }
-
- // add include
- const int insertPos = file->position(lastIncludeLine + 1, 1) - 1;
- ChangeSet changes;
- changes.insert(insertPos, QLatin1String("\n#include ") + m_include);
- file->setChangeSet(changes);
- file->apply();
- }
-
- private:
- QString m_include;
- };
-};
-
-/**
- * Switches places of the parameter declaration under cursor
- * with the next or the previous one in the parameter declaration list
- *
- * Activates on: parameter declarations
- */
+ // for QSomething, propose a <QSomething> include -- if such a class was in the locator
+ if (classExists
+ && className.size() > 2
+ && className.at(0) == QLatin1Char('Q')
+ && className.at(1).isUpper()) {
+ const QString include = QLatin1Char('<') + className + QLatin1Char('>');
+ result += CppQuickFixOperation::Ptr(
+ new AddIncludeForUndefinedIdentifierOp(interface, 1, include));
+ }
+}
-class RearrangeParamDeclList : public CppQuickFixFactory
+class RearrangeParamDeclarationListOp: public CppQuickFixOperation
{
public:
- enum Target
- {
- TargetPrevious,
- TargetNext
- };
+ enum Target { TargetPrevious, TargetNext };
-public:
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+ RearrangeParamDeclarationListOp(const CppQuickFixInterface &interface, AST *currentParam,
+ AST *targetParam, Target target)
+ : CppQuickFixOperation(interface)
+ , m_currentParam(currentParam)
+ , m_targetParam(targetParam)
{
- const QList<AST *> path = interface->path();
-
- ParameterDeclarationAST *paramDecl = 0;
- int index = path.size() - 1;
- for (; index != -1; --index) {
- paramDecl = path.at(index)->asParameterDeclaration();
- if (paramDecl)
- break;
- }
-
- if (index < 1)
- return;
+ QString targetString;
+ if (target == TargetPrevious)
+ targetString = QApplication::translate("CppTools::QuickFix",
+ "Switch with Previous Parameter");
+ else
+ targetString = QApplication::translate("CppTools::QuickFix",
+ "Switch with Next Parameter");
+ setDescription(targetString);
+ }
- ParameterDeclarationClauseAST *paramDeclClause = path.at(index-1)->asParameterDeclarationClause();
- QTC_ASSERT(paramDeclClause && paramDeclClause->parameter_declaration_list, return);
+ void perform()
+ {
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+
+ int targetEndPos = currentFile->endOf(m_targetParam);
+ ChangeSet changes;
+ changes.flip(currentFile->startOf(m_currentParam), currentFile->endOf(m_currentParam),
+ currentFile->startOf(m_targetParam), targetEndPos);
+ currentFile->setChangeSet(changes);
+ currentFile->setOpenEditor(false, targetEndPos);
+ currentFile->apply();
+ }
- ParameterDeclarationListAST *paramListNode = paramDeclClause->parameter_declaration_list;
- ParameterDeclarationListAST *prevParamListNode = 0;
- while (paramListNode) {
- if (paramDecl == paramListNode->value)
- break;
- prevParamListNode = paramListNode;
- paramListNode = paramListNode->next;
- }
+private:
+ AST *m_currentParam;
+ AST *m_targetParam;
+};
- if (!paramListNode)
- return;
+void RearrangeParamDeclarationList::match(const CppQuickFixInterface &interface,
+ QuickFixOperations &result)
+{
+ const QList<AST *> path = interface->path();
- if (prevParamListNode)
- result.append(CppQuickFixOperation::Ptr(new Operation(interface, paramListNode->value,
- prevParamListNode->value, TargetPrevious)));
- if (paramListNode->next)
- result.append(CppQuickFixOperation::Ptr(new Operation(interface, paramListNode->value,
- paramListNode->next->value, TargetNext)));
+ ParameterDeclarationAST *paramDecl = 0;
+ int index = path.size() - 1;
+ for (; index != -1; --index) {
+ paramDecl = path.at(index)->asParameterDeclaration();
+ if (paramDecl)
+ break;
}
-private:
- class Operation: public CppQuickFixOperation
- {
- public:
- Operation(const CppQuickFixInterface &interface,
- AST *currentParam, AST *targetParam,
- Target target)
- : CppQuickFixOperation(interface)
- , m_currentParam(currentParam)
- , m_targetParam(targetParam)
- {
- QString targetString;
- if (target == TargetPrevious)
- targetString = QApplication::translate("CppTools::QuickFix",
- "Switch with Previous Parameter");
- else
- targetString = QApplication::translate("CppTools::QuickFix",
- "Switch with Next Parameter");
- setDescription(targetString);
- }
+ if (index < 1)
+ return;
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+ ParameterDeclarationClauseAST *paramDeclClause = path.at(index-1)->asParameterDeclarationClause();
+ QTC_ASSERT(paramDeclClause && paramDeclClause->parameter_declaration_list, return);
- int targetEndPos = currentFile->endOf(m_targetParam);
- ChangeSet changes;
- changes.flip(currentFile->startOf(m_currentParam), currentFile->endOf(m_currentParam),
- currentFile->startOf(m_targetParam), targetEndPos);
- currentFile->setChangeSet(changes);
- currentFile->setOpenEditor(false, targetEndPos);
- currentFile->apply();
- }
+ ParameterDeclarationListAST *paramListNode = paramDeclClause->parameter_declaration_list;
+ ParameterDeclarationListAST *prevParamListNode = 0;
+ while (paramListNode) {
+ if (paramDecl == paramListNode->value)
+ break;
+ prevParamListNode = paramListNode;
+ paramListNode = paramListNode->next;
+ }
- private:
- AST *m_currentParam;
- AST *m_targetParam;
- };
-};
+ if (!paramListNode)
+ return;
-/**
- * Reformats a pointer, reference or rvalue reference type/declaration.
- *
- * Works also with selections (except when the cursor is not on any AST).
- *
- * Activates on: simple declarations, parameters and return types of function
- * declarations and definitions, control flow statements (if,
- * while, for, foreach) with declarations.
- */
-class PointerDeclarationFormatterOp : public CppQuickFixFactory
+ if (prevParamListNode)
+ result.append(CppQuickFixOperation::Ptr(
+ new RearrangeParamDeclarationListOp(interface, paramListNode->value,
+ prevParamListNode->value, RearrangeParamDeclarationListOp::TargetPrevious)));
+ if (paramListNode->next)
+ result.append(CppQuickFixOperation::Ptr(
+ new RearrangeParamDeclarationListOp(interface, paramListNode->value,
+ paramListNode->next->value, RearrangeParamDeclarationListOp::TargetNext)));
+}
+
+class ReformatPointerDeclarationOp: public CppQuickFixOperation
{
public:
- typedef Utils::ChangeSet ChangeSet;
-
- void match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+ ReformatPointerDeclarationOp(const CppQuickFixInterface &interface,
+ const Utils::ChangeSet change)
+ : CppQuickFixOperation(interface)
+ , m_change(change)
{
- const QList<AST *> &path = interface->path();
- CppRefactoringFilePtr file = interface->currentFile();
-
- Overview overview = CppCodeStyleSettings::currentProjectCodeStyleOverview();
- overview.showArgumentNames = true;
- overview.showReturnTypes = true;
-
- const QTextCursor cursor = file->cursor();
- ChangeSet change;
- PointerDeclarationFormatter formatter(file, overview,
- PointerDeclarationFormatter::RespectCursor);
-
- if (cursor.hasSelection()) {
- // This will no work always as expected since this method is only called if
- // interface-path() is not empty. If the user selects the whole document via
- // ctrl-a and there is an empty line in the end, then the cursor is not on
- // any AST and therefore no quick fix will be triggered.
- change = formatter.format(file->cppDocument()->translationUnit()->ast());
- if (! change.isEmpty())
- result.append(QuickFixOperation::Ptr(new Operation(interface, change)));
- } else {
- for (int index = path.size() - 1; index >= 0; --index) {
- AST *ast = path.at(index);
-
- change = formatter.format(ast);
- if (! change.isEmpty()) {
- result.append(QuickFixOperation::Ptr(new Operation(interface, change)));
- return;
- }
- }
- }
+ QString description;
+ if (m_change.operationList().size() == 1) {
+ description = QApplication::translate("CppTools::QuickFix",
+ "Reformat to \"%1\"").arg(m_change.operationList().first().text);
+ } else { // > 1
+ description = QApplication::translate("CppTools::QuickFix",
+ "Reformat Pointers or References");
+ }
+ setDescription(description);
}
-private:
- class Operation: public CppQuickFixOperation
+ void perform()
{
- public:
- Operation(const CppQuickFixInterface &interface, const ChangeSet change)
- : CppQuickFixOperation(interface)
- , m_change(change)
- {
- QString description;
- if (m_change.operationList().size() == 1) {
- description = QApplication::translate("CppTools::QuickFix",
- "Reformat to \"%1\"").arg(m_change.operationList().first().text);
- } else { // > 1
- description = QApplication::translate("CppTools::QuickFix",
- "Reformat Pointers or References");
- }
- setDescription(description);
- }
-
- void perform()
- {
- CppRefactoringChanges refactoring(snapshot());
- CppRefactoringFilePtr currentFile = refactoring.file(fileName());
- currentFile->setChangeSet(m_change);
- currentFile->apply();
- }
+ CppRefactoringChanges refactoring(snapshot());
+ CppRefactoringFilePtr currentFile = refactoring.file(fileName());
+ currentFile->setChangeSet(m_change);
+ currentFile->apply();
+ }
- private:
- ChangeSet m_change;
- };
+private:
+ Utils::ChangeSet m_change;
};
-} // end of anonymous namespace
-
-void registerQuickFixes(ExtensionSystem::IPlugin *plugIn)
+void ReformatPointerDeclaration::match(const CppQuickFixInterface &interface,
+ QuickFixOperations &result)
{
- plugIn->addAutoReleasedObject(new UseInverseOp);
- plugIn->addAutoReleasedObject(new FlipBinaryOp);
- plugIn->addAutoReleasedObject(new RewriteLogicalAndOp);
- plugIn->addAutoReleasedObject(new SplitSimpleDeclarationOp);
- plugIn->addAutoReleasedObject(new AddBracesToIfOp);
- plugIn->addAutoReleasedObject(new MoveDeclarationOutOfIfOp);
- plugIn->addAutoReleasedObject(new MoveDeclarationOutOfWhileOp);
- plugIn->addAutoReleasedObject(new SplitIfStatementOp);
- plugIn->addAutoReleasedObject(new WrapStringLiteral);
- plugIn->addAutoReleasedObject(new TranslateStringLiteral);
- plugIn->addAutoReleasedObject(new CStringToNSString);
- plugIn->addAutoReleasedObject(new ConvertNumericLiteral);
- plugIn->addAutoReleasedObject(new CompleteSwitchCaseStatement);
- plugIn->addAutoReleasedObject(new FixForwardDeclarationOp);
- plugIn->addAutoReleasedObject(new AddLocalDeclarationOp);
- plugIn->addAutoReleasedObject(new ToCamelCaseConverter);
- plugIn->addAutoReleasedObject(new InsertQtPropertyMembers);
- plugIn->addAutoReleasedObject(new DeclFromDef);
- plugIn->addAutoReleasedObject(new DefFromDecl);
- plugIn->addAutoReleasedObject(new ApplyDeclDefLinkChanges);
- plugIn->addAutoReleasedObject(new IncludeAdder);
- plugIn->addAutoReleasedObject(new ExtractFunction);
- plugIn->addAutoReleasedObject(new GetterSetter);
- plugIn->addAutoReleasedObject(new RearrangeParamDeclList);
- plugIn->addAutoReleasedObject(new PointerDeclarationFormatterOp);
+ const QList<AST *> &path = interface->path();
+ CppRefactoringFilePtr file = interface->currentFile();
+
+ Overview overview = CppCodeStyleSettings::currentProjectCodeStyleOverview();
+ overview.showArgumentNames = true;
+ overview.showReturnTypes = true;
+
+ const QTextCursor cursor = file->cursor();
+ Utils::ChangeSet change;
+ PointerDeclarationFormatter formatter(file, overview,
+ PointerDeclarationFormatter::RespectCursor);
+
+ if (cursor.hasSelection()) {
+ // This will no work always as expected since this method is only called if
+ // interface-path() is not empty. If the user selects the whole document via
+ // ctrl-a and there is an empty line in the end, then the cursor is not on
+ // any AST and therefore no quick fix will be triggered.
+ change = formatter.format(file->cppDocument()->translationUnit()->ast());
+ if (! change.isEmpty()) {
+ result.append(QuickFixOperation::Ptr(
+ new ReformatPointerDeclarationOp(interface, change)));
+ }
+ } else {
+ for (int index = path.size() - 1; index >= 0; --index) {
+ AST *ast = path.at(index);
+
+ change = formatter.format(ast);
+ if (! change.isEmpty()) {
+ result.append(QuickFixOperation::Ptr(
+ new ReformatPointerDeclarationOp(interface, change)));
+ return;
+ }
+ }
+ }
}
diff --git a/src/plugins/cppeditor/cppquickfixes.h b/src/plugins/cppeditor/cppquickfixes.h
new file mode 100644
index 0000000000..967f8a83bf
--- /dev/null
+++ b/src/plugins/cppeditor/cppquickfixes.h
@@ -0,0 +1,393 @@
+/****************************************************************************
+**
+** 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:
+ void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
+};
+
+/*!
+ Base class for converting numeric literals between decimal, octal and hex.
+ Does the base check for the specific ones and parses the number.
+
+ Test cases:
+ 0xFA0Bu;
+ 0X856A;
+ 298.3;
+ 199;
+ 074;
+ 199L;
+ 074L;
+ -199;
+ -017;
+ 0783; // invalid octal
+ 0; // border case, allow only hex<->decimal
+
+ Activates on: numeric literals
+*/
+class ConvertNumericLiteral: public CppQuickFixFactory
+{
+public:
+ void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
+};
+
+/*!
+ Replace
+ "abcd"
+
+ With
+ tr("abcd") or
+ QCoreApplication::translate("CONTEXT", "abcd") or
+ QT_TRANSLATE_NOOP("GLOBAL", "abcd")
+
+ depending on what is available.
+
+ Activates on: the string literal
+*/
+class TranslateStringLiteral: public CppQuickFixFactory
+{
+public:
+ void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
+};
+
+/*!
+ Replace
+ "abcd" -> QLatin1String("abcd")
+ @"abcd" -> QLatin1String("abcd") (Objective C)
+ 'a' -> QLatin1Char('a')
+ 'a' -> "a"
+ "a" -> 'a' or QLatin1Char('a') (Single character string constants)
+ "\n" -> '\n', QLatin1Char('\n')
+
+ Except if they are already enclosed in
+ QLatin1Char, QT_TRANSLATE_NOOP, tr,
+ trUtf8, QLatin1Literal, QLatin1String
+
+ Activates on: the string or character literal
+*/
+
+class WrapStringLiteral: public CppQuickFixFactory
+{
+public:
+ enum ActionFlags {
+ EncloseInQLatin1CharAction = 0x1,
+ EncloseInQLatin1StringAction = 0x2,
+ EncloseInQStringLiteralAction = 0x4,
+ EncloseActionMask = EncloseInQLatin1CharAction
+ | EncloseInQLatin1StringAction | EncloseInQStringLiteralAction,
+ TranslateTrAction = 0x8,
+ TranslateQCoreApplicationAction = 0x10,
+ TranslateNoopAction = 0x20,
+ TranslationMask = TranslateTrAction
+ | TranslateQCoreApplicationAction | TranslateNoopAction,
+ RemoveObjectiveCAction = 0x40,
+ ConvertEscapeSequencesToCharAction = 0x100,
+ ConvertEscapeSequencesToStringAction = 0x200,
+ SingleQuoteAction = 0x400,
+ DoubleQuoteAction = 0x800
+ };
+
+ enum Type { TypeString, TypeObjCString, TypeChar, TypeNone };
+
+ void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
+
+ static QString replacement(unsigned actions);
+ static QByteArray stringToCharEscapeSequences(const QByteArray &content);
+ static QByteArray charToStringEscapeSequences(const QByteArray &content);
+
+ static ExpressionAST *analyze(const QList<AST *> &path, const CppRefactoringFilePtr &file,
+ Type *type,
+ QByteArray *enclosingFunction = 0,
+ CallAST **enclosingFunctionCall = 0);
+};
+
+/*!
+ Turns "an_example_symbol" into "anExampleSymbol" and
+ "AN_EXAMPLE_SYMBOL" into "AnExampleSymbol".
+
+ Activates on: identifiers
+*/
+class ConvertToCamelCase : public CppQuickFixFactory
+{
+public:
+ void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
+};
+
+/*!
+ Replace
+ if (Type name = foo()) {...}
+
+ With
+ Type name = foo;
+ if (name) {...}
+
+ Activates on: the name of the introduced variable
+*/
+class MoveDeclarationOutOfIf: public CppQuickFixFactory
+{
+public:
+ void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
+};
+
+/*!
+ Replace
+ while (Type name = foo()) {...}
+
+ With
+ Type name;
+ while ((name = foo()) != 0) {...}
+
+ Activates on: the name of the introduced variable
+*/
+class MoveDeclarationOutOfWhile: public CppQuickFixFactory
+{
+public:
+ void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
+};
+
+/*!
+ Replace
+ if (something && something_else) {
+ }
+
+ with
+ if (something)
+ if (something_else)
+ }
+
+ and
+ if (something || something_else)
+ x;
+
+ with
+ if (something)
+ x;
+ else if (something_else)
+ x;
+
+ Activates on: && or ||
+*/
+class SplitIfStatement: public CppQuickFixFactory
+{
+public:
+ void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
+};
+
+/*!
+ Rewrite
+ int *a, b;
+
+ As
+ int *a;
+ int b;
+
+ Activates on: the type or the variable names.
+*/
+class SplitSimpleDeclaration: public CppQuickFixFactory
+{
+public:
+ void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
+
+private:
+ static bool checkDeclaration(SimpleDeclarationAST *declaration);
+};
+
+/*!
+ Rewrites
+ a = foo();
+
+ As
+ Type a = foo();
+
+ Where Type is the return type of foo()
+
+ Activates on: the assignee, if the type of the right-hand side of the assignment is known.
+*/
+class AddLocalDeclaration: public CppQuickFixFactory
+{
+public:
+ void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
+};
+
+/*!
+ Add curly braces to a if statement that doesn't already contain a
+ compound statement. I.e.
+
+ if (a)
+ b;
+ becomes
+ if (a)
+ b;
+
+ Activates on: the if
+*/
+class AddBracesToIf: public CppQuickFixFactory
+{
+public:
+ void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
+};
+
+/*!
+ Switches places of the parameter declaration under cursor
+ with the next or the previous one in the parameter declaration list
+
+ Activates on: parameter declarations
+*/
+class RearrangeParamDeclarationList : public CppQuickFixFactory
+{
+public:
+ void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
+};
+
+/*!
+ Reformats a pointer, reference or rvalue reference type/declaration.
+
+ Works also with selections (except when the cursor is not on any AST).
+
+ Activates on: simple declarations, parameters and return types of function
+ declarations and definitions, control flow statements (if,
+ while, for, foreach) with declarations.
+*/
+class ReformatPointerDeclaration : public CppQuickFixFactory
+{
+public:
+ void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
+};
+
+} // namespace Internal
+} // namespace CppEditor
+
+#endif // CPPQUICKFIXES_H